20

我正在研究scons,我只是想确保我知道替代方案是什么,然后再将一大块脑细胞投入到完全不同的东西中。我过去一直在使用 GNU make,但从来没有对它特别满意。

特别是:为什么 Ant 不经常用于 C / C++ 项目?(鉴于有ant cpptasks)我读过一些帖子说 Ant 更面向 Java(显然),但这样做有什么缺点?为什么 scons 比 make 好很多?

我正在使用 TI DSP 的交叉编译器,通常一个项目中有 20-50 个 cpp 文件。看起来构建管理中最难的部分是自动依赖检查。其他一切只是将文件列表与一组编译器选项映射在一起。

编辑:为什么交叉编译会改变什么?它是一个编译器,其运行方式与 gcc 的运行方式相同,只是它生成的目标文件/可执行文件无法在我的 PC 上运行。

4

5 回答 5

25

对于交叉编译,我认为您的最佳选择是CMakeAutotools。特别是如果您可以为多个架构/平台编译代码。我通常在本机机器上编译我的代码子集以进行单元测试,并将所有代码都用于目标平台。CMake 处理得特别好,因为它允许您指定交叉编译库的位置。因此,与其在 /usr/lib 中搜索交叉编译的 libpng,不如在 /opt/arm-eabi-gcc/ 或构建机器上安装了工具链库的任何地方进行查找。您可以为不同的变体创建多个构建目录,并使用 make 手动编译每个变体,或者使用脑残的手动递归 make 触发批次。

Ant 的缺点是它基本上与 vanilla Make 一样好或一样坏,另外一个缺点是您使用的东西对于 C 或 C++ 来说不是特别主流。您必须处理所有自己的依赖项——包括内部依赖项,例如 C 文件到头文件到库或可执行文件,以及外部依赖项,例如必须与 3rd 方库链接。另外,我认为 Ant C 任务并没有真正维护那么多。我见过的每个使用 Ant for C 的人都提倡使用 exec 任务来调用 GCC。

SCons 更好,但交叉编译不是它的强项。它也不是像 CMake 或 Autotools 这样的“构建系统”,它只是一个构建工具。正如他们的 wiki 上所说,它几乎是“使用 Python 制作”。不过,它确实内置了对依赖项的处理,这意味着您不必使用“gcc -MM -MD”或其他任何东西在那里滚动自己的,所以这比 Make 更有优势。SCons 还支持检测已安装的 3rd 方库,但通常执行的方式会大大增加您的构建时间。与其他系统不同,SCons 每次运行时都会运行检查阶段,尽管大多数结果都会被缓存。SCons 也因其较长的构建时间而臭名昭著,尽管对于 50 个文件来说这不是问题。正如邮件列表上的这个线程所讨论的那样。通常,您强制构建类似于 Unix 平台,然后覆盖 C 编译器的名称。构建多个变体或将构建目录与源目录分离充满了陷阱,这使得它不太适合交叉和本地编译代码。

CMake 和 Autotools 的依赖问题解决得很好,autotools 的交叉编译支持也很成熟。CMake 自 2008 年 4 月发布的 2.6.0 版以来就进行了交叉编译。您可以免费获得这些功能,以及打包和运行单元测试(“make check”或类似目标)等其他功能。这两种工具的缺点是它们需要引导。对于 CMake,您需要安装 CMake 二进制文件以创建 Makefile 或 Visual Studio 解决方案文件。在 Autotools 的情况下,它稍微复杂一些,因为不是每个编译软件的人都需要安装 automake 和 autoconf,只有那些需要更改构建系统的人(添加新文件被视为更改构建系统)。2 阶段引导 (configure.ac -> configure,

对于编辑:交叉编译在构建系统中是一个额外的麻烦,因为它增加了程序和库的自动检测的复杂性。SCons 不处理这个问题,它留给你来解决。Ant 同样什么也不做。Autoconf 在 autotools 的情况下会处理这个问题,但是当您在链接阶段尝试使用 /usr/lib 时,您可能必须在配置时在命令行上提供“--with-libfoobar=/some/path”,否则会遇到断开的链接. CMake 的方法是使用工具链文件更重一些,但这意味着您不必指定所有工具和库(CC、CXX、RANLIB、--with-ibfoo= 等),因为它们是从一个标准的约定。理论上,您可以在多个项目中重用适当制作的 CMake 工具链文件来交叉编译它们。

于 2009-06-23T20:58:58.633 回答
6

几年前我大量使用 Ant+CppTasks 构建非常大的代码库,通过 JNI 集成到新的 Java 代码中,并且对非常可靠的 C++ 代码增量构建的结果非常满意,良好的灵活性(在构建文件中,或通过调整代码)。但是,CppTasks 是一个没有社区的项目,维护者(Curt Arnold)很长一段时间都没有对它做任何事情。它仍然非常好用,但请注意,很少有人知道或使用 CppTasks(例如,当我需要 C 文件的特定编译器时,编译器“投标”文件的方式会咬我一口,而不同的 C++ 编译器正在挑选这些文件)反而)。

CppTasks 跟踪编译选项的方式,并动态扫描源头的依赖项,一直足够快(有一些依赖项缓存),这意味着我使用过的唯一一个具有准确增量构建的系统,这在当构建非常大的代码库。

因此,正如我在 Ant 用户/开发人员列表中所说的,如果你有很多 Java 的东西并且已经在 Ant 上进行了投资,并且不害怕深入研究 CppTasks的文档代码,那么现在需要构建 JNI“胶水”代码,和/或胶水代码公开的“遗留”本机库,这是一个有价值的竞争者,而且回报可能很大。

我为 Windows dll 轻松集成了 <rc> 以添加完整的版本信息,例如,编写一个小 Ant 任务来正确格式化 .res 文件。它对我有用,但 Ant+CppTasks 绝对更适合“高级”Ant 用户/开发人员恕我直言。

我希望这有帮助。--DD

于 2009-06-24T17:26:20.647 回答
3

我想推荐terp从 ANT 构建 C++ 项目。我们开发 terp 是因为 ANT 是我们选择的构建工具,而 CppTasks 有点长,而且我们想在不同的抽象级别上工作。terp 支持很多不同的编译器,它由我们公司提供支持。但对于大多数项目来说,它不是免费的。

我们设计 terp 主要是为了完全重建,而不是使用依赖分析进行增量构建。我们正在到达那里,但它还没有到达那里。terp 的最佳选择是在多平台、多procarch、多编译器版本中,您不想为所有组合维护n 个不同的配置。目前(2009 年 7 月)它处于公开测试阶段,但很快就会发布。

于 2009-07-13T19:08:40.410 回答
2

在过去的五年里,我一直在从事一个使用 ant 进行 x86 和 arm 构建的项目。为了我们的目的,我们调整了 cpptasks 以生成一个通用编译器,我们只需将前缀传递给......例如 arm-gum-linux-gnueabi- 然后将其添加到实际工具(例如 g++ 或 ar 或其他)之前。没有前缀意味着您获得了开发平台构建工具。用于交叉编译的工具链在其构建工具二进制文件中具有这些前缀。使用 Ant 而不是任何基于 make 的东西的几乎全部原因是 cpptasks 能够进行非必要的构建,以及为了让 autoconf 满意而必须发生的大量事情。我们能够支持几乎所有源文件的范例,特别是那些在库集的文件夹树结构中的源文件,可以创建/重命名/删除,并且不需要对构建文件进行编辑。一个小缺点是链接文件会以一种会导致不必要的重建的方式更新属性。

<target name="lib.cvp">
<fetch.and.log.version 
    svnvers.target="common/cvp" 
    svnvers.property="libcvp.version"/>
    <cc objdir="${obj.dir}/common/cvp" 
        commandPrefix="${command.prefix}" 
        compilerName="${compiler.name}"
        outfile="${lib.dir}/cvp" outtype="static">
        <compiler extends="base.compiler"/>
        <compilerarg 
            value="-D__CVP_LIB_BUILD_VERSION__=&quot;${libcvp.version}&quot;"/>
        <compilerarg 
            value="-D__BUILD_NOTES__=&quot;${libcvp.toolversion}&quot;"/>
        <compilerarg if="is.x86" value="-DARCH_X86"/>
        <linker extends="base.linker"/>
        <includepath refid="common.inc"/>
        <fileset dir="${project.home}/common/cvp">
            <include name="*.c"/>
            <include name="*.cpp"/>
        </fileset>
    </cc>
</target>
于 2011-09-23T06:04:17.823 回答
1

Ant 有一个非常依赖 Java 的用户群(出于自然原因)。Ant 在更广泛的环境中非常有用的事实是大多数非 Java 开发人员不知道的。因此,如果您使用 Ant 来构建您的 C/C++ 代码,那么如果您使用具有更大用户群(CMake 或 SCons)的系统,那么您自己构建的代码要多得多。

我个人对 CMake 非常满意,主要是因为它是唯一可以生成真正 Visual Studio 项目的构建系统。SCons 也可以,但它们只对 SCons 进行外部调用,而 CMake 生成的项目使用 Visual Studio 自己的构建引擎。如果您与习惯于 Visual Studio 的人一起工作,这将非常有用。

我不确定我是否会将 CMake 对交叉编译的支持称为“成熟”,因为它还很年轻。但是 CMake 的人对此很认真,所以我会毫不犹豫地尝试一下。

于 2009-06-24T10:15:15.443 回答