I have an autotools-managed project ( sscce tar.gz package here ) with this structure:
My configure.ac
is:
AC_INIT([foo], [1.0], [foo@bar.ba])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
My Makefile.am
were:
bin_PROGRAMS = main
main_SOURCES = main.c foo.c foo.h
It compiled and ran perfectly... but then I note my Makefile.am
was not correct. It stated that my main code depended upon foo.h
, but the real file was foo/foo.h
. I changed it, and the compilation was working as expected, as it was before:
bin_PROGRAMS = main
main_SOURCES = main.c foo.c foo/foo.h
However, it made me wonder: how did it work when the dependencies were wrong? It worked so well that I could even edit foo/foo.h
and make
would recompile the dependent files. Actually, I could even remove the header file from the dependencies...
bin_PROGRAMS = main
main_SOURCES = main.c foo.c
...and it would be still scanned an would trigger the recompilation of dependent files.
So, my questions are:
Makefile
know that foo/foo.h
is a dependency to be analyzed during the make
invocation? main_SOURCES
variable? make
fail in the first case, since I am declaring that a non-existent file is a dependency? Have a look at the automake manual . Dependency computation is done at build time, as a side-effect of compilation. The history of dependency tracking might also be interesting to you. Note that there's an error in the manual here: it makes it sound like depcomp
is unconditionally invoked, which is not the case (a test at configure
time checks if your compiler can do without it: see the @am__fastdepCC_TRUE@
lines in Makefile.in
.
So what happens is that files listing the dependencies of each object are stored in a hidden subdirectory called .deps
. These files are initally empty and get overwritten as their corresponding source file is compiled. (For gcc
, this is done via -MD
and related flags.)
You should absolutely list your headers in the main_SOURCES
variable, so that your Makefile
will package them up when you run make dist
(or better yet, make distcheck
).
make
won't fail if you list a non-existent header, because you're not actually listing the dependencies in your main_SOURCES
line. automake
will process that assignment and then write out the rules for building main
(which will depend on object files only) and the various object files (via a suffix rule). The headers aren't the direct input file to anything in the build process, so you skate by. Running make dist
on your sample project gives the error:
make: *** No rule to make target `foo.h', needed by `distdir'. Stop.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.