Files
cad-agent/cmake/functions.cmake
T
gjm a7eaa8483f add
增加了 plugin 工程
2026-10-02 23:43:18 +08:00

307 lines
11 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.
# cmake/functions.cmake
# 判断时否时中望版本
function (IsZWCAD out)
if (DEFINED CACHE{ZWCAD})
set(${out} TRUE PARENT_SCOPE)
else()
set(${out} FALSE PARENT_SCOPE)
endif()
endfunction()
function(apply_arx_definitions TARGET_NAME)
if(MSVC)
target_compile_definitions(${TARGET_NAME} PRIVATE
_ALLOW_RTCc_IN_STL
_WIN32_IE=0x0600
WIN
WIN32
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1
_AFXDLL
UNICODE
_UNICODE
#_CRT_STDIO_ISO_WIDE_SPECIFIERS=0
)
endif()
endfunction()
function(apply_arx_optimization TARGET_NAME)
if(MSVC)
# ==========================================
# Debug 配置选项
# ==========================================
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CONFIG:Debug>:/Od> # 禁用优化 (Optimization: Disabled)
$<$<CONFIG:Debug>:/Zi> # 禁用优化 (Optimization: Disabled)
$<$<CONFIG:Debug>:/Ob0> # 禁用优化 (Optimization: Disabled)
#$<$<CONFIG:Debug>:/RTC1> # 启用快速检查 (BasicRuntimeChecks: EnableFastChecks)
#$<$<CONFIG:Debug>:/RTCc> # 较小类型检查 (SmallerTypeCheck: true)
)
# ==========================================
# Release 配置选项
# ==========================================
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CONFIG:Release>:/O2> # 最大优化速度 (Optimization: MaxSpeed)
$<$<CONFIG:Release>:/Ob2> # 任何合适的内联扩展 (InlineFunctionExpansion: AnySuitable)
$<$<CONFIG:Release>:/Oi> # 启用内部函数 (IntrinsicFunctions: true)
$<$<CONFIG:Release>:/Ot> # 代码速度优先 (FavorSizeOrSpeed: Speed)
$<$<CONFIG:Release>:/Oy> # 省略帧指针 (OmitFramePointers: true)[cite: 2]
$<$<CONFIG:Release>:/GT> # 纤程安全优化 (EnableFiberSafeOptimizations: true)[cite: 2]
)
# 预处理器宏定义
target_compile_definitions(${TARGET_NAME} PRIVATE
$<$<CONFIG:Release>:_NDEBUG=1> # 预处理器定义 (PreprocessorDefinitions)[cite: 2]
$<$<CONFIG:Release>:NDEBUG=1> # 预处理器定义 (PreprocessorDefinitions)[cite: 2]
)
if (DEFINED(WholeProgramOptimization))
# 注意: 这里的 /GL (WholeProgramOptimization) 配合下方的 /LTCG 使用[cite: 2]
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CONFIG:Release>:/GL>
)
# 链接器选项
target_link_options(${TARGET_NAME} PRIVATE
$<$<CONFIG:Release>:/LTCG> # 链接时代码生成 (LinkTimeCodeGeneration: UseLinkTimeCodeGeneration)[cite: 2]
)
endif()
endif()
endfunction()
# 简单判断是中望还是ACAD,根据结果来链接相应sdk
function (simple_link_cad_sdk
TARGET_NAME)
IsZWCAD(isZW)
if (isZW)
target_link_libraries(${TARGET_NAME} PRIVATE ThirdParty::ZRX)
else()
target_link_libraries(${TARGET_NAME} PRIVATE ThirdParty::ARX)
endif()
apply_arx_optimization(${TARGET_NAME})
apply_arx_definitions(${TARGET_NAME})
endfunction()
function (get_sdk_version out)
IsZWCAD(isZW)
set(VER ${CAD_SDK_VERSION})
if (isZW)
string(REGEX MATCH "..$" VER "${CAD_SDK_VERSION}")
endif()
set(${out} ${VER} PARENT_SCOPE)
endfunction()
function (get_sdk_sub_version out)
IsZWCAD(isZW)
set(VER ${CAD_SDK_SUBVERSION})
if (isZW)
set(VER "0")
endif()
set(${out} ${VER} PARENT_SCOPE)
endfunction()
# 根据 ZWCAD宏,来判断需要的def文件名称,保存到表_SOURCES 里面
function (add_def_file_name
_SOURCES
_BASE_NAME)
set (tmp "${${_SOURCES}}")
IsZWCAD(isZW)
if (isZW)
list(APPEND tmp "${_BASE_NAME}_zrx.def")
else()
list(APPEND tmp "${_BASE_NAME}.def")
endif()
set(${_SOURCES} "${tmp}" PARENT_SCOPE)
endfunction()
# 得到加密类型
function(get_encryption_modes
_modes)
set (tmp "${${_modes}}")
list(APPEND tmp "BAL_REMOTE" "TRIAL_YEAR")
set(${_modes} "${tmp}" PARENT_SCOPE)
endfunction()
# 根据加密方式为工程设置宏和输出路径
function(set_encryption_definitions_and_output_path
TARGET_NAME
MODE)
# ${TRIAL_YEAR} 在 cmakepresets.json内定义
# ${PRODUCT} 在 cmakepresets.json内定义
# 下面处理加密
if (MODE STREQUAL "TRIAL_YEAR") # TRIAL_YEAR 理论上不需要debug模式
target_compile_definitions(${TARGET_NAME} PRIVATE
BAL_REMOTE # TRIAL_YEAR加密默认BAL_REMOTE宏
$<$<CONFIG:Release>:TRIAL_YEAR=${TRIAL_YEAR}> # ${TRIAL_YEAR} 在 cmakepresets.json内定义
$<$<CONFIG:Debug>:WF2023>
$<$<CONFIG:Release>:${PRODUCT}>
)
else()
target_compile_definitions(${TARGET_NAME} PRIVATE
# 实际上,debug版本一直要带着加密,默认是BAL_REMOTE,但由于程序中检测加密锁是auto模式, REMOTE和LOCAL模式都可以通过验证
$<$<CONFIG:Debug>:WF2023>
$<$<CONFIG:Debug>:BAL_REMOTE>
$<$<CONFIG:Release>:${PRODUCT}>
$<$<CONFIG:Release>:${MODE}>
)
endif()
set_target_properties(${TARGET_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG
# 和上面的target_compile_definitions() debug 的情况一致使用 /WF2023/BAL_REMOTE 做为目录
"${GLOBAL_BIN_DIR}/Debug-x64-${GENERATE_DIR_TAG}/WF2023/BAL_REMOTE")
set_target_properties(${TARGET_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_RELEASE
"${GLOBAL_BIN_DIR}/Release-x64-${GENERATE_DIR_TAG}/${PRODUCT}-${MODE}")
set_target_properties(${TARGET_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG
"${GLOBAL_LIB_DIR}/Debug-x64-${GENERATE_DIR_TAG}/WF2023-BAL_REMOTE"
)
set_target_properties(${TARGET_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_RELEASE
"${GLOBAL_LIB_DIR}/Release-x64-${GENERATE_DIR_TAG}/${PRODUCT}-${MODE}"
)
target_link_libraries(${TARGET_NAME} PRIVATE ThirdParty::BitAnswer)
endfunction()
function(target_link_objectarx
TARGET_NAME
# 每个工程的dll标识宏都不一样,所以这里允许传入宏定义
_EXTENSION
)
if (ARGC LESS 2)
message(FATAL_ERROR "target_link_objectarx() 函数至少需要两个参数: TARGET_NAME 和 _EXTENSION")
endif()
target_link_libraries(${TARGET_NAME} PRIVATE ShsGlobalIncludes)
target_include_directories(${TARGET_NAME} PRIVATE "${DEP_INC_ROOT}")
# 1. 确定具体的 SDK 目录 (假设你的 SDK 按版本号平铺放置)
simple_link_cad_sdk(${TARGET_NAME})
#[[if (DEFINED CACHE{ZWCAD})
target_link_libraries(${TARGET_NAME} PRIVATE ThirdParty::ZRX)
else()
target_link_libraries(${TARGET_NAME} PRIVATE ThirdParty::ARX)
endif()]]
target_link_libraries(${TARGET_NAME} PRIVATE "rpcrt4.lib")
# 4. 配置必须的宏定义和编译选项
target_compile_definitions(${TARGET_NAME} PRIVATE
CMAKE
ARX=${SDK_VERSION}
SUB_ARX=${SDK_SUBVERSION}
${_EXTENSION} # 指示这是一个 ARX 扩展
)
endfunction()
# 定义函数:设置 Target 的输出名称和后缀
function(target_set_name_and_suffix
target_name
new_name
new_suffix)
# 1. 检查目标是否存在,防止拼写错误导致静默失败
if(NOT TARGET ${target_name})
message(FATAL_ERROR "[ObjectARX-CMake] Target '${target_name}' 不存在!")
endif()
# 2. 设置基础输出名称 (OUTPUT_NAME)
# 无论是 exe, dll, arx 还是 lib,OUTPUT_NAME 都会统一修改主输出文件的 Base Name
if(NOT "${new_name}" STREQUAL "")
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME "${new_name}")
endif()
# 3. 设置后缀 (SUFFIX)
if(NOT "${new_suffix}" STREQUAL "")
# 获取 Target 的类型 (EXECUTABLE, SHARED_LIBRARY, MODULE_LIBRARY, STATIC_LIBRARY 等)
get_target_property(target_type ${target_name} TYPE)
# 如果是 ".arx" 那么判断一下是不是中望版本,如果是则自动变成".zrx"
if ("${new_suffix}" STREQUAL ".arx" AND IS_ZWCAD)
set(new_suffix ".zrx")
endif()
# 设置主输出文件的后缀
set_target_properties(${target_name} PROPERTIES SUFFIX "${new_suffix}")
# 【核心细节】:针对动态库和导出符号的 EXE 进行导入库保护
# 在 MSVC 中,构建 SHARED_LIBRARY (或开启 ENABLE_EXPORTS 的 EXE) 时,
# 会同时生成 主文件(如 .arx) 和 导入库(如 .lib)。
# 修改 SUFFIX 虽然主要作用于主文件,但为了防止某些 CMake 版本的意外行为或全局变量污染,
# 显式将 IMPORT_SUFFIX 锁定为 ".lib" 是非常严谨的做法。
if(target_type MATCHES "^(SHARED_LIBRARY|MODULE_LIBRARY|EXECUTABLE)$")
set_target_properties(${target_name} PROPERTIES
IMPORT_SUFFIX ".lib"
IMPORT_PREFIX ""
)
endif()
# 注:如果是 STATIC_LIBRARY,CMake 原生就使用 SUFFIX 属性来控制后缀,
# 传入 ".lib" 会完美适配,无需额外设置 IMPORT_SUFFIX。
endif()
endfunction()
# 为工程的debug模式,设置分发路径,把生成物copy到相应的插件目录下面
function(set_debug_post_build
target_name # 工程名
arx_name # 文件名
ext # 后缀
)
set(CONFIG_JSON "sh_output_path.json")
if (IS_ZWCAD)
set(CONFIG_JSON "zw_output_path.json")
endif()
add_custom_command(
TARGET ${target_name}
POST_BUILD
# 核心:精准构造命令行参数
COMMAND "$<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/copyarx.exe>"
"$<$<CONFIG:Debug>:CMAKE>"
"$<$<CONFIG:Debug>:$<TARGET_FILE:${target_name}>>"
"$<$<CONFIG:Debug>:${GENERATE_DIR_TAG}>"
"$<$<CONFIG:Debug>:${CMAKE_SOURCE_DIR}/${CONFIG_JSON}>"
COMMENT "正在调用 copyarx.exe 部署 ARX 模块..."
VERBATIM
)
endfunction()
function(add_custom_module_2 dir_path target_name folder_path)
# 1. 声明库
add_subdirectory(${dir_path})
# 2. 设置 ARX 特有属性
set_target_properties(${target_name} PROPERTIES
FOLDER "${folder_path}" # 动态传入分组路径
)
endfunction()
function(add_custom_module dir_path folder_path)
get_filename_component(target_name "${dir_path}" NAME)
add_custom_module_2(${dir_path} ${target_name} ${folder_path})
endfunction()