|
|
@ -3,105 +3,86 @@ cmake_minimum_required(VERSION 3.10) |
|
|
get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) |
|
|
get_filename_component(TARGET_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) |
|
|
string(TOUPPER ${TARGET_NAME} TARGET_NAME_UPPER) |
|
|
string(TOUPPER ${TARGET_NAME} TARGET_NAME_UPPER) |
|
|
|
|
|
|
|
|
if(DEFINED BUILD_${TARGET_NAME_UPPER}_HAS_TEST) |
|
|
# ─── Test / Standalone 选项 ─────────────────────────────────────────── |
|
|
set(MY_HAS_TEST ${BUILD_${TARGET_NAME_UPPER}_HAS_TEST}) |
|
|
if(BUILD_${TARGET_NAME_UPPER}_HAS_TEST) |
|
|
else() |
|
|
option(BUILD_${TARGET_NAME_UPPER}_STANDALONE |
|
|
set(MY_HAS_TEST OFF) |
|
|
"Build ${TARGET_NAME_UPPER} as a standalone executable" OFF) |
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
if(MY_HAS_TEST) |
|
|
|
|
|
option(BUILD_${TARGET_NAME_UPPER}_STANDALONE "Build ${TARGET_NAME_UPPER} as a standalone executable" OFF) |
|
|
|
|
|
# mark_as_advanced(BUILD_${TARGET_NAME_UPPER}_STANDALONE) |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
set(FINAL_MODULE_SRCS "") |
|
|
# ─── 判断顶层独立构建 vs 子模块嵌入 ───────────────────────────────── |
|
|
set(FLAT_SRC_DIR "${CMAKE_BINARY_DIR}/flat_sources/${TARGET_NAME}") |
|
|
|
|
|
set(NEED_FLATTEN FALSE) |
|
|
|
|
|
|
|
|
|
|
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) |
|
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) |
|
|
set(IS_TOP_LEVEL TRUE) |
|
|
set(IS_TOP_LEVEL TRUE) |
|
|
message(STATUS "[${TARGET_NAME}] Detected Top-Level Project. Enabling recursive flatten build.") |
|
|
message(STATUS "[${TARGET_NAME}] Top-level project — enabling recursive flatten build.") |
|
|
set(NEED_FLATTEN TRUE) |
|
|
set(NEED_FLATTEN TRUE) |
|
|
else() |
|
|
else() |
|
|
set(IS_TOP_LEVEL FALSE) |
|
|
set(IS_TOP_LEVEL FALSE) |
|
|
file(GLOB ALL_C_FILES "*.c") |
|
|
set(NEED_FLATTEN FALSE) |
|
|
set(MODULE_SRCS "") |
|
|
|
|
|
foreach(SRC_FILE ${ALL_C_FILES}) |
|
|
|
|
|
get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
|
|
|
|
|
if(FILE_NAME MATCHES ".*~$" OR FILE_NAME MATCHES "\\.bak$" OR FILE_NAME MATCHES "\\.swp$") |
|
|
|
|
|
continue() |
|
|
|
|
|
else() |
|
|
|
|
|
list(APPEND MODULE_SRCS ${SRC_FILE}) |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
endforeach() |
|
|
|
|
|
set(FINAL_MODULE_SRCS ${MODULE_SRCS}) |
|
|
# ─── 收集源文件 ────────────────────────────────────────────────────── |
|
|
|
|
|
if(NOT NEED_FLATTEN) |
|
|
|
|
|
file(GLOB MODULE_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.c") |
|
|
|
|
|
# 过滤编辑器临时文件 |
|
|
|
|
|
list(FILTER MODULE_SRCS EXCLUDE REGEX ".*[~]$|.*\\.bak$|.*\\.swp$") |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
# ─── 顶层构建: 扁平化拷贝所有源文件 ───────────────────────────────── |
|
|
if(NEED_FLATTEN) |
|
|
if(NEED_FLATTEN) |
|
|
message(STATUS "[${TARGET_NAME}] Searching for files in: ${CMAKE_CURRENT_SOURCE_DIR}") |
|
|
set(FLAT_SRC_DIR "${CMAKE_BINARY_DIR}/flat_sources/${TARGET_NAME}") |
|
|
|
|
|
|
|
|
file(GLOB_RECURSE ALL_SOURCE_FILES |
|
|
file(GLOB_RECURSE ALL_SOURCE_FILES CONFIGURE_DEPENDS |
|
|
CONFIGURE_DEPENDS |
|
|
|
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/*.c" |
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/*.c" |
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/*.h" |
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/*.h" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
set(FILTERED_SOURCE_FILES "") |
|
|
# 过滤: 构建目录 / CMake 内部文件 / 编辑器临时文件 |
|
|
|
|
|
set(FILTERED_FILES "") |
|
|
foreach(SRC_FILE ${ALL_SOURCE_FILES}) |
|
|
foreach(SRC_FILE ${ALL_SOURCE_FILES}) |
|
|
get_filename_component(ABS_FILE ${SRC_FILE} ABSOLUTE) |
|
|
get_filename_component(ABS_FILE ${SRC_FILE} ABSOLUTE) |
|
|
|
|
|
get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
|
|
|
|
|
|
|
|
if(ABS_FILE MATCHES "^${CMAKE_BINARY_DIR}") |
|
|
if(ABS_FILE MATCHES "^${CMAKE_BINARY_DIR}") |
|
|
continue() |
|
|
continue() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
if(FILE_NAME MATCHES "CMakeCCompilerId\\.c$|CMakeTmp") |
|
|
get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
|
|
|
|
|
if(FILE_NAME MATCHES "CMakeCCompilerId\\.c$" OR FILE_NAME MATCHES "CMakeTmp") |
|
|
|
|
|
continue() |
|
|
continue() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
if(FILE_NAME MATCHES "[~]$|\\.bak$|\\.swp$") |
|
|
if(FILE_NAME MATCHES ".*~$" OR FILE_NAME MATCHES "\\.bak$" OR FILE_NAME MATCHES "\\.swp$") |
|
|
|
|
|
continue() |
|
|
continue() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
list(APPEND FILTERED_SOURCE_FILES ${SRC_FILE}) |
|
|
list(APPEND FILTERED_FILES ${SRC_FILE}) |
|
|
endforeach() |
|
|
endforeach() |
|
|
|
|
|
|
|
|
set(ALL_SOURCE_FILES ${FILTERED_SOURCE_FILES}) |
|
|
list(LENGTH FILTERED_FILES FILE_COUNT) |
|
|
|
|
|
|
|
|
list(LENGTH ALL_SOURCE_FILES FILE_COUNT) |
|
|
|
|
|
message(STATUS "[${TARGET_NAME}] Found ${FILE_COUNT} valid files after filtering.") |
|
|
message(STATUS "[${TARGET_NAME}] Found ${FILE_COUNT} valid files after filtering.") |
|
|
|
|
|
if(NOT FILTERED_FILES) |
|
|
if(NOT ALL_SOURCE_FILES) |
|
|
message(FATAL_ERROR "[${TARGET_NAME}] No valid source files found.") |
|
|
message(FATAL_ERROR "[${TARGET_NAME}] No valid source files found after filtering.") |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
set(FLAT_SRCS_LIST "") |
|
|
# 将所有文件拷贝到 flat 目录(避免同名冲突) |
|
|
|
|
|
set(FLAT_SRCS "") |
|
|
set(COPY_COMMANDS "") |
|
|
set(COPY_COMMANDS "") |
|
|
|
|
|
foreach(SRC_FILE ${FILTERED_FILES}) |
|
|
foreach(SRC_FILE ${ALL_SOURCE_FILES}) |
|
|
|
|
|
get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
|
|
get_filename_component(FILE_NAME ${SRC_FILE} NAME) |
|
|
get_filename_component(FILE_EXT ${SRC_FILE} EXT) |
|
|
get_filename_component(FILE_EXT ${SRC_FILE} EXT) |
|
|
|
|
|
|
|
|
set(DEST_FILE "${FLAT_SRC_DIR}/${FILE_NAME}") |
|
|
set(DEST_FILE "${FLAT_SRC_DIR}/${FILE_NAME}") |
|
|
|
|
|
|
|
|
if(EXISTS "${DEST_FILE}") |
|
|
if(EXISTS "${DEST_FILE}") |
|
|
message(WARNING "[${TARGET_NAME}] Filename conflict: '${FILE_NAME}'. Skipping ${SRC_FILE}.") |
|
|
message(WARNING "[${TARGET_NAME}] Filename conflict: '${FILE_NAME}', skipping ${SRC_FILE}") |
|
|
continue() |
|
|
continue() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
list(APPEND COPY_COMMANDS |
|
|
list(APPEND COPY_COMMANDS |
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC_FILE} ${DEST_FILE} |
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC_FILE} ${DEST_FILE} |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
if(FILE_EXT STREQUAL ".c") |
|
|
if(FILE_EXT STREQUAL ".c") |
|
|
list(APPEND FLAT_SRCS_LIST ${DEST_FILE}) |
|
|
list(APPEND FLAT_SRCS ${DEST_FILE}) |
|
|
endif() |
|
|
endif() |
|
|
endforeach() |
|
|
endforeach() |
|
|
|
|
|
|
|
|
set(FINAL_MODULE_SRCS ${FLAT_SRCS_LIST}) |
|
|
if(NOT FLAT_SRCS) |
|
|
|
|
|
message(FATAL_ERROR "[${TARGET_NAME}] No .c files to compile!") |
|
|
if(NOT FINAL_MODULE_SRCS) |
|
|
|
|
|
message(FATAL_ERROR "[${TARGET_NAME}] No .c files found to compile!") |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
add_custom_target(${TARGET_NAME}_flatten_sources |
|
|
add_custom_target(${TARGET_NAME}_flatten_sources |
|
|
@ -109,161 +90,124 @@ if(NEED_FLATTEN) |
|
|
COMMENT "[${TARGET_NAME}] Flattening sources..." |
|
|
COMMENT "[${TARGET_NAME}] Flattening sources..." |
|
|
BYPRODUCTS ${FLAT_SRC_DIR} |
|
|
BYPRODUCTS ${FLAT_SRC_DIR} |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${FLAT_SRC_DIR}") |
|
|
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${FLAT_SRC_DIR}") |
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
set(MODULE_SRCS ${FINAL_MODULE_SRCS}) |
|
|
set(MODULE_SRCS ${FLAT_SRCS}) |
|
|
|
|
|
set_source_files_properties(${MODULE_SRCS} PROPERTIES GENERATED TRUE) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
if(NOT MODULE_SRCS AND NOT NEED_FLATTEN) |
|
|
# ─── 无源文件时创建 header-only INTERFACE 库 ──────────────────────── |
|
|
if(NOT IS_TOP_LEVEL) |
|
|
if(NOT MODULE_SRCS AND NOT IS_TOP_LEVEL) |
|
|
message(STATUS "[${TARGET_NAME}] No source files found. Creating INTERFACE (header-only) library.") |
|
|
message(STATUS "[${TARGET_NAME}] No source files — creating INTERFACE (header-only) library.") |
|
|
add_library(${TARGET_NAME} INTERFACE) |
|
|
add_library(${TARGET_NAME} INTERFACE) |
|
|
|
|
|
|
|
|
set(INTERFACE_INCLUDES "") |
|
|
set(INTERFACE_INCLUDES "") |
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include") |
|
|
foreach(inc |
|
|
list(APPEND INTERFACE_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include") |
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/include" |
|
|
endif() |
|
|
"${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}" |
|
|
if(EXISTS "${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}") |
|
|
"${PROJECT_SOURCE_DIR}/include" |
|
|
list(APPEND INTERFACE_INCLUDES "${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}") |
|
|
) |
|
|
endif() |
|
|
if(EXISTS "${inc}") |
|
|
if(EXISTS "${PROJECT_SOURCE_DIR}/include") |
|
|
list(APPEND INTERFACE_INCLUDES "${inc}") |
|
|
list(APPEND INTERFACE_INCLUDES "${PROJECT_SOURCE_DIR}/include") |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
endforeach() |
|
|
target_include_directories(${TARGET_NAME} INTERFACE ${INTERFACE_INCLUDES}) |
|
|
target_include_directories(${TARGET_NAME} INTERFACE ${INTERFACE_INCLUDES}) |
|
|
message(STATUS "[${TARGET_NAME}] INTERFACE includes: ${INTERFACE_INCLUDES}") |
|
|
message(STATUS "[${TARGET_NAME}] INTERFACE includes: ${INTERFACE_INCLUDES}") |
|
|
return() |
|
|
return() |
|
|
endif() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
set(EXPLICIT_STANDALONE OFF) |
|
|
|
|
|
if(DEFINED BUILD_${TARGET_NAME_UPPER}_STANDALONE AND BUILD_${TARGET_NAME_UPPER}_STANDALONE) |
|
|
|
|
|
set(EXPLICIT_STANDALONE ON) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
set(IMPLICIT_STANDALONE OFF) |
|
|
# ─── 判断是否构建独立可执行文件 ───────────────────────────────────── |
|
|
if(IS_TOP_LEVEL AND DEFINED MAIN AND MAIN) |
|
|
|
|
|
set(IMPLICIT_STANDALONE ON) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
if(EXPLICIT_STANDALONE OR IMPLICIT_STANDALONE) |
|
|
|
|
|
set(SHOULD_BUILD_EXECUTABLE TRUE) |
|
|
|
|
|
else() |
|
|
|
|
|
set(SHOULD_BUILD_EXECUTABLE FALSE) |
|
|
set(SHOULD_BUILD_EXECUTABLE FALSE) |
|
|
|
|
|
if(BUILD_${TARGET_NAME_UPPER}_STANDALONE) |
|
|
|
|
|
set(SHOULD_BUILD_EXECUTABLE TRUE) |
|
|
|
|
|
elseif(IS_TOP_LEVEL AND MAIN) |
|
|
|
|
|
set(SHOULD_BUILD_EXECUTABLE TRUE) |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
if(NEED_FLATTEN AND FINAL_MODULE_SRCS) |
|
|
# ─── 创建目标 ──────────────────────────────────────────────────────── |
|
|
set_source_files_properties(${FINAL_MODULE_SRCS} PROPERTIES GENERATED TRUE) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
if(SHOULD_BUILD_EXECUTABLE) |
|
|
if(SHOULD_BUILD_EXECUTABLE) |
|
|
set(CURRENT_TARGET_NAME ${TARGET_NAME}) |
|
|
add_executable(${TARGET_NAME} ${MODULE_SRCS}) |
|
|
add_executable(${CURRENT_TARGET_NAME} ${MODULE_SRCS}) |
|
|
target_compile_definitions(${TARGET_NAME} PRIVATE MAIN STANDALONE_BUILD) |
|
|
|
|
|
set_target_properties(${TARGET_NAME} PROPERTIES |
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug") |
|
|
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output |
|
|
target_compile_definitions(${CURRENT_TARGET_NAME} PUBLIC DEBUG) |
|
|
) |
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
target_compile_definitions(${TARGET_NAME} PRIVATE ${GLOBAL_ENABLED_MACROS}) |
|
|
|
|
|
|
|
|
|
|
|
if(NEED_FLATTEN) |
|
|
|
|
|
add_dependencies(${CURRENT_TARGET_NAME} ${TARGET_NAME}_flatten_sources) |
|
|
|
|
|
target_include_directories(${CURRENT_TARGET_NAME} PRIVATE ${FLAT_SRC_DIR}) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
target_compile_definitions(${CURRENT_TARGET_NAME} PRIVATE MAIN STANDALONE_BUILD) |
|
|
|
|
|
set_target_properties(${CURRENT_TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output) |
|
|
|
|
|
message(STATUS "[${TARGET_NAME}] Building Standalone: ${CURRENT_TARGET_NAME} (Sources count: ${MODULE_SRCS})") |
|
|
|
|
|
else() |
|
|
else() |
|
|
set(CURRENT_TARGET_NAME ${TARGET_NAME}) |
|
|
|
|
|
if(MY_BUILD_STATIC) |
|
|
if(MY_BUILD_STATIC) |
|
|
add_library(${TARGET_NAME} STATIC ${MODULE_SRCS}) |
|
|
add_library(${TARGET_NAME} STATIC ${MODULE_SRCS}) |
|
|
|
|
|
elseif(MY_BUILD_SHARED_LIBS) |
|
|
|
|
|
add_library(${TARGET_NAME} SHARED ${MODULE_SRCS}) |
|
|
else() |
|
|
else() |
|
|
if(A_BUILD_MAIN_AS_STATIC_LIB) |
|
|
|
|
|
add_library(${TARGET_NAME} OBJECT ${MODULE_SRCS}) |
|
|
add_library(${TARGET_NAME} OBJECT ${MODULE_SRCS}) |
|
|
else() |
|
|
|
|
|
add_library(${TARGET_NAME} SHARED ${MODULE_SRCS}) |
|
|
|
|
|
endif() |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug") |
|
|
|
|
|
target_compile_definitions(${TARGET_NAME} PUBLIC DEBUG) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
target_compile_definitions(${TARGET_NAME} PRIVATE ${GLOBAL_ENABLED_MACROS}) |
|
|
|
|
|
|
|
|
|
|
|
if(NEED_FLATTEN) |
|
|
|
|
|
add_dependencies(${CURRENT_TARGET_NAME} ${TARGET_NAME}_flatten_sources) |
|
|
|
|
|
target_include_directories(${CURRENT_TARGET_NAME} PRIVATE ${FLAT_SRC_DIR}) |
|
|
|
|
|
endif() |
|
|
|
|
|
|
|
|
|
|
|
set_target_properties(${TARGET_NAME} PROPERTIES |
|
|
set_target_properties(${TARGET_NAME} PROPERTIES |
|
|
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output |
|
|
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output |
|
|
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output |
|
|
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output |
|
|
) |
|
|
) |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
set(MY_PUBLIC_INCLUDES "") |
|
|
message(STATUS "[${TARGET_NAME}] Configured target: ${TARGET_NAME} (Sources: ${MODULE_SRCS})") |
|
|
|
|
|
|
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include") |
|
|
# ─── Flatten 依赖 ──────────────────────────────────────────────────── |
|
|
list(APPEND MY_PUBLIC_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/include") |
|
|
if(NEED_FLATTEN) |
|
|
message(STATUS "[${TARGET_NAME}] Found local include: ${CMAKE_CURRENT_SOURCE_DIR}/include") |
|
|
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_flatten_sources) |
|
|
|
|
|
target_include_directories(${TARGET_NAME} PRIVATE ${FLAT_SRC_DIR}) |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
if(EXISTS "${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}") |
|
|
# ─── 编译宏定义 ───────────────────────────────────────────────────── |
|
|
list(APPEND MY_PUBLIC_INCLUDES "${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}") |
|
|
target_compile_definitions(${TARGET_NAME} |
|
|
message(STATUS "[${TARGET_NAME}] Found global sub-include: ${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}") |
|
|
PRIVATE ${GLOBAL_ENABLED_MACROS} |
|
|
endif() |
|
|
$<$<CONFIG:Debug>:DEBUG> |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
if(EXISTS "${PROJECT_SOURCE_DIR}/include") |
|
|
# ─── Include 目录 ──────────────────────────────────────────────────── |
|
|
list(APPEND MY_PUBLIC_INCLUDES "${PROJECT_SOURCE_DIR}/include") |
|
|
set(MY_PUBLIC_INCLUDES "") |
|
|
message(STATUS "[${TARGET_NAME}] Found global root include: ${PROJECT_SOURCE_DIR}/include") |
|
|
foreach(inc |
|
|
|
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/include" |
|
|
|
|
|
"${PROJECT_SOURCE_DIR}/include/${TARGET_NAME}" |
|
|
|
|
|
"${PROJECT_SOURCE_DIR}/include" |
|
|
|
|
|
) |
|
|
|
|
|
if(EXISTS "${inc}") |
|
|
|
|
|
list(APPEND MY_PUBLIC_INCLUDES "${inc}") |
|
|
|
|
|
message(STATUS "[${TARGET_NAME}] Found include: ${inc}") |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
endforeach() |
|
|
|
|
|
|
|
|
if(NOT MY_PUBLIC_INCLUDES) |
|
|
if(NOT MY_PUBLIC_INCLUDES) |
|
|
if(NEED_FLATTEN) |
|
|
|
|
|
list(APPEND MY_PUBLIC_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") |
|
|
list(APPEND MY_PUBLIC_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") |
|
|
else() |
|
|
message(STATUS "[${TARGET_NAME}] Fallback include: source dir") |
|
|
list(APPEND MY_PUBLIC_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") |
|
|
|
|
|
endif() |
|
|
|
|
|
message(STATUS "[${TARGET_NAME}] Fallback to source dir: ${CMAKE_CURRENT_SOURCE_DIR}") |
|
|
|
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
target_include_directories(${CURRENT_TARGET_NAME} |
|
|
target_include_directories(${TARGET_NAME} |
|
|
PUBLIC ${MY_PUBLIC_INCLUDES} |
|
|
PUBLIC ${MY_PUBLIC_INCLUDES} |
|
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} |
|
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
target_link_libraries(${CURRENT_TARGET_NAME} |
|
|
# ─── 链接依赖 ──────────────────────────────────────────────────────── |
|
|
PRIVATE m |
|
|
target_link_libraries(${TARGET_NAME} PRIVATE m) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME_LOWER) |
|
|
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME_LOWER) |
|
|
if(CMAKE_CROSSCOMPILING AND NOT SYSTEM_NAME_LOWER MATCHES "linux|windows|darwin|android") |
|
|
if(CMAKE_CROSSCOMPILING AND NOT SYSTEM_NAME_LOWER MATCHES "linux|windows|darwin|android") |
|
|
message(STATUS ">>> 检测到裸机/RTOS 环境 (${CMAKE_SYSTEM_NAME}),屏蔽 pthread。") |
|
|
message(STATUS ">>> 裸机/RTOS 环境 (${CMAKE_SYSTEM_NAME}),屏蔽 pthread") |
|
|
else() |
|
|
else() |
|
|
find_package(Threads REQUIRED) |
|
|
find_package(Threads REQUIRED) |
|
|
target_link_libraries(${CURRENT_TARGET_NAME} |
|
|
target_link_libraries(${TARGET_NAME} |
|
|
PUBLIC Threads::Threads |
|
|
PUBLIC Threads::Threads |
|
|
PRIVATE ${CMAKE_DL_LIBS} |
|
|
PRIVATE ${CMAKE_DL_LIBS} |
|
|
) |
|
|
) |
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") |
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") |
|
|
target_link_libraries(${CURRENT_TARGET_NAME} PRIVATE rt) |
|
|
target_link_libraries(${TARGET_NAME} PRIVATE rt) |
|
|
endif() |
|
|
endif() |
|
|
endif() |
|
|
endif() |
|
|
|
|
|
|
|
|
target_compile_options(${CURRENT_TARGET_NAME} |
|
|
# ─── 编译选项 ──────────────────────────────────────────────────────── |
|
|
PRIVATE |
|
|
target_compile_options(${TARGET_NAME} PRIVATE |
|
|
-Wall |
|
|
-Wall -Werror |
|
|
-Werror |
|
|
-ffunction-sections -fdata-sections |
|
|
$<$<CONFIG:Debug>:-g -O0> |
|
|
$<$<CONFIG:Debug>:-g -O0> |
|
|
$<$<CONFIG:Release>:-O2> |
|
|
$<$<CONFIG:Release>:-O2> |
|
|
-ffunction-sections -fdata-sections |
|
|
|
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
target_link_options(${CURRENT_TARGET_NAME} |
|
|
target_link_options(${TARGET_NAME} PRIVATE |
|
|
PRIVATE |
|
|
|
|
|
-Wl,--gc-sections |
|
|
-Wl,--gc-sections |
|
|
$<$<CONFIG:Release>:-s> |
|
|
$<$<CONFIG:Release>:-s> |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
message(STATUS "[${TARGET_NAME}] Configured target: ${CURRENT_TARGET_NAME}") |
|
|
|