我正在开发一个静态C库,并且一直在使用一个简单的Makefile。我们现在不得不支持异地安装等等,现在是时候采用更强大的构建标准了。我真的希望它是autotools - 我喜欢GNU Build System的自动一致性,我也发现它很容易使用。
那就是说,我有一个问题。
以下是项目结构的概述:
project/
common/
pkg/
inc/
src/
submodule1/
some_thing/
some_other_thing/
submodule2/
. . .
common
包含将安装在目标系统上的头文件 - 一个直接在常见下的头文件,以及一些常见的/ pkg内容。 (嗯,这不是真正的pkg,这只是一个例子。)common
下的所有内容都是.h
。
inc
包含严格与实现相关的内部包含文件,不应公开。 inc
下的所有内容均为.h
。
src
有一个用于多个子模块中每个子模块的目录,每个子模块可能会也可能不会被分成几个部分(子模块,如果需要)。 src
下的所有内容均为.c
。
原始makefile将设置一个SOURCES
变量,该变量由在src中递归发现的每个.c
文件组成,添加-I./common -I./inc
,构建目标文件,并将它们存档到库中。很简单。
嗯,使用automake,它似乎并不那么简单。我想到了为构建目标添加标志,例如`project_CPPFLAGS = -I。/ inc -I./common“ - 这解决了部分问题,但我觉得我做错了什么,不知何故。< / p>
使用那些(次优?)设置,我可以进行自动构建和链接库,这已经足够令人兴奋,但我在这里的真正原因是make install
。
common
包含库的公共接口。需要构建源,但也需要安装。如果我从project/
添加,则automake会看到common/thing.h
和common/pkg/other.h
等路径,并在安装时includedir
中显示错误路径。我想过把它递归到那个目录来构建一个只有安装头的项目,但是这不仅闻起来很糟糕,而且在我尝试它时它不起作用。库头文件需要一个特定的树结构 - 如何维护lib头树结构,使它们可用于所有源文件,并根据common
安装它们?
此外,是否有一些更优雅的方式来处理包含而不是强制-I
?我知道我必须将它们指定为HEADERS
才能将它们放入分发包中,但实际上似乎并没有将它们包括在内,让我有点迷失。
我觉得automake(也许是一般的GNU)期待我的项目的一些结构,我只是没有看到。 如果是这种情况,请告诉我 - 我非常愿意花一些时间来重构/重新组织项目。我真的觉得我错过了一些哲学观点 - 目前的结构是在没有指导或经验的情况下设计的,我并不依赖它。
感谢任何帮助。
答案 0 :(得分:6)
我认为使用-I
没有任何问题。它甚至允许在树和使用pkg / foo.h的第三方项目中始终使用非常#include <pkg/foo.h>
表示法。
AM_CPPFLAGS = -I${top_srcdir}/common -I${top_srcdir}/inc
要在common
中安装文件,您可以使用SUBDIRS = common
(来自顶级Makefile.am
),
# <top>/common/Makefile.am
nobase_include_HEADERS = pkg/foo.h pkg2/bar.h
或者,如果您选择执行非递归方法,例如
# <top>/Makefile.am
xxxpkgdir = ${includedir}/pkg
xxxpkg_HEADERS = common/pkg/foo.h
xxxpkg2dir = ${includedir}/pkg2
xxxpkg2_HEADERS = common/pkg2/bar.h