2009-05-27 45 views
5

我有一个C++ autoconf管理项目,我正在适应在FreeBSD主机上编译。 原始系统是Linux,所以我让一个AM_CONDITIONAL来区分我正在构建的主机并将代码分离到系统特定的文件中。Automake和同名文件

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 

当我运行automake的失败与此类型的消息:

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

如何配置automake的任何想法甚至在Makefile.in构建过程中尊重这个条件?

我这个作品,如果文件有不同的名称,但它的c + +代码,我试图保持文件名相同的类名。

在此先感谢!

+1

Makefile.am中有一个输入错误:“IS_FREEBSD”应为“if IS_FREEBSD”。 – adl 2009-05-28 07:44:29

+0

谢谢adl,修改 – 2009-05-28 11:52:26

回答

11

你可以请求的对象要建在他们各自的子目录里

AUTOMAKE_OPTIONS = subdir-objects 
+1

完美答案,只需要说这是一个Makefile.am选项! 谢谢! – 2009-05-28 11:54:37

7

另一种选择,除了子目录对象,是给每个子项目的一些自定义每个项目建立的标志。当你这样做的时候,automake改变它的* .o命名规则以将目标名称预先加到模块名称上。例如,这样的:

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

将导致输出文件mylib_la-a.o和mylib_la-B.O,而不是a.o和b.o.因此,您可以拥有两个不同的项目,它们具有相同的输出目录,每个项目都有一个b.cpp文件,并且不会产生冲突。

请注意,我是通过将项目特定的CXXFLAGS设置为automake已经使用的值AM_CXXFLAGS来实现的。 Automake不够智能,无法检测到这个技巧并使用较短的* .o名称。如果碰巧你需要每个项目的构建选项,你当然可以做到这一点,而不是这个黑客。

有一个automake变量的whole list,当设置在每个可执行的基础上,给出相同的效果。因此,举例来说,也许一个子项目需要特别的链接标志了,所以你给它这样的:

mylib_la_LDFLAGS=-lfoo 

这会给你的前缀* .o文件就像AM_CXXFLAGS伎俩一样,只是现在你“合法地”使用这个功能,而不是欺骗automake做这件事。

顺便说一下,改变程序的构建方式仅仅是基于它所构建的操作系统,这是很糟糕的autoconf风格。良好的autoconf风格仅用于检查特定的平台功能,而不是整个平台,因为平台会发生变化。今天FreeBSD可能是一种特定的方式,但也许在下一个版本中,它会从Linux复制一个功能,这将消除您需要以两种不同的方式构建您的程序。或者,您今天使用的功能可能已被弃用,并会在下一个版本中删除。

在autotools,grasshopper中有四十年的便携式Unix编程智慧。我给出的“maybes”以上有发生在过去,并且肯定会再这样做。测试各个功能是应对不断变化的平台的最敏捷的方式。

您也可以从这种方法中获得意想不到的奖励。例如,也许你的程序需要两个不可移植的功能来完成它的工作。说在FreeBSD上,这些是A和B的特性,而在Linux上,它们是X和Y的特性; A和X是类似的机制,但接口不同,B和Y也是如此。它可能是来自原始BSD的特性,并且在Solaris中,因为它在80年代具有来自SunOS的BSD根,并且Solaris也具有从90年代初期基于系统V的重新设计开始具备Y功能。通过测试这些功能,您的程序也可以在Solaris上运行,因为它具有程序需要的功能,而不是与FreeBSD和Linux相同。