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