【问题标题】:How do I specify in a Makefile.am script that I only want to compile object .o files?如何在 Makefile.am 脚本中指定我只想编译对象 .o 文件?
【发布时间】:2011-01-17 09:06:03
【问题描述】:

我有一个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 的二进制文件?

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

我做错了什么?

【问题讨论】:

    标签: makefile automake gnu-make


    【解决方案1】:

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

    您可以通过三种方式来做您想做的事,它们都涉及将您的源文件绑定到某个目标。

    1. 不要使用src/ctrnn/Makefile.am,只需引用src/Makefile.am 中的子目录源文件即可:

      bin_PROGRAMS = foo foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp 请注意,这将在与main.o 相同的目录中构建network.oneuron.o。如果您想要子目录中的对象,请使用AUTOMAKE_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_ 前缀来判断):它只是在构建期间使用。这是一个静态库,所以结果与在链接foo 时将crtnn/libcrtnn.a 替换为crtnn/network.ocrtn/neuro.o 相同。
    3. 使用 Libtool 便利库。如果您尚未使用 Libtool,则需要进行更多设置。您应该在configure.ac 中添加调用LT_INIT 并重新运行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 的静态库不能。

    【讨论】:

    • 谢谢!我最终使用了 libtool 方法,效果很好:-)
    • 感谢您帮助我在 autotools/libtool 地狱中奋斗。并帮我们大家一个忙:长寿和繁荣!
    • foo_LDADD?那不应该是 foo_LIBADD
    • @EgbertS _LIBADD 用于将对象添加到库中,但 foo 不是库。
    • 精湛全面的答案。谢谢!
    【解决方案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。

    【讨论】:

      【解决方案3】:

      更好的是,您可以通过执行以下操作强制使用无源目标生成:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-26
        • 1970-01-01
        • 2015-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多