当我使用cmake构建项目时,如何在使用`ninja`构建时仍然使用`make`?

问题描述 投票:0回答:1

Ninja 作为构建工具比 Make 更先进且更有助于调试。

但是,由于右-右-右-右-左的模式,输入

ninja
的速度要慢得多,而
make
的右-左-右-左的模式则非常快。我想在使用 make
构建
打字
ninja

我有几个项目,由于历史原因,我必须使用 make 或 ninja,我想将所有项目标准化为

make

我考虑过使用一些 shell 技巧,比如

alias make='/bin/make || ninja'
但有一些缺点:

  1. 它们始终依赖于手动或 .bashrc 设置环境变量。我不想那样做。

  2. 别名取决于了解

    make
    ninja
    二进制文件

    的位置

所以我正在考虑将 something 添加到我的 CMakeLists.txt 文件中的最简单方法,这样它就会删除

Makefile
,例如
drop_makefile()
。即使成本是将该行添加到项目中的每个行中。

很容易丢弃类似的东西

all:
    ninja

如果您所做的只是

make
,那么效果很好。

但是,如果我想制作忍者中存在的特定目标,它就不会像

make tests
那样工作,它应该翻译成
ninja tests

cmake makefile ninja
1个回答
0
投票

如果你想要生成一个包含所有已知目标的

Makefile
对于 CMake,您可以使用
BUILDSYSTEM_TARGETS
属性。由于这是一个 Directory 属性,您将需要遍历项目的所有目录。 幸运的是,答案 以编程方式获取 CMake 项目中的所有目标 已经展示了如何做到这一点。我用用户ilya1725的功能
get_all_targets
进行了测试。

剩下的就是迭代列表并创建像这样调用

ninja
的 Makefile 语法:

function(drop_makefile)
    # Bail if CMake is already generating Makefiles
    if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
        return()
    endif()

    # Function get_all_targets taken from 
https://stackoverflow.com/questions/60211516/programmatically-get-all-targets-in-a-cmake-project
    get_all_targets(_all_targets .)

    # Make magic "all" target the first one
    list(PREPEND _all_targets "all")
    foreach(_target IN LISTS _all_targets)
        string(APPEND _makefile ".PHONY: ${_target}\n${_target}:\n\tninja ${_target}\n")
    endforeach()
    file(WRITE ${CMAKE_BINARY_DIR}/Makefile ${_makefile})
endfunction(drop_makefile)

在项目的根目录中调用该函数,结果将是一个包含项目已知的所有(非导入)目标的

Makefile
。我无法摆脱这种违背 CMake 目的的感觉。

顺便说一句,

make
将评估其选项,但不会将其转发给
ninja
。 像
make -j32
这样的东西会产生 32 个工作,但不会在后台调用
ninja -j32

此外,CMake 为构建工具提供了自己的抽象,如

cmake --build
。这将调用正确的工具并消化一些常见选项,例如
--jobs
。在这个问题中,击键是一个因素,对于它们来说,这是不可能的。

一个更简单的解决方案是为每个项目提供自己的配置文件

alias_make.sh
,其中包含以下行之一:

alias make=make              # for a native Makefile project
alias make=ninja             # for a native ninja project
alias make='cmake --build'   # for all CMake projects

当开始处理一个项目时,您需要做的就是

source alias_make.sh
并且您可以在幸福无知的情况下使用
make
实际调用
ninja
(好吧,除非它因为它们不一样而崩溃,当然).

顺便说一句,我经常使用

mak
来表示此类
alias
或 shell
function
,因为它可以节省 又一个 击键。如果您认为自己可以克服肌肉记忆,请考虑删除最后一个字母。

最后,我要说的是

make
ninja
并不相同,因此每次尝试将其中一个伪装成另一个都会导致泄漏抽象

© www.soinside.com 2019 - 2024. All rights reserved.