如何用CMake检查编译器是否支持_Float16类型?
在CMake中检测_Float16支持性的方案
针对你的需求,这里提供两种可靠的CMake检测方案,解决CheckTypeSize()可能遗漏头文件的问题,确保只有编译器支持_Float16时才编译相关代码:
方案一:用CheckCSourceCompiles自定义检测逻辑
这种方式最灵活,可以直接编写完整的测试代码,明确包含所需头文件并验证_Float16的有效性:
include(CheckCSourceCompiles) # 编写测试代码:包含必要头文件,验证_Float16的声明和大小 set(TEST_FLOAT16_SNIPPET " #include <stddef.h> int main() { _Float16 test_val = 0.0f16; // 确保类型大小符合半精度预期(2字节) return sizeof(test_val) == 2 ? 0 : 1; } ") # 执行编译检测 check_c_source_compiles("${TEST_FLOAT16_SNIPPET}" HAVE_FLOAT16) # 根据检测结果处理后续编译逻辑 if(HAVE_FLOAT16) # 定义宏供代码中使用(可选) add_definitions(-DHAVE_FLOAT16) # 编译使用_Float16的目标程序 add_executable(float16_demo src/use_float16_module.c) else() message(STATUS "当前编译器不支持_Float16,跳过相关模块编译") endif()
方案二:改进CheckTypeSize的用法
如果你倾向于使用CheckTypeSize,可以通过设置CMAKE_REQUIRED_INCLUDES指定需要包含的头文件,确保检测环境正确:
include(CheckTypeSize) # 指定检测时需要包含的头文件 set(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};stddef.h") # 检测_Float16的类型大小 check_type_size("_Float16" FLOAT16_BYTE_SIZE) # 重置变量,避免影响其他检测逻辑 set(CMAKE_REQUIRED_INCLUDES "") # 判断是否支持有效_Float16类型 if(FLOAT16_BYTE_SIZE EQUAL 2) set(HAVE_FLOAT16 ON) else() set(HAVE_FLOAT16 OFF) endif() # 后续编译逻辑同方案一 if(HAVE_FLOAT16) # ... 编译相关程序 endif()
补充:针对特殊编译器的适配
部分编译器(如GCC在ARM平台)需要开启特定编译选项才能支持_Float16,你可以扩展检测逻辑,尝试添加必要选项后再次检测:
include(CheckCSourceCompiles) set(TEST_FLOAT16_SNIPPET " #include <stddef.h> int main() { _Float16 test_val = 0.0f16; return sizeof(test_val) == 2 ? 0 : 1; } ") # 先尝试默认编译选项 check_c_source_compiles("${TEST_FLOAT16_SNIPPET}" HAVE_FLOAT16) # 默认不支持时,尝试添加C11标准和_Float16相关编译选项 if(NOT HAVE_FLOAT16) set(CMAKE_REQUIRED_FLAGS "-std=c11 -ffloat16") check_c_source_compiles("${TEST_FLOAT16_SNIPPET}" HAVE_FLOAT16_WITH_FLAGS) set(CMAKE_REQUIRED_FLAGS "") # 重置选项 if(HAVE_FLOAT16_WITH_FLAGS) set(HAVE_FLOAT16 ON) # 给相关目标添加必要编译选项 add_compile_options(-std=c11 -ffloat16) endif() endif()
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

