2009-05-27 31 views
5

Tengo un proyecto administrado por C++ autoconf que me estoy adaptando para compilar en hosts FreeBSD. El sistema original era Linux, así que hice un AM_CONDITIONAL para distinguir el host que estoy construyendo y separar el código en archivos específicos del sistema.Automake y archivos con el mismo nombre

configure.ac

 

AC_CANONICAL_HOST 
AM_CONDITIONAL([IS_FREEBSD],false) 
case $host in 
     *free*)  
      AC_DEFINE([IS_FREEBSD],[1],[FreeBSD Host]) 
      AM_CONDITIONAL([IS_FREEBSD],true) 
      BP_ADD_LDFLAG([-L/usr/local/lib]) 
       ;; 
esac 

Makefile.am

 

lib_LTLIBRARIES=mylib.la 
mylib_la_SOURCES=a.cpp \ 
       b.cpp 

if IS_FREEBSD 
    mylib_la_SOURCES+=freebsd/c.cpp 
else 
    mylib_la_SOURCES+=linux/c.cpp 
endif 

Cuando corro automake falla con este tipo de mensaje:

 
Makefile.am: object `c.lo' created by `linux/c.cpp' and `freebsd/c.cpp' 

¿Alguna idea sobre cómo configurar automake para respetar este condicional incluso en el proceso de compilación Makefile.in?

Esto funciona si los archivos tienen diferentes nombres, pero es código de C++ y estoy tratando de mantener los nombres de los archivos iguales al nombre de la clase.

¡Gracias de antemano!

+1

Hay un error tipográfico en su Makefile.am: "IS_FREEBSD" debería decir "if IS_FREEBSD". – adl

+0

Gracias adl, modificado –

Respuesta

11

Se puede solicitar para los objetos que se construirá en sus respectivos subdirectorios con

AUTOMAKE_OPTIONS = subdir-objects 
+1

¡Respuesta perfecta, solo hay que decir que esta es una opción de Makefile.am! ¡Gracias! –

+5

También es posible configurar esta opción de automake en 'AM_INIT_AUTOMAKE ([... subdir-objects ...])' en 'configure.ac'. – ndim

+0

¿Por qué automake crea archivos de objetos para el código que no está indicado para compilar? Dado que se está compilando en una condición, debería tomar solo un archivo a la vez, incluso si está en el mismo nombre. Estoy en lo correcto? –

7

Otra opción, además subdirectorio-objetos, es dar a cada sub-proyecto alguna costumbre por proyecto construir banderas. Cuando hace esto, automake cambia sus reglas de nomenclatura * .o para anteponer el nombre del objetivo al nombre del módulo. Por ejemplo, esto:

mylib_la_CXXFLAGS=$(AM_CXXFLAGS) 
mylib_la_SOURCES=a.cpp b.cpp 

se traducirá en los archivos de salida mylib_la-a.o y mylib_la-b.o, en lugar de a.o y B.O. Por lo tanto, puede tener dos proyectos diferentes con el mismo directorio de salida que cada uno tenga, por ejemplo, un archivo b.cpp, y no tengan conflictos de salida.

Tenga en cuenta que hice esto al configurar los CXXFLAGS específicos del proyecto a los valores que automake ya iba a utilizar, AM_CXXFLAGS. Automake no es lo suficientemente inteligente como para detectar este truco y utilizar los nombres * .o más cortos. Si sucede que necesita opciones de compilación por proyecto, puede hacerlo en lugar de hacerlo.

Hay un whole list de las variables de automake que, cuando se configuran por ejecutable, dan el mismo efecto. Así, por ejemplo, tal vez un sub-proyecto necesita banderas de enlace especial ya, así que darle algo como:

mylib_la_LDFLAGS=-lfoo 

Esto le dará el prefijo * .o archivos al igual que el truco AM_CXXFLAGS hizo, sólo que ahora está "legítimamente" usar esta característica, en lugar de engañar a automake para que lo haga.

Por cierto, es malo el estilo de autoconf para cambiar la forma en que su programa se basa solo en el sistema operativo para el que está siendo desarrollado. Un buen estilo de autoconf es comprobar solo las características específicas de la plataforma, no las plataformas completas, porque las plataformas cambian. FreeBSD podría ser de cierta manera hoy, pero tal vez en la próxima versión copie una característica de Linux que borre la necesidad de que construyas tu programa de dos maneras diferentes. O tal vez la función que está utilizando hoy está obsoleta y se eliminará en la próxima versión.

Hay cuarenta años de sabiduría de programación portátil de Unix en los autotools, saltamontes.Los "maybes" que he dado anteriormente tienen sucedió en el pasado, y sin duda lo volveré a hacer. Probar las características individuales es la forma más ágil de lidiar con las plataformas en constante cambio.

También puede obtener bonificaciones inesperadas con este enfoque. Por ejemplo, tal vez su programa necesite dos características no portables para hacer su trabajo. Digamos que en FreeBSD, estas son las características A y B, y en Linux, son las características X e Y; A y X son mecanismos similares pero con interfaces diferentes, y lo mismo para B e Y. Podría ser que la característica A provenga de los BSD originales, y esté en Solaris porque tiene raíces BSD de SunOS en los 80, y Solaris también tiene característica Y de su rediseño basado en System V a principios de los 90. Al probar estas características, su programa también podría ejecutarse en Solaris, ya que tiene las características que su programa necesita, pero no en la misma combinación que en FreeBSD y Linux.

+4

+1 para "verificar características, no plataformas". –

Cuestiones relacionadas