C++ 非递归(非递归)自动生成

C++ 非递归(非递归)自动生成,c++,c,makefile,autoconf,automake,C++,C,Makefile,Autoconf,Automake,我正在尝试将一个项目转换为使用非递归自动生成。基于对的搜索,我可以看到该主题已被涵盖到一定程度。但是,关于如何将递归automake项目转换为非递归automake项目,实际上并没有任何问题。我已经读过了,当然还有。有一个问题,但它没有解释如何转换项目。唯一能解释一点的问题似乎是关于。但我无法用这些资源转换我的项目。所以这个问题 让我们从一个简单的项目设置开始: project/ \-- configure.ac |-- Makefile.am \-- src/ \

我正在尝试将一个项目转换为使用非递归自动生成。基于对的搜索,我可以看到该主题已被涵盖到一定程度。但是,关于如何将递归automake项目转换为非递归automake项目,实际上并没有任何问题。我已经读过了,当然还有。有一个问题,但它没有解释如何转换项目。唯一能解释一点的问题似乎是关于。但我无法用这些资源转换我的项目。所以这个问题

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

project/
   \-- configure.ac
   |-- Makefile.am
   \-- src/
      \-- Makefile.am
      |-- foo.c
      |-- foo.h
      \-- main.c
configure.ac
中,我只添加了
subdir对象
选项:

AM_INIT_AUTOMAKE([subdir-objects])
Makefile.am
中,我从根
Makefile.am
SUBDIRS
变量中删除了
src
目录。然后我从configure.AC中的
AC\u CONFIG\u FILES
宏中删除了
src/Makefile
条目

Karel Zak的博客建议命名子目录
Makemodule.am
中包含的Makefile,但是如果为
SUBDIRS
变量删除子文件夹,并且从
AC\u CONFIG\u FILES
CONFIG FILES宏中删除
Makefile
条目,Makefile.am似乎也可以工作

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

bin_PROGRAMS=
include src/Makefile.am
src/Makefile.am
中,我更改了:

bin_PROGRAMS=foo
致:

我还将所有出现的
foo\u XXX
更改为
src\u foo\u XXX
。我在
src\u foo\u SOURCES
中的所有.c和.h文件名中添加了前缀
src/

但程序未生成,并给出了有关未找到包含文件的错误,例如:

fatal error: debug.h: No such file or directory
 #include <debug.h>
但我真的不明白为什么这是必要的,为什么在我使用递归automake时它构建得很好

关于这个问题的答案,我还有一个问题。他写道:

您可以使用“$(srcdir)/sourceA.cpp”,但该目录仍然是隐式的。您所需要的只是:

libadapter\u la\u SOURCES=sourceA.cpp sourceB.cpp

但是如果不在路径前面加上前缀,我就无法让它工作,所以我觉得这似乎不对,有人能证实我的经验吗


更新:我对
po/
subdir也有问题,我如何才能使其非递归?
po/
中没有Makefile.am,只有一个Makevars文件。有一个,表明不支持使用gettext的非递归make,但该帖子是2011年发布的。我不确定在此期间是否有任何变化。

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

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

如果您使用Karel建议的方法(
automake
,或者至少它的某些版本,将为无法正常工作的子目录生成一个
Makefile.in
文件),我还建议您不要重复使用名称
Makefile.am
),如果你的软件自给自足,比如它只有一个二进制目标,那么不要考虑使用卡雷尔的方法。Karel的用例是
LinuxUtils
,这是一个相当稀疏的项目,有几十个目标,每个目标都有自己的源文件集


我将试着对你提到的Brett Hale的回答发表评论,因为我认为这完全是一个误解。

好吧,看来我不能对Brett的回答发表评论,因为我在这里没有足够的声誉(即使我自己写了指南)。简而言之,永远不要在源代码中使用$(srcdir)。在进行树外构建时,它可能会导致许多工具出现问题,而不会给您带来任何好处
automake
使用
VPATH
查找源代码。您可以使用的(但也不会给您带来任何东西)是,您可以将您的源定义为
foo\u sources=%D%/foo.c%D%/foo.h
我的项目是,这确实是一个只有一个二进制文件的非常小的项目。但我主要是把它作为一个学习的例子,这样我就可以开始重构另一个更大的项目,比如gnome面板。我不知道你所说的
reldir
不会给我带来任何好处的话是什么意思?如果我不使用
reldir
,那么我必须在每个源文件前面加上文件夹名,但这意味着移动文件夹或重命名文件夹更加困难。是的,如果你要重构一个更大的项目,那么如果你计划移动目录,使用reldir(%D%)是个好主意。另一方面,它仍然不允许您更改二进制文件的输出目录,因为如果我没有弄错的话,您不能将其声明为%D%\u foo\u SOURCES。没有什么能阻止你在顶层构建所有东西并使用reldir。谢谢你的澄清。但是关于%D%,你错了。实际上,您可以使用bin\u程序+=%D%/foo,然后使用
%C%\u foo\u源=…
。区别在于在前缀中使用
%C%
%canon\u reldir%
作为cano
fatal error: debug.h: No such file or directory
 #include <debug.h>
src_foo_CPPFLAGS = \
    $(AM_CPPFLAGS) \
    -I$(top_builddir)/src \
    -DDATADIR='"$(datadir)"' \
    -DMODULEDIR='"$(moduledir)"' \
    -DLIBEXECDIR='"$(libexecdir)"'