10

使用 CMake 和 Make 构建项目时,您可以make从构建树的子目录(即从包含您的顶级目录的任何目录下方的目录Makefile)执行,并且make将(据我所知)构建位于或以下的所有目标那个目录。这是因为 CMake 会Makefile为每个包含目标的目录生成一个,因此当您在具有目标的目录中时,会make找到Makefile用于构建这些目标的目录。

然而,当 CMake 生成 Ninja 文件时,它只生成一个 build.ninja文件,该文件位于构建树的顶层。ninja因此从顶级目录以外的目录调用失败(即使该-f选项也不起作用,因为ninja找不到rules.ninja文件)。

有没有办法模拟在目录及其下方构建目标的“make-like”行为?据我所知,没有对应于“特定目录下的所有目标”的 Ninja 目标。(这可以使用以每个目录命名的虚假目标来模拟,这些目标依赖于该目录及其下方的所有目标,但默认情况下 CMake 不会生成此类目标。)

4

3 回答 3

8

ninja <DIR>/all适用于最新版本的 Ninja (1.7.2)。1.3.4 版不允许这样做。

我在手册上找不到对此的参考。但是,CMake 在这里记录这一点:

最新版本的 ninja 程序可以通过“all”目标构建项目。还提供了“安装”目标。

对于项目的每个子目录 sub/dir,都会生成额外的目标:

  • sub/dir/all
    取决于子目录所需的所有目标。
  • sub/dir/install
    在子目录中运行安装步骤(如果有)。
  • sub/dir/test
    在子目录中运行测试步骤(如果有)。
  • sub/dir/package
    运行子目录中的打包步骤(如果有)。
于 2017-07-15T11:05:03.523 回答
2

这对我有用:

cd <build-root>
DIRECTORY=<path-relative-to-build-root>
ninja -t targets all | egrep "^${DIRECTORY}/" | egrep CXX_EXECUTABLE_LINKER | \
    sed -e 's/:.*//g' | xargs ninja

ninja -t targets all - 列出所有目标(包括目标类型)

egrep "^${DIRECTORY}/" - 过滤目标列表以仅包含所需目录中的目标

egrep CXX_EXECUTABLE_LINKER - 将目标限制为 C++ 可执行文件。您可以删除或调整它以获得您感兴趣的目标集。

sed -e 's/:.*//g' - 删除目标类型,例如“:CXX_EXECUTABLE_LINKER”

xargs ninja - 调用 ninja 来构建目标

于 2016-12-07T19:44:19.943 回答
1

好问题。如果你找到了,我想知道答案。我自己正在过渡到 cmake+ninja 的过程中。

我发现我无法在不同级别创建具有相同名称的目标(如果有一种我有兴趣知道的方法)。所以我为不同的目标采用了命名约定,例如 name - builds program or library test.name - runs tests for the named program or library doxygen.name - build doxygen for the named program or library

对于更深层次的层次结构,您可以执行以下操作: doxygen.subproject doxygen.subproject.name

使用此模式,您可以精确控制构建的内容,但您必须从顶级构建目录发出命令。我认为在我习惯了这一点后,我会发现它更有效率,因为在构建或运行某些东西之前不需要更改目录,虽然有时需要额外输入一些 shell 历史记录,但通常已经涵盖了它。

这是通过使用add_custom_target()并添加适当的依赖项在后台实现的。我使用自动执行此操作,以便宏“ add_doxygen() ”将为程序添加 doxygen 目标,并使用add_dependencies()使每个更高级别的 doxygen 目标依赖它。

于 2016-02-08T15:07:55.477 回答