Search code examples
csdl-2autotools

Make Autotools project with SDL2


I am spinning up a new project. I want to use autotools for my build system, and the project will link to SDL2. However, I'm stuck writing the configure.ac file.

The documented way to link to SDL2 when it is installed on the system uses an installed command that outputs linker flags:

gcc -o myprogram myprogram.c `sdl2-config --cflags --libs`

I find it reasonable to assume that the output of sdl2-config may change depending on the system, and that it should be run in configure, then passed to make (this may be wrong!). I'm having a dog of a time trying to set this up, though. Maybe it's because my knowledge of M4sh is very limited, but I can't figure out how to do command substitution on the target computer.

How do I properly integrate linking SDL2 and autotools into a project, and why is it done that way so I can apply those principles to future libraries I have this issue with?


Solution

  • I agree with @Orion's answer that using PKG_CHECK_MODULES is the way to do this. I have a few remarks to add.

    • As PKG_CHECK_MODULES already does AC_SUBST its variables, you do not need any extra lines which AC_SUBST the variables defined by PKG_CHECK_MODULES.

    • Do add a check that the PKG_CHECK_MODULES macro is actually available (m4_pattern_forbid([^PKG_CHECK_MODULES])dnl) so that if it is not, autoreconf will fail immediately with a useful error message instead of generating a broken configure script which will 100% abort with a less helpful error message but only later. This advise applies to any macro which is not part of Automake and Autoconf (AM_, AC_, AS_, m4_).

    • If SDL2 is actually required for your project, you do not need to deal with the conditional arguments to PKG_CHECK_MODULES at all: PKG_CHECK_MODULES will abort the configure script if SDL2 is not found and there are no conditional arguments.

      The only reason to deal with the conditonal arguments to PKG_CHECK_MODULES for a SDL required project is to print additional information in case SDL is not found. You are not doing that, so you can get rid of the conditional arguments.

    This simplifies the configure.ac snippet to:

    m4_pattern_forbid([^PKG_CHECK_MODULES])dnl
    PKG_CHECK_MODULES([SDL2], [sdl2 >= 2.0.22])
    

    About the Makefile.am snippet:

    • It is a bit inconsistent to add the sdl2 cflags to all compilation units (AM_CPPFLAGS), but the library only to one program target (hello_LDADD). I would suggest explicit per compile target definitions: hello_CPPFLAGS and hello_LDADD.

      bin_PROGRAMS = hello
      hello_SOURCES = src/main.c
      hello_CPPFLAGS = @SDL2_CFLAGS@
      hello_LDADD = @SDL2_LIBS@
      
    • If your project ends up using multiple libraries in addition to SDL2, the readability starts decreasing as it becomes less obvious that both the cflags and the libs are added for all libraries:

      bin_PROGRAMS = hello
      hello_SOURCES = src/main.c
      hello_CPPFLAGS = @SDL2_CFLAGS@ @LIBUSB_CFLAGS@ @ZLIB_CFLAGS@ @OPENSSL_CFLAGS@
      hello_LDADD = @SDL2_LIBS@ @LIBUSB_CFLAGS@ @ZLIB_LIBS@ @OPENSSL_LIBS@
      

      and I find grouping the library specific things together helps with that

      bin_PROGRAMS = hello
      hello_SOURCES = src/main.c
      hello_CPPFLAGS =
      hello_LDADD =
      
      hello_CPPFLAGS += @SDL2_CFLAGS@
      hello_LDADD    += @SDL2_LIBS@
      
      hello_CPPFLAGS += @LIBUSB_CFLAGS@
      hello_LDADD    += @LIBUSB_CFLAGS@  # oh wait, that should have been _LIBS!
      
      hello_CPPFLAGS += @ZLIB_CFLAGS@
      hello_LDADD    += @ZLIB_LIBS@
      
      hello_CPPFLAGS += @OPENSSL_CFLAGS@
      hello_LDADD    += @OPENSSL_LIBS@