CMakeLists.txt 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. cmake_minimum_required(VERSION 3.12)
  2. project(common_api VERSION 1.0.0 LANGUAGES CXX)
  3. # === 基础配置 ===
  4. set(CMAKE_CXX_STANDARD 17)
  5. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  6. set(CMAKE_CXX_EXTENSIONS OFF)
  7. set(CMAKE_POSITION_INDEPENDENT_CODE ON)
  8. # 添加编译选项: -g 生成调试信息, -fPIC 位置无关代码
  9. add_compile_options(-g -fPIC)
  10. # 添加地址 sanitizer 选项(用于检测内存错误)
  11. # 仅在 Debug 模式下启用,避免影响 Release 性能
  12. set(SANITIZE_OPTIONS -fsanitize=address)
  13. add_compile_options($<$<CONFIG:Debug>:${SANITIZE_OPTIONS}>)
  14. link_libraries($<$<CONFIG:Debug>:${SANITIZE_OPTIONS}>)
  15. # === 输出目录配置 ===
  16. set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
  17. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
  18. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
  19. # === 路径配置 ===
  20. set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
  21. set(INCLUDE_DIR ${SRC_DIR})
  22. # 配置ResDataObject相关路径(明确指定位置)
  23. set(RES_DATA_INCLUDE_DIR "${CMAKE_BINARY_DIR}/../../Deliver/include")
  24. set(RES_DATA_LIB_DIR "${CMAKE_BINARY_DIR}/../../Deliver/lib") # 明确设置ResDataObject库所在目录
  25. get_filename_component(RES_DATA_INCLUDE_DIR ${RES_DATA_INCLUDE_DIR} ABSOLUTE)
  26. get_filename_component(RES_DATA_LIB_DIR ${RES_DATA_LIB_DIR} ABSOLUTE)
  27. message(STATUS "ResDataObject 头文件目录: ${RES_DATA_INCLUDE_DIR}")
  28. message(STATUS "ResDataObject 库文件目录: ${RES_DATA_LIB_DIR}")
  29. set(DELIVER_DIR "${CMAKE_BINARY_DIR}/../../Deliver" CACHE PATH "交付目录路径")
  30. get_filename_component(DELIVER_DIR ${DELIVER_DIR} ABSOLUTE)
  31. message(STATUS "交付目录: ${DELIVER_DIR}")
  32. # === 源文件与头文件 ===
  33. set(SRC_FILES
  34. ${SRC_DIR}/common_api.cpp
  35. )
  36. set(HEADER_FILES
  37. ${INCLUDE_DIR}/common_api.h
  38. )
  39. # 验证头文件是否存在
  40. foreach(header ${HEADER_FILES})
  41. if(NOT EXISTS ${header})
  42. message(FATAL_ERROR "头文件不存在: ${header}")
  43. endif()
  44. endforeach()
  45. # 验证ResDataObject相关文件是否存在
  46. if(NOT EXISTS "${RES_DATA_INCLUDE_DIR}/ResDataObject.h")
  47. message(FATAL_ERROR "ResDataObject.h 不存在于 ${RES_DATA_INCLUDE_DIR}")
  48. endif()
  49. # 查找ResDataObject库(精确匹配指定目录)
  50. find_library(RES_DATA_LIB
  51. NAMES ResDataObject libResDataObject # 同时检查带lib前缀和不带前缀的库名
  52. PATHS ${RES_DATA_LIB_DIR}
  53. NO_DEFAULT_PATH # 只在指定目录查找,不搜索系统默认路径
  54. )
  55. if(NOT RES_DATA_LIB)
  56. # 找不到库时列出目录内容帮助调试
  57. message(FATAL_ERROR "找不到ResDataObject库,路径: ${RES_DATA_LIB_DIR}\n目录内容: $(ls ${RES_DATA_LIB_DIR})")
  58. else()
  59. message(STATUS "找到ResDataObject库: ${RES_DATA_LIB}")
  60. endif()
  61. # === 构建共享库 ===
  62. add_library(common_api SHARED ${SRC_FILES} ${HEADER_FILES})
  63. # === 目标属性配置 ===
  64. set_target_properties(common_api PROPERTIES
  65. VERSION ${PROJECT_VERSION}
  66. SOVERSION 1
  67. OUTPUT_NAME "common_api"
  68. PUBLIC_HEADER "${HEADER_FILES}"
  69. )
  70. # === 编译选项 ===
  71. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  72. target_compile_options(common_api PRIVATE -Wall -Wextra -Wpedantic -Werror=return-type)
  73. elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  74. target_compile_options(common_api PRIVATE -Wall -Wextra -Wpedantic -Werror=return-type)
  75. endif()
  76. # === 依赖配置 ===
  77. target_include_directories(common_api
  78. PUBLIC
  79. $<BUILD_INTERFACE:${INCLUDE_DIR}>
  80. $<BUILD_INTERFACE:${RES_DATA_INCLUDE_DIR}>
  81. $<INSTALL_INTERFACE:include>
  82. )
  83. # 链接ResDataObject库和系统库
  84. target_link_libraries(common_api
  85. PUBLIC
  86. ${RES_DATA_LIB} # 链接ResDataObject库
  87. PRIVATE
  88. pthread
  89. dl
  90. )
  91. # === 交付与安装 ===
  92. file(MAKE_DIRECTORY
  93. ${DELIVER_DIR}/lib
  94. ${DELIVER_DIR}/include
  95. )
  96. add_custom_command(TARGET common_api POST_BUILD
  97. COMMENT "复制构建产物到交付目录: ${DELIVER_DIR}"
  98. # 1. 确保交付目录存在(避免链接/复制失败)
  99. COMMAND ${CMAKE_COMMAND} -E make_directory "${DELIVER_DIR}/lib"
  100. COMMAND ${CMAKE_COMMAND} -E make_directory "${DELIVER_DIR}/include"
  101. # 2. 复制核心库文件(唯一真实二进制文件,如 libcommon_api.so.1.0.0)
  102. COMMAND ${CMAKE_COMMAND} -E echo "复制common_api核心库文件..."
  103. COMMAND ${CMAKE_COMMAND} -E copy_if_different
  104. "$<TARGET_FILE:common_api>" # 源:完整版本核心库(含全版本号)
  105. "${DELIVER_DIR}/lib/" # 目标:交付目录的lib文件夹
  106. # 3. 创建主版本符号链接(如 libcommon_api.so.1 -> libcommon_api.so.1.0.0)
  107. COMMAND ${CMAKE_COMMAND} -E echo "创建common_api主版本符号链接..."
  108. COMMAND ${CMAKE_COMMAND} -E create_symlink
  109. "$<TARGET_FILE_NAME:common_api>" # 链接指向的目标(核心库文件名)
  110. "${DELIVER_DIR}/lib/$<TARGET_SONAME_FILE_NAME:common_api>" # 链接文件本身(主版本名)
  111. # 4. 创建通用符号链接(如 libcommon_api.so -> libcommon_api.so.1)
  112. COMMAND ${CMAKE_COMMAND} -E echo "创建common_api通用符号链接..."
  113. COMMAND ${CMAKE_COMMAND} -E create_symlink
  114. "$<TARGET_SONAME_FILE_NAME:common_api>" # 链接指向的目标(主版本链接名)
  115. "${DELIVER_DIR}/lib/$<TARGET_LINKER_FILE_NAME:common_api>" # 链接文件本身(通用名)
  116. # 5. 复制头文件(保持原逻辑,确保头文件正确交付)
  117. COMMAND ${CMAKE_COMMAND} -E echo "复制common_api头文件..."
  118. COMMAND ${CMAKE_COMMAND} -E copy_if_different
  119. ${HEADER_FILES}
  120. ${DELIVER_DIR}/include/
  121. )
  122. # 安装配置
  123. install(TARGETS common_api
  124. EXPORT common_apiTargets
  125. LIBRARY DESTINATION lib
  126. ARCHIVE DESTINATION lib
  127. PUBLIC_HEADER DESTINATION include
  128. )
  129. install(EXPORT common_apiTargets
  130. FILE common_apiConfig.cmake
  131. DESTINATION lib/cmake/common_api
  132. EXPORT_LINK_INTERFACE_LIBRARIES
  133. )
  134. # === 调试辅助 ===
  135. message(STATUS "common_api 源文件: ${SRC_FILES}")
  136. message(STATUS "common_api 头文件: ${HEADER_FILES}")
  137. message(STATUS "common_api 链接库: ${RES_DATA_LIB} pthread dl")