344 lines
9.6 KiB
CMake
344 lines
9.6 KiB
CMake
|
||
|
||
|
||
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 子系统,驱动常用 |