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

发布于 2024-08-21 12:16:22 字数 976 浏览 18 评论 0原文

我有一个 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'

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

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

我做错了什么?

I have a Makefile.am which will be responsible for building a final application binary:

project/src/Makefile.am

Also in the src directory is a sub-directory called ctrnn which contains an additional Makefile.am:

project/src/ctrnn/Makefile.am

Now, ctrnn/Makefile.am should only generate object .o files with the idea being that the top-level Makefile.am should use the object files generated in subdirectory ctrnn to build the binary.

This is the ctrnn/Makefile.am:

SOURCES = network.cpp\
    neuron.cpp

AM_CPPFLAGS=  @CXXFLAGS@

Based on this Makefile.am file, I want to end up with network.o and neuron.o. I am generating the according Makefile using Automake etc, yet when I try and then execute the make file, it doesn't do anything and just says:

make: Nothing to be done for `all'

I know why this is, I need to specify the build target. But how do I do this in the ctrnn/Makefile.am script given that I don't want to build a binary which would require bin_PROGRAMS but actual object files network.o and neuron.o?

(Note if I do specify a bin_PROGRAMS name, it rightly ends up complaining of an undefined reference to main).

What am I do wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

顾铮苏瑾 2024-08-28 12:16:22

如果没有使用这些对象的显式目标(程序、库),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_ 前缀来判断):它仅在构建期间使用。这是一个静态库,因此结果与将 crtnn/libcrtnn.a 替换为 crtnn/network.ocrtn/neuro 相同.o 链接 foo 时。

  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 的静态库不能。

Automake cannot build objects without an explicit target (program, library) that will use these objects. One reason is that compilation options are specified per-target. If two targets, e.g. two binaries use the same object but have different compilation option, the same object may have to be compiled twice.

You have three ways to do what you want, they all involve tying your source files to some target.

  1. Do not use a src/ctrnn/Makefile.am, just make reference to the subdirectory source files from your src/Makefile.am:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    

    Note that this will build network.o and neuron.o in the same directory as main.o. If you want objects in subdirectories, use AUTOMAKE_OPTIONS = subdir-objects.

  2. Use a convenience library. In src/crtnn/Makefile.am make a library of your two objects:

    noinst_LIBRARIES = libcrtnn.a
    libcrtnn_a_SOURCES = network.cpp neuron.cpp
    

    and in src/Makefile.am, link your executable to the library:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.a
    SUBDIRS = crtnn
    

    It's called "convenience" when it is not going to be installed (you can tell because of the noinst_ prefix): it is just used during the build. And this is a static library, so the result is the same as if you had replaced crtnn/libcrtnn.a by crtnn/network.o and crtn/neuro.o when linking foo.

  3. Use a Libtool convenience library. This requires more setup if you are not using Libtool already. You should add a call LT_INIT in configure.ac and rerun autoreconf to install the libtool files. Then you can update src/crtnn/Makefile.am to make a library of your two objects as follows:

    noinst_LTLIBRARIES = libcrtnn.la
    libcrtnn_la_SOURCES = network.cpp neuron.cpp
    

    and src/Makefile.am as follows:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c
    foo_LDADD = crtnn/libcrtnn.la
    SUBDIRS = crtnn
    

    What is the difference? you may ask, almost none. One advantage of using Libtool convenience libraries is that they can be nested: a Libtool library can include another Libtool library (this is convenient when you have a deep hierarchy of source code and you are building a library at each level). Also Libtool convenience libraries can be used to build a shared library if you want. Automake's static libraries cannot.

笔芯 2024-08-28 12:16:22

您可以简单地在 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。

You could simply specify source files in project/src/Makefile.am and not have a Makefile.am in ctrnn:

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

or you can use a libtool convenience library. In ctrnn/Makefile.am, put:

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

and in src/Makefile.am, put

LDADD = ctrnn/libmylib.la

If you aren't already using libtool, you'll also need to add LT_INIT to configure.ac.

逆光飞翔i 2024-08-28 12:16:22

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

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

Better yet, you could FORCE a make using a source-less target by doing this:

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 \
...

The secret gravy is nodist_EXTRA_xxxx_la_SOURCES.

More details in here: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文