CMake如何检查是否需要构建目标

4

我将尝试为您提供帮助:如何检查构建目标?

请考虑以下CMake脚本:

cmake_minimum_required(VERSION 3.5.1)
project(cppTests)

# How to check at this point the target of build
if(TARGET "cppTests")
    message(STATUS "Target is cppTests")
else()
    message(STATUS "Target is not cppTests")
endif()


message(STATUS "Target is ${TARGET}")
set(CMAKE_CXX_STANDARD 11)

set(SOURCE_FILES main.cpp)
add_executable(cppTests ${SOURCE_FILES})

然后我调用以下内容:

/home/username/Software/clion-2017.1.1/bin/cmake/bin/cmake --build /home/username/Projects/cppTests/cmake-build-debug --target cppTests -- -j 8

如何在CMake脚本中使用 --target 选项后检查目标 cppTests?我想要类似 Makefiles 中的 MAKECMDGOALS 的东西。我找不到任何有用的解决方案...
4个回答

5
在CMake生成项目文件后,开发者选择要构建的目标。当CMake运行时,它不知道开发者将要构建哪个目标。因此,你所询问的在CMake项目中并没有实际意义。在Makefile中,没有单独的configure步骤,它是构建的一部分,这也是为什么它可以提供像MAKECMDGOALS这样的功能。此外,可能值得重新考虑是否真的需要这种Makefile功能,因为它并不适合一般使用(强调我的部分可参考这里)。
在你的示例中,你还误用了if(TARGET...)。这个结构是用来测试是否由项目定义了特定的CMake目标(在你的示例中,在if()命令之后它并没有被定义,因此会始终评估为false)。有关详细信息,请参阅此处的文档。

我可以用add_custom_command(TARGET cppTests PRE_BUILD)替换MAKECMDGOALS,但实际上它不起作用,无论是在现实生活中还是根据CMake的文档。我想在构建特定目标之前生成一些文件。如果add_custom_command(TARGET cppTests PRE_BUILD)能够工作,那么它将解决我的问题。 - Denis Kotov

4

在CMake的世界里,你所问的并没有意义。一个CMake项目的时间线由三个不同的步骤组成:

configure time  >  generate time  >  build time
\---------------v--------------/     \---v----/
        CMake is running           make is running

配置步骤中,CMake读取并解析CMakeLists.txt文件,并将处理后的数据存储在内存中。当您在CMake GUI中按下Configure按钮时,会发生这种情况。
生成步骤中,CMake根据内存中的数据生成构建系统文件(Makefiles、Visual Studio解决方案和项目等)。当您在CMake GUI中按下Generate按钮时,会发生这种情况。
从命令行运行cmake会立即进行配置,然后是生成。
然后,CMake完成了构建系统并终止其运行。现在,您有一个可以被构建工具(如makemsbuild)处理的工作构建系统。即使您使用cmake --build运行此构建工具,这个新的cmake调用也不会读取您的CMakeLists.txt文件。它只是从生成的CMakeCache.txt中访问最少量的信息,以确定要运行哪个构建工具,并运行该工具。
您没有说明您想通过这些信息实现什么目标,但也许您可以使用像add_custom_command(TARGET cppTests PRE_LINK)这样的东西?

您的说法并不完全正确...事实上,在cmake为构建生成文件之后,您可以使用类似于以下命令的cmake运行命令来运行构建:/home/redra/Software/clion-2017.1.1/bin/cmake/bin/cmake --build /home/redra/Projects/cppTests/cmake-build-debug --target cppTests -- -j 8 - Denis Kotov
add_custom_command(TARGET cppTests PRE_LINK) - 我需要使用 add_custom_command(TARGET cppTests PRE_BUILD) 来替换 if else,但是由于某些原因它在 Linux 工具如 Make 中无法工作。文档中也提到了这一点。 - Denis Kotov
我不太明白为什么没有 PRE_BUILD 的位置,我们可以创建 .PHONY 目标,这个目标运行 shell 命令,并使基本目标依赖于它。 - Denis Kotov
关于 PRE_BUILD:makefile 是否允许您指定在分析其他依赖项之前必须满足特定依赖项的要求? - Angew is no longer proud of SO
1
如果你做得正确,它确实可以保证正确的重新生成。如果你在创建文件的add_custom_command()中指定了依赖项,CMake会遵守它们。 - Angew is no longer proud of SO
显示剩余4条评论

2

我找到了一个解决方案:


add_custom_command(
        OUTPUT fidl_files_generated
        DEPENDS "./interfaces/*.fidl"
        COMMAND touch fidl_files_generated
        COMMAND /home/redra/Projects/Automotive/cgen/commonapi-generator/commonapi-generator-linux-x86_64 -sk ../interfaces/ *.fidl
        COMMAND /home/redra/Projects/Automotive/cgen/commonapi_dbus_generator/commonapi-dbus-generator-linux-x86_64 ../interfaces/ *.fidl
)

add_custom_target(fidl_gen
                  DEPENDS fidl_files_generated)

set(GENERATED_FILES "../cmake-build-debug/src-gen/v1/commonapi/HelloWorldDBusProxy.cpp"
                    "../cmake-build-debug/src-gen/v1/commonapi/HelloWorldDBusDeployment.cpp"
                    "../cmake-build-debug/src-gen/v1/commonapi/HelloWorldDBusStubAdapter.cpp"
                    "../cmake-build-debug/src-gen/v1/commonapi/HelloWorldStubDefault.cpp"
                    "../cmake-build-debug/src-gen/v1/commonapi/HelloWorldDBusDeployment.cpp")
set_source_files_properties(${GENERATED_FILES} PROPERTIES GENERATED TRUE)

add_executable(
        CommonAPI_Server
        ${SOURCE_FILES}
        ${GENERATED_FILES})
add_dependencies(CommonAPI_Server fidl_gen)

感谢大家的支持!!

特别感谢Angew提供的支持和帮助!!!


这一切都很棒,但是当你不知道将会得到什么GENERATED_FILES时,它就无法工作:-( GLOB_RECURSE在这里会失败,因为它在配置时间可操作。 真正的问题是add_custom_command没有提供从命令获取结果的工具。看看execute_process-你可以获得返回值、错误等。 所以你不能创建一个自定义命令,它会“返回”在某个目录中找到的GENERATED文件列表:-( 不要紧,只是大声思考。 - Andrey Borisovich

0

我不确定我完全理解了你的问题,但是根据我的理解,你正在寻找变量CMAKE_PROJECT_NAMEPROJECT_NAME

if (${CMAKE_PROJECT_NAME} STREQUAL "cppTests")
    message("CMAKE_PROJECT_NAME is \"cppTests\"")
else ()
    message("CMAKE_PROJECT_NAME is NOT \"cppTests\"")
endif ()

查看常用变量列表此处。每当我使用CMake时,我经常会保持此链接处于打开状态;我认为您也会觉得这很有用。


不,我不是在寻找 ${CMAKE_PROJECT_NAME},因为同一个项目中可能会有不同名称的各种目标,例如:add_executable(cppExe ${SOURCE_FILES}); add_library(cppLib ${SOURCE_FILES})。 - Denis Kotov
我正在寻找类似于 Makefile 中的 MAKECMDGOALS 的东西。 - Denis Kotov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接