CMake报“Cannot find source file”是因为只在CMAKE_CURRENT_SOURCE_DIR下查找路径,需用ls/dir验证物理路径是否存在;“No SOURCES given”则因add_executable后未指定文件或变量为空,应检查语法和变量定义顺序。

“Cannot find source file” 是路径没对上
这个错误不是 CMake 故意刁难,而是它老老实实按规则找文件——只在 CMAKE_CURRENT_SOURCE_DIR(当前 CMakeLists.txt 所在目录)下查你写的路径。比如你在项目根目录写了 add_executable(main src/main.cpp),CMake 就会去 ./src/main.cpp 找;但如果 main.cpp 实际在 ./src/core/main.cpp,它就找不到。
- 用
ls -l ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp(Linux/macOS)或dir %CD%\src\main.cpp(Windows)直接验证路径是否存在 - 别依赖 IDE 的“看起来在那儿”,终端里
pwd+ls才是真相 - 如果源文件在子目录的
CMakeLists.txt里定义,父目录的add_executable不能直接引用它——变量不跨作用域,得显式写相对路径或用file(GLOB_RECURSE)
“No SOURCES given to target” 说明根本没传文件进去
这通常不是路径问题,而是语法或逻辑断了链:目标名后面压根没跟任何源文件,或者你用了变量但变量是空的。
- 检查
add_executable调用是否形如add_executable(myapp main.cpp)—— 第一个参数是目标名,后面必须至少有一个源文件 - 如果用了变量(比如
set(SRCS src/main.cpp)),加一行message(STATUS "SRCS = ${SRCS}")看输出是不是空;常见原因是set()写在了add_executable后面,或者file(GLOB)没匹配到任何文件(比如扩展名拼错、大小写不符) - ROS 项目里常写成
add_executable(${PROJECT_NAME}_node src/node.cpp),注意${PROJECT_NAME}必须已通过project()正确定义,否则展开为空,变成add_executable(_node src/node.cpp),路径又错一层
file(GLOB) 看似省事,其实埋雷最多
file(GLOB_RECURSE SRCS "src/*.cpp") 这种写法容易让新手觉得“一劳永逸”,但它有三个硬伤:
- 不会自动感知新增文件:改完
CMakeLists.txt后,新加的.cpp文件不会被自动加入构建,除非手动删掉build/目录重来 - 可能误吞不该编译的文件:比如
src/test_main.cpp或临时生成的src/generated.cpp,全被扫进去了 - 路径拼错时静默失败:如果
"src/*.cpp"实际该写成"./src/*.cpp"或"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp",GLOB可能返回空列表,但 CMake 不报错,直到add_executable那行才爆No SOURCES
多级 CMakeLists.txt 下最容易漏掉 add_subdirectory
如果你把 src/CMakeLists.txt 单独写了 add_executable,但根目录的 CMakeLists.txt 里没写 add_subdirectory(src),那整个 src/ 目录下的配置根本不会执行——CMake 不会自动递归扫描子目录。
- 子目录的
CMakeLists.txt只有被add_subdirectory()显式调用,里面的命令才生效 - 子目录里的
add_executable定义的目标,父目录无法直接引用(比如target_link_libraries里写子目录目标名会失败),必须用add_subdirectory接入后才能跨目录依赖 - CLion 或 VS Code 的 CMake 插件有时会“假装”加载了子目录配置,但实际
cmake ..时没走add_subdirectory,构建照样失败
message() 打印变量,再终端里 ls 验证物理路径,比瞎改 add_executable 行有效得多。


















