set_target_properties() 是 CMake 中用于设置目标属性的关键命令,它允许精细控制库、可执行文件等目标的构建行为、输出特性和安装配置。
基本语法
cmake
set_target_properties(target1 target2 ...
PROPERTIES
property1 value1
property2 value2
...
)
属性分类详解
一、输出文件属性
1. 名称和前缀后缀
cmake
set_target_properties(mylib PROPERTIES
OUTPUT_NAME "mylib" # 输出文件基本名(不包含扩展名)
PREFIX "" # 前缀(默认:共享库"lib",Windows DLL 无前缀)
SUFFIX ".so.1" # 后缀(覆盖默认扩展名)
IMPORT_PREFIX "lib" # 导入库前缀
IMPORT_SUFFIX ".dll.a" # 导入库后缀(MinGW)
)
2. 版本控制属性
cmake
set_target_properties(mylib PROPERTIES
VERSION 2.5.3 # 完整版本号(影响文件命名)
SOVERSION 2 # API 版本号(影响符号链接)
MACHO_COMPATIBILITY_VERSION "2.0" # macOS 兼容版本
MACHO_CURRENT_VERSION "2.5.3" # macOS 当前版本
BUNDLE_VERSION "2.5.3" # macOS Bundle 版本
)
3. 输出目录属性
cmake
# 通用输出目录
set_target_properties(myapp PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
# 按配置的输出目录
set_target_properties(myapp PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/lib"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/lib"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/bin"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/lib"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/lib"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/bin"
)
# 按配置的后缀
set_target_properties(myapp PROPERTIES
DEBUG_POSTFIX "_d" # Debug 后缀
RELEASE_POSTFIX "" # Release 后缀
RELWITHDEBINFO_POSTFIX "_rd" # RelWithDebInfo 后缀
MINSIZEREL_POSTFIX "_ms" # MinSizeRel 后缀
)
二、编译属性
1. 语言标准属性
cmake
set_target_properties(myapp PROPERTIES
C_STANDARD 11 # C 标准版本
C_STANDARD_REQUIRED ON # 必须使用指定标准
C_EXTENSIONS OFF # 禁用编译器扩展
CXX_STANDARD 17 # C++ 标准版本
CXX_STANDARD_REQUIRED ON # 必须使用指定标准
CXX_EXTENSIONS OFF # 禁用编译器扩展
)
2. 编译特性
cmake
set_target_properties(myapp PROPERTIES
COMPILE_DEFINITIONS "USE_FEATURE_X=1;ANOTHER_DEFINE=2"
COMPILE_DEFINITIONS_DEBUG "DEBUG_MODE=1;LOG_LEVEL=3"
COMPILE_DEFINITIONS_RELEASE "NDEBUG;OPTIMIZE"
COMPILE_OPTIONS "-Wall;-Wextra;-Werror"
COMPILE_OPTIONS_DEBUG "-O0;-g3"
COMPILE_OPTIONS_RELEASE "-O3;-flto"
COMPILE_PDB_NAME "myapp" # PDB 文件名(MSVC)
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/pdb"
)
3. 平台相关编译属性
cmake
# Windows 特定
if(WIN32)
set_target_properties(myapp PROPERTIES
WIN32_EXECUTABLE TRUE # Windows GUI 应用程序
VS_SCC_LOCALPATH "." # Visual Studio 源代码控制
VS_SCC_PROJECTNAME "MyProject"
VS_SCC_PROVIDER "Git"
VS_GLOBAL_SECTION_PRE_MySection "key=value"
)
endif()
# macOS 特定
if(APPLE)
set_target_properties(myapp PROPERTIES
MACOSX_BUNDLE TRUE # 创建应用程序包
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/Info.plist.in"
MACOSX_BUNDLE_BUNDLE_NAME "MyApp"
MACOSX_BUNDLE_BUNDLE_VERSION "1.0.0"
MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.company.myapp"
MACOSX_BUNDLE_ICON_FILE "MyApp.icns"
MACOSX_BUNDLE_COPYRIGHT "Copyright © 2023 Company"
MACOSX_RPATH ON # 启用 RPATH
INSTALL_NAME_DIR "@rpath" # 安装名称目录
)
endif()
三、链接属性
1. 链接选项和标志
cmake
set_target_properties(myapp PROPERTIES
LINK_FLAGS "-Wl,--as-needed"
LINK_FLAGS_DEBUG "-fsanitize=address"
LINK_FLAGS_RELEASE "-s"
LINK_DEPENDS_NO_SHARED ON # 即使有共享库也链接静态库
LINK_INTERFACE_LIBRARIES "pthread;dl" # 接口库
LINK_INTERFACE_LIBRARIES_DEBUG "debug_lib"
LINK_INTERFACE_LIBRARIES_RELEASE "optimized_lib"
LINK_WHAT_YOU_USE ON # 仅链接实际使用的库(clang/ld.lld)
LINK_SEARCH_START_STATIC ON # 优先静态链接
LINK_SEARCH_END_STATIC ON # 结束静态搜索
)
2. 共享库特定属性
cmake
set_target_properties(mylib PROPERTIES
POSITION_INDEPENDENT_CODE ON # 启用 PIC(位置无关代码)
NO_SONAME FALSE # 是否生成 SONAME(Unix)
SOVERSION 2 # SONAME 版本
VERSION 2.5.3 # 文件版本
# Windows DLL 特定
WINDOWS_EXPORT_ALL_SYMBOLS ON # 自动导出所有符号
DEFINE_SYMBOL "MYLIB_EXPORTS" # 导出宏定义
IMPORTED_IMPLIB "${CMAKE_BINARY_DIR}/lib/mylib.lib" # 导入库
# macOS 框架特定
FRAMEWORK TRUE
FRAMEWORK_VERSION A
PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/include/mylib.h"
PRIVATE_HEADER "${CMAKE_SOURCE_DIR}/src/internal.h"
RESOURCE "${CMAKE_SOURCE_DIR}/resources/icon.icns"
)
3. 符号可见性
cmake
set_target_properties(mylib PROPERTIES
C_VISIBILITY_PRESET "hidden" # C 符号可见性
CXX_VISIBILITY_PRESET "hidden" # C++ 符号可见性
VISIBILITY_INLINES_HIDDEN ON # 内联函数可见性
# 显式控制符号导出
EXPORT_NAME "MyLib" # 导出时的名称
EXPORT_PROPERTIES "VERSION;SOVERSION"
)
四、安装属性
1. 安装路径属性
cmake
include(GNUInstallDirs)
set_target_properties(myapp PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib" # 运行时库搜索路径
INSTALL_RPATH_USE_LINK_PATH ON # 使用链接路径作为 RPATH
BUILD_WITH_INSTALL_RPATH ON # 构建时使用安装 RPATH
SKIP_BUILD_RPATH OFF # 不禁用构建 RPATH
# 安装名称(macOS)
INSTALL_NAME_DIR "@rpath"
BUILD_WITH_INSTALL_NAME_DIR ON
)
2. 组件安装
cmake
set_target_properties(myapp PROPERTIES
ARCHIVE_OUTPUT_NAME "myapp" # 静态库安装名
LIBRARY_OUTPUT_NAME "myapp" # 共享库安装名
RUNTIME_OUTPUT_NAME "myapp" # 可执行文件安装名
# 按组件设置安装属性
COMPONENT "runtime" # 运行时组件
EXCLUDE_FROM_DEFAULT_BUILD ON # 从默认构建中排除
EXCLUDE_FROM_ALL ON # 从所有构建中排除
)
五、IDE 和生成器属性
1. Visual Studio 属性
cmake
if(MSVC)
set_target_properties(myapp PROPERTIES
VS_GLOBAL_KEYWORD "Win32Proj"
VS_GLOBAL_PROJECT_TYPES "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
VS_GLOBAL_ROOTNAMESPACE "MyApp"
# 平台工具集
VS_PLATFORM_TOOLSET "v143"
VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0"
# 调试配置
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
VS_DEBUGGER_ENVIRONMENT "PATH=${CMAKE_BINARY_DIR}/bin/$<CONFIG>;%PATH%"
VS_DEBUGGER_COMMAND_ARGUMENTS "--config test"
# 输出文件
VS_USER_PROPS "${CMAKE_SOURCE_DIR}/myprops.props"
VS_SDK_REFERENCES "WindowsApp"
)
endif()
2. Xcode 属性
cmake
if(CMAKE_GENERATOR STREQUAL "Xcode")
set_target_properties(myapp PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "ABCD1234EF"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "MyApp Profile"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "14.0"
XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "11.0"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES"
XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "$(GCC_OPTIMIZATION_LEVEL_$(CONFIGURATION))"
)
endif()
3. 通用 IDE 属性
cmake
set_target_properties(myapp PROPERTIES
FOLDER "MyProject/Applications" # Visual Studio/Xcode 文件夹
LABELS "application;gui" # 目标标签
XCODE_SCHEME_ENVIRONMENT "DISABLE_ANIMATIONS=1"
XCODE_SCHEME_ARGUMENTS "--verbose"
XCODE_SCHEME_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
# 源码分组
VS_SOURCE_GROUP "Header Files" FILES ${HEADER_FILES}
VS_SOURCE_GROUP "Source Files" FILES ${SOURCE_FILES}
VS_SOURCE_GROUP "Resources" FILES ${RESOURCE_FILES}
)
高级用法
1. 条件属性设置
cmake
# 根据配置设置不同属性
set_target_properties(myapp PROPERTIES
$<$<CONFIG:Debug>:DEBUG_POSTFIX> "_d"
$<$<CONFIG:Debug>:OUTPUT_NAME> "myapp_debug"
$<$<CONFIG:Release>:OUTPUT_NAME> "myapp_release"
# 根据编译器设置
$<$<CXX_COMPILER_ID:GNU>:COMPILE_OPTIONS> "-Wall;-Wextra"
$<$<CXX_COMPILER_ID:MSVC>:COMPILE_OPTIONS> "/W4;/WX"
# 根据平台设置
$<$<PLATFORM_ID:Windows>:SUFFIX> ".exe"
$<$<PLATFORM_ID:Linux>:SUFFIX> ""
$<$<PLATFORM_ID:Darwin>:SUFFIX> ".app"
)
2. 多目标批量设置
cmake
# 为多个目标设置相同属性
set(ALL_TARGETS app1 app2 app3 lib1 lib2)
set_target_properties(${ALL_TARGETS} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)
# 或使用循环
foreach(target IN LISTS ALL_TARGETS)
set_target_properties(${target} PROPERTIES
FOLDER "MyProject"
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
endforeach()
3. 继承和覆盖属性
cmake
# 创建基目标
add_library(base INTERFACE)
set_target_properties(base PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "BASE_DEFINE=1"
INTERFACE_COMPILE_OPTIONS "-Wall"
)
# 派生目标
add_library(derived STATIC derived.cpp)
target_link_libraries(derived PUBLIC base)
# 覆盖/添加属性
set_target_properties(derived PROPERTIES
COMPILE_DEFINITIONS "${BASE_DEFINE};DERIVED_DEFINE=2"
COMPILE_OPTIONS "${BASE_OPTIONS};-Wextra"
)
4. 动态属性计算
cmake
# 动态计算输出目录
set(BIN_DIR "${CMAKE_BINARY_DIR}/bin")
set(LIB_DIR "${CMAKE_BINARY_DIR}/lib")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BIN_DIR "${BIN_DIR}/debug")
set(LIB_DIR "${LIB_DIR}/debug")
endif()
set_target_properties(myapp PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${BIN_DIR}
LIBRARY_OUTPUT_DIRECTORY ${LIB_DIR}
ARCHIVE_OUTPUT_DIRECTORY ${LIB_DIR}
)
# 动态生成版本信息
string(TIMESTAMP BUILD_DATE "%Y%m%d")
set_target_properties(myapp PROPERTIES
COMPILE_DEFINITIONS "BUILD_DATE=\"${BUILD_DATE}\""
)
实际项目示例
示例1:跨平台库项目
cmake
cmake_minimum_required(VERSION 3.15)
project(CrossPlatformLib VERSION 2.3.1)
# 创建库
add_library(cplib SHARED
src/libcore.cpp
src/libutils.cpp
)
# 设置通用属性
set_target_properties(cplib PROPERTIES
# 输出命名
OUTPUT_NAME "cplib"
PREFIX ""
SUFFIX ""
# 版本控制
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
# 编译标准
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
# 符号可见性
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN ON
)
# 平台特定属性
if(WIN32)
set_target_properties(cplib PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS ON
DEFINE_SYMBOL "CPLIB_EXPORTS"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" # DLL 到 bin
)
elseif(APPLE)
set_target_properties(cplib PROPERTIES
MACOSX_RPATH ON
INSTALL_NAME_DIR "@rpath"
BUILD_WITH_INSTALL_RPATH ON
INSTALL_RPATH "@loader_path/../lib"
)
else()
# Linux/Unix
set_target_properties(cplib PROPERTIES
NO_SONAME FALSE
INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/../lib64"
BUILD_WITH_INSTALL_RPATH TRUE
)
endif()
# 按配置设置
set_target_properties(cplib PROPERTIES
DEBUG_POSTFIX "_d"
RELEASE_POSTFIX ""
RELWITHDEBINFO_POSTFIX "_rd"
MINSIZEREL_POSTFIX "_ms"
# 输出目录(按配置)
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/lib"
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/lib"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/debug/bin"
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/lib"
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/lib"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/release/bin"
)
# 包含目录
target_include_directories(cplib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# 安装属性
include(GNUInstallDirs)
set_target_properties(cplib PROPERTIES
PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/include/cplib.h"
PRIVATE_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/internal.h"
# 安装到正确位置
ARCHIVE_OUTPUT_NAME "cplib"
LIBRARY_OUTPUT_NAME "cplib"
RUNTIME_OUTPUT_NAME "cplib"
# 组件
COMPONENT "runtime"
)
示例2:GUI应用程序
cmake
cmake_minimum_required(VERSION 3.16)
project(PhotoEditor VERSION 1.5.2)
# 创建应用程序
add_executable(photoeditor WIN32 MACOSX_BUNDLE
src/main.cpp
src/editor_window.cpp
src/image_processor.cpp
)
# 通用应用程序属性
set_target_properties(photoeditor PROPERTIES
OUTPUT_NAME "PhotoEditor"
DEBUG_POSTFIX "_d"
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
)
# Windows 特定
if(WIN32)
set_target_properties(photoeditor PROPERTIES
WIN32_EXECUTABLE TRUE
VS_DEBUGGER_COMMAND_ARGUMENTS "--open test.jpg"
VS_DEBUGGER_ENVIRONMENT "PATH=${CMAKE_BINARY_DIR}/bin/$<CONFIG>;%PATH%"
VS_USER_PROPS "${CMAKE_SOURCE_DIR}/win32/PhotoEditor.props"
)
# 添加清单文件
if(EXISTS "${CMAKE_SOURCE_DIR}/win32/PhotoEditor.manifest")
set_target_properties(photoeditor PROPERTIES
VS_CPP_MANIFEST_FILE "${CMAKE_SOURCE_DIR}/win32/PhotoEditor.manifest"
)
endif()
endif()
# macOS 特定
if(APPLE)
set_target_properties(photoeditor PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/macos/Info.plist.in"
MACOSX_BUNDLE_BUNDLE_NAME "PhotoEditor"
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.company.photoeditor"
MACOSX_BUNDLE_ICON_FILE "PhotoEditor.icns"
MACOSX_BUNDLE_COPYRIGHT "Copyright © 2023 Company"
MACOSX_BUNDLE_LS_MINIMUM_SYSTEM_VERSION "10.15"
MACOSX_BUNDLE_NS_HUMAN_READABLE_COPYRIGHT "Copyright 2023"
# Xcode 属性
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development"
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "XYZ123ABC"
XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "$(GCC_OPTIMIZATION_LEVEL_$(CONFIGURATION))"
)
# 设置文件夹
set_target_properties(photoeditor PROPERTIES
FOLDER "Applications"
)
endif()
# 设置输出目录
set_target_properties(photoeditor PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin/debug"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin/release"
# Visual Studio 文件夹组织
VS_SOURCE_GROUP "Source Files" FILES ${APP_SOURCES}
VS_SOURCE_GROUP "Header Files" FILES ${APP_HEADERS}
VS_SOURCE_GROUP "Resources" FILES ${APP_RESOURCES}
VS_SOURCE_GROUP "UI Files" FILES ${APP_UI_FILES}
)
# Qt 特定(如果使用 Qt)
if(QT_FOUND)
set_target_properties(photoeditor PROPERTIES
AUTOMOC ON
AUTORCC ON
AUTOUIC ON
# Qt 插件路径
QT_PLUGIN_PATH "${QT_INSTALL_PLUGINS}"
# Windows: 复制 Qt DLLs
WIN32_DEPLOYMENT_TARGET "10.0"
)
endif()
示例3:库版本管理和ABI兼容
cmake
cmake_minimum_required(VERSION 3.18)
project(ABIStableLib VERSION 3.2.0)
# 确定 ABI 版本
math(EXPR ABI_VERSION "${PROJECT_VERSION_MAJOR} + 1") # 示例:API 变化时增加
add_library(abilib SHARED
src/abi_stable.cpp
src/compatibility.cpp
)
# 严格的版本控制
set_target_properties(abilib PROPERTIES
# 文件命名
OUTPUT_NAME "abilib"
# 版本信息
VERSION ${PROJECT_VERSION} # 文件版本:3.2.0
SOVERSION ${ABI_VERSION} # ABI 版本:4 (soname: libabilib.so.4)
# macOS 版本
MACHO_COMPATIBILITY_VERSION "${ABI_VERSION}.0"
MACHO_CURRENT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
# 严格的符号控制
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN ON
# 位置无关代码
POSITION_INDEPENDENT_CODE ON
)
# 平台特定的符号导出
if(WIN32)
set_target_properties(abilib PROPERTIES
DEFINE_SYMBOL "ABILIB_EXPORTS"
WINDOWS_EXPORT_ALL_SYMBOLS OFF # 显式控制导出
)
endif()
# ABI 检查标记
target_compile_definitions(abilib PRIVATE
ABILIB_ABI_VERSION=${ABI_VERSION}
ABILIB_API_VERSION=${PROJECT_VERSION_MAJOR}
)
# 安装配置
include(GNUInstallDirs)
set_target_properties(abilib PROPERTIES
# 安装路径
ARCHIVE_OUTPUT_NAME "abilib"
LIBRARY_OUTPUT_NAME "abilib"
# RPATH 设置
INSTALL_RPATH "$ORIGIN/../lib"
BUILD_WITH_INSTALL_RPATH ON
# 头文件安装
PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/include/abilib.h"
# 导出设置
EXPORT_NAME "ABILib"
EXPORT_PROPERTIES "VERSION;SOVERSION"
)
# 生成版本头文件
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/include/abilib_version.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/include/abilib_version.h"
)
target_include_directories(abilib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# 创建别名以保持向后兼容
add_library(abilib_v${PROJECT_VERSION_MAJOR} ALIAS abilib)
add_library(abilib_abi${ABI_VERSION} ALIAS abilib)
调试和验证
查看目标属性
cmake
# 获取并打印所有属性
function(print_target_properties target)
if(NOT TARGET ${target})
message(WARNING "目标 ${target} 不存在")
return()
endif()
message(STATUS "=== ${target} 的属性 ===")
# 预定义属性列表(部分)
set(PROPERTY_LIST
OUTPUT_NAME
PREFIX
SUFFIX
VERSION
SOVERSION
CXX_STANDARD
CXX_STANDARD_REQUIRED
CXX_EXTENSIONS
DEBUG_POSTFIX
RELEASE_POSTFIX
ARCHIVE_OUTPUT_DIRECTORY
LIBRARY_OUTPUT_DIRECTORY
RUNTIME_OUTPUT_DIRECTORY
COMPILE_DEFINITIONS
COMPILE_OPTIONS
LINK_FLAGS
INSTALL_RPATH
FOLDER
TYPE
)
foreach(prop ${PROPERTY_LIST})
get_target_property(value ${target} ${prop})
if(value)
message(STATUS "${prop}: ${value}")
endif()
endforeach()
# 获取所有属性(包括自定义的)
get_target_property(all_props ${target} PROPERTIES)
if(all_props)
message(STATUS "--- 所有属性 ---")
foreach(prop ${all_props})
get_target_property(value ${target} ${prop})
if(value AND NOT prop IN_LIST PROPERTY_LIST)
message(STATUS "${prop}: ${value}")
endif()
endforeach()
endif()
message(STATUS "====================")
endfunction()
# 使用示例
add_library(mylib SHARED mylib.cpp)
set_target_properties(mylib PROPERTIES
OUTPUT_NAME "mylib"
VERSION "1.0.0"
CXX_STANDARD 17
)
print_target_properties(mylib)
验证属性设置
cmake
# 验证关键属性
function(validate_target_properties target)
if(NOT TARGET ${target})
message(FATAL_ERROR "目标 ${target} 不存在")
endif()
# 检查必要属性
get_target_property(target_type ${target} TYPE)
if(target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
get_target_property(version ${target} VERSION)
get_target_property(soversion ${target} SOVERSION)
if(NOT version)
message(WARNING "共享库 ${target} 未设置 VERSION 属性")
endif()
if(NOT soversion)
message(WARNING "共享库 ${target} 未设置 SOVERSION 属性")
endif()
get_target_property(pic ${target} POSITION_INDEPENDENT_CODE)
if(NOT pic)
message(STATUS "建议为共享库 ${target} 设置 POSITION_INDEPENDENT_CODE ON")
endif()
endif()
# 检查编译标准
get_target_property(cxx_std ${target} CXX_STANDARD)
if(NOT cxx_std)
message(STATUS "目标 ${target} 未设置 C++ 标准")
endif()
# 检查输出名称
get_target_property(output_name ${target} OUTPUT_NAME)
if(NOT output_name)
message(DEBUG "目标 ${target} 使用默认输出名称")
endif()
endfunction()
最佳实践
1. 属性组织策略
cmake
# 将属性分组到变量中
set(COMPILE_PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN ON
)
set(OUTPUT_PROPERTIES
DEBUG_POSTFIX "_d"
RELEASE_POSTFIX ""
OUTPUT_NAME "mylib"
)
set(VERSION_PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
# 批量设置
set_target_properties(mylib PROPERTIES
${COMPILE_PROPERTIES}
${OUTPUT_PROPERTIES}
${VERSION_PROPERTIES}
)
2. 平台抽象层
cmake
# 定义平台抽象属性
if(WIN32)
set(PLATFORM_PROPERTIES
WINDOWS_EXPORT_ALL_SYMBOLS ON
DEFINE_SYMBOL "MYLIB_EXPORTS"
)
elseif(APPLE)
set(PLATFORM_PROPERTIES
MACOSX_RPATH ON
INSTALL_NAME_DIR "@rpath"
)
else()
set(PLATFORM_PROPERTIES
NO_SONAME FALSE
INSTALL_RPATH "$ORIGIN/../lib"
)
endif()
# 应用到目标
set_target_properties(mylib PROPERTIES ${PLATFORM_PROPERTIES})
3. 配置相关属性管理
cmake
# 定义配置相关的属性
set(CONFIG_DEBUG_PROPERTIES
DEBUG_POSTFIX "_d"
COMPILE_DEFINITIONS "DEBUG=1;_DEBUG"
COMPILE_OPTIONS "-O0;-g3"
)
set(CONFIG_RELEASE_PROPERTIES
COMPILE_DEFINITIONS "NDEBUG"
COMPILE_OPTIONS "-O3;-DNDEBUG"
)
# 使用生成器表达式应用
set_target_properties(mylib PROPERTIES
$<$<CONFIG:Debug>:DEBUG_POSTFIX> "_d"
$<$<CONFIG:Debug>:COMPILE_DEFINITIONS> "DEBUG=1;_DEBUG"
$<$<CONFIG:Debug>:COMPILE_OPTIONS> "-O0;-g3"
$<$<CONFIG:Release>:COMPILE_DEFINITIONS> "NDEBUG"
$<$<CONFIG:Release>:COMPILE_OPTIONS> "-O3;-DNDEBUG"
)
set_target_properties() 是 CMake 中用于精细控制目标行为的核心命令,掌握它可以让你的构建系统更加专业和强大。合理使用目标属性可以大大提升项目的可维护性、可移植性和专业性。