结论:CMake报“Cannot find source file”90%是文件物理不存在、路径相对CMAKE_CURRENT_SOURCE_DIR写错或大小写不匹配;必须先用ls/dir确认文件真实存在且路径准确,再检查变量赋值和大小写一致性。

直接说结论:CMake 报 Cannot find source file,90% 是文件根本不存在、路径写错、或大小写不匹配——不是 CMake 本身坏了,而是它老实执行了你写的路径,而那个路径下真没东西。
文件物理存在性是第一道关卡
别急着改 CMakeLists.txt,先用终端确认文件是否真的在那儿:
- 运行
ls -l src/client_example_node.cpp(Linux/macOS)或dir srcclient_example_node.cpp(Windows),看输出有没有这个文件 - 如果提示“no such file”,说明文件压根没放对位置;ROS 包里常见错误是把
.cpp放在了src/外面,或者误删了 - 注意:CMake 不会帮你创建文件,它只读已存在的文件。生成代码的脚本(如
rosidl_generate_interfaces)必须提前跑完,否则add_executable时那些 .cpp 还没诞生
路径写法必须和项目结构严格对齐
add_executable(target_name src/speed_publisher_node.cpp) 这行里的 src/speed_publisher_node.cpp 是相对于 CMAKE_CURRENT_SOURCE_DIR(即当前 CMakeLists.txt 所在目录)的相对路径。
- 如果
CMakeLists.txt在包根目录,而speed_publisher_node.cpp确实在src/子目录下,那就没问题 - 如果文件实际在
nodes/speed_publisher_node.cpp,就得写成nodes/speed_publisher_node.cpp,不能硬套src/ - Windows 下反斜杠
在 CMake 字符串里要转义为\或统一用正斜杠/,否则路径解析失败 - ROS 2 中常用
ament_auto_add_executable,它默认只查src/,但前提是你的CMakeLists.txt里已调用ament_package()并正确设置ament_cmake_auto
变量为空或拼写错误导致“No SOURCES given to target”
这个错误常和上一条并发出现,本质是 add_executable 最后一个参数展开后是空字符串。
- 检查是否用了变量但没赋值,比如写了
add_executable(my_node ${MY_SOURCES}),却漏了set(MY_SOURCES src/my_node.cpp) - 变量名大小写敏感:
SRCS和srCs是两个不同变量;ROS 的ament_auto_add_executable依赖EXECUTABLES变量,拼错就失效 - 用
message(STATUS "SOURCES: ${MY_SOURCES}")插在add_executable前,立刻看到变量值是不是空或异常 - 避免滥用
file(GLOB):它不会触发 CMake 重新 configure,新增 .cpp 后得手动删build/再重跑;更稳妥的是显式列出,或用file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "src/*.cpp")
大小写和文件系统差异是隐形陷阱
Windows 文件系统默认不区分大小写,Linux/macOS 严格区分——这会让同一份 CMakeLists.txt 在不同平台表现不一。
- 错误示例:
add_executable(foo FOO.cpp),但实际文件叫foo.cpp→ Windows 可能过,Linux 必报错 - ROS 工作空间里尤其要注意:
catkin_make或colcon build通常在 Linux 下运行,必须按真实大小写写路径 - 编辑器有时会自动重命名文件但不更新
CMakeLists.txt,比如把LibBridge.cpp改成libbridge.cpp,而 CMake 还在找大写的 - 用
find . -iname "libbridge*"全局搜,确认磁盘上到底存的是哪个名字
最麻烦的不是找不到文件,而是你以为它在那儿——所以每次改完路径,务必先 ls 或 dir 实锤,再让 CMake 跑。路径、存在性、大小写,三者缺一不可。


















