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?
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@