2012-07-22 14 views
5

tengo un proyecto de autotools gestionados (sscce paquete tar.gz here) con esta estructura:¿Autoflores Makefile considera automáticamente los archivos de encabezado incluidos como dependencias?

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

Mi configure.ac es:

AC_INIT([foo], [1.0], [[email protected]]) 
AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 
AC_PROG_CC 
AC_CONFIG_HEADERS([config.h]) 
AC_CONFIG_FILES([Makefile]) 

AC_OUTPUT 

Mi Makefile.am eran :

bin_PROGRAMS = main 
main_SOURCES = main.c foo.c foo.h 

Se compiló y funcionó perfectamente ... pero luego observo que mi Makefile.am no era correcto. Estableció que mi código principal dependía de foo.h, pero el archivo real era foo/foo.h. He cambiado, y la compilación estaba trabajando como era de esperar, como lo era antes:

bin_PROGRAMS = main 
main_SOURCES = main.c foo.c foo/foo.h 

Sin embargo, me hizo extrañar: ¿cómo funcionaba cuando las dependencias estaban equivocados? Funcionó tan bien que incluso pude editar foo/foo.h y make volvería a compilar los archivos dependientes. De hecho, podría incluso eliminar el archivo de cabecera de las dependencias ...

bin_PROGRAMS = main 
main_SOURCES = main.c foo.c 

... y sería todavía un escaneado daría lugar a la recopilación de archivos dependientes.

Por lo tanto, mis preguntas son:

  • ¿Cómo las autotools-generados Makefile saben que foo/foo.h es una dependencia para ser analizados durante la invocación make?
  • ¿Debo agregar los archivos de encabezado a la variable main_SOURCES?
  • ¿No debería fallar make en el primer caso, ya que estoy declarando que un archivo inexistente es una dependencia?
+0

Por curiosidad, ¿omite algunos detalles? ¿Cómo entra '-I $ (srcdir)/foo' en' CPPFLAGS'? –

+0

@WilliamPursell Bueno, estoy omitiendo algunos detalles de mi escenario * real *, pero el siguiente ejemplo se compila como se esperaba. En este caso, no hay necesidad de '-I $ (srcdir)/foo' porque ambos' foo.c' y 'main.c' incluyen el archivo con el nombre de directorio:' #include "foo/foo.h" 'como se ve [aquí] (http://pastebin.com/p9d1XNcU). – brandizzi

Respuesta

5

Eche un vistazo a automake manual. El cómputo de dependencia se realiza en tiempo de compilación, como un efecto secundario de la compilación. El history of dependency tracking también puede ser interesante para usted. Tenga en cuenta que hay un error en el manual aquí: se hace sonar como depcomp está incondicionalmente invocado, lo cual no es el caso (a prueba en configure tiempo comprueba si su compilador puede prescindir de él:. Ver @[email protected] líneas en Makefile.in

Entonces, lo que sucede es que los archivos que enumeran las dependencias de cada objeto se almacenan en un subdirectorio oculto llamado .deps. Estos archivos están inicialmente vacíos y se sobrescriben cuando se compila su archivo fuente correspondiente. (Para gcc, esto se hace a través de -MD y banderas relacionadas .)

Debe listar absolutamente sus encabezados en la variable main_SOURCES, de modo que su Makefile los empaquetará cuando ejecute make dist (o mejor aún, make distcheck).

make no fallará si incluye un encabezado inexistente, porque en realidad no está enumerando las dependencias en su línea main_SOURCES. automake procesará esa asignación y luego escribirá las reglas para compilar main (que dependerá únicamente de los archivos de objeto) y los diversos archivos de objeto (mediante una regla de sufijo). Los encabezados no son el directo archivo de entrada a nada en el proceso de compilación, por lo que se desliza por. Al ejecutar make dist en su proyecto de ejemplo, aparece el error:

make: *** No rule to make target `foo.h', needed by `distdir'. Stop. 
Cuestiones relacionadas