cmake_minimum_required(VERSION 3.16)
project(YourProjectName C)
# 设置 C 和 C++ 标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -fexceptions")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# 添加编译器警告选项
add_compile_options(
-Wswitch
-Wno-deprecated-declarations
-Wempty-body
-Wconversion
-Wreturn-type
-Wparentheses
-Wno-pointer-sign
-Wno-format
-Wuninitialized
-Wunreachable-code
-Wunused-function
-Wunused-value
-Wunused-variable
-Wall
-fno-strict-aliasing
-g2
-gdwarf-2
-O0
-fthreadsafe-statics
-frtti
-fno-omit-frame-pointer
)
# 添加链接器选项
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,noexecstack -Wl,--no-undefined")
# 添加头文件
# ${CMAKE_SOURCE_DIR} 是 CMake 提供的变量,表示你的项目的源码根目录。
# 如果你的 CMakeLists.txt 文件位于你的项目的根目录下,那么 ${CMAKE_SOURCE_DIR} 就会是这个根目录的路径。
# 亦可使用绝对路径或相对路径
include_directories(${CMAKE_SOURCE_DIR}/include)
# 指定生成目标
add_executable(YourProjectName ${SOURCE_FILES})
# 添加链接库
target_link_libraries(YourProjectName
sqlite3
pthread
)
#设置输出文件名称
set_target_properties(
YourProjectName
PROPERTIES
OUTPUT_NAME "test"
)
# 设置输出目录
set (EXECUTABLE_OUTPUT_PATH ../run)
# 源文件目录(假设你的源代码放在 src 目录下)
aux_source_directory(./src SOURCE_FILES)
下面是对每一项 CMake 设置的简要解释:
set(CMAKE_C_STANDARD 99): 设置 C 项目使用的 C 语言标准为 C99。
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -fexceptions"):
-std=gnu99: 在 CMake 中,已通过 CMAKE_C_STANDARD 设置了 C99,此选项为 GCC 特有,启用 GNU99 标准,使用 GNU 扩展。
-fexceptions: 开启 C 语言的异常支持。
set(CMAKE_CXX_STANDARD 11): 设置 C++ 项目使用的 C++ 语言标准为 C++11。
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11"): 这是个多余的设定,因为CMAKE_CXX_STANDARD 已经指定了 C++11 标准。
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,noexecstack -Wl,--no-undefined"): 设置用于链接执行文件的链接器标志。
-Wl,-z,relro: 让链接器启用 RELRO,一种安全特性,提高程序的安全性。
-Wl,-z,noexecstack: 不允许执行栈,防止栈上的数据被执行,又是一种安全措施。
-Wl,--no-undefined: 要求所有符号在链接时必须解析,没有任何未定义的符号。
add_compile_options(...): 添加编译器标志。
-Wswitch: 警告在 switch 语句中丢失 case 语句。
-Wno-deprecated-declarations: 不要警告使用已废弃的特性。
-Wempty-body: 警告如果一个条件语句或循环体为空。
-Wconversion: 警告潜在的类型转换问题。
-Wreturn-type: 警告在有返回值的函数中,缺少 return 语句。
-Wparentheses: 警告可能存在逻辑错误的括号使用。
-Wno-pointer-sign: 关闭警告指针符号类型不匹配。
-Wno-format: 关闭警告格式字符串和参数类型不匹配。
-Wuninitialized: 警告使用未初始化的变量。
-Wunreachable-code: 警告代码中可能存在无法到达的区域。
-Wunused-function: 警告未使用的函数。
-Wunused-value: 警告未使用的值。
-Wunused-variable: 警告未使用的变量。
-Wall: 开启所有警告。
-fno-strict-aliasing: 禁用严格别名规则,即允许两个指针指向相同地址的不同类型的数据。
-g2: 启用调试信息,但不包含所有调试信息。
-gdwarf-2: 使用 DWARF2 格式输出调试信息。
-O0: 不进行优化,适合调试。
-fthreadsafe-statics: 保证静态初始化的线程安全。
-frtti: 启用 C++ 的运行时类型信息支持。
-fno-omit-frame-pointer: 保留函数帧指针,便于调试和性能分析。
要在 CMake 中关闭某个具体的编译警告,你可以在 add_compile_options
中使用 -Wno-
跟上相应的警告选项。对于关闭 -Wuninitialized
警告,即警告使用未初始化的变量,你可以这样操作:
add_compile_options(-Wno-uninitialized)
将以上行加入到 CMakeLists.txt
中的 add_compile_options
调用内部,可以关闭编译器关于未初始化变量的警告。这样,在编译过程中就不会出现因使用未初始化的变量而产生的警告信息。
project
project
命令定义了工程的名称和使用的编程语言。project(test C)
指定了当前工程的名称是 test,并且它是使用 C 语言编写的。
# 设置工程名称及使用的语言
project(test C)
CMAKE_RUNTIME_OUTPUT_DIRECTORY
EXECUTABLE_OUTPUT_PATH
在 CMake 中,CMAKE_RUNTIME_OUTPUT_DIRECTORY
和 EXECUTABLE_OUTPUT_PATH
都用于指定可执行文件的输出目录,但它们在使用方式和细节上有所不同。
-
CMAKE_RUNTIME_OUTPUT_DIRECTORY
:- 这是一个多配置生成器(例如 Visual Studio 或 Xcode)支持的目标属性,用于特定目标(executable、library 或其他)的输出位置。
- 你可以为不同的目标指定不同的输出目录。
- 你还可以为不同的构建类型(Debug、Release等)设置不同的输出目录。
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
-
EXECUTABLE_OUTPUT_PATH
:- 这是一个全局变量,用于指定所有可执行文件的输出目录,并且对所有目标生效。
- 它不区分不同的构建类型,所有的构建类型都将使用这个路径作为输出。
- 如果设置了这个变量,在生成的 Makefile 或其他构建系统文件中,所有可执行文件的构建目标都会被放在这个目录下。
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
通常来说,CMAKE_RUNTIME_OUTPUT_DIRECTORY
比 EXECUTABLE_OUTPUT_PATH
更加灵活,特别是你想要对不同目标或不同构建类型分别指定输出目录时。不过,如果你的项目结构比较简单,只需要一个统一的路径来存放所有构建的可执行文件,使用 EXECUTABLE_OUTPUT_PATH
会更简单。
如果同时设置了这两个参数,CMAKE_RUNTIME_OUTPUT_DIRECTORY
将会覆盖 EXECUTABLE_OUTPUT_PATH
的设定。
在现代 CMake(版本3.x以后)建议使用 CMAKE_RUNTIME_OUTPUT_DIRECTORY
,因为它提供了比 EXECUTABLE_OUTPUT_PATH
更细粒度的控制。此外,可以在目标级别上用 set_target_properties
命令明确指定每个目标的属性。
aux_source_directory
aux_source_directory
命令在 CMake 中用于收集指定目录下所有源文件的名字,并将列表存储在一个变量中,这通常用于随后的编译指令中。这个命令可以确保在添加新的源文件时,不需要手动修改 CMakeLists.txt
文件,只要将源文件放在指定目录下,CMake 在配置生成阶段会自动将它们加入。
这个命令的基本用法如下:
aux_source_directory(目录 变量)
目录
是你想要搜集源文件的路径。变量
是用于存储收集到的源文件路径列表的变量。
aux_source_directory(src SOURCE_FILES)
这里,src
是包含源文件的目录,SOURCE_FILES
是存储找到的源文件路径的变量。
然而,值得注意的是,aux_source_directory
可能并不是最佳实践。它会将目录下所有的源文件包括在内,没有办法排除不想编译的文件。另外,如果只是添加了新文件,而没有修改 CMakeLists.txt
文件,那么构建系统是不会自动重新运行 CMake 来更新这些新文件的。因此,一个更推荐的做法是显式指定所有的源文件到相应的 CMake 命令中,尽管这意味着每次添加或移除文件时需要手动更新 CMakeLists.txt
文件。
set_target_properties
et_target_properties
命令在 CMake 中被用来设置一个或多个目标的属性。使用这个命令,你可以针对特定的目标(例如可执行文件、库等)设置一系列的属性,比如输出名称、位置等。
set_target_properties
命令的基本语法如下:
set_target_properties(目标名称
PROPERTIES
属性1 值1
属性2 倀2
...)
这里,目标名称
是需要设置属性的目标的名字,它可以是你使用 add_executable
或 add_library
创建的任意目标。属性
可以是多个不同的属性,如 OUTPUT_NAME
、COMPILE_FLAGS
或其他有效的目标属性,随之其值。
例如,如果你想为一个叫做 my_app
的可执行文件设置输出名称和定义一个预处理器标记,可以这样写:
set_target_properties(my_app
PROPERTIES
OUTPUT_NAME "my_cool_app"
COMPILE_DEFINITIONS "USE_COOL_FEATURE")
在这个例子中,当你构建项目时,生成的可执行文件名将不再是 my_app
,而是 my_cool_app
,并且会在编译 my_app
目标时定义宏 USE_COOL_FEATURE
。