Files
build_infra/0_cmake_library/core_install.cmake
T
2026-06-16 10:23:51 +08:00

336 lines
13 KiB
CMake

include(${CMAKE_CURRENT_LIST_DIR}/core.cmake)
function(_install_src_attach_file_list _component_name_ _path_ rely)
get_property(_attach_file_list_ TARGET ${_rely_} PROPERTY _attach_file_list_)
get_property(_main_dir_ TARGET ${_rely_} PROPERTY _main_dir_)
if(NOT "${_attach_file_list_}" STREQUAL "")
if("${_main_dir_}" STREQUAL "")
install(
FILES "${_attach_file_list_}"
DESTINATION ${_path_}/include
COMPONENT ${_component_name_}
)
else()
foreach(_attach_file_ ${_attach_file_list_})
file(RELATIVE_PATH RELATIVE_DIR ${_main_dir_} ${_attach_file_})
install(
FILES "${_attach_file_}"
DESTINATION ${RELATIVE_DIR}
COMPONENT ${_component_name_}
)
endforeach()
endif()
endif()
endfunction()
function(_install_attach_file_list _component_name_ _path_ rely)
get_property(_attach_file_list_ TARGET ${_rely_} PROPERTY _attach_file_list_)
get_property(_main_dir_ TARGET ${_rely_} PROPERTY _main_dir_)
if(NOT "${_attach_file_list_}" STREQUAL "")
if("${_main_dir_}" STREQUAL "")
foreach(_attach_file_ ${_attach_file_list_})
get_filename_component(ext ${_attach_file_} EXT)
if(ext STREQUAL "h" OR ext STREQUAL "hpp")
file(RELATIVE_PATH RELATIVE_DIR ${_main_dir_} ${_attach_file_})
install(
FILES "${_attach_file_}"
DESTINATION ${_path_}/include
COMPONENT ${_component_name_}
)
endif()
endforeach()
else()
foreach(_attach_file_ ${_attach_file_list_})
get_filename_component(ext ${_attach_file_} EXT)
if(ext STREQUAL "h" OR ext STREQUAL "hpp")
file(RELATIVE_PATH RELATIVE_DIR ${_main_dir_} ${_attach_file_})
install(
FILES "${_attach_file_}"
DESTINATION ${RELATIVE_DIR}
COMPONENT ${_component_name_}
)
endif()
endforeach()
endif()
endif()
endfunction()
function(_install_src_Ex _component_name_ _target_list_var_name_)
# 此函数用于安装源码 同时创建 component 也可加入到cpack 安装包里
__check_none_extr_params(${ARGC} "${ARGN}" "${ARGV}")
set(_path_ ${_component_name_})
__bfs_traverse_targets(_dependency_list_ ${_target_list_var_name_} _relys_)
foreach (_rely_ ${_relys_})
_install_src_attach_file_list(${_component_name_} ${_path_} ${_rely_})
get_property(_attach_include_list_ TARGET ${_rely_} PROPERTY _attach_include_list_)
foreach (_rely_dir_ ${_attach_include_list_})
get_filename_component(_base_name_ "${_rely_dir_}" NAME)
install(
DIRECTORY ${_rely_dir_}/
DESTINATION ${_path_}/${_base_name_}
COMPONENT ${_component_name_}
)
endforeach()
endforeach()
install(
DIRECTORY ${CMAKE_SOURCE_DIR}/0_cmake_library
DESTINATION ${_path_}
COMPONENT ${_component_name_}
)
install(
FILES ${CMAKE_SOURCE_DIR}/0_cmake_library/extract_src/CMakeLists.txt
DESTINATION ${_path_}
COMPONENT ${_component_name_}
)
add_custom_target(${_component_name_}_install
# COMMAND chcp 65001
COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}" --component ${_component_name_}
COMMENT "wyc install ${_component_name_} package!"
)
endfunction()
function(_install_file_dir_Ex _component_name_ relative_install_dir _file_list_var_name_)
foreach(_file_ ${${_file_list_var_name_}})
if(IS_DIRECTORY "${_file_}")
# 如果是目录,使用 install(DIRECTORY)
install(
DIRECTORY "${_file_}"
DESTINATION "${_component_name_}/${relative_install_dir}"
COMPONENT ${_component_name_}
)
else()
# 如果是文件,使用 install(FILE)
install(
FILES "${_file_}"
DESTINATION "${_component_name_}/${relative_install_dir}"
COMPONENT ${_component_name_}
)
endif()
endforeach()
endfunction()
function(_install_target_Ex _component_name_ _target_list_var_name_)
__check_none_extr_params(${ARGC} "${ARGN}" "${ARGV}")
set(_relys_)
set(_path_ ${_component_name_})
set(_config_path_ ${_path_}/lib/cmake/${_component_name_})
set(_config_file_name_ ${_component_name_}Config.cmake)
set(_export_name_ ${_component_name_}_Target)
set(_runtime_dir_ ${_path_}/runtime)
__bfs_traverse_targets(_dependency_list_ ${_target_list_var_name_} _relys_)
# set(codes)
foreach (_rely_ ${_relys_})
get_property(_attach_include_list_ TARGET ${_rely_} PROPERTY _attach_include_list_)
_install_attach_file_list(${_component_name_} ${_path_} ${_rely_})
foreach (_rely_dir_ ${_attach_include_list_})
set(_public_headers_)
get_filename_component(_base_name_ "${_rely_dir_}" NAME)
set(_h_list_)
set(_hpp_list_)
get_property(_h_list_ TARGET ${_rely_} PROPERTY h_${_base_name_})
get_property(_hpp_list_ TARGET ${_rely_} PROPERTY hpp_${_base_name_})
list(APPEND _public_headers_ ${_h_list_})
list(APPEND _public_headers_ ${_hpp_list_})
set(dest "${CMAKE_INSTALL_PREFIX}/${G_Architecture_Name}/${_component_name_}/include/${_base_name_}")
_install_files_with_dirStructure(${dest} ${_rely_dir_} _public_headers_)
foreach (file ${_public_headers_})
string(REPLACE ${_rely_dir_}/ "" file ${file})
get_filename_component(subdirectory ${file} DIRECTORY)
string(APPEND codes "\n file(COPY ${_rely_dir_}/${file} DESTINATION ${dest}/${subdirectory})")
endforeach()
# DESTINATION ${dest}/include 要写相对路径 不然打不了包
install(
DIRECTORY ${_rely_dir_}
DESTINATION ${_path_}/include/${_base_name_}
COMPONENT ${_component_name_}
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "*.ipp"
)
endforeach ()
endforeach ()
install(CODE "${codes}" COMPONENT ${_component_name_})
#
# https://cmake.org/cmake/help/v3.30/module/CMakePackageConfigHelpers.html#cmakepackageconfighelpers-examples
# 这个函数在cmake加载的时候执行 默认生成在 ${CMAKE_CURRENT_BINARY_DIR}下
configure_package_config_file(
${G_Root_Cmake_Library_Dir}/Config.cmake.in
${_config_file_name_}
INSTALL_DESTINATION ${_path_}
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${_config_file_name_}
DESTINATION ${_config_path_}
COMPONENT ${_component_name_}
)
# 安装编译产物 声明导出了一个对象是 ${_export_name_} 后续再安装这个对象
install(
TARGETS ${_relys_}
EXPORT "${_export_name_}"
COMPONENT ${_component_name_}
LIBRARY DESTINATION ${_path_}/lib
ARCHIVE DESTINATION ${_path_}/lib
RUNTIME DESTINATION ${_path_}/bin
)
# 生成导出文件, 安装时生成
install(
EXPORT "${_export_name_}"
DESTINATION ${_config_path_} #必须写相对路径
NAMESPACE "${_component_name_}::"
COMPONENT ${_component_name_}
)
# 安装msvc环境库
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE)
set(CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE)
endif()
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${_runtime_dir_}")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT ${_component_name_})
include(InstallRequiredSystemLibraries) #自动寻找 vcruntime140.dll 这种东西
# TODO -install 参数不知道用处是什么? 查文档 install 好像是cmake_install.cmake的目录
add_custom_target(${_component_name_}_install
# COMMAND chcp 65001
COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_CURRENT_BINARY_DIR}" --component ${_component_name_}
COMMENT "wyc install ${_component_name_} package!"
)
# 不加依赖未编译安装 安装失败!
add_dependencies(${_component_name_}_install ${_relys_})
endfunction()
#Generators
#7Z = 7-Zip file format
#DEB = Debian packages
#External = CPack External packages
#IFW = Qt Installer Framework
#INNOSETUP = Inno Setup packages
#NSIS = Null Soft Installer https://nsis.sourceforge.io/Main_Page
#NSIS64 = Null Soft Installer (64-bit)
#NuGet = NuGet packages https://blog.csdn.net/WitheredSkull/article/details/142438867
#STGZ = Self extracting Tar GZip compression
#TBZ2 = Tar BZip2 compression
#TGZ = Tar GZip compression
#TXZ = Tar XZ compression
#TZ = Tar Compress compression
#TZST = Tar Zstandard compression
#WIX = MSI file format via WiX tools https://wixtoolset.org/releases
#ZIP = ZIP file format
# RPM
function(_install_qt_runtime _component_name_ exe_path)
set(_path_ ${G_Architecture_Name}/${_component_name_})
set(_runtime_dir_ ${_path_}/runtime)
install(FILES ${exe_path} DESTINATION ${CMAKE_INSTALL_PREFIX}/${_runtime_dir_})
get_filename_component(exe_name ${exe_path} NAME)
set(abs ${CMAKE_INSTALL_PREFIX}/${_runtime_dir_})
if (WIN32)
_windows_deploy_qt(
${_component_name_}
${abs}/${exe_name}
${abs})
else ()
_linux_deploy_qt(
${_component_name_}
${abs}/${exe_name}
${abs})
endif ()
endfunction()
# TODO: 很逆天的一件事情是 我的组件名称取名com1 这是不被允许的???
# 整个安装分三个层次 包package 组件component 目标target
# _create_p(WIN_ECAP)
# _install(aacom1 ecap_server)
# _package_add_component(WIN_ECAP aacom1)
function(_install_target _component_name_)
set(_temp_list_ "${ARGN}")
_install_target_Ex(${_component_name_} _temp_list_)
endfunction()
function(_install_src _component_name_)
set(_temp_list_ "${ARGN}")
_install_src_Ex(${_component_name_} _temp_list_)
endfunction()
function(_install_file_dir _component_name_ relative_install_dir )
set(_temp_list_ "${ARGN}")
_install_file_dir_Ex(${_component_name_} ${relative_install_dir} _temp_list_)
endfunction()
function(_create_p _package_name_)
# 创建安装包
# https://cmake.org/cmake/help/latest/module/CPack.html
# 7Z DEB TBZ2 TGZ TXZ TZ TZST ZIP
set(CPACK_GENERATOR ZIP )
set(CPACK_SOURCE_GENERATOR ZIP)
set(CPACK_PACKAGE_NAME ${_package_name_})
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${_package_name_})
set(CPACK_OUTPUT_CONFIG_FILE "cpack/${G_Architecture_Name}/${_package_name_}_CPackConfig.cmake")
set(CPACK_SOURCE_OUTPUT_CONFIG_FILE "cpack/${G_Architecture_Name}/${_package_name_}_CPackSourceConfig.cmake")
set(CPACK_PACKAGE_DIRECTORY "cpack/${G_Architecture_Name}") #安装根目录父目录
# CPACK_PACKAGE_INSTALL_DIRECTORY 安装目录。一些 CPack 生成器(如 NSIS)可能会使用它来创建一个安装目录,例如,在安装前缀下方的“CMake 2.5”。所有已安装的元素都将放入此目录中
set(CPACK_PACKAGE_FILE_NAME "${_package_name_}") # 安装根目录名称,压缩包名称
set(CPACK_PACKAGE_CONTACT "1104749580@qq.com")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "1104749580@qq.com")
add_custom_target(${_package_name_}
COMMAND ${CMAKE_CPACK_COMMAND} --config "${CPACK_OUTPUT_CONFIG_FILE}"
COMMENT "${_package_name_} run ${CMAKE_CPACK_COMMAND}"
)
include(CPack)
endfunction()
function(_package_add_component_Ex _package_name_ _component_name_list_var_name_)
# https://cmake.org/cmake/help/latest/module/CPackComponent.html#module:CPackComponent
set(dependencies)
foreach(_component_name_ ${${_component_name_list_var_name_}})
cpack_add_component(
${_component_name_}
DISPLAY_NAME "DISPLAY_NAME: ${_component_name_}"
DESCRIPTION "DESCRIPTION: ${_component_name_}"
GROUP "GROUP_${_package_name_}"
ARCHIVE_FILE "use_for_download"
)
list(APPEND dependencies ${_component_name_}_install)
endforeach()
add_dependencies(${_package_name_} ${dependencies})
endfunction()
function(_package_add_component _package_name_)
set(_temp_list_ "${ARGN}")
_package_add_component_Ex(${_package_name_} _temp_list_)
endfunction()