1.目录结构
2.父Cmake内容:
cmake_minimum_required(VERSION 3.15 FATAL_ERROR) set(PROJECT_NAME "DemoCMakeProject") project(${PROJECT_NAME} VERSION 1.0.0 LANGUAGES C CXX) # ===================== 核心配置 ===================== set(DEFAULT_BUILD_TYPE "Release") # Debug/Release set(TARGET_ARCH "x64") # Windows:x86/x64 | Linux:x86_64/aarch64 set(FORCE_UTF8_ENCODING ON) # 强制UTF8 # ===================== 基础配置 ===================== # UTF8编码(不变) if(FORCE_UTF8_ENCODING) if(MSVC) add_compile_options("/utf-8") add_definitions(-DUNICODE -D_UNICODE) else() add_compile_options(-finput-charset=utf-8 -fexec-charset=utf-8) endif() endif() # 输出目录:改为 配置_架构 格式(如 Release_x64) set(EXE_OUT "${CMAKE_SOURCE_DIR}/bin") set(LIB_OUT "${CMAKE_SOURCE_DIR}/bin") # 仅对单配置系统(Linux)设置构建类型 if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING "Choose the build type." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release") endif() #Windows可以通过vs的管理配置切换 #Linux 可以通过命令指定“cmake -DCMAKE_BUILD_TYPE=Release ..” set(BUILD_ARCH_DIR "${CMAKE_BUILD_TYPE}_${TARGET_ARCH}") # 关键修改:适配多配置(VS)的输出目录 → Release_x64/Debug_x64 foreach(OUTPUT_CONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUT_CONFIG} OUTPUT_CONFIG_UPPER) # 拼接目录:Release_x64 / Debug_x64 set(CONFIG_ARCH_DIR "${OUTPUT_CONFIG}_${TARGET_ARCH}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${EXE_OUT}/${CONFIG_ARCH_DIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${LIB_OUT}/${CONFIG_ARCH_DIR}") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${LIB_OUT}/${CONFIG_ARCH_DIR}") endforeach() # 单配置系统(Linux)的输出目录 → Release_x64 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${EXE_OUT}/${BUILD_ARCH_DIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${LIB_OUT}/${BUILD_ARCH_DIR}") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${LIB_OUT}/${BUILD_ARCH_DIR}") # 平台/架构识别 + 编译参数(不变) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(PLATFORM_STR "Windows") if(CMAKE_GENERATOR MATCHES "Visual Studio") set(CMAKE_GENERATOR_PLATFORM ${TARGET_ARCH} CACHE STRING "" FORCE) else() if(TARGET_ARCH STREQUAL "x86") add_compile_options(/M32) else() # x64 add_compile_options(/M64) endif() endif() else() # Linux set(PLATFORM_STR "Linux") if(TARGET_ARCH STREQUAL "aarch64") set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") else() endif() endif() # 编译标准(不变) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(MSVC) add_compile_options(/MP /W4 /wd4996) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG /INCREMENTAL:NO") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /MD /DNDEBUG") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /INCREMENTAL:NO") else() add_compile_options(-Wall -Wextra) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG") endif() # 公共头文件 include_directories(${CMAKE_SOURCE_DIR}/Common/inc) #平台专属库 if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(PLATFORM_LIBS "") else() set(PLATFORM_LIBS dl pthread m) endif() # 公共源码 set(COMMON_SRC_DIR ${CMAKE_SOURCE_DIR}/Common/src) # 检查公共源码目录是否存在 if(NOT EXISTS ${COMMON_SRC_DIR}) message(FATAL_ERROR "Common源码目录不存在:${COMMON_SRC_DIR}") endif() file(GLOB_RECURSE COMMON_SRCS ${COMMON_SRC_DIR}/*.cpp ${COMMON_SRC_DIR}/*.c # 如果有C文件,加上这行 ) #编译公共源码为静态库 add_library(common_lib STATIC ${COMMON_SRCS}) # 核心修复:为静态库强制添加 -fPIC 编译选项 target_compile_options(common_lib PRIVATE -fPIC) # 或者全局开启(推荐,确保所有目标都加 -fPIC) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # 子目录 add_subdirectory(FfmpegO) add_subdirectory(TestDemo) # 配置输出(新增架构目录提示) if(CMAKE_CONFIGURATION_TYPES) message(STATUS "平台: ${PLATFORM_STR} | 架构: ${TARGET_ARCH} | 支持的配置: ${CMAKE_CONFIGURATION_TYPES} | 输出目录格式: bin/配置_架构") else() message(STATUS "平台: ${PLATFORM_STR} | 架构: ${TARGET_ARCH} | 类型: ${CMAKE_BUILD_TYPE} | 输出目录: ${EXE_OUT}/${BUILD_ARCH_DIR}") endif()2.子项目FfmpegO的Cmake内容:
set(MODULE_NAME "FfmpegO") message(STATUS "开始编译子项目:${MODULE_NAME}") # ===================== 唯一版本控制入口 ===================== set(MODULE_VERSION "1.0.10") # 改版本仅改这里(x.y.z格式) string(REPLACE "." ";" VERSION_LIST ${MODULE_VERSION}) list(GET VERSION_LIST 0 MODULE_VERSION_MAJOR) list(GET VERSION_LIST 1 MODULE_VERSION_MINOR) list(GET VERSION_LIST 2 MODULE_VERSION_PATCH) # 基础配置:继承主CMake公共头文件 + 子项目私有头文件 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/inc ) # 源码收集(不变) file(GLOB SRCS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) if(NOT SRCS) message(WARNING "[${MODULE_NAME}] 无源码文件,跳过编译") return() endif() # ===================== 核心:库名拼接(保留原有逻辑)===================== set(MODULE_OUTPUT_NAME ${MODULE_NAME}) # Debug版本加_d后缀(兼容VS多配置) if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_CFG_INTDIR STREQUAL "Debug") set(MODULE_OUTPUT_NAME "${MODULE_NAME}_d") endif() # Linux带版本号(无软链接) if(NOT MSVC) set(MODULE_OUTPUT_NAME "${MODULE_OUTPUT_NAME}.${MODULE_VERSION}") endif() # Windows:动态生成带版本号的RC(不变) if(MSVC) set(RC_FILE ${CMAKE_BINARY_DIR}/version_${MODULE_NAME}.rc) file(WRITE ${RC_FILE} " #include <windows.h> VS_VERSION_INFO VERSIONINFO FILEVERSION ${MODULE_VERSION_MAJOR},${MODULE_VERSION_MINOR},${MODULE_VERSION_PATCH},0 PRODUCTVERSION ${MODULE_VERSION_MAJOR},${MODULE_VERSION_MINOR},${MODULE_VERSION_PATCH},0 FILEOS 0x40004L FILETYPE 0x2L BEGIN BLOCK \"StringFileInfo\" BEGIN BLOCK \"080404B0\" BEGIN VALUE \"FileVersion\", \"${MODULE_VERSION}\\0\" VALUE \"ProductVersion\", \"${MODULE_VERSION}\\0\" VALUE \"OriginalFilename\", \"${MODULE_NAME}.dll\\0\" END END BLOCK \"VarFileInfo\" BEGIN VALUE \"Translation\", 0x804, 936 END END") list(APPEND SRCS ${RC_FILE}) endif() # 生成动态库(核心逻辑) add_library(${MODULE_NAME} SHARED ${SRCS}) # ===================== 输出配置(仅保留必要属性,路径继承主工程)===================== set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_OUTPUT_NAME} # 保留库名规则(Debug加_d、Linux带版本号) NO_SONAME ON # Linux禁用软链接 ) # Windows Debug PDB配置(自动放到Release_x64/Debug_x64) if(MSVC) set_target_properties(${MODULE_NAME} PROPERTIES COMPILE_PDB_OUTPUT_DIRECTORY "$<TARGET_FILE_DIR:${MODULE_NAME}>" COMPILE_PDB_NAME_DEBUG ${MODULE_NAME} ) endif() target_link_libraries(${MODULE_NAME} common_lib # 主CMake生成的外部静态库 ${PLATFORM_LIBS} # 主CMake定义的系统专用库 ) # 编译完成提示(显示最终输出目录) message(STATUS "[${MODULE_NAME}] 编译完成 → 输出路径:${EXE_OUT}/${CMAKE_BUILD_TYPE}_${TARGET_ARCH}")3.TestDemo的Cmake内容:
set(MODULE_NAME "TestDemo") message(STATUS "开始编译子项目:${MODULE_NAME}") include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/inc ) # 生成可执行文件Test add_executable(Test ${CMAKE_CURRENT_SOURCE_DIR}/src/Test.cpp) target_link_libraries(Test common_lib # 主CMake生成的外部静态库 ${PLATFORM_LIBS} # 主CMake定义的系统专用库 # 生成可执行文件RecorTest add_executable(RecorTest ${CMAKE_CURRENT_SOURCE_DIR}/src/RecorTest.cpp) target_link_libraries(RecorTest common_lib # 主CMake生成的外部静态库 ${PLATFORM_LIBS} # 主CMake定义的系统专用库 )