如何在CMake中检查系统是否符合POSIX.1-2008/POSIX.1c标准?
在CMake中验证POSIX.1-2008与POSIX.1c实际合规性(非交叉编译)
核心思路
不依赖官方认证,通过检查POSIX标准强制要求的宏定义、核心函数可用性、头文件特性,验证系统的实际合规性。利用CMake内置的检查模块,结合预处理器输出确认标准版本,最终控制指定源文件的构建逻辑。
具体实现步骤
1. 启用POSIX标准编译模式
先通过编译器宏开启POSIX.1-2008的接口暴露,确保编译器提供符合标准的函数和宏:
# 针对C/C++分别设置POSIX标准宏,覆盖POSIX.1-2008及POSIX.1c线程扩展 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=200809L") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_POSIX_C_SOURCE=200809L")
2. 包含CMake检查模块
加载CMake内置的检查工具,用于验证宏、函数和头文件:
include(CheckSymbolExists) include(CheckFunctionExists) include(CheckIncludeFile)
3. 验证POSIX.1-2008核心合规性
检查标准版本宏
_POSIX_VERSION是POSIX标准定义的版本标识,POSIX.1-2008对应值为200809L:
CheckSymbolExists(_POSIX_VERSION "unistd.h" HAVE_POSIX_VERSION) if(HAVE_POSIX_VERSION) # 提取宏的具体数值 execute_process( COMMAND ${CMAKE_C_COMPILER} -E -dM -x c /dev/null | grep "_POSIX_VERSION" | awk '{print $3}' OUTPUT_VARIABLE POSIX_VERSION_VALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) set(POSIX_2008_COMPLIANT $<EQUAL:${POSIX_VERSION_VALUE},200809L>) else() set(POSIX_2008_COMPLIANT OFF) endif()
检查核心函数与特性
验证POSIX.1-2008新增或强制要求的函数/常量:
# 检查带O_CLOEXEC标志的open函数支持 CheckFunctionExists(open HAVE_OPEN) CheckSymbolExists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) # 检查字符串复制函数strdup CheckFunctionExists(strdup HAVE_STRDUP)
4. 验证POSIX.1c(线程扩展)合规性
POSIX.1c定义了线程相关的接口,需检查线程宏和核心函数:
# 检查线程支持宏_POSIX_THREADS CheckSymbolExists(_POSIX_THREADS "pthread.h" HAVE_POSIX_THREADS) if(HAVE_POSIX_THREADS) execute_process( COMMAND ${CMAKE_C_COMPILER} -E -dM -x c /dev/null | grep "_POSIX_THREADS" | awk '{print $3}' OUTPUT_VARIABLE POSIX_THREADS_VALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) set(POSIX_1C_COMPLIANT $<EQUAL:${POSIX_THREADS_VALUE},200809L>) else() set(POSIX_1C_COMPLIANT OFF) endif() # 检查核心线程函数 CheckFunctionExists(pthread_create HAVE_PTHREAD_CREATE) CheckFunctionExists(pthread_mutex_init HAVE_PTHREAD_MUTEX_INIT) CheckFunctionExists(pthread_key_create HAVE_PTHREAD_KEY_CREATE)
5. 综合判断与构建控制
合并所有检查结果,仅在完全合规时构建指定源文件:
# 补充判断:所有核心函数必须存在才视为合规 if(NOT (HAVE_OPEN AND HAVE_O_CLOEXEC AND HAVE_STRDUP AND HAVE_PTHREAD_CREATE AND HAVE_PTHREAD_MUTEX_INIT AND HAVE_PTHREAD_KEY_CREATE)) set(POSIX_2008_COMPLIANT OFF) set(POSIX_1C_COMPLIANT OFF) endif() # 控制POSIX专属源文件的构建 if(POSIX_2008_COMPLIANT AND POSIX_1C_COMPLIANT) add_executable(posix_specific_app posix_only_source1.c posix_only_source2.c) # 部分系统需显式链接线程库 target_link_libraries(posix_specific_app PRIVATE pthread) else() # 根据需求选择报错或跳过,这里以报错为例 message(FATAL_ERROR "系统未完全符合POSIX.1-2008和POSIX.1c标准,无法构建POSIX专属目标") # 若需跳过可替换为: # message(WARNING "跳过POSIX专属目标:系统不满足合规要求") endif()
兼容性说明
- 代码兼容CMake 3.10及以上版本(
$<EQUAL:...>生成器表达式从3.10开始支持,若需兼容更低版本,可替换为if(POSIX_VERSION_VALUE EQUAL 200809L)的条件判断)。 - 非交叉编译场景下,
${CMAKE_C_COMPILER}指向系统原生编译器,预处理器输出能准确反映系统的POSIX支持情况。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

