我有一个使用 CMake 作为构建系统的C++项目。总而言之,它在项目的根目录中有一个CMakeLists.txt
,用于配置一些变量,设置主要源,并将主要源添加到主可执行文件中;然后,它继续调用add_library
并多次target_link_libraries
(对于 SDL2、GLAD 和 JsonCPP(。接下来,它创建第二个可执行文件,其中包含一些自己的源代码以及主可执行文件中使用的一些源代码和库。尽管与问题无关,但此可执行文件仅包含单元测试。
虽然我当前的配置确实产生了想要的结果,即一个包含项目本身的可执行文件和一个包含单元测试的完全独立的可执行文件,但它仍然会增加构建时间的开销。你看,每当我调用make
时,总是构建主可执行文件和第二个可执行文件。我想要的是让make
只构建主可执行文件,而make test
(或make tests
,或make catch
(构建第二个可执行文件。
我尝试了几种方法,但由于某种原因没有成功,我在互联网上的搜索几乎没有结果。我有一种感觉,答案就在add_custom_command
,我根本无法正确理解它。
您还应该确保单元测试目标和主目标尚未与依赖项(例如add_dependencies
命令(链接。当然,如果这两个目标共享一个源文件(他们不应该!(,那么如果不进行广泛的重构,就没有太多事情可以做。
可以在第二个单元测试目标上使用EXCLUDE_FROM_ALL
目标属性。但是,具有单独的源(如前所述(可以避免在更改主源文件时不必要地重新生成单元测试。
此外,要使用自定义名称调用该目标(如果不希望更改可执行文件的名称(,您可以添加一个空的自定义目标,然后从所需的实际目标添加对其的依赖项,如下所示:
add_custom_target(tests)
# various other unit test targets
add_executable(FooUnitTest [...])
add_dependencies(tests FooUnitTest)
这将允许您键入make tests
并构建虚假目标所依赖的所有过时目标。
一个普通的make
隐式调用make all
。因此,如果要构建单个目标,则必须通过make <target>
显式调用它。
要列出 CMake 生成的所有目标,请调用make help
。
您可以在 cmake 中创建两个可执行文件,而无需使用对象库编译源代码两次。
add_library( common_objects OBJECT ${MY_SOURCES})
add_executable(exec1 $<TARGET_OBJECTS:common_objects> ${SOURCES_ONLY_FOR_FIRST})
# different configuration may be set
add_executable(exec2 $<TARGET_OBJECTS:common_objects> ${SOURCES_ONLY_FOR_SECOND})