如何在Makefile.am脚本中指定我只想编译对象.o文件?

时间:2010-02-16 12:03:40

标签: makefile automake gnu-make

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

project/src/Makefile.am

在src目录中还有一个名为ctrnn的子目录,其中包含一个额外的Makefile.am

project/src/ctrnn/Makefile.am

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

这是ctrnn/Makefile.am

SOURCES = network.cpp\
    neuron.cpp

AM_CPPFLAGS=  @CXXFLAGS@

基于这个Makefile.am文件,我想最终得到network.o和neuron.o。我正在使用Automake等生成相应的Makefile,但是当我尝试然后执行make文件时,它什么也没做,只是说:

make: Nothing to be done for `all'

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

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

我做错了什么?

3 个答案:

答案 0 :(得分:27)

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

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

  1. 请勿使用src/ctrnn/Makefile.am,只需引用src/Makefile.am中的子目录源文件:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    
    请注意,这会在与network.o相同的目录中构建neuron.omain.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.acrtnn/network.ocrtn/neuro.o替换foo的结果相同。

  3. 使用Libtool便利库。如果您尚未使用Libtool,则需要更多设置。您应该在LT_INIT中添加一个调用configure.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的静态库不能。

答案 1 :(得分:2)

您可以在project / src / Makefile.am中指定源文件,而在ctrnn中没有Makefile.am:

maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp

或者您可以使用libtool便利库。在ctrnn / Makefile.am中,输入:

noinst_LTLIBRARIES = libctrnn.la
libctrnn_la_SOURCES = network.cpp neuron.cpp

并在src / Makefile.am中,输入

LDADD = ctrnn/libmylib.la

如果您尚未使用libtool,则还需要将LT_INIT添加到configure.ac。

答案 2 :(得分:0)

更好的是,你可以通过这样做来强制使用无源目标:

SUBDIRS = sub1 sub2 …
lib_LTLIBRARIES = libtop.la
libtop_la_SOURCES =
# Dummy C++ source to cause C++ linking.
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx
libtop_la_LIBADD = \
  sub1/libsub1.la \
  sub2/libsub2.la \
...

秘密肉汁是nodist_EXTRA_xxxx_la_SOURCES

此处有更多详细信息:https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html