Files
build_infra/0_cmake_library/main.cmake
T
2026-08-10 10:11:00 +08:00

572 lines
26 KiB
CMake
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
include(${CMAKE_CURRENT_LIST_DIR}/register_libaray/rcl_register_ex.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/package_zip.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/color_output.cmake)
macro(w_install files dir)
install(FILES ${files} DESTINATION "${dir}")
endmacro()
macro(_install_command _package_name_ command)
install(CODE "execute_process(COMMAND ${command})" COMPONENT ${_package_name_})
endmacro()
function(_make_vs2019_project)
_install_command("${CMAKE_COMMAND}" -G "Visual Studio 16 2019" -A x64 -B "${CMAKE_INSTALL_PREFIX}/vs2019/" -S "${CMAKE_SOURCE_DIR}/")
# _install_command("/"${CMAKE_COMMAND}/" -G /"Visual Studio 16 2019/" -A x64 -B /"${CMAKE_INSTALL_PREFIX}/vs2019/" -S /"${CMAKE_SOURCE_DIR}/"")
# _install_command("${CMAKE_COMMAND}" -G "Visual Studio 16 2019" -A x64 -B "${CMAKE_INSTALL_PREFIX}/vs2019" -S "${CMAKE_SOURCE_DIR}")
endfunction()
set(G_Architecture_Name)
set(EXTERNAL_DIR)
set(EXTERNAL_BUILD_DIR)
set(EXTERNAL_INSTALL_DIR)
set(EXTERNAL_SRC_DIR)
set(_root_dir)
set(_system_build_tool_install_dir_name)
set(_system_build_tool_install_dir)
set(_system_build_tool_build_dir)
function(w_append_flag_string var)
set(_value "${${var}}")
foreach (_flag ${ARGN})
string(FIND " ${_value} " " ${_flag} " _pos)
if (_pos EQUAL -1)
string(APPEND _value " ${_flag}")
endif ()
endforeach ()
string(STRIP "${_value}" _value)
set(${var} "${_value}" PARENT_SCOPE)
endfunction()
function(_initialize_cxx_default_options)
if (TARGET global_default_options)
return()
endif ()
add_library(global_default_options INTERFACE)
if (MSVC)
target_compile_options(
global_default_options
INTERFACE
/wd4819
/utf-8
/Zc:preprocessor
/EHsc
/bigobj
)
target_compile_definitions(
global_default_options
INTERFACE
NOMINMAX
_USE_MATH_DEFINES
)
target_link_options(
global_default_options
INTERFACE
"$<$<CONFIG:Release>:/PROFILE>"
)
else ()
target_compile_options(
global_default_options
INTERFACE
-Wall
-Wextra
-Werror=return-type
-fvisibility=hidden
-fvisibility-inlines-hidden
-Wpedantic
-Wshadow
-Wconversion
-Wsign-conversion
)
if (USE_RUNPATH)
target_link_options(
global_default_options
INTERFACE
"LINKER:--enable-new-dtags"
)
else ()
target_link_options(
global_default_options
INTERFACE
"LINKER:--disable-new-dtags"
)
endif ()
if (ENABLE_ASAN)
target_compile_options(
global_default_options
INTERFACE
-fsanitize=address
)
target_link_options(
global_default_options
INTERFACE
-fsanitize=address
)
endif ()
endif ()
endfunction()
macro(_load_cmake_library)
if (MSVC)
message(STATUS "Using MSVC")
# 关闭警告 C4819: 无效的字符。避免中文注释被警告
add_compile_options(
"/wd4819"
)
# 关闭 /showIncludes
string(REPLACE "/showIncludes" "" CMAKE_DEPFILE_FLAGS_C "${CMAKE_DEPFILE_FLAGS_C}")
string(REPLACE "/showIncludes" "" CMAKE_DEPFILE_FLAGS_CXX "${CMAKE_DEPFILE_FLAGS_CXX}")
endif ()
_initialize_cxx_default_options()
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_moudle")
# set(CMAKE_C_LINKER_LAUNCHER "D:/ae/proj/ae/0_cmake_library/set_utf8.bat")
# set(CMAKE_CXX_LINKER_LAUNCHER "D:/ae/proj/ae/0_cmake_library/set_utf8.bat")
# 清除默认环境
set(CMAKE_GRAPHVIZ_OUTPUT_DIR "${CMAKE_BINARY_DIR}/graphviz")
enable_testing()
# 让 find_package 产生的 targets 在全局可见
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#windows系统动态库生成lib文件命令
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_BUILD_RPATH "$ORIGIN:$ORIGIN/../lib:$ORIGIN/lib")
set(CMAKE_INSTALL_RPATH "$ORIGIN:$ORIGIN/../lib:$ORIGIN/lib")
# 这个地方反复触发是 工具链编译器 和 toolchain写的不一样导致的
if (NOT DEFINED CMAKE_TOOLCHAIN_FILE OR CMAKE_TOOLCHAIN_FILE STREQUAL "")
message(FATAL_ERROR "没有使用 toolchain 文件")
endif ()
get_filename_component(name "${CMAKE_TOOLCHAIN_FILE}" NAME)
string(REGEX REPLACE "\\.cmake$" "" name "${name}")
set(_system_build_tool_install_dir_name "${name}")
set(G_Architecture_Name "${name}_${CMAKE_BUILD_TYPE}")
message(STATUS "当前使用 toolchain 文件: [${CMAKE_TOOLCHAIN_FILE}]")
message(STATUS "当前 toolchain 名称: [${name}]")
if (NOT MINGW)
#set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/build/install/${G_Architecture_Name})
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
# 控制构建(build)目录下生成的可执行文件/so,是否使用“安装后的 rpath” (INSTALL_RPATH)。
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #这样可以在构建过程中禁用 RPATH 修改
# 控制安装后的目标文件(在 make install 时),其 INSTALL_RPATH 是否自动追加所有 link 时用到的库
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
endif ()
# 检查当前编译器是否是 GCC GCC一般程序都需要 pthread
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# 如果是 GCC,添加 -pthread 标志
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
endif ()
# 外部库构建目录
# if(WIN32)
# set(_root_dir "D:/ae")
# else()
# set(_root_dir "/aenv")
# endif()
if (CMAKE_HOST_WIN32)
set(_root_dir "D:/ae")
elseif (CMAKE_HOST_UNIX)
set(_root_dir "/aenv")
else ()
message(FATAL_ERROR "Unsupported host system: ${CMAKE_HOST_SYSTEM_NAME}")
endif ()
message("_root_dir ${_root_dir}")
set(EXTERNAL_DIR "${_root_dir}/cached_external_library")
# 创建文件夹(如果不存在的话)
file(MAKE_DIRECTORY ${EXTERNAL_DIR})
set(EXTERNAL_BUILD_DIR "${CMAKE_BINARY_DIR}/_yc_deps")
set(EXTERNAL_INSTALL_DIR "${EXTERNAL_DIR}/${G_Architecture_Name}")
set(GIT_CACHE_DIR "${EXTERNAL_DIR}/git_cache")
list(APPEND EXTERNAL_SRC_DIR "${EXTERNAL_DIR}/src_dirs")
set(_system_build_tool_install_dir "${_root_dir}/toolchain/${_system_build_tool_install_dir_name}")
set(_system_build_tool_build_dir "${_root_dir}/build_toolchain/${_system_build_tool_install_dir_name}")
# find_package 使用的路径
# set(CMAKE_PREFIX_PATH)
list(APPEND CMAKE_PREFIX_PATH "${EXTERNAL_INSTALL_DIR}")
if (CMAKE_HOST_WIN32)
list(APPEND CMAKE_PREFIX_PATH "C:/wyc/library/${G_Architecture_Name}")
elseif (CMAKE_HOST_UNIX)
list(APPEND CMAKE_PREFIX_PATH "/aenv/library/${G_Architecture_Name}")
endif ()
list(APPEND CMAKE_FIND_ROOT_PATH
${CMAKE_PREFIX_PATH}
)
_print_help_info()
# if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# include(${G_Root_Cmake_Library_Dir}/windows_driver/export.cmake)
# endif ()
endmacro()
function(_query_and_print zh_comment query_string)
cmake_host_system_information(RESULT var QUERY ${query_string})
message(STATUS "${zh_comment}: ${var}")
endfunction()
macro(_print_help_info)
message("##################### SystemInfo #####################")
message(STATUS "==============================================")
message(STATUS "CXX showIncludes prefix=[${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}]")
message(STATUS "C showIncludes prefix=[${CMAKE_C_CL_SHOWINCLUDES_PREFIX}]")
message(STATUS "Common showIncludes prefix=[${CMAKE_CL_SHOWINCLUDES_PREFIX}]")
message(STATUS "${R}CMAKE_SOURCE_DIR${E}: ${B}${CMAKE_SOURCE_DIR}${E}")
message(STATUS "${R}CMAKE_BINARY_DIR${E}: ${B}${CMAKE_BINARY_DIR}${E}")
message(STATUS "${R}G_Architecture_Name${E}: ${B}${G_Architecture_Name}${E}")
message(STATUS "${R}EXTERNAL_DIR${E}: ${B}${EXTERNAL_DIR}${E}")
message(STATUS "${R}EXTERNAL_BUILD_DIR${E}: ${B}${EXTERNAL_BUILD_DIR}${E}")
message(STATUS "${R}EXTERNAL_INSTALL_DIR${E}: ${B}${EXTERNAL_INSTALL_DIR}${E}")
message(STATUS "${R}EXTERNAL_SRC_DIR${E}: ${B}${EXTERNAL_SRC_DIR}${E}")
message(STATUS "${R}GIT_CACHE_DIR${E}: ${B}${GIT_CACHE_DIR}${E}")
message(STATUS "${R}_system_build_tool_install_dir${E}: ${B}${_system_build_tool_install_dir}${E}")
message(STATUS "${R}_system_build_tool_build_dir${E}: ${B}${_system_build_tool_build_dir}${E}")
message(STATUS "${R}CMAKE_PREFIX_PATH${E}: ${B}${CMAKE_PREFIX_PATH}${E}")
message(STATUS "${R}CMAKE_FIND_ROOT_PATH${E}: ${B}${CMAKE_FIND_ROOT_PATH}${E}")
message(STATUS "${R}CMAKE_INSTALL_PREFIX${E}: ${B}${CMAKE_INSTALL_PREFIX}${E}")
message(STATUS "${R}CMAKE_C_COMPILER_ID${E}:${B}${CMAKE_C_COMPILER_ID}${E}")
message(STATUS "${R}CMAKE_CXX_COMPILER_ID${E}:${B}${CMAKE_CXX_COMPILER_ID}${E}")
message(STATUS "${R}CMAKE_C_COMPILER${E}:${B}${CMAKE_C_COMPILER}${E}")
message(STATUS "${R}CMAKE_CXX_COMPILER${E}:${B}${CMAKE_CXX_COMPILER}${E}")
message(STATUS "${R}CMAKE_C_COMPILER_VERSION${E}:${B}${CMAKE_C_COMPILER_VERSION}${E}")
message(STATUS "${R}CMAKE_CXX_COMPILER_VERSION${E}:${B}${CMAKE_CXX_COMPILER_VERSION}${E}")
message(STATUS "${R}CMAKE_SYSTEM_PROCESSOR${E}:${B}${CMAKE_SYSTEM_PROCESSOR}${E}")
message(STATUS "${R}CMAKE_HOST_SYSTEM_PROCESSOR${E}:${B}${CMAKE_HOST_SYSTEM_PROCESSOR}${E}")
message(STATUS "${R}CMAKE_CROSSCOMPILING${E}:${B}${CMAKE_CROSSCOMPILING}${E}")
if (MSVC)
message(STATUS "if(MSVC) ok")
endif ()
message(STATUS "==============================================")
message(STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}")
message(STATUS "CMAKE_MAKE_PROGRAM: ${CMAKE_MAKE_PROGRAM}")
message(STATUS "CXX Flags: ${CMAKE_CXX_FLAGS}")
message(STATUS "CXX Flags for Debug: ${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "CXX Flags for Release: ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "CXX Flags for MinSizeRel: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
message(STATUS "CXX Flags for RelWithDebInfo: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message(STATUS "CXX Flags for Debug Init: ${CMAKE_CXX_FLAGS_DEBUG_INIT}")
message(STATUS "CXX Flags for Release Init: ${CMAKE_CXX_FLAGS_RELEASE_INIT}")
# message(STATUS "C Flags: ${CMAKE_C_FLAGS}")
# message(STATUS "C Flags for Debug: ${CMAKE_C_FLAGS_DEBUG}")
# message(STATUS "C Flags for Release: ${CMAKE_C_FLAGS_RELEASE}")
# message(STATUS "C Flags for MinSizeRel: ${CMAKE_C_FLAGS_MINSIZEREL}")
# message(STATUS "C Flags for RelWithDebInfo: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
# message(STATUS "C Flags for Debug Init: ${CMAKE_C_FLAGS_DEBUG_INIT}")
# message(STATUS "C Flags for Release Init: ${CMAKE_C_FLAGS_RELEASE_INIT}")
# 这些变量通常在所有版本的CMake中都可用,所以可以直接使用
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_SYSTEM: ${CMAKE_SYSTEM}")
message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_C_COMPILER_VERSION: ${CMAKE_C_COMPILER_VERSION}")
message(STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}")
message(STATUS "CMAKE_GENERATOR_INSTANCE: ${CMAKE_GENERATOR_INSTANCE}")
message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
message(STATUS "CMAKE_GENERATOR_TOOLSET: ${CMAKE_GENERATOR_TOOLSET}")
message(STATUS "CMAKE_SYSROOT: ${CMAKE_SYSROOT}")
message(STATUS "CMAKE_C_STANDARD_LIBRARIES: ${CMAKE_C_STANDARD_LIBRARIES}")
message(STATUS "CMAKE_CXX_STANDARD_LIBRARIES: ${CMAKE_CXX_STANDARD_LIBRARIES}")
message(STATUS "CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "CMAKE_CXX_STANDARD_LIBRARIES=${CMAKE_CXX_STANDARD_LIBRARIES}")
message(STATUS "CMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "CMAKE_EXE_LINKER_FLAGS_RELEASE=${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
message(STATUS "CMAKE_C_CREATE_CONSOLE_EXE=${CMAKE_C_CREATE_CONSOLE_EXE}")
message(STATUS "CMAKE_CXX_CREATE_CONSOLE_EXE=${CMAKE_CXX_CREATE_CONSOLE_EXE}")
message(STATUS "CMAKE_C_LINK_EXECUTABLE=${CMAKE_C_LINK_EXECUTABLE}")
message(STATUS "CMAKE_CXX_LINK_EXECUTABLE=${CMAKE_CXX_LINK_EXECUTABLE}")
# dump_current_default_env()
# clear_and_cache_default_env()
# dump_saved_default_env()
# dump_current_default_env()
message(STATUS "CMAKE_C_COMPILER_ARCHITECTURE_ID: ${CMAKE_C_COMPILER_ARCHITECTURE_ID}")
message(STATUS "CMAKE_CXX_COMPILER_ARCHITECTURE_ID: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
# 获取系统信息
# https://cmake.org/cmake/help/v3.31/command/cmake_host_system_information.html#cmake-host-system-information
# 根据CMake版本选择不同的查询方式
# 3.10就有下面的
message(STATUS "宿主机(host)系统信息如下")
_query_and_print("逻辑核心数" NUMBER_OF_LOGICAL_CORES)
_query_and_print("物理核心数" NUMBER_OF_PHYSICAL_CORES)
_query_and_print("主机名" HOSTNAME)
_query_and_print("完全限定域名" FQDN)
_query_and_print("总虚拟内存 (MiB)" TOTAL_VIRTUAL_MEMORY)
_query_and_print("可用虚拟内存 (MiB)" AVAILABLE_VIRTUAL_MEMORY)
_query_and_print("总物理内存 (MiB)" TOTAL_PHYSICAL_MEMORY)
_query_and_print("可用物理内存 (MiB)" AVAILABLE_PHYSICAL_MEMORY)
_query_and_print("处理器是否为64位" IS_64BIT)
_query_and_print("处理器是否有浮点运算单元" HAS_FPU)
_query_and_print("MMX指令集(整数运算优化)" HAS_MMX)
_query_and_print("HAS_MMX_PLUS指令集" HAS_MMX_PLUS)
_query_and_print("SSE指令集(浮点运算优化)" HAS_SSE)
_query_and_print("SSE2指令集" HAS_SSE2)
_query_and_print("SSE_FP指令集" HAS_SSE_FP)
_query_and_print("SSE_MMX指令集" HAS_SSE_MMX)
_query_and_print("AMD_3DNOW指令集(3D优化)" HAS_AMD_3DNOW)
_query_and_print("AMD_3DNOW_PLUS指令集" HAS_AMD_3DNOW_PLUS)
_query_and_print("IA64指令集(高性能服务器和工作站)" HAS_IA64)
_query_and_print("是否有处理器序列号" HAS_SERIAL_NUMBER)
_query_and_print("处理器序列号" PROCESSOR_SERIAL_NUMBER)
_query_and_print("处理器名称" PROCESSOR_NAME)
_query_and_print("操作系统名称" OS_NAME)
_query_and_print("操作系统版本(子类型)" OS_RELEASE)
_query_and_print("操作系统版本ID" OS_VERSION)
_query_and_print("操作系统平台" OS_PLATFORM)
# if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22")
# cmake_host_system_information(RESULT DISTRO QUERY DISTRIB_INFO)
# foreach(VAR IN LISTS DISTRO)
# _query_and_print(${VAR} "${VAR}" "${VAR}")
# endforeach()
# endif()
# if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28")
# _query_and_print("人类可读的处理器名称" MSYSTEM_PREFIX)
# endif()
message("##################### SystemInfo #####################")
message("\n\n\n")
endmacro()
function(_generate_system_info_file file_path)
macro(_G zh_comment query_string)
cmake_host_system_information(RESULT var QUERY ${query_string})
#message(STATUS "${zh_comment}: ${var}")
#set(content "${content}/t//${zh_comment}/n/tconst std::string ${query_string} = /"${var}/"/;/n")
set(content "${content}/t//${zh_comment}/n/tconst std::string ${query_string} = \"${var}\";/n")
endmacro()
set(content "")
_G("逻辑核心数" NUMBER_OF_LOGICAL_CORES)
_G("物理核心数" NUMBER_OF_PHYSICAL_CORES)
_G("主机名" HOSTNAME)
_G("完全限定域名" FQDN)
_G("总虚拟内存 (MiB)" TOTAL_VIRTUAL_MEMORY)
_G("可用虚拟内存 (MiB)" AVAILABLE_VIRTUAL_MEMORY)
_G("总物理内存 (MiB)" TOTAL_PHYSICAL_MEMORY)
_G("可用物理内存 (MiB)" AVAILABLE_PHYSICAL_MEMORY)
_G("处理器是否为64位" IS_64BIT)
_G("处理器是否有浮点运算单元" HAS_FPU)
_G("MMX指令集(整数运算优化)" HAS_MMX)
_G("HAS_MMX_PLUS指令集" HAS_MMX_PLUS)
_G("SSE指令集(浮点运算优化)" HAS_SSE)
_G("SSE2指令集" HAS_SSE2)
_G("SSE_FP指令集" HAS_SSE_FP)
_G("SSE_MMX指令集" HAS_SSE_MMX)
_G("AMD_3DNOW指令集(3D优化)" HAS_AMD_3DNOW)
_G("AMD_3DNOW_PLUS指令集" HAS_AMD_3DNOW_PLUS)
_G("IA64指令集(高性能服务器和工作站)" HAS_IA64)
_G("是否有处理器序列号" HAS_SERIAL_NUMBER)
_G("处理器序列号" PROCESSOR_SERIAL_NUMBER)
_G("处理器名称" PROCESSOR_NAME)
_G("操作系统名称" OS_NAME)
_G("操作系统版本(子类型)" OS_RELEASE)
_G("操作系统版本ID" OS_VERSION)
_G("操作系统平台" OS_PLATFORM)
set(start "#include <string>/nnamespace System {/n")
set(end "}")
set(content "${start}${content}${end}")
file(WRITE ${file_path} ${content})
message("[generate ${file_path}]")
endfunction()
function(_create_directory_with_permissions dir_path)
# 检查目录是否存在
if (NOT EXISTS ${dir_path})
# 如果目录不存在,创建目录
file(MAKE_DIRECTORY ${dir_path})
message(STATUS "Directory ${dir_path} created.")
# 改变文件夹权限(Linux/macOS
if (NOT WIN32)
execute_process(
COMMAND chmod 755 ${dir_path}
RESULT_VARIABLE chmod_result
OUTPUT_VARIABLE chmod_output
ERROR_VARIABLE chmod_error
)
if (chmod_result)
message(FATAL_ERROR "Failed to change permissions: ${chmod_error}")
else ()
message(STATUS "Permissions changed to 755 on ${dir_path}")
endif ()
endif ()
if (WIN32)
execute_process(
COMMAND icacls ${dir_path} /grant "Everyone:(OI)(CI)F"
RESULT_VARIABLE icacls_result
OUTPUT_VARIABLE icacls_output
ERROR_VARIABLE icacls_error
)
if (icacls_result)
message(FATAL_ERROR "Failed to change permissions: ${icacls_error}")
else ()
message(STATUS "Permissions changed on ${dir_path} to Everyone:(OI)(CI)F")
endif ()
endif ()
else ()
message(STATUS "Directory ${dir_path} already exists.")
endif ()
endfunction()
function(_add_directory_to_clion2 dir)
include_directories(${dir})
endfunction()
function(_add_directory_to_clion dir)
# 获取构建目录的文件名(不带扩展名)
get_filename_component(dir_name "${dir}" NAME_WE)
if (NOT EXISTS "${dir}")
message(FATAL_ERROR "目录不存在: ${R}${dir}${E}")
return()
endif ()
if (NOT EXISTS "${dir}/CMakeLists.txt")
# 如果不存在,则创建并写入
file(WRITE "${dir}/CMakeLists.txt" "# 这个文件没有实际含义,就是为了clion里能看到这个目录。")
message(STATUS "Created CMakeLists.txt in ${dir}")
else ()
#message(STATUS "CMakeLists.txt already exists in ${dir}")
endif ()
message("加载目录成功! ${P}${dir}${E}")
# 添加子目录
add_subdirectory(${dir} "${CMAKE_BINARY_DIR}/clion_none_${dir_name}_dir")
endfunction()
function(_add_binary_to_clion)
get_filename_component(dir "${CMAKE_BINARY_DIR}" DIRECTORY)
message("_add_binary_to_clion dir【${dir}】")
if (NOT ${dir} STREQUAL ${CMAKE_SOURCE_DIR})
_add_directory_to_clion("${dir}")
endif ()
endfunction()
# MSYS
# MINGW64
# MINGW32
# UCRT64
# CLANG64
# CLANGARM64
#function(add_msys_powershell_target target_name work_dir script)
# add_custom_target(${target_name}
# COMMAND powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command
# "$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; \
# $env:CHERE_INVOKING = '1'; \
# $env:MSYSTEM = 'MINGW64'; \
# $env:LANG = 'zh_CN.UTF-8'; \
# $env:LC_ALL = 'zh_CN.UTF-8'; \
# Set-Location -LiteralPath '${work_dir}'; \
# & 'C:/msys64/usr/bin/bash.exe' --login -lc '${script}'"
# VERBATIM
# )
#endfunction()
#function(add_msys_powershell_target target_name work_dir script)
# add_custom_target(${target_name}
# COMMAND powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command
# "$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; \
# $env:CHERE_INVOKING = '1'; \
# $env:MSYSTEM = 'MINGW64'; \
# $env:LANG = 'zh_CN.UTF-8'; \
# $env:LC_ALL = 'zh_CN.UTF-8'; \
# Set-Location -LiteralPath '${work_dir}'; \
# & 'C:/msys64/usr/bin/bash.exe' -lc '${script}'"
# VERBATIM
# )
#endfunction()
function(_load_proj_impl dir)
set(_ls "${B}[======== ${E}")
set(_le "${B} ========]${E}")
set(_proj_dir_list)
get_filename_component(PARENT_DIR ${dir} DIRECTORY)
list(APPEND _proj_dir_list "${dir}")
list(APPEND _proj_dir_list "${PARENT_DIR}")
foreach (name ${ARGN})
set(_found FALSE)
set(s_name "${P}【${E}${R}${name}${E}${P}】${E}")
foreach (base_dir ${_proj_dir_list})
if (EXISTS "${base_dir}/${name}")
set(_proj_dir "${base_dir}/${name}")
if (EXISTS "${_proj_dir}")
string(TIMESTAMP NOW "%Y-%m-%d %H:%M:%S")
message("[${NOW}] ${_ls} ${s_name} 开始加载!${_le} ${_proj_dir}/main.cmake:0")
set(Main_Cmake "${_proj_dir}/main.cmake")
if (NOT EXISTS "${Main_Cmake}")
message("main.cmake 不存在主动创建 ${Main_Cmake}")
file(WRITE "${Main_Cmake}" "")
endif ()
include("${Main_Cmake}")
set(CMAKE_LIST_POS "${_proj_dir}/CMakeLists.txt")
if (NOT EXISTS "${CMAKE_LIST_POS}")
message("CMakeLists.txt 不存在主动创建 ${CMAKE_LIST_POS}")
file(WRITE "${CMAKE_LIST_POS}" "")
endif ()
add_subdirectory("${_proj_dir}" psc/${name})
#message("${_ls} ${s_name} 加载完毕!${_le}")
set(_found TRUE)
break()
else ()
message(WARNING "${name}项目配置文件不存在!${_proj_dir}")
endif ()
endif ()
endforeach ()
if (_found)
else ()
message(WARNING
"未找到项目 ${name},已在以下目录中查找:/n ${_proj_dir_list}"
)
endif ()
endforeach ()
endfunction()
# 收集源码文件
function(append_glob_source src_var_name)
set(_args ${ARGN})
set(_total_srcs)
foreach (_dir IN LISTS _args)
if (NOT IS_DIRECTORY "${_dir}")
continue()
endif ()
file(GLOB_RECURSE _srcs CONFIGURE_DEPENDS
"${_dir}/*.h"
"${_dir}/*.hpp"
"${_dir}/*.ipp"
"${_dir}/*.inl"
"${_dir}/*.c"
"${_dir}/*.cpp"
"${_dir}/*.cxx"
"${_dir}/*.cc"
"${_dir}/*.qrc"
)
list(APPEND _total_srcs ${_srcs})
endforeach ()
list(APPEND ${src_var_name} ${_total_srcs})
set(${src_var_name} "${${src_var_name}}" PARENT_SCOPE)
endfunction()
# 从候选目录搜索出存在的目录
macro(select_first_existing_directory out_var)
unset(${out_var})
foreach (candidate ${ARGN})
if (IS_DIRECTORY "${candidate}")
set(${out_var} "${candidate}")
break()
endif ()
endforeach ()
if (NOT DEFINED ${out_var})
message(FATAL_ERROR "No candidate directory exists for ${out_var}: ${ARGN}")
endif ()
endmacro()
# 聚合一组文件变成一个文件
function(generate_aggregate_sources source_dir output_dir include_prefix output_name)
file(GLOB_RECURSE headers CONFIGURE_DEPENDS
"${source_dir}/*.h"
"${source_dir}/*.hpp"
)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
"${source_dir}/*.cpp"
)
set(output_header "${output_dir}/${output_name}.h")
set(output_source "${output_dir}/${output_name}.cpp")
set(header_content "#pragma once\n")
set(source_content "")
foreach (header IN LISTS headers)
file(RELATIVE_PATH relative_header "${source_dir}" "${header}")
string(APPEND header_content "#include \"${include_prefix}/${relative_header}\"\n")
endforeach ()
foreach (source IN LISTS sources)
file(RELATIVE_PATH relative_source "${source_dir}" "${source}")
string(APPEND source_content "#include \"${include_prefix}/${relative_source}\"\n")
endforeach ()
file(WRITE "${output_header}" "${header_content}")
file(WRITE "${output_source}" "${source_content}")
endfunction()
function(_attach_post_build_file_Ex _name_ _file_list_var_name_)
add_custom_command(
TARGET ${_name_}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${${_file_list_var_name_}}
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "拷贝配置文件到目标目录"
)
endfunction()
function(_attach_post_build_file _name_)
set(_temp_list_ "${ARGN}")
_attach_post_build_file_Ex(${_name_} _temp_list_)
endfunction()