CMake编译C++分文件项目报错:未定义引用及编译器切换问题
嘿,作为C++新手遇到这种编译链接的问题太正常了,我来一步步帮你理清这两个问题:
1. 让CMake使用g++而非gcc的两种方法
其实CMake对于C项目默认会调用g,但有时候环境配置可能会出偏差,你可以通过下面两种方式明确指定:
修改CMakeLists.txt直接指定编译器
在你的CMakeLists.txt里,cmake_minimum_required之后添加一行,强制设置C编译器为g:cmake_minimum_required(VERSION 2.8) set(CMAKE_CXX_COMPILER g++) # 新增这行指定编译器 project(manual) include_directories(include) add_executable(main func.cpp main.cpp)执行cmake时通过命令行参数指定
如果你不想改动CMakeLists.txt,也可以在生成Makefile的时候用参数指定:cmake -DCMAKE_CXX_COMPILER=g++ .(如果用了单独的build目录,就把
.换成..,根据你的项目结构调整路径)
另外你说得没错,gcc是C语言的编译器,它不会自动链接C标准库,所以编译C代码必须用g++。
2. 单文件编译正常,拆分后报错的原因
你遇到的undefined reference to charout(int, char)是链接错误,问题出在你执行make main这个操作上,而非CMakeLists.txt本身!
看你的错误输出:
g++ main.cpp -o main
这说明Makefile里的main目标只编译了main.cpp,完全没处理func.cpp——但你的CMakeLists.txt明明写了add_executable(main func.cpp main.cpp),原因是:
当你用CMake生成Makefile后,正确的编译命令是直接执行make(不带任何目标),或者make all。CMake生成的Makefile里,main这个目标其实只是对应main.cpp的单独编译步骤,而完整的可执行文件需要把func.cpp编译出的目标文件和main.cpp的目标文件链接起来,这个完整流程是由all目标处理的。
而单文件的时候,add_executable(main main.cpp),这时候make main就是直接编译生成可执行文件,不需要链接其他文件,所以不会报错。拆分文件后,你必须让CMake把两个源文件都参与编译链接,这时候执行make(不带参数)才会正确完成整个流程。
简单说,你之前的操作错在执行make main,改成直接执行make就没问题了,你的CMakeLists.txt本身是正确的。
内容的提问来源于stack exchange,提问作者viscous_flow

