Nanomsg库CMakeLists.txt文件阅读笔记
1、CMakeLists.txt 中用到的检测和配置模块
1.1、CheckFunctionExists
用于检查目标函数是不是存在于目标系统中,代码示例如下:
include (CheckFunctionExists)
check_function_exists(malloc HAVE_MALLOC)# 在代码中使用
if(HAVE_MALLOC)message(STATUS "malloc function is available")add_definitions(-DHAVE_MALLOC=1)
else()message(WARNING "malloc function not found!")
endif()
1.2、CheckSymbolExists
用于检查特定的符号,比如宏、函数、变量,是否在头文件中定义,代码示例如下:
include (CheckSymbolExists)
# 检查宏定义
check_symbol_exists(ENABLE_FEATURE "features.h" HAVE_ENABLE_FEATURE)
# 检查枚举值
check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC)
# 检查函数声明
check_symbol_exists(signal "signal.h" HAVE_SIGNAL_DECL)if(HAVE_CLOCK_MONOTONIC)add_definitions(-DHAVE_CLOCK_MONOTONIC)
endif()
1.3、CheckStructHasMember
用于检查指定结构体中是不是包含指定的成员,代码示例如下:
include (CheckStructHasMember)
# 检查 struct stat 是否有 st_mtime 成员
check_struct_has_member("struct stat" st_mtime "sys/stat.h" HAVE_STAT_ST_MTIME)
# 检查 struct tm 是否有 tm_gmtoff 成员
check_struct_has_member("struct tm" tm_gmtoff "time.h" HAVE_TM_GMTOFF)# 使用示例
if(HAVE_STAT_ST_MTIME)message(STATUS "struct stat has st_mtime member")
endif()
1.4、CheckLibraryExists
用于检查特定的库是不是包含特定的函数,示例如下:
include (CheckLibraryExists)
# 检查数学库中的 sqrt 函数
check_library_exists(m sqrt "" HAVE_SQRT_IN_LIBM)
# 检查 pthread 库中的 pthread_create 函数
check_library_exists(pthread pthread_create "" HAVE_PTHREAD_LIB)
# 检查需要特定库路径的情况
check_library_exists(dl dlopen "" HAVE_DLOPEN)# 使用示例
if(HAVE_SQRT_IN_LIBM)target_link_libraries(myapp m) # 链接数学库
endif()
if(HAVE_PTHREAD_LIB)target_link_libraries(myapp pthread)
endif()
1.5、CheckCSourceCompiles
用于检查C代码是不是能编译成功,示例代码如下:
include(CheckCSourceCompiles)# 检查 C11 特性支持
check_c_source_compiles("_Thread_local int x = 0;int main() { return x; }
" HAVE_THREAD_LOCAL)# 检查特定函数调用是否工作
check_c_source_compiles("#include <stdio.h>int main() {char buffer[10];snprintf(buffer, 10, \"test\");return 0;}
" HAVE_SNPRINTF)# 检查复杂特性
check_c_source_compiles("#include <complex.h>#include <math.h>int main() {double complex z = csqrt(-1.0);return (creal(z) == 0.0) ? 0 : 1;}
" HAVE_COMPLEX_NUMBERS)
1.6、GNUInstallDirs
提供符合 GNU 编码标准的安装目录变量,代码示例如下:
include(GNUInstallDirs)# 这些变量会根据平台自动设置合理的默认值
message(STATUS "Binary dir: ${CMAKE_INSTALL_BINDIR}") # bin
message(STATUS "Library dir: ${CMAKE_INSTALL_LIBDIR}") # lib, lib64
message(STATUS "Include dir: ${CMAKE_INSTALL_INCLUDEDIR}") # include
message(STATUS "Data dir: ${CMAKE_INSTALL_DATADIR}") # share
message(STATUS "Doc dir: ${CMAKE_INSTALL_DOCDIR}") # share/doc# 在安装命令中使用
install(TARGETS myappRUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)install(FILES myheader.hDESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject
)
2、CMake中使用正则表达式
已知在 nn.h中定义了版本号,下面的代码可以通过正则表达式将版本号提取出来,代码如下:
file (READ src/nn.h NN_HDR_STR) #将文件中的内容读到变量中
string(REGEX REPLACE ".*#define +NN_VERSION_CURRENT +([0-9]+).*" # 正则表达式模式"\\1" # 替换模式,这里引用的是第一个捕获组的内容,这个是版本号NN_VERSION_CURRENT # 输出变量"${NN_HDR_STR}" # 输入字符串
)
3、GCC/Clang 警告级别
标志 | 含义 | 包含的警告 |
---|---|---|
-w | 禁用所有警告 | 真正忽略警告 |
-Wall | 启用主要警告 | 未使用变量、函数未声明、隐式转换等 |
-Wextra | 额外警告 | 符号比较、空语句、多余分号等 |
-Wpedantic | 严格标准符合 | ISO C/C++ 标准违反 |
-Werror | 将警告视为错误 | 编译失败而不是警告 |
4、CMake中的宏语法
在CMake中也可以定义相关的宏,用法如下:
macro (nn_check_func SYM DEF)check_function_exists (${SYM} ${DEF})if (${DEF})add__definitions (-D${DEF}=1)endif ()
endmacro (nn_check_func)
5、设置编译输出结果路径
通过下面的指令设置编译输出路径,这样就可以自动将编译好的bin、动态库、静态库方法读应的位置,而不需要每个在设置一遍
set_target_properties(${PROJECT_NAME} PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/binLIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib
)# 添加目标时不需要再单独设置输出目录
add_executable(myapp src/main.cpp) # 自动输出到 bin/
add_library(mylib SHARED src/mylib.cpp) # 自动输出到 lib/
add_library(mylib_static STATIC src/mylib.cpp) # 自动输出到 lib/