【问题标题】:Non recursive (non-recursive) AutomakeNon recursive (非递归) Automake
【发布时间】:2023-03-05 18:59:01
【问题描述】:

我正在尝试将项目转换为使用非递归 automake。基于对 SO 的搜索,我可以看到该主题已在一定程度上被涵盖。但是对于如何将递归 automake 项目转换为非递归项目并没有任何问题。我已经读过Karel Zak's blog,当然还有autotools-mythbusterexperiences regarding non-recursive automake 有一个问题,但它没有解释如何转换项目。唯一解释一点的问题似乎是关于subdir-objects option。但是我无法使用这些资源转换我的项目。因此提出了这个问题。

让我们从一个简单的项目设置开始:

project/
   \-- configure.ac
   |-- Makefile.am
   \-- src/
      \-- Makefile.am
      |-- foo.c
      |-- foo.h
      \-- main.c

configure.ac 我只是添加subdir-objects 选项:

AM_INIT_AUTOMAKE([subdir-objects])

Makefile.am 中,我从根Makefiles.amSUBDIRS 变量中删除了src 目录。然后我从 `configure.ac 中的 AC_CONFIG_FILES 宏中删除了 src/Makefile 条目。

Karel Zak 的博客建议将子目录中包含的 Makefile 命名为 Makemodule.am,但 Makefile.am 似乎也可以工作,如果删除了 SUBDIRS 变量的子文件夹并且从AC_CONFIG_FILES 配置文件宏。

接下来我为根目录Makefile.am中的程序定义了一个全局变量,并包含了src/Makefile.am

bin_PROGRAMS=
include src/Makefile.am

src/Makefile.am我改了:

bin_PROGRAMS=foo

到:

bin_PROGRAMS+=src/foo

我还将所有出现的foo_XXX 更改为src_foo_XXX。我在src_foo_SOURCES 中的所有.c 和.h 文件名中添加了前缀src/

但是程序没有构建并且给出了关于找不到包含文件的错误,例如:

fatal error: debug.h: No such file or directory
 #include <debug.h>

最初我的 src 目录 Makefile.am 仅包含内容变量 src_foo_SOURCESsrc_foo_CFLAGSsrc_foo_LDFLAGSsrc_foo_LDADD。我对这个问题的解决方案是像这样添加src_foo_CPPFLAGS

src_foo_CPPFLAGS = \
    $(AM_CPPFLAGS) \
    -I$(top_builddir)/src \
    -DDATADIR='"$(datadir)"' \
    -DMODULEDIR='"$(moduledir)"' \
    -DLIBEXECDIR='"$(libexecdir)"'

但我真的不明白为什么这是必要的,以及为什么当我使用递归 automake 时它构建得很好?

关于Brett Hale in this question的回答我还有一个问题。他写道:

你可以使用“$(srcdir)/sourceA.cpp”,但是这个目录是隐含的。您只需要:

libadapter_la_SOURCES = sourceA.cpp sourceB.cpp

但是如果没有前缀路径我无法让它工作,所以这对我来说似乎是错误的,有人可以确认我的经验吗?

更新:我也遇到了 po/ 子目录的问题,我怎样才能使它成为非递归的? po/ 中没有 Makefile.am,只是一个 Makevars 文件。有一个 post on autotools-mythbuster,表示不支持使用 gettext 进行非递归生成,但该帖子是 2011 年发布的。我不确定在此期间是否有任何变化。

【问题讨论】:

    标签: c++ c makefile autoconf automake


    【解决方案1】:

    我将从下往上开始:自 2011 年以来,gettext 没有任何变化,不幸的是,po/ 目录仍应递归处理。 gtk-doc 也是如此。原因是它们构建了一些与automake 兼容的Makefile.in 文件,但它们并不是真正基于automake 的。

    至于找不到头文件,现在失败的原因是你使用了错误的#include语句格式:你应该使用#include "debug.h",然后它就可以工作而无需添加-Isrc到命令行。预处理器将在与源文件相同的目录中查找 "" 封闭的标头,并在包含路径中查找 &lt;&gt; 封闭的标头; automake 默认使用-I. 将当前目录添加到包含路径中,这意味着使用递归Makefile.am 时可以满足,但现在“当前目录”不再匹配您的源文件目录。

    如果您使用的是 Karel 建议的方法(automake,或至少它的某些版本,则会为子目录生成一个 Makefile.in 文件,我还建议您不要重复使用名称 Makefile.am将无法正常工作),并且如果您的软件足够独立,例如如果它只有一个二进制目标,请考虑根本不使用 Karel 的方法。 Karel 的用例是 linux-utils,这是一个相当稀疏的项目,有几十个目标,每个目标都有自己的一组源文件。

    我将尝试对您提到的 Brett Hale 的回答发表评论,因为我认为这完全存在误解。

    【讨论】:

    • 好吧,看来我无法评论布雷特的回答,因为我在这里没有足够的声誉(即使我自己编写了指南)。简短的回答是,永远不要在 _SOURCES 中使用 $(srcdir)。在进行树外构建时,它可能会导致许多工具出现问题,并且不会给您带来任何好处。 automake 使用 VPATH 来查找源代码。您可以使用(但也不会给您带来任何东西)是reldir,因此您可以将您的来源定义为foo_SOURCES = %D%/foo.c %D%/foo.h
    • 我的项目是github.com/lanoxx/tilda,确实是一个很小的项目,只有一个二进制文件。但我主要将其用作学习示例,因此我可以开始重构另一个更大的项目,例如 gnome-panel。我不确定你所说的reldir 不会给我带来什么?如果我不使用reldir,那么我必须在每个源文件前面加上文件夹名称,但这意味着移动文件夹或重命名文件夹会更加困难。
    • 是的,如果您要重构一个更大的项目,那么如果您打算移动目录,那么使用 reldir (%D%) 是一个好主意。另一方面,它仍然不允许您更改二进制文件的输出目录,因为如果我没记错的话,您不能将其声明为 %D%_foo_SOURCES。没有什么能阻止您在顶层构建所有内容并使用 reldir。
    • 感谢您的澄清。但是您对 %D% 的看法是错误的。您实际上可以使用 bin_PROGRAMS += %D%/foo 然后使用%C%_foo_SOURCES=...。不同之处在于在前缀中使用%C%%canon_reldir% 作为规范化形式。然后将在相应的源目录中构建二进制文件。
    • 关于 Makefile.am,根据 automake 手册:AC_CONFIG_FILES 宏声明配置应从其 *.in 模板创建的文件列表。 Automake 还会扫描此列表以查找它必须处理的 Makefile.am 文件。 [...] 向您的项目添加新目录时,您应该将其 Makefile 添加到此列表中,否则 Automake 将永远不会处理新的 Makefile.am [...])。由于 %C% 和 %D% 是特定于 automake 1.14 的,因此我认为应该保存为 Makefile.am。如果这是错误的,请随意反驳。
    猜你喜欢
    • 2023-03-12
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多