13

我有一个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。我正在Makefile使用 Automake 等生成相应的文件,但是当我尝试然后执行 make 文件时,它什么也没做,只是说:

make: Nothing to be done for `all'

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

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

我做错了什么?

4

3 回答 3

28

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

你有三种方法可以做你想做的事,它们都涉及将你的源文件绑定到某个目标。

  1. 不要使用 a src/ctrnn/Makefile.am,只需参考您的子目录源文件src/Makefile.am

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

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

    noinst_LIBRARIES = libcrtnn.a
    libcrtnn_a_SOURCES = network.cpp 神经元.cpp
    
    在 中src/Makefile.am,将您的可执行文件链接到库:
    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.a
    子目录 = crtnn
    
    它在不安装时称为“方便”(您可以通过noinst_前缀来判断):它只是在构建期间使用。crtnn/libcrtnn.a这是一个静态库,所以结果与链接时替换为crtnn/network.oandcrtn/neuro.o时的结果相同foo

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

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

于 2010-02-21T11:43:43.107 回答
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 神经元.cpp

在 src/Makefile.am 中,放入

LDADD = ctrnn/libmylib.la

如果您还没有使用 libtool,您还需要将 LT_INIT 添加到 configure.ac。

于 2010-02-16T20:53:20.797 回答
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

于 2016-10-12T14:16:09.087 回答