使用CMake、clangcl与VS2022构建zlib时出现编译错误求助
当使用CMake -T clangcl 选项构建zlib时,出现资源编译器(RC)错误:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\lib\clang\17\include\stddef.h(18): warning RC4067: unexpected characters following '#if/#elif' directive; newline expected
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\lib\clang\17\include\vadefs.h(12): fatal error RC1021: invalid preprocessor command 'include_next'
问题根源
ClangCL是适配MSVC的Clang前端,但资源编译器rc.exe是MSVC原生工具,它不支持Clang特有的#include_next预处理器指令。zlib默认CMake配置未区分C编译与资源编译的头文件路径,导致RC错误地加载了Clang的系统头文件,进而触发报错。
解决方案
方案1:CMake配置时指定资源编译器及参数
在CMake配置命令中,强制指定资源编译器为MSVC的rc.exe,并手动指定MSVC的头文件路径(替换为你本地VS对应的MSVC版本路径):
cmake -G "Visual Studio 17 2022" -T clangcl ^ -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" ^ -DZLIB_BUILD_EXAMPLES:BOOL=OFF ^ -DCMAKE_RC_COMPILER="rc.exe" ^ -DCMAKE_RC_FLAGS="-I\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/include\"" ..
方案2:修改zlib的CMakeLists.txt
找到zlib源码中添加资源文件的段落,针对ClangCL环境为资源编译单独设置MSVC头文件路径:
- 打开zlib根目录下的
CMakeLists.txt,找到类似以下的代码块:
if(MSVC) add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} zlib1.rc) else() add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS}) endif()
- 修改为:
if(MSVC) add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} zlib1.rc) # 针对ClangCL环境,强制资源编译使用MSVC头文件 if(CMAKE_C_COMPILER_ID STREQUAL "Clang") set_target_properties(zlib PROPERTIES RC_COMPILE_FLAGS "-I${CMAKE_VS_MSVC_INCLUDE_PATH}" ) endif() else() add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS}) endif()
- 重新执行CMake配置与构建命令即可。
验证
修改后重新执行构建命令:
cmake --build .
即可正常完成编译,不会再出现RC相关错误。
内容的提问来源于stack exchange,提问作者user5706966

