简体   繁体   中英

Does autotools Makefile automatically consider included header files as dependencies?

I have an autotools-managed project ( sscce tar.gz package here ) with this structure:

./main.c
./foo.c
./foo/foo.h

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:

  • How does the autotools-generated Makefile know that foo/foo.h is a dependency to be analyzed during the make invocation?
  • Should I add the header files to the main_SOURCES variable?
  • Shouldn't 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM