CMake - 如何在每次构建项目时停止构建每个依赖项
CMake - How to stop building every dependency every time I build my project
我有一个 cmake 列表文件,它通过 ExternalProject_Add
引入依赖项。在我的项目(使用这些依赖项)的初始编译中,我希望它们被构建(或者如果配置从 Debug 更改为 Release)。发生这种情况,但它发生在项目源中的任何后续代码更改之后。因此,例如,如果我简单地向 cout
添加一行到终端并构建我的项目,visual studio 会遍历与我的项目关联的每个项目并重建它。当然,它会在不必要时跳过实际的重新编译,但是为每个依赖项执行整个构建步骤并不理想。
因此我想知道如何构建此 cmake 项目以避免每次更改项目源时都必须构建每个依赖项?
下面是我的 CMakeLists.txt
文件。这是一项正在进行的工作。我只是在添加部分并进行测试,以确保我收到我想要的结果(这里还有一些非跨平台的东西,目前只是为了测试目的而完成的):
cmake_minimum_required(VERSION 3.20.0)
# Define our project name
set(PROJECT_NAME test)
project(${PROJECT_NAME})
if(MSVC)
get_filename_component(_vs_bin_path "${CMAKE_LINKER}" DIRECTORY)
set(libexe "${_vs_bin_path}/lib.exe")
message("LOOKHERE3:${libexe}")
endif()
# Make sure binary directory is not the same as source directory
if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(
FATAL_ERROR
"In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
)
endif()
# This Project Depends on External Project(s)
include(ExternalProject)
# SETUP GLFW
set(libGLFW glfw)
ExternalProject_Add(${libGLFW}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.4
GIT_SHALLOW ON
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install
-DGLFW_BUILD_DOCS:BOOL=OFF
-DGLFW_BUILD_EXAMPLES:BOOL=OFF
-DGLFW_BUILD_TESTS:BOOL=OFF
)
set(GLFW_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install)
add_library(GLFW_LIBRARY STATIC IMPORTED)
set_target_properties(GLFW_LIBRARY PROPERTIES IMPORTED_LOCATION ${GLFW_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}glfw3${CMAKE_STATIC_LIBRARY_SUFFIX})
#message("LOOKHERE:${CMAKE_STATIC_LIBRARY_PREFIX}glfw3${CMAKE_STATIC_LIBRARY_SUFFIX}")
# SETUP GLAD
set(libGLAD glad)
ExternalProject_Add(${libGLAD}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}
GIT_REPOSITORY https://github.com/Dav1dde/glad.git
GIT_TAG origin/master
GIT_SHALLOW ON
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}/install
-DGLAD_INSTALL:BOOL=ON
-DGLAD_PROFILE:STRING="core"
-DGLAD_ALL_EXTENSIONS:BOOL=ON
-DUSE_MSVC_RUNTIME_LIBRARY_DLL:BOOL=OFF
)
set(GLAD_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}/install)
add_library(GLAD_LIBRARY STATIC IMPORTED)
set_target_properties(GLAD_LIBRARY PROPERTIES IMPORTED_LOCATION ${GLAD_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}glad${CMAKE_STATIC_LIBRARY_SUFFIX})
# CREATE OUR LIBRARY
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/inc/*.h")
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(${PROJECT_NAME} STATIC ${headers} ${sources})
add_dependencies(${PROJECT_NAME} ${libGLFW} ${libGLAD})
# Add all include file paths
target_include_directories(${PROJECT_NAME}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
PUBLIC ${GLFW_INSTALL_DIR}/include
PUBLIC ${GLAD_INSTALL_DIR}/include
)
# JOIN ALL LIBS
set(LIBNAME "${CMAKE_CURRENT_BINARY_DIR}/final/combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND ${libexe} /OUT:${LIBNAME} $<TARGET_FILE:GLFW_LIBRARY> $<TARGET_FILE:GLAD_LIBRARY> $<TARGET_FILE:${PROJECT_NAME}>
DEPENDS GLFW_LIBRARY GLAD_LIBRARY ${PROJECT_NAME}
COMMENT "Combining libs..."
)
add_custom_target(combinedLibGenerator
DEPENDS ${LIBNAME}
)
add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)
这是我在每次构建后 visual studio 中收到的输出:
1>------ Build started: Project: ZERO_CHECK, Configuration: Release x64 ------
2>------ Build started: Project: glad, Configuration: Release x64 ------
2>Performing update step for 'glad'
2>HEAD is now at 71b2aa6... readme: updates conan link
2>No patch step for 'glad'
2>Performing configure step for 'glad'
2>-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.18362.
2>-- Configuring done
2>-- Generating done
2>-- Build files have been written to: C:/Users/myuserid/Desktop/test/build/dep/glad/src/glad-build
2>Performing build step for 'glad'
2>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
2>Copyright (C) Microsoft Corporation. All rights reserved.
2>
2> glad.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glad\src\glad-build\Release\glad.lib
2>Performing install step for 'glad'
2>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
2>Copyright (C) Microsoft Corporation. All rights reserved.
2>
2> glad.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glad\src\glad-build\Release\glad.lib
2> -- Install configuration: "Release"
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/glad.lib
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/include/glad/glad.h
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/include/KHR/khrplatform.h
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladConfig.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladConfigVersion.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladTargets.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladTargets-release.cmake
2>Completed 'glad'
3>------ Build started: Project: glfw, Configuration: Release x64 ------
3>Performing update step for 'glfw'
3>No patch step for 'glfw'
3>Performing configure step for 'glfw'
3>-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.18362.
3>-- Using Win32 for window creation
3>-- Configuring done
3>-- Generating done
3>-- Build files have been written to: C:/Users/myuserid/Desktop/test/build/dep/glfw/src/glfw-build
3>Performing build step for 'glfw'
3>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
3>Copyright (C) Microsoft Corporation. All rights reserved.
3>
3> glfw.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glfw\src\glfw-build\src\Release\glfw3.lib
3>Performing install step for 'glfw'
3>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
3>Copyright (C) Microsoft Corporation. All rights reserved.
3>
3> glfw.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glfw\src\glfw-build\src\Release\glfw3.lib
3> -- Install configuration: "Release"
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW/glfw3.h
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW/glfw3native.h
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Config.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3ConfigVersion.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Targets.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Targets-release.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/pkgconfig/glfw3.pc
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/glfw3.lib
3>Completed 'glfw'
4>------ Build started: Project: test, Configuration: Release x64 ------
4>Test.cpp
4>test.vcxproj -> C:\Users\myuserid\Desktop\test\build\Release\test.lib
========== Build: 4 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
将 UPDATE_COMMAND ""
添加到 ExternalProject_Add
实现了我想要的行为。这可以防止构建系统遍历每个依赖项并在每次构建依赖于它的东西时检查它是否有更改。切换配置(即 Debug/Release)会按预期触发重建。然后,如果您需要重建,只需重建特定的依赖项即可。
# SETUP GLFW
set(libGLFW glfw)
ExternalProject_Add(${libGLFW}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.4
GIT_SHALLOW ON
CMAKE_ARGS -
# BEGIN ADD THIS
UPDATE_COMMAND ""
# END ADD THIS
DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install
-DGLFW_BUILD_DOCS:BOOL=OFF
-DGLFW_BUILD_EXAMPLES:BOOL=OFF
-DGLFW_BUILD_TESTS:BOOL=OFF
)
CMake 中存在一个错误,导致 ExternalProject_Add 总是重建 GIT_TAG,因为它不知道 git 更新是否改变了什么。参见:
https://gitlab.kitware.com/cmake/cmake/-/issues/16419
https://gitlab.kitware.com/cmake/cmake/-/issues/19703
正如 whitwhoa 的回答,使用 UPDATE_COMMAND 可能会解决这个问题。
我有一个 cmake 列表文件,它通过 ExternalProject_Add
引入依赖项。在我的项目(使用这些依赖项)的初始编译中,我希望它们被构建(或者如果配置从 Debug 更改为 Release)。发生这种情况,但它发生在项目源中的任何后续代码更改之后。因此,例如,如果我简单地向 cout
添加一行到终端并构建我的项目,visual studio 会遍历与我的项目关联的每个项目并重建它。当然,它会在不必要时跳过实际的重新编译,但是为每个依赖项执行整个构建步骤并不理想。
因此我想知道如何构建此 cmake 项目以避免每次更改项目源时都必须构建每个依赖项?
下面是我的 CMakeLists.txt
文件。这是一项正在进行的工作。我只是在添加部分并进行测试,以确保我收到我想要的结果(这里还有一些非跨平台的东西,目前只是为了测试目的而完成的):
cmake_minimum_required(VERSION 3.20.0)
# Define our project name
set(PROJECT_NAME test)
project(${PROJECT_NAME})
if(MSVC)
get_filename_component(_vs_bin_path "${CMAKE_LINKER}" DIRECTORY)
set(libexe "${_vs_bin_path}/lib.exe")
message("LOOKHERE3:${libexe}")
endif()
# Make sure binary directory is not the same as source directory
if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(
FATAL_ERROR
"In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there."
)
endif()
# This Project Depends on External Project(s)
include(ExternalProject)
# SETUP GLFW
set(libGLFW glfw)
ExternalProject_Add(${libGLFW}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.4
GIT_SHALLOW ON
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install
-DGLFW_BUILD_DOCS:BOOL=OFF
-DGLFW_BUILD_EXAMPLES:BOOL=OFF
-DGLFW_BUILD_TESTS:BOOL=OFF
)
set(GLFW_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install)
add_library(GLFW_LIBRARY STATIC IMPORTED)
set_target_properties(GLFW_LIBRARY PROPERTIES IMPORTED_LOCATION ${GLFW_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}glfw3${CMAKE_STATIC_LIBRARY_SUFFIX})
#message("LOOKHERE:${CMAKE_STATIC_LIBRARY_PREFIX}glfw3${CMAKE_STATIC_LIBRARY_SUFFIX}")
# SETUP GLAD
set(libGLAD glad)
ExternalProject_Add(${libGLAD}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}
GIT_REPOSITORY https://github.com/Dav1dde/glad.git
GIT_TAG origin/master
GIT_SHALLOW ON
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}/install
-DGLAD_INSTALL:BOOL=ON
-DGLAD_PROFILE:STRING="core"
-DGLAD_ALL_EXTENSIONS:BOOL=ON
-DUSE_MSVC_RUNTIME_LIBRARY_DLL:BOOL=OFF
)
set(GLAD_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLAD}/install)
add_library(GLAD_LIBRARY STATIC IMPORTED)
set_target_properties(GLAD_LIBRARY PROPERTIES IMPORTED_LOCATION ${GLAD_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}glad${CMAKE_STATIC_LIBRARY_SUFFIX})
# CREATE OUR LIBRARY
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/inc/*.h")
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(${PROJECT_NAME} STATIC ${headers} ${sources})
add_dependencies(${PROJECT_NAME} ${libGLFW} ${libGLAD})
# Add all include file paths
target_include_directories(${PROJECT_NAME}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
PUBLIC ${GLFW_INSTALL_DIR}/include
PUBLIC ${GLAD_INSTALL_DIR}/include
)
# JOIN ALL LIBS
set(LIBNAME "${CMAKE_CURRENT_BINARY_DIR}/final/combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND ${libexe} /OUT:${LIBNAME} $<TARGET_FILE:GLFW_LIBRARY> $<TARGET_FILE:GLAD_LIBRARY> $<TARGET_FILE:${PROJECT_NAME}>
DEPENDS GLFW_LIBRARY GLAD_LIBRARY ${PROJECT_NAME}
COMMENT "Combining libs..."
)
add_custom_target(combinedLibGenerator
DEPENDS ${LIBNAME}
)
add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)
这是我在每次构建后 visual studio 中收到的输出:
1>------ Build started: Project: ZERO_CHECK, Configuration: Release x64 ------
2>------ Build started: Project: glad, Configuration: Release x64 ------
2>Performing update step for 'glad'
2>HEAD is now at 71b2aa6... readme: updates conan link
2>No patch step for 'glad'
2>Performing configure step for 'glad'
2>-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.18362.
2>-- Configuring done
2>-- Generating done
2>-- Build files have been written to: C:/Users/myuserid/Desktop/test/build/dep/glad/src/glad-build
2>Performing build step for 'glad'
2>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
2>Copyright (C) Microsoft Corporation. All rights reserved.
2>
2> glad.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glad\src\glad-build\Release\glad.lib
2>Performing install step for 'glad'
2>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
2>Copyright (C) Microsoft Corporation. All rights reserved.
2>
2> glad.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glad\src\glad-build\Release\glad.lib
2> -- Install configuration: "Release"
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/glad.lib
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/include/glad/glad.h
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/include/KHR/khrplatform.h
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladConfig.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladConfigVersion.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladTargets.cmake
2> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glad/install/lib/cmake/glad/gladTargets-release.cmake
2>Completed 'glad'
3>------ Build started: Project: glfw, Configuration: Release x64 ------
3>Performing update step for 'glfw'
3>No patch step for 'glfw'
3>Performing configure step for 'glfw'
3>-- Selecting Windows SDK version 10.0.16299.0 to target Windows 10.0.18362.
3>-- Using Win32 for window creation
3>-- Configuring done
3>-- Generating done
3>-- Build files have been written to: C:/Users/myuserid/Desktop/test/build/dep/glfw/src/glfw-build
3>Performing build step for 'glfw'
3>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
3>Copyright (C) Microsoft Corporation. All rights reserved.
3>
3> glfw.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glfw\src\glfw-build\src\Release\glfw3.lib
3>Performing install step for 'glfw'
3>Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
3>Copyright (C) Microsoft Corporation. All rights reserved.
3>
3> glfw.vcxproj -> C:\Users\myuserid\Desktop\test\build\dep\glfw\src\glfw-build\src\Release\glfw3.lib
3> -- Install configuration: "Release"
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW/glfw3.h
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/include/GLFW/glfw3native.h
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Config.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3ConfigVersion.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Targets.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/cmake/glfw3/glfw3Targets-release.cmake
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/pkgconfig/glfw3.pc
3> -- Up-to-date: C:/Users/myuserid/Desktop/test/build/dep/glfw/install/lib/glfw3.lib
3>Completed 'glfw'
4>------ Build started: Project: test, Configuration: Release x64 ------
4>Test.cpp
4>test.vcxproj -> C:\Users\myuserid\Desktop\test\build\Release\test.lib
========== Build: 4 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
将 UPDATE_COMMAND ""
添加到 ExternalProject_Add
实现了我想要的行为。这可以防止构建系统遍历每个依赖项并在每次构建依赖于它的东西时检查它是否有更改。切换配置(即 Debug/Release)会按预期触发重建。然后,如果您需要重建,只需重建特定的依赖项即可。
# SETUP GLFW
set(libGLFW glfw)
ExternalProject_Add(${libGLFW}
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.4
GIT_SHALLOW ON
CMAKE_ARGS -
# BEGIN ADD THIS
UPDATE_COMMAND ""
# END ADD THIS
DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/dep/${libGLFW}/install
-DGLFW_BUILD_DOCS:BOOL=OFF
-DGLFW_BUILD_EXAMPLES:BOOL=OFF
-DGLFW_BUILD_TESTS:BOOL=OFF
)
CMake 中存在一个错误,导致 ExternalProject_Add 总是重建 GIT_TAG,因为它不知道 git 更新是否改变了什么。参见:
https://gitlab.kitware.com/cmake/cmake/-/issues/16419 https://gitlab.kitware.com/cmake/cmake/-/issues/19703
正如 whitwhoa 的回答,使用 UPDATE_COMMAND 可能会解决这个问题。