cmake的:复制升压构建的"在Jamfile中&QUOT创造一切条件;行为? [英] cmake: replicate boost-build's "build everything in Jamfile" behaviour?
问题描述
我转换一个 升压构建
构建系统CMake的。
I am converting a boost-build
build system to cmake.
一个升压构建的功能是,你可以指定一个的Jamfile
(将A 的CMakeLists.txt 等价路径code>文件),其中规定的所有目标将建成。
One of the features of boost-build is that you can specify a path to a Jamfile
(the equivalent of a CMakeLists.txt
file) and all the targets specified therein will be built.
例如,具有以下项目的结构:
For example, with the following project structure:
root
|
+--- foo
| |
| +--- test
|
+--- bar
| |
| +--- test
|
+--- app
如果您输入以下命令:
$ b2 foo
的的Jamfile
在根/富
将被执行,从而在富
图书馆正在兴建,而测试
测试正在建造和运行
The Jamfile
under root/foo
will be executed, resulting in the foo
library being built, and the test
tests being built and run
下面是一个使用简单的构建配置升压构建
:
Here is a simple build configuration using boost-build
:
Jamroot中
:
Jamroot
:
using gcc ;
project proj : requirements
<link>static
<include>.
;
build-project foo ;
富/ Jamfile中
:
foo/Jamfile
:
lib foo : [ glob *.cpp ] ;
build-project test ;
富/测试/ Jamfile中
:
foo/test/Jamfile
:
import testing ;
unit-test foo-tests
: [ glob *.cpp ]
..//foo
;
您会注意到 Foo的Jamfile的内
有一个指令建设项目测试
You will notice that within foo's Jamfile
there is a directive build-project test
这意味着,如果我键入 B2富
然后在的lib / Jamfile中
一切都将被执行,从而导致富
和 富/测试
正在建设中。
This means that if I type b2 foo
then everything in lib/Jamfile
will be executed, resulting in foo
and foo/test
being built.
此外,在 Jamroot中
有一个指令建设项目富
这意味着,如果我只需键入 B2
然后一切都在 Jamroot中
将被执行,从而富
和富/测试
正在建设中。
This means that if I just type b2
then everything in Jamroot
will be executed, resulting in foo
and foo/test
being built.
有这样容易建立在整个项目并获得所有来源和内置的所有测试。
It is thus easy to build the whole project and get all sources and all tests built.
这也很容易建立只是一个子目录并获得只有它的来源和试验建立。
It is also easy to build just a subdirectory and get only it's sources and tests build.
有这种行为我试图复制。
It is this behaviour I'm trying to replicate.
根/的CMakeLists.txt
:
root/CMakeLists.txt
:
cmake_minimum_required(VERSION 3.2.2)
project(proj CXX)
add_subdirectory(foo)
富/的CMakeLists.txt
:
foo/CMakeLists.txt
:
file(GLOB src "*.cpp")
add_library(foo STATIC ${src})
add_subdirectory(test)
富/测试/的CMakeLists.txt
:
foo/test/CMakeLists.txt
:
file(GLOB src "*.cpp")
add_executable(foo_test ${src})
add_test(foo_test foo_test foo)
# run tests if foo_test.passed is missing or outdated
add_custom_command(
OUTPUT foo_test.passed
COMMAND foo_test
COMMAND ${CMAKE_COMMAND} -E touch foo_test.passed
DEPENDS foo_test
)
# make tests run as part of ALL target
add_custom_target(run_foo_test
ALL
DEPENDS foo_test.passed)
以上的CMakeLists.txt
结构允许我制作
键,同时拥有富
和 foo_test
建。
The above CMakeLists.txt
structure allows me to make
and have both foo
and foo_test
built.
不过,如果我指定使富
,仅 富
将建成,但 foo_test
不会,并且测试将不会被运行。
However, if I specify make foo
, only foo
will be built, but foo_test
won't be, and the tests won't be run.
问:
- 怎样才可以有内一切
富/的CMakeLists.txt
建当我输入使富
? - 另外,我怎么能引起目标
foo_test.passed
来建设成为更新的目标富
<强的一部分>和打造像所有
的一部分目标?
- How can I have everything within
foo/CMakeLists.txt
built when I typemake foo
? - Alternately, how can I cause target
foo_test.passed
to be built as part of updating targetfoo
AND build as part of theALL
target?
推荐答案
下面是达到要求的实现。
Here is an implementation which achieves the requirements.
这是一个有点令人费解,因为它需要多个假目标和依赖链接。
It's a bit convoluted as it requires several phony targets and dependency chaining.
第1步:
- 创建这对于一个模块的所有其他目标将在 收集假目标
- 添加假目标
所有
,以便它是建立在作为全球构建过程的一部分
- create a phony target which all other targets for a "module" will be collected under
- add the phony target to
ALL
so that it is built as part of the global build process
富/的CMakeLists.txt
:
# create a phony target which all 'foo' related items will be added to
add_custom_target(foo
ALL
)
第二步:
- 模块作为一个依赖中添加的每个目标这个假目标
libfoo的
:
libfoo
:
- 注意这里我已经更名为
富
到libfoo的
,因为我们现在已经使用富
我们前面伪目标。 - (这将在事实上导致了生成的库被称为
liblibfoo.a
,这是一个有点难看)
- Note here I have renamed
foo
tolibfoo
as we've now usedfoo
for our earlier phony target. - (This will in fact result in the generated library being called
liblibfoo.a
, which is a bit ugly)
富/的CMakeLists.txt
:
add_library(libfoo STATIC ${src})
# add libfoo as a dependency of foo, so 'make foo' will build libfoo
add_dependencies(foo
libfoo)
foo_test
:
foo_test
:
使测试自动运行作为构建的一部分有点令人费解。
Making the tests run automatically as part of the build is a bit convoluted.
您必须:
- 创建测试可执行
- 添加
custom_command
它运行测试,并生成一个标记文件(foo_test.passed
),如果他们通过 - 添加
custom_target
(foo_test.run
),这取决于定点(foo_test .passed
) - 添加之间的依赖
富
和foo_test.run
- create the test executable
- add a
custom_command
which runs the tests and generates a sentinel file (foo_test.passed
) if they pass - add a
custom_target
(foo_test.run
) which depends on the sentinel (foo_test.passed
) - add a dependency between
foo
andfoo_test.run
foo_test /的CMakeLists.txt
:
add_executable (foo_test main.cpp)
target_link_libraries(foo_test libfoo ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
# create foo_test.passed command which generates the sentinel file when the tests pass
add_custom_command(
OUTPUT foo_test.passed
COMMAND foo_test
COMMAND ${CMAKE_COMMAND} -E touch foo_test.passed
DEPENDS foo_test
)
# create foo_test.run target which depends on foo_test.passed
add_custom_target(foo_test.run
DEPENDS foo_test.passed
)
# add foo_test.run as a dependency of foo, so 'make foo' will build foo_test.run
add_dependencies(foo
foo_test.run
)
因此,目标富
的 libfoo的
和 foo_test.run
作为依赖。
这样一来,既制作
和使富
建立 libfoo的
和构建和运行 foo_test
(通过 foo_test.run
和 foo_test.passed
)
As a result, both make
and make foo
build libfoo
and build and run foo_test
(via foo_test.run
and foo_test.passed
)
感知clunkiness:
-
的
富
- >foo_test.run
- >foo_test.passed
- >foo_test
依赖链
The
foo
->foo_test.run
->foo_test.passed
->foo_test
dependency chain.
在升压构建
您可以命名库富
而不引起<$之间的冲突C $ C>富假目标和富
库(和 B2富
建立两个在富
库及其测试)
In boost-build
you can name the library foo
without causing a clash between the foo
phony target and the foo
library (and b2 foo
builds both the foo
library and its tests)
然而,它的工作原理,并在没有更好的解决方案,都会给我我想要的东西。
However, it works, and in the absence of a more elegant solution, will give me what I want.
这篇关于cmake的:复制升压构建的&QUOT;在Jamfile中&QUOT创造一切条件;行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!