优化 CMake 配置并添加操作系统检测脚本
This commit is contained in:
@@ -1,33 +1,99 @@
|
||||
# ==============================================================================
|
||||
# NinaEngine - 构建脚本
|
||||
#
|
||||
# 核心职责:
|
||||
# 该 CMakeLists.txt 文件负责定义 "NinaEngine" 可执行文件的完整构建流程。
|
||||
# 它涵盖了从项目基础配置、依赖库的查找与链接,到 Protocol Buffers
|
||||
# 文件的自动代码生成等所有关键步骤。
|
||||
#
|
||||
# 设计思路:
|
||||
# 脚本遵循模块化和声明式的原则,将不同阶段的构建逻辑清晰地分离开来。
|
||||
# 通过引入外部的 cmake_script 模块,将通用的配置(如C++标准、文件检索)
|
||||
# 与核心构建逻辑解耦,提高了可维护性和复用性。
|
||||
# ==============================================================================
|
||||
|
||||
# --- 项目基础设置 (Basic Project Setup) ---
|
||||
# 定义了项目构建所需的最低 CMake 版本和项目名称。
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(NinaEngine)
|
||||
|
||||
include(../cmake_script/project_cpp_standard.cmake)
|
||||
include(../cmake_script/retrieve_files.cmake)
|
||||
include(../cmake_script/utils.cmake)
|
||||
# --- 自定义脚本与配置 (Custom Scripts & Configuration) ---
|
||||
# 引入外部 CMake 脚本模块以处理通用任务,保持主脚本的整洁。
|
||||
include(../cmake_script/project_cpp_standard.cmake) # 负责设置 C++ 标准。
|
||||
include(../cmake_script/retrieve_files.cmake) # 负责递归查找源文件。
|
||||
include(../cmake_script/utils.cmake) # 提供其他工具函数,如 compile_proto_files。
|
||||
|
||||
# 使用自定义函数来配置项目的编译选项。
|
||||
# @param STANDARD: 指定C++语言标准,此处为 C++23。
|
||||
# @param INTERFACE_TARGET: 创建一个名为 config_target 的 INTERFACE 目标,
|
||||
# 用于传递编译选项、宏定义等,方便统一管理。
|
||||
setup_project_options(
|
||||
STANDARD 23
|
||||
INTERFACE_TARGET config_target
|
||||
)
|
||||
|
||||
# NOTE: 硬编码构建目录可能会降低灵活性。
|
||||
# 通常,更推荐的做法是让用户在调用 CMake 时通过 -B <build_dir> 参数来指定构建目录,
|
||||
# 以支持灵活的 out-of-source builds。
|
||||
# 此处强制将构建目录设置在项目根目录的上一级中的 `build` 文件夹。
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/../../build)
|
||||
|
||||
# 调用自定义函数为项目配置默认的编译器警告、输出路径等。
|
||||
configure_project_defaults()
|
||||
|
||||
set(SRC_FILS "")
|
||||
# --- 源代码文件管理 (Source File Management) ---
|
||||
# 初始化一个变量用于存储所有源文件的路径。
|
||||
set(SRC_FILES "")
|
||||
|
||||
# 调用自定义函数递归地从 'src' 目录中检索所有源文件,
|
||||
# 并将文件列表追加到 SRC_FILES 变量中。
|
||||
# @param CMAKE_CURRENT_SOURCE_DIR/src: 要搜索的源文件根目录。
|
||||
# @param SRC_FILES: 用于接收文件列表的输出变量。
|
||||
retrieve_files(${CMAKE_CURRENT_SOURCE_DIR}/src SRC_FILES)
|
||||
|
||||
# --- 依赖库查找 (Dependency Discovery) ---
|
||||
# 查找项目所需的核心第三方库。`REQUIRED` 参数表示如果找不到库,CMake 将会报错并停止构建。
|
||||
find_package(gRPC CONFIG REQUIRED)
|
||||
find_package(Protobuf CONFIG REQUIRED)
|
||||
find_package(ZeroMQ CONFIG REQUIRED)
|
||||
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(Protobuf REQUIRED)
|
||||
find_package(ZeroMQ REQUIRED)
|
||||
|
||||
# --- 可执行文件目标定义 (Executable Target Definition) ---
|
||||
# 创建一个名为 NinaEngine (与项目名相同) 的可执行文件。
|
||||
# @param ${PROJECT_NAME}: 目标名称。
|
||||
# @param ${SRC_FILES}: 构成该目标的所有源文件。
|
||||
add_executable(${PROJECT_NAME} ${SRC_FILES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE config_target)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE gRPC::grpc++ protobuf::libprotobuf zmq)
|
||||
|
||||
# 将依赖库链接到我们的可执行文件目标。
|
||||
# @param ${PROJECT_NAME}: 要链接的目标。
|
||||
# @param PRIVATE: 表示链接的依赖项仅对 ${PROJECT_NAME} 自身可见,
|
||||
# 不会传递给链接到 ${PROJECT_NAME} 的其他目标。
|
||||
# @param config_target: 链接之前创建的接口目标,以应用通用的编译设置。
|
||||
# @param gRPC::grpc++: gRPC 库提供的 C++ 目标。
|
||||
# @param protobuf::libprotobuf: Protobuf 运行时库目标。
|
||||
# @param zmq: ZeroMQ 库目标。
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
config_target
|
||||
gRPC::grpc++
|
||||
protobuf::libprotobuf
|
||||
libzmq
|
||||
)
|
||||
|
||||
# --- Protocol Buffers 编译 (Protocol Buffers Compilation) ---
|
||||
# 使用自定义函数编译 .proto 文件,自动生成 C++ 源代码和 gRPC 服务代码。
|
||||
# 这是一个典型的代码生成步骤,需要在编译主程序源代码之前完成。
|
||||
# @param TARGET_NAME: 为生成的代码创建一个内部目标名称,用于依赖管理。
|
||||
# @param PROTO_PATH: 存放 .proto 定义文件的目录。
|
||||
# @param OUTPUT_PATH: 生成的 .pb.h, .pb.cc, .grpc.pb.h, .grpc.pb.cc 文件的输出目录。
|
||||
# @param GRPC_ENABLED: 设置为 TRUE,表示同时生成 gRPC 服务相关的代码。
|
||||
compile_proto_files(
|
||||
TARGET_NAME ${PROJECT_NAME}_proto
|
||||
PROTO_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../proto
|
||||
OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/proto
|
||||
GRPC_ENABLED TRUE
|
||||
)
|
||||
|
||||
# --- 目标依赖关系 (Target Dependencies) ---
|
||||
# 显式声明主目标对 proto 代码生成目标的依赖。
|
||||
# 这确保了在编译 NinaEngine 之前,所有 .proto 文件都已经被成功编译和生成。
|
||||
# 如果没有这个依赖关系,构建可能会因为找不到生成的头文件而失败。
|
||||
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_proto)
|
||||
@@ -2,7 +2,7 @@
|
||||
"dependencies": [
|
||||
"grpc",
|
||||
"protobuf",
|
||||
"zeromq",
|
||||
"cppzmq",
|
||||
"gtest"
|
||||
],
|
||||
"version": "0.0.1",
|
||||
|
||||
131
src/cmake_script/detect_os.cmake
Normal file
131
src/cmake_script/detect_os.cmake
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
# 定义一个函数,为指定的目标添加操作系统和架构相关的预处理器定义
|
||||
function(add_os_definitions target)
|
||||
# 检查 target 参数是否提供
|
||||
if(NOT target)
|
||||
message(FATAL_ERROR "函数 add_os_definitions 需要一个 target 参数。")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# --- 阶段 1: 确定宏的值 ---
|
||||
|
||||
# 初始化所有平台、架构和特性宏的值为 0
|
||||
set(mirage_def_windows 0)
|
||||
set(mirage_def_macos 0)
|
||||
set(mirage_def_linux 0)
|
||||
set(mirage_def_freebsd 0)
|
||||
set(mirage_def_ios 0)
|
||||
set(mirage_def_android 0)
|
||||
set(mirage_def_cygwin 0)
|
||||
set(mirage_def_unix 0)
|
||||
set(mirage_def_posix 0)
|
||||
set(mirage_def_mobile 0)
|
||||
set(mirage_def_arch_64bit 0)
|
||||
set(mirage_def_arch_32bit 0)
|
||||
|
||||
# -- 操作系统检测与赋值 --
|
||||
# 注意检测顺序:优先检测更具体的平台
|
||||
if(CYGWIN)
|
||||
# Cygwin 环境比较特殊,它在 Windows 上模拟 Unix
|
||||
set(mirage_def_windows 1) # 基础是 Windows
|
||||
set(mirage_def_cygwin 1) # 明确是 Cygwin
|
||||
set(mirage_def_unix 1) # 提供 Unix API
|
||||
set(mirage_def_posix 1) # 提供 POSIX API
|
||||
message(STATUS "检测到 **Cygwin** 环境 (运行于 Windows)")
|
||||
elseif(WIN32)
|
||||
# 非 Cygwin 的 Windows 环境 (MSVC, MinGW, etc.)
|
||||
set(mirage_def_windows 1)
|
||||
message(STATUS "检测到 **Windows** 操作系统 (非 Cygwin)")
|
||||
elseif(ANDROID)
|
||||
# Android 平台 (通常需要特定工具链设置 ANDROID 变量)
|
||||
set(mirage_def_android 1)
|
||||
set(mirage_def_unix 1) # Android NDK 基于 Unix
|
||||
set(mirage_def_posix 1) # NDK 提供 POSIX API
|
||||
set(mirage_def_mobile 1) # 移动平台
|
||||
message(STATUS "检测到 **Android** 操作系统")
|
||||
elseif(IOS)
|
||||
# iOS 平台 (通常需要特定工具链设置 IOS 变量)
|
||||
# 需要在 APPLE 之前判断,因为 iOS 下 APPLE 也为 TRUE
|
||||
set(mirage_def_ios 1)
|
||||
set(mirage_def_unix 1) # iOS (Darwin) 基于 Unix
|
||||
set(mirage_def_posix 1) # 提供 POSIX API
|
||||
set(mirage_def_mobile 1) # 移动平台
|
||||
message(STATUS "检测到 **iOS** 操作系统")
|
||||
elseif(APPLE)
|
||||
# 此时排除了 iOS,确定是 macOS
|
||||
set(mirage_def_macos 1)
|
||||
set(mirage_def_unix 1) # macOS (Darwin) 基于 Unix
|
||||
set(mirage_def_posix 1) # 提供 POSIX API
|
||||
message(STATUS "检测到 **macOS** 操作系统")
|
||||
elseif(UNIX)
|
||||
# 此时排除了 Apple, Android, Cygwin 的其他 Unix-like 系统
|
||||
set(mirage_def_unix 1)
|
||||
set(mirage_def_posix 1)
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(mirage_def_linux 1)
|
||||
message(STATUS "检测到 **Linux** 操作系统")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
set(mirage_def_freebsd 1)
|
||||
message(STATUS "检测到 **FreeBSD** 操作系统")
|
||||
else()
|
||||
message(WARNING "检测到未知的 类Unix 操作系统: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "检测到未知的操作系统: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
|
||||
# -- 架构检测与赋值 --
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(mirage_def_arch_64bit 1)
|
||||
set(mirage_def_arch_32bit 0) # 明确设置为 0
|
||||
message(STATUS "检测到 **64-bit** 架构")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(mirage_def_arch_64bit 0) # 明确设置为 0
|
||||
set(mirage_def_arch_32bit 1)
|
||||
message(STATUS "检测到 **32-bit** 架构")
|
||||
else()
|
||||
# 对于未知或未定义的指针大小,两者都保持 0
|
||||
message(WARNING "无法明确检测到 32-bit 或 64-bit 架构 (CMAKE_SIZEOF_VOID_P = ${CMAKE_SIZEOF_VOID_P})。将两者都设置为 0。")
|
||||
endif()
|
||||
|
||||
# --- 阶段 2: 组装定义列表 ---
|
||||
set(definitions_list "") # 初始化空列表
|
||||
|
||||
# 添加平台定义
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_WINDOWS=${mirage_def_windows}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_MACOS=${mirage_def_macos}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_LINUX=${mirage_def_linux}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_FREEBSD=${mirage_def_freebsd}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_IOS=${mirage_def_ios}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_ANDROID=${mirage_def_android}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_CYGWIN=${mirage_def_cygwin}")
|
||||
|
||||
# 添加架构定义
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_64BIT=${mirage_def_arch_64bit}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_32BIT=${mirage_def_arch_32bit}")
|
||||
|
||||
# 添加特性定义
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_UNIX=${mirage_def_unix}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_POSIX=${mirage_def_posix}")
|
||||
list(APPEND definitions_list "MIRAGE_PLATFORM_IS_MOBILE=${mirage_def_mobile}")
|
||||
|
||||
# --- 阶段 3: 应用所有定义 ---
|
||||
# **关键:使用一次调用将所有定义添加到目标**
|
||||
if(definitions_list) # 确保列表非空
|
||||
target_compile_definitions(${target} PUBLIC ${definitions_list})
|
||||
endif()
|
||||
|
||||
# 函数作用域结束时,mirage_def_* 变量会自动销毁,无需显式 unset
|
||||
|
||||
endfunction()
|
||||
|
||||
# --- 使用示例 ---
|
||||
# project(MyProject)
|
||||
# add_executable(my_app main.c)
|
||||
#
|
||||
# # 调用函数为 my_app 添加平台定义
|
||||
# add_os_definitions(my_app)
|
||||
#
|
||||
# # 你也可以为库调用
|
||||
# # add_library(my_lib STATIC my_lib.c)
|
||||
# # add_os_definitions(my_lib)
|
||||
@@ -24,9 +24,16 @@
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1"/>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.32.0-rc2" />
|
||||
<PackageReference Include="Grpc.Core.Api" Version="2.71.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.72.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NetMQ" Version="4.0.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="..\proto\daw\*.proto" GrpcServices="Client" />
|
||||
<Protobuf Include="..\proto\*.proto" GrpcServices="Client" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user