Linux下CMake编译C++项目报cc1plus文件名过多错误如何解决?
问题原文(格式化后)
编辑1: 已补充make的详细输出,见下文
我当前在新设备上使用CMake编译C++项目,CMake配置无报错,执行make后出现如下错误:
$ make /usr/bin/cmake -S/home/luc/coding/hiwi/peltier-control-panel -B/home/luc/coding/hiwi/peltier-control-panel/build --check-build-system CMakeFiles/Makefile.cmake 0 /usr/bin/cmake -E cmake_progress_start /home/luc/coding/hiwi/peltier-control-panel/build/CMakeFiles /home/luc/coding/hiwi/peltier-control-panel/build//CMakeFiles/progress.marks make -f CMakeFiles/Makefile2 all make[1]: Entering directory '/home/luc/coding/hiwi/peltier-control-panel/build' make -f CMakeFiles/sio_client.dir/build.make CMakeFiles/sio_client.dir/depend make[2]: Entering directory '/home/luc/coding/hiwi/peltier-control-panel/build' cd /home/luc/coding/hiwi/peltier-control-panel/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/luc/coding/hiwi/peltier-control-panel /home/luc/coding/hiwi/peltier-control-panel /home/luc/coding/hiwi/peltier-control- panel/build /home/luc/coding/hiwi/peltier-control-panel/build /home/luc/coding/hiwi/peltier-control- panel/build/CMakeFiles/sio_client.dir/DependInfo.cmake --color= make[2]: Leaving directory '/home/luc/coding/hiwi/peltier-control-panel/build' make -f CMakeFiles/sio_client.dir/build.make CMakeFiles/sio_client.dir/build make[2]: Entering directory '/home/luc/coding/hiwi/peltier-control-panel/build' [ 6%] Building CXX object CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.o /usr/bin/c++ -DSIMULATION -I/home/luc/coding/hiwi/peltier-control-panel/include -I/home/luc/coding/hiwi/peltier-control-panel/src -I/home/luc/coding/hiwi/peltier-control-panel/lib -I/home/luc/coding/hiwi/peltier-control-panel/lib/websocketpp -I/home/luc/coding/hiwi/peltier-control-panel/lib/rapidjson/include -I/home/luc/coding/hiwi/peltier-control-panel/lib/WiringPi/wiringPi -Wall -Wextra -o3 -std=gnu++11 -MD -MT CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.o -MF CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.o.d -o CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.o -c /home/luc/coding/hiwi/peltier-control-panel/lib/socket.io-client-cpp/src/sio_client.cpp cc1plus: error: too many filenames given; type ‘cc1plus --help’ for usage cc1plus: fatal error: CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.d: No such file or directory compilation terminated. make[2]: *** [CMakeFiles/sio_client.dir/build.make:79: CMakeFiles/sio_client.dir/lib/socket.io-client-cpp/src/sio_client.cpp.o] Error 1 make[2]: Leaving directory '/home/luc/coding/hiwi/peltier-control-panel/build' make[1]: *** [CMakeFiles/Makefile2:175: CMakeFiles/sio_client.dir/all] Error 2 make[1]: Leaving directory '/home/luc/coding/hiwi/peltier-control-panel/build' make: *** [Makefile:94: all] Error 2
同一份代码在旧设备Ubuntu 16系统上可正常编译,说明问题与代码无关。新设备运行Arch系统,工具链版本更高,项目依赖Boost库但报错出现在链接Boost前,仅列环境信息供参考:
- Ubuntu 16环境:
- CMake: 3.15.4
- Make: 4.1
- g++/gcc: 5.4.0
- libboost 1.68.0
- Arch环境:
- CMake: 3.21.2
- Make: 4.2
- g++/gcc: 11.1.0
- libboost 1.76.0
网上检索到的同类问题均为Windows下mingw安装路径带空格导致,与我的场景不符。CMake输出如下:
cmake .. -DSIMULATION=TRUE -- The C compiler identification is GNU 11.1.0 -- The CXX compiler identification is GNU 11.1.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done Using simulated temperature data... -- Found Boost: /usr/lib64/cmake/Boost-1.76.0/BoostConfig.cmake (found version "1.76.0") found components: system -- Linking against boost shared libraries -- location of boost libraries -- Boost::system -- Looking for pthread.h -- Looking for pthread.h - found -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed -- Check if compiler accepts -pthread -- Check if compiler accepts -pthread - yes -- Found Threads: TRUE -- Linking SIMULATION -- Configuring done -- Generating done -- Build files have been written to: /home/luc/coding/hiwi/peltier-control-panel/build
我注意到Arch环境下CMake跳过了C/CXX编译器可用性检查,但编译器本身可正常编译简单程序。我从未遇到过该问题,检索未找到解决方案,希望有相关经验的开发者指点方向。
感谢@Stephen Newell的提示,我排查发现同一份CMakeLists.txt在两套环境生成的编译命令不一致:
Ubuntu 16生成的编译命令:
/usr/bin/c++ -DSIMULATION -I/home/luc/coding/hiwi/peltier-heater/include -I/home/luc/coding/hiwi/peltier-heater/src -I/home/luc/coding/hiwi/peltier-heater/lib -I/home/luc/coding/hiwi/peltier-heater/lib/websocketpp -I/home/luc/coding/hiwi/peltier-heater/lib/rapidjson/include -Wall -Wextra -o3 -std=gnu++11 -o CMakeFiles/PIDController.dir/src/PIDController.cpp.o -c /home/luc/coding/hiwi/peltier-heater/src/PIDController.cpp
Arch生成的编译命令:
/usr/bin/c++ -DSIMULATION -I/home/luc/coding/hiwi/peltier-heater/include -I/home/luc/coding/hiwi/peltier-heater/src -I/home/luc/coding/hiwi/peltier-heater/lib -I/home/luc/coding/hiwi/peltier-heater/lib/websocketpp -I/home/luc/coding/hiwi/peltier-heater/lib/rapidjson/include -Wall -Wextra -o3 -std=gnu++11 -MT CMakeFiles/PIDController.dir/src/PIDController.cpp.o -MF CMakeFiles/PIDController.dir/src/PIDController.cpp.o.d -o CMakeFiles/PIDController.dir/src/PIDController.cpp.o -c /home/luc/coding/hiwi/peltier-heater/src/PIDController.cpp
Arch的编译命令多了-MF和-MT参数,我手动去掉这两个参数后可正常完成该文件的编译。请问为什么两套环境下CMake生成的编译命令存在该差异?我可以关闭这两个参数的生成吗?还是需要修改CMakeLists.txt配置解决问题?
问题解答
根本原因定位
你在CMakeLists中指定编译优化参数时错误使用了小写的-o3,而非正确的大写-O3。
小写-o是GCC的输出文件指定参数,-o3会被编译器解析为「将输出文件命名为3」,后续所有参数都会被误识别为输入源文件,直接触发「文件名过多」报错,连带依赖文件生成流程失败,触发第二个找不到.d文件的报错。新旧环境表现不同的原因
CMake 3.20及以上版本默认开启了CMAKE_DEPENDS_USE_COMPILER选项,会直接在编译阶段通过编译器的-MD/-MT/-MF参数生成头文件依赖信息,替换了旧版本中单独执行cmake_depend流程生成依赖的逻辑,所以高版本CMake生成的编译命令会多这两个参数。
旧版CMake生成的编译命令中,-o3之后没有-MT、-MF这类带参数的选项,后续紧接的是-o 输出目标文件参数,编译器会把最后一个-o的参数作为最终输出文件名,前面的-o3参数被覆盖,属于巧合性兼容,才没有暴露参数写错的问题。解决方案
直接修改你CMakeLists.txt中的编译优化参数,把-o3改成-O3即可,不需要关闭依赖生成相关的参数,也不需要调整其他配置。修改后清空build目录重新执行cmake、make即可正常编译。
内容的提问来源于stack exchange,提问作者ljbkusters

