Files
2026-08-01 01:49:52 +08:00

344 lines
9.6 KiB
CMake
Raw Permalink 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.
set(prefix __PSC_)
macro(_clear_and_cache name)
set(_var_name "${prefix}${name}")
if( "${${_var_name}}" STREQUAL "")
set(${_var_name} ${${name}} CACHE STRING "" FORCE)
set(${name} "" CACHE STRING "" FORCE)
endif()
endmacro()
macro(_clear_and_cache2 name)
set(${prefix}${name} ${${name}} PARENT_SCOPE)
set(${name} "" PARENT_SCOPE)
endmacro()
set(build_type_list DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
function(_clear_env)
set(language_list C CXX)
foreach(language IN LISTS language_list)
set(list
CMAKE_${language}_FLAGS
CMAKE_${language}_STANDARD_LIBRARIES
)
foreach(bt IN LISTS build_type_list)
list(APPEND list CMAKE_${language}_FLAGS_${bt})
endforeach()
foreach(li IN LISTS list)
_clear_and_cache(${li})
endforeach()
endforeach()
foreach(language IN LISTS language_list)
set(list
CMAKE_${language}_CREATE_CONSOLE_EXE
CMAKE_${language}_CREATE_WIN32_EXE
)
foreach(li IN LISTS list)
_clear_and_cache2(${li})
endforeach()
endforeach()
set(target_type_list
EXE
MODULE
SHARED
STATIC
)
foreach(target_type IN LISTS target_type_list)
set(list CMAKE_${target_type}_LINKER_FLAGS)
foreach(bt IN LISTS build_type_list)
list(APPEND list CMAKE_${target_type}_LINKER_FLAGS_${bt})
endforeach()
foreach(li IN LISTS list)
_clear_and_cache(${li})
endforeach()
endforeach()
endfunction()
function(_target_isolate_global tgt)
# ========== 1. 编译选项隔离 ==========
set_target_properties(${tgt} PROPERTIES
COMPILE_OPTIONS ""
)
# ========== 2. 宏定义隔离 ==========
set_target_properties(${tgt} PROPERTIES
COMPILE_DEFINITIONS ""
)
# ========== 3. 头文件路径隔离 ==========
set_target_properties(${tgt} PROPERTIES
INCLUDE_DIRECTORIES ""
)
# ========== 4. 链接选项隔离 ==========
set_target_properties(${tgt} PROPERTIES
LINK_FLAGS ""
LINK_FLAGS_DEBUG ""
LINK_FLAGS_RELEASE ""
LINK_OPTIONS ""
)
# ========== 5. 运行时库隔离 ==========
set_target_properties(${tgt} PROPERTIES
C_STANDARD_LIBRARIES ""
CXX_STANDARD_LIBRARIES ""
)
# Windows MSVC 运行时隔离
set_target_properties(${tgt} PROPERTIES
WIN32_EXECUTABLE FALSE
)
if(MSVC)
set_target_properties(${tgt} PROPERTIES
MSVC_RUNTIME_LIBRARY ""
MSVC_DEBUG_INFORMATION_FORMAT ""
MSVC_RUNTIME_CHECKS ""
MSVC_RUNTIME_LIBRARY ""
)
endif()
endfunction()
function(_get_mapped_target_type out_var tgt)
if(NOT TARGET ${tgt})
message(FATAL_ERROR "get_mapped_target_type: target '${tgt}' does not exist")
endif()
get_target_property(_cmake_type ${tgt} TYPE)
if(_cmake_type STREQUAL "EXECUTABLE")
set(_mapped_type "EXE")
elseif(_cmake_type STREQUAL "MODULE_LIBRARY")
set(_mapped_type "MODULE")
elseif(_cmake_type STREQUAL "SHARED_LIBRARY")
set(_mapped_type "SHARED")
elseif(_cmake_type STREQUAL "STATIC_LIBRARY")
set(_mapped_type "STATIC")
else()
set(_mapped_type "")
endif()
set(${out_var} "${_mapped_type}" PARENT_SCOPE)
endfunction()
macro(_gather_list list_name input_name)
set(cur_list)
separate_arguments(cur_list NATIVE_COMMAND "${${input_name}}")
list(APPEND ${list_name} ${cur_list})
endmacro()
# 给target添加上默认的 编译选项
# _build_type 填入空值的话那么就是使用默认构建类型
function(_attach_target _target _build_type)
if(NOT TARGET "${_target}")
return()
endif()
if(_build_type STREQUAL "")
set(_build_type ${CMAKE_BUILD_TYPE})
endif()
string(TOUPPER "${_build_type}" _build_type)
if(NOT _build_type IN_LIST build_type_list)
message(FATAL_ERROR "attach_target Invalid build type: ${_build_type}")
endif()
# ---------- 防止同一个 target / build_type 重复 attach ----------
get_property(_has_attached_build_types
TARGET "${_target}"
PROPERTY PSC_ATTACHED_BUILD_TYPES
SET
)
if(_has_attached_build_types)
get_property(_attached_build_types
TARGET "${_target}"
PROPERTY PSC_ATTACHED_BUILD_TYPES
)
else()
set(_attached_build_types "")
endif()
if("${_build_type}" IN_LIST _attached_build_types)
message(STATUS "skip already attached target: ${_target}, build_type=${_build_type}")
return()
else()
message(STATUS "attached target: ${_target}, build_type=${_build_type}")
endif()
set(target_type)
set(link_options)
set(flags)
set(link_libraries)
set(language CXX)
_get_mapped_target_type(target_type ${_target})
_gather_list(link_options ${prefix}CMAKE_${target_type}_LINKER_FLAGS)
_gather_list(link_options ${prefix}CMAKE_${target_type}_LINKER_FLAGS_${_build_type})
_gather_list(flags ${prefix}CMAKE_${language}_FLAGS)
_gather_list(flags ${prefix}CMAKE_${language}_FLAGS_${_build_type})
_gather_list(link_libraries ${prefix}CMAKE_${language}_STANDARD_LIBRARIES)
# ---------- 列表自身去重 ----------
list(REMOVE_DUPLICATES link_options)
list(REMOVE_DUPLICATES flags)
list(REMOVE_DUPLICATES link_libraries)
set(options)
set(definitions)
foreach(_flag IN LISTS flags)
# /DWIN32, /D_WINDOWS, /DNDEBUG
# -DWIN32 也兼容
if(_flag MATCHES "^[/\\-]D(.+)$")
set(_def "${CMAKE_MATCH_1}")
# 去掉可能存在的外层双引号,例如 /D"NAME=VALUE"
string(REGEX REPLACE "^\"(.*)\"$" "\\1" _def "${_def}")
list(APPEND definitions "${_def}")
else()
list(APPEND options "${_flag}")
endif()
endforeach()
list(REMOVE_DUPLICATES options)
list(REMOVE_DUPLICATES definitions)
# ---------- 非空才调用,避免空 PUBLIC 调用污染 target_link_libraries 模式 ----------
if(link_options)
target_link_options(${_target} PUBLIC ${link_options})
endif()
if(options)
target_compile_options(${_target} PUBLIC ${options})
endif()
if(definitions)
target_compile_definitions(${_target} PUBLIC ${definitions})
endif()
if(link_libraries)
target_link_libraries(${_target} PUBLIC ${link_libraries})
endif()
# ---------- 标记已经 attach 过 ----------
list(APPEND _attached_build_types "${_build_type}")
list(REMOVE_DUPLICATES _attached_build_types)
set_property(
TARGET "${_target}"
PROPERTY PSC_ATTACHED_BUILD_TYPES "${_attached_build_types}"
)
# if(G_Enable_CCache AND MSVC)
# set_target_properties("${_target}" PROPERTIES
# MSVC_DEBUG_INFORMATION_FORMAT "Embedded"
# )
# endif()
endfunction()
# 这个库的影响是会 影响 add_subdirectory 的目标 针对 不同的选项没了 默认优化参数
# 可以通过 最外层拿 BUILDSYSTEM_TARGETS 但是考虑 递归add_subdirectory 只能覆盖拦截处理
function(add_subdirectory)
set(source_dir "${ARGV0}")
# message("start ============ add_subdirectory ARGV: ${ARGV} ${CMAKE_CURRENT_LIST_FILE}")
_add_subdirectory(${ARGV})
if(IS_ABSOLUTE "${source_dir}")
set(source_dir_abs "${source_dir}")
else()
get_filename_component(
source_dir_abs
"${CMAKE_CURRENT_SOURCE_DIR}/${source_dir}"
ABSOLUTE
)
endif()
get_property(
subdir_targets
DIRECTORY "${source_dir_abs}"
PROPERTY BUILDSYSTEM_TARGETS
)
#message(STATUS "targets in ${source_dir}: ${subdir_targets}")
if(subdir_targets)
foreach(target IN LISTS subdir_targets)
if(NOT TARGET "${target}")
continue()
endif()
get_target_property(target_type "${target}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY"
OR target_type STREQUAL "UTILITY"
OR target_type STREQUAL "UNKNOWN_LIBRARY"
OR target_type STREQUAL "OBJECT_LIBRARY"
# OR target_type STREQUAL "STATIC_LIBRARY"
)
message(STATUS "skip target: ${target}, type=${target_type}")
continue()
endif()
_attach_target("${target}" "")
endforeach()
endif()
# message("end ============ add_subdirectory ARGV: ${ARGV}")
endfunction()
macro(attach_current_source_dir )
get_property(_targets DIRECTORY "." PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS _targets)
get_target_property(target_type "${target}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY"
OR target_type STREQUAL "UTILITY"
OR target_type STREQUAL "UNKNOWN_LIBRARY"
OR target_type STREQUAL "OBJECT_LIBRARY"
# OR target_type STREQUAL "STATIC_LIBRARY"
)
#message(STATUS "skip target: ${target}, type=${target_type}")
continue()
endif()
_attach_target("${target}" "")
endforeach()
endmacro()
#/DRIVER
#/SUBSYSTEM:NATIVE
#/ENTRY:DriverEntry
#/NODEFAULTLIB
#/DRIVER
#/DRIVER:WDM
#/DRIVER:UPONLY
#/SUBSYSTEM:CONSOLE 用户态控制台程序
#/SUBSYSTEM:WINDOWS 用户态 GUI 程序
#/SUBSYSTEM:NATIVE Native