Let's assume the following project structure composed of one executable in src and two libraries, lib1 and its dependency lib1_dep:
+--src/
| |
| +--Makefile.am
| +--main.c
|
+--lib/
| |
| +--Makefile.am
| +--library1.c
| +--library1.h
+--lib_dep/
| |
| +--Makefile.am
| +--library1_dep.c
| +--library1_dep.h
+--Makefile.am
+--configure.ac
The contents of the files are
configure.ac
# Add libraries dependance
AC_CONFIG_SUBDIRS([lib_dep])
AC_CONFIG_SUBDIRS([lib])
# Add src files
AC_CONFIG_FILES([Makefile
lib_dep/Makefile
lib/Makefile
src/Makefile
])
Makefile.am
SUBDIRS = lib_dep lib src
lib1_dep/Makefile.am
lib_LTLIBRARIES = lib_libdep.la
# Dynamic library
lib_libdep_la_SOURCES = library1_dep.c library1_dep.h
lib_libdep_la_LIBADD =
# Compiler options.
lib_libdep_la_CPPFLAGS = $(AM_CPPFLAGS)
lib1/Makefile.am
lib_LTLIBRARIES = lib_lib.la
# Dynamic library
lib_lib_la_SOURCES = library1.c library1.h
lib_lib_la_LIBADD = $(top_builddir)/lib_dep/lib_libdep.la
# Compiler options.
lib_lib_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/lib_dep/lib_dep.h
src/Makefile.am
bin_PROGRAMS = main
main_SOURCES = main.c
main_LDADD = $(AM_LDADD) $(top_builddir)/lib/lib_lib.la $(top_builddir)/lib_dep/lib_libdep.la
# Compiler options.
main_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/lib_dep/lib_dep.h -I$(top_srcdir)/lib/lib_lib.h
Observation
The build and install work well but I doubt I do it properly. The main program only uses functions defined in lib (not in lib_dep), so it looks strange that I have to also diretly link the main program to lib_dep. I would like your feedbacks on this please.
Question
Is there a way to build/compile lib so that I don't have to add the LDAPP and CPPFLAGS related to lib_dep when I build y main program (src/Makefile.am) ?
Thanks
The build and install work well but I doubt I do it properly. The main program only uses functions defined in lib (not in lib_dep), so it looks strange that I have to also diretly link the main program to lib_dep. I would like your feedbacks on this please.
It is system-dependent whether indirect shared-library dependencies need to be included in the link. On Linux, they do. Compare to the situation with static library dependencies, which absolutely need to be included in the final link, on any system.
However, since you are using libtool
, in a context where you can rely on its generated .la files to be available, you shouldn't need to provide explicitly for linking indirect dependencies. Libtool can handle that for you.
Is there a way to build/compile lib so that I don't have to add the LDAPP and CPPFLAGS related to lib_dep when I build y main program (src/Makefile.am) ?
That's actually two separate questions, one for LDADD
and one for CPPFLAGS
.
The CPPFLAGS
are relevant only for compilation, not linking. Roughly speaking, if the main program's sources #include
any headers from lib_dep/
, whether directly or indirectly, then it is necessary for its CPPFLAGS
to contain an -I
flag for that directory. Otherwise, not.
An indirect inclusion would be if main.c
includes library1.h
and library1.h
includes library1_dep.h
.
Since you are using libtool
to build both libraries, and consistently declaring link dependencies by putting the appropriate libtool archives in the LIBADD
/ LDADD
variables, you do not need to specify the indirect library dependency in the main program's LDADD
. libtool can and will figure out the indirect library dependency and add it to the main program's link if needed, and at the correct location in the link command.
Thus, if the main program has neither a compile-time dependency nor a direct link dependency on libdep
, then its Makefile.am
could look like this:
bin_PROGRAMS = main
main_SOURCES = main.c
main_LDADD = $(top_builddir)/lib/lib_lib.la
main_CPPFLAGS = -I$(top_srcdir)/lib
NOTE: it is not wrong to add $(AM_LDADD)
to main_LDADD
or to add $(AM_CPPFLAGS)
to main_CPPFLAGS
, as in the version of this Makefile.am
presented in the question, but that is useful only if you've actually defined values for those AM_*
variables.
NOTE2: Your -I
flags should specify directories to search for header files, not the names of specific header files.