[英]Add 'install' target to 'all' in CMake
我有一個帶有以下目錄樹的 CMake 項目:
build/
assets/
dest/
<other files>
dest
是所有已安裝文件所在的目錄:
可執行文件,使用簡單的make
進入dest/
,這是由CMAKE_RUNTIME_OUTPUT_DIRECTORY
控制的
資產,位於assets/
,在make install
后轉到dest/
。
但我不想發出make install
來復制所有文件做dest/
dir:我想要一個簡單的make
來做到這一點。
從這個意義上說,如何將install
目標添加到默認目標( all
)? 或者,有沒有更好的方法來解決這個問題?
這將在構建<target_name>
(可能是all
)后執行install
目標:
add_custom_command(
TARGET <target_name>
POST_BUILD
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install
)
使用以下不會導致遞歸。 需要 CMake >= 3.15。
add_custom_command(
TARGET ${MY_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --config $<CONFIG>
)
額外:您可能希望提供默認(本地)安裝路徑,以便在 Windows 上不會失敗。
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "install" CACHE PATH "Default install path." FORCE)
endif()
我通過使用以下宏為指定目標生成數據依賴規則解決了這個問題。 這些規則只需要make
而不需要make install
。
宏將源樹中的任意文件映射到“暫存”樹,其中每個樹結構可能不同,您可以選擇重命名文件。 分階段數據隨時保持更新,因此,如果你在你的源代碼樹改變它,然后它會被你的下一次更新make
。
# Macro used to create dependencies for staging data files (e.g. config files, assets) and keeping them up-to-date.
# The given "source" file is copied (and possibly renamed) to "staged" for the given "target".
#
# It works by creating a rule that creates "staged" by copying "source", then creating a target that depends upon "staged",
# then making the given "target" depend upon the new target. Or in makefile speak:
#
# staged: source
# cp source staged
#
# targetData1: staged
#
# target: <existing dependencies...> targetData1
# <existing commands...>
#
# The intermediate rule is used for parallel build robustness. For details, see:
# http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:add_custom_command
#
# Example:
# target = myExeTarget
# source = "${CMAKE_CURRENT_SOURCE_DIR}/../../data/images/bush1.png"
# staged = "${STAGING_DATA_DIR}/images/bush1.png"
macro(add_data_dependency target source staged)
add_custom_command(
OUTPUT "${staged}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source}" "${staged}" # Dir(s) will be created if needed.
DEPENDS "${source}"
)
if (NOT DEFINED add_data_dependency_counter)
#message(status "Setting tmp counter......")
set(add_data_dependency_counter "0")
endif()
math(EXPR add_data_dependency_counter "${add_data_dependency_counter} + 1")
#message(status "tmp counter is ${add_data_dependency_counter}......")
set(customTarget "${target}Data${add_data_dependency_counter}")
add_custom_target(${customTarget} DEPENDS "${staged}")
add_dependencies(${target} ${customTarget})
endmacro()
在您的情況下,用法類似於:
add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/file1.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/file1.ext")
add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/file2.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/file2.ext")
add_data_dependency(myTarget "${CMAKE_CURRENT_SOURCE_DIR}/assets/rename_me.ext" "${CMAKE_CURRENT_SOURCE_DIR}/dest/renamed.ext")
:
:
然后,無論何時make
,如果文件丟失或過期(假設myTarget
是all
一部分),就會復制這些文件。
使用 CMake 的正常方法是在項目外創建一個構建目錄,並將所有編譯的二進制文件放在那里。 當您完成開發並希望將一些二進制文件安裝到您的系統中時,您可以調用make install
。 通過這種方式,您可以使您的項目源文件夾免受所有編譯器生成的內容的影響。
示例文件目錄結構:
my_project/
my_project_build/
從 my_project_build 調用cmake ../my_project
來生成構建文件。 調用make
來構建它,所有二進制文件都將在my_project_build
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.