如何在Makefile.am脚本中指定我只想编译以后可以链接的对象.o文件?

Ben*_*n J 12 automake makefile gnu-make

我有一个Makefile.am,它将负责构建最终的应用程序二进制文件:

项目/ src目录/ Makefile.am

同样在src目录中的是一个名为ctrnn的子目录,它包含一个Makefile.am:

项目/ src目录/ ctrnn/Makefile.am

现在,ctrnn/Makefile.am应该只生成对象.o文件,其思想是顶级Makefile.am应该使用子目录ctrnn中生成的目标文件来构建二进制文件.

这是ctrnn/Makefile.am

project/src/Makefile.am
Run Code Online (Sandbox Code Playgroud)

基于这个Makefile.am文件,我想最终得到network.o和neuron.o.我使用automake等生成相应的Makefile,但是当我尝试然后执行make文件时,它没有做任何事情,只是说:

make:'all'无所事事

我知道为什么会这样,我需要指定构建目标.但是我如何在ctrnn/Makefile.am脚本中执行此操作,因为我不想构建需要bin_PROGRAMS但实际目标文件为network.o和neuron.o的二进制文件?

(注意,如果我确实指定了bin_PROGRAMS名称,它最终会抱怨对main的未定义引用).

我做错了什么?

谢谢,本.

adl*_*adl 27

如果没有将使用这些对象的显式目标(程序,库),Automake无法构建对象.一个原因是每个目标都指定了编译选项.如果两个目标(例如,两个二进制文件)使用相同的对象但具有不同的编译选项,则可能必须编译两次相同的对象.

您有三种方法可以执行您想要的操作,它们都涉及将源文件绑定到某个目标.

  1. 不要使用a src/ctrnn/Makefile.am,只需从以下内容中引用子目录源文件src/Makefile.am:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    
    请注意,这将构建network.oneuron.o在与...相同的目录中main.o.如果您想要子目录中的对象,请使用AUTOMAKE_OPTIONS = subdir-objects.

  2. 使用便利库.在src/crtnn/Makefile.am制作两个对象的库时:

    noinst_LIBRARIES = libcrtnn.a
    libcrtnn_a_SOURCES = network.cpp neuron.cpp
    
    并在src/Makefile.am,将您的可执行文件链接到库:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.a
    SUBDIRS = crtnn
    
    它不会被安装时称为"便利"(因为noinst_前缀可以告诉):它只是在构建期间使用.这是一个静态库,所以结果是一样的,如果你已经取代crtnn/libcrtnn.a通过crtnn/network.ocrtn/neuro.o链接时foo.

  3. 使用Libtool便利库.如果您尚未使用Libtool,则需要更多设置.您应该添加通话LT_INITconfigure.ac并重新运行autoreconf安装libtool的文件.然后,您可以更新src/crtnn/Makefile.am以创建两个对象的库,如下所示:

    noinst_LTLIBRARIES = libcrtnn.la
    libcrtnn_la_SOURCES = network.cpp neuron.cpp
    
    并且src/Makefile.am,如下所示:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.la
    SUBDIRS = crtnn
    
    有什么不同?你可能会问,几乎没有.使用Libtool便捷库的一个优点是它们可以嵌套:Libtool库可以包含另一个Libtool库(当您拥有深层次的源代码并且在每个级别构建库时,这很方便).如果需要,还可以使用Libtool便捷库来构建共享库.Automake的静态库不能.

  • 感谢您帮助我在autotools/libtool地狱中奋斗.帮助我们:长寿,繁荣! (3认同)
  • @EgbertS`_LIBADD`用于向库中添加对象,但`foo`不是库. (2认同)