CMake项目不同CPP文件如何无绝对路径访问根目录公共资源文件夹
方案说明
现有方案的缺陷
std::filesystem::current_path()依赖程序运行时的工作目录,只要执行程序时的所在目录发生变化,拼接出来的路径就会失效,比如你在系统根目录直接调用build目录下的可执行文件,就完全找不到images目录,稳定性极差。
更优实现方案(开发阶段首选)
通过CMake编译定义把固定路径直接传给代码,完全不需要依赖运行时环境,操作非常简单:
1. 配置根目录CMakeLists.txt
在项目根目录的CMakeLists.txt的project()命令之后,添加如下内容:
# PROJECT_SOURCE_DIR是CMake内置变量,指向根目录CMakeLists.txt所在的路径 add_compile_definitions(PROJECT_ROOT_DIR="${PROJECT_SOURCE_DIR}") # 可直接定义常用目录的路径,省得代码中重复拼接 add_compile_definitions(IMAGES_DIR="${PROJECT_SOURCE_DIR}/images") add_compile_definitions(MODELS_DIR="${PROJECT_SOURCE_DIR}/Models")
2. 代码中直接使用宏定义
所有.cpp文件中都可以直接调用上面定义的宏,不需要额外封装路径逻辑:
// 示例:拼接images目录下的output.png存储路径 std::filesystem::path img_save_path = std::string(IMAGES_DIR) + "/output.png"; // 示例:加载Models目录下的resnet.onnx模型 std::filesystem::path model_path = std::string(MODELS_DIR) + "/resnet.onnx";
这个方案完全不受运行工作目录、可执行文件生成位置的影响,只要CMake配置正常,路径100%正确,对CMake新手非常友好。
发布场景兼容方案
如果后续需要打包发布程序,不想把开发环境的绝对路径编译进二进制,可以配合CMake安装逻辑做兼容:
- 发布时将可执行文件统一放在
bin目录,images、Models目录和bin目录同级 - 代码中拼接路径时优先读取可执行文件自身的路径做拼接:
// argv[0]是程序启动的路径,提取父路径再拼接目标目录 std::filesystem::path app_dir = std::filesystem::path(argv[0]).parent_path(); std::filesystem::path images_dir = app_dir / "../images";
内容的提问来源于stack exchange,提问作者a a
相关产品推荐
相关产品推荐

