CMake生成预处理文件失败:链接器提示文件格式无法识别
问题原因与解决方案
问题根源
你在CMake中添加的add_compile_options(-E -v)里,-E是GCC/Clang的专属编译选项——它会让编译器仅完成预处理步骤,输出宏展开、头文件嵌入后的纯文本内容,不会生成链接阶段需要的二进制目标文件(.o)。
而add_executable的默认逻辑是:先编译源文件生成.o二进制目标文件,再调用链接器将目标文件打包成可执行程序。但因为-E的存在,生成的main.cpp.o实际是纯文本格式的预处理输出,并非合法的二进制目标文件,所以链接器ld无法识别该格式,抛出报错。
解决方案
根据你的实际需求分两种场景处理:
场景1:仅需生成预处理文件(.i)
无需使用add_executable,改用CMake的自定义命令生成预处理文件:
cmake_minimum_required(VERSION 3.14) project(url_email LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 自定义命令:生成预处理文件url_email.i add_custom_command( OUTPUT url_email.i COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -E ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -o url_email.i MAIN_DEPENDENCY main.cpp COMMENT "Generating preprocessed file url_email.i" ) # 自定义目标,允许直接通过make触发预处理文件生成 add_custom_target(generate_preprocess ALL DEPENDS url_email.i)
执行cmake .. && make后,构建目录下会生成url_email.i文件,内容即为宏处理后的预处理结果。
场景2:同时生成可执行文件与预处理文件
不能将-E加入全局编译选项,需单独为预处理步骤设置该选项:
cmake_minimum_required(VERSION 3.14) project(url_email LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 正常编译生成可执行文件 add_executable(url_email main.cpp) target_link_libraries(url_email) # 单独生成预处理文件 add_custom_command( OUTPUT url_email.i COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} -E ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -o url_email.i MAIN_DEPENDENCY main.cpp COMMENT "Generating preprocessed file url_email.i" ) add_custom_target(generate_preprocess ALL DEPENDS url_email.i)
执行make时,会同时生成可执行程序url_email和预处理文件url_email.i,不会触发链接错误。
内容的提问来源于stack exchange,提问作者user3597635
相关产品推荐
相关产品推荐

