我有一个 C++ cmake 项目。在这个项目中,我构建(除其他外)一个示例,我需要在其中使用另一个项目,将其称为 Foo
。此 Foo
项目不提供 cmake 构建系统。相反,它有一个预制的 Makefile.custom.in。为了构建一个使用 Foo
特性的可执行文件,需要在他的项目中复制这个 makefile,并修改它(通常设置 SOURCES 变量和一些编译器标志)。基本上,这个 Makefile 最终包含您的可执行文件的源代码以及 Foo
项目的所有源文件。您最终不会将 Foo
用作库。
现在,这是一个我不喜欢的设计,但为了这个问题,假设我们坚持使用它。
为了在我的 cmake 构建中创建我的示例,我添加了一个自定义目标:
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/Makefile.custom.in Makefile.custom)
ADD_CUSTOM_TARGET(my_target COMMAND $(MAKE) -f Makefile.custom
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
这行得通。我可以为 cmake 指定一些变量,这些变量在对 CONFIGURE_FILE
的调用中得到解析,我最终得到一个有效的 Makefile.custom。然后,从构建目录调用 make my_target
,我可以构建可执行文件。我什至可以将它添加到 all
目标(以节省我键入 make my_target
的精力)
SET_TARGET_PROPERTIES(my_target PROPERTIES EXCLUDE_FROM_ALL FALSE)
甜甜的。但是,cmake 似乎将单个作业分配给自定义目标,从而减慢了我的编译时间(Foo
源文件夹包含几十个 cpp 文件)。最重要的是,make clean
目标不会转发到自定义 makefile。我最终不得不添加另一个目标:
ADD_CUSTOM_TARGET(really-clean COMMAND "$(MAKE)" clean
COMMAND "$(MAKE)" -f Makefile.custom clean
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
与 my_target
和 all
不同,我不能将其包含在 clean
目标中(可以吗?)。
现在,我知道一个更简洁的解决方案是将 Foo
项目构建为外部项目,然后链接到它。然而,我被“推荐”使用他们的 Makefile.custom.in makefile,修改我需要的几行(添加我的源代码,指定编译器标志,以及其他一些小的修改)。因此,无论这种设计模式多么整洁干净,我的问题是:
- 有没有办法告诉 cmake make 在制作目标 my_target 时应该使用超过 1 个作业?
- 是否有更简洁的方法将预先存在的 makefile 包含在 cmake 项目中?请注意,我不想(不能?)将
Foo
用作库(并链接到它)。我想(需要?)使用不是由 cmake 生成的 makefile 将它与我的可执行文件一起编译(好吧,cmake 可以通过CONFIGURE_FILE
解决一些变量,但仅此而已)。
注意:我知道 ExternalProject(同样在 this 回答中建议),但我认为这并不是我在这里需要的(因为它会构建 Foo
然后将其用作图书馆)。此外,我的项目和 Foo
都是专门用 C++ 编写的(完全不确定这个问题)。
我希望这个问题是有道理的(不管最终的设计有多丑陋/烦人/不令人满意)。
编辑:我使用的是 cmake 版本 3.5.2
最佳答案
首先,由于您定义了自己的目标,您可以直接在 CMakeLists.txt
中为目标 my_target
的构建过程分配更多核心。
您可以包含 Cmake 模块 ProcessCount
以确定机器中的内核数量,然后将其用于并行构建。
include(ProcessorCount)
ProcessorCount(N)
if(NOT N EQUAL 0)
# given that cores != 0 you could modify
# math(EXPR N "${N}+1") # modify (increment/decrement) N at your will, in this case, just incrementing N by one
set(JOBS_IN_PARALLEL -j${N})
endif(NOT N EQUAL 0)
当你定义你的自定义目标时有如下内容:
ADD_CUSTOM_TARGET(my_target
COMMAND ${CMAKE_MAKE_PROGRAM} ${JOBS_IN_PARALLEL} -f Makefile.custom
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
顺便说一下,我认为您没有必要在目标的 COMMAND
中也包含 CMAKE_BUILD_TOOL
。
我相信您可以调用
make -j8 my_target
它可能会在不修改 CMakeLists.txt
的情况下启动 8 个作业(只是一个例子),但我不能保证这个工作已经按照你的方式定义了 COMMAND,如果足够的话就试试吧。< br/>
对于第二点,我现在想不出“更清洁”的方法。
关于c++ - CMake:包含外部 makefile 时的编译速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41816836/