CMake C++项目中相对路径使用及项目根路径获取咨询
关于C++文件路径的两个问题
项目结构
|Project |--data | |--assets | |--file1.txt | |--file2.txt |--Module | |--src | |--dumpFileToAssets.cpp |--build | |--out.exe
二进制文件生成在build/out.exe。
绝对路径可正常工作
std::string path = "/Users/Username/Project/data/assets/file1.txt"; std::ofstream myfile; myfile.open(path); myfile << "Writing this to a file.\n"; myfile.close();
从build目录出发的相对路径无法工作
调用.open()无法生成file1.txt,也无法写入内容:
std::string path = "./../data/assets/file1.txt"; std::ofstream myfile; myfile.open(path); myfile << "Writing this to a file.\n"; myfile.close();
测试结果
- 在终端运行二进制文件时,相对路径有效;
- 在Xcode中运行项目时,由于
out.exe路径不同,相对路径失效,需修改路径适配新的二进制路径。
问题解答
1. 代码内的相对路径均相对于二进制生成路径的理解是否正确?
不正确。代码中的相对路径不是以二进制文件的生成路径为基准,而是以**进程运行时的当前工作目录(CWD)**为基准。
- 终端运行时,你是进入
build目录后执行./out.exe,此时进程的CWD就是build目录,所以./../data/assets/file1.txt能正确定位到目标文件; - Xcode默认会将进程的CWD设置为项目根目录(或Scheme中配置的其他路径),此时用同样的相对路径会从根目录向上查找,自然找不到文件,导致写入失败。
2. 是否可以在代码中获取Project根路径来实现文件读写?
可以,常用方案有三种:
方案1:编译时注入根路径
在编译配置中添加预定义宏,将项目根路径传递到代码里。比如CMake中可以这么配置:
add_definitions(-DPROJECT_ROOT="${CMAKE_SOURCE_DIR}")
代码中直接使用该宏拼接路径:
std::string asset_path = PROJECT_ROOT "/data/assets/file1.txt"; std::ofstream myfile(asset_path); // 后续写入操作...
方案2:通过可执行文件路径推导
先获取当前可执行文件的绝对路径,再通过路径层级推导项目根目录。以macOS为例:
#include <iostream> #include <string> #include <filesystem> #include <mach-o/dyld.h> namespace fs = std::filesystem; fs::path get_project_root() { char exe_path[PATH_MAX]; uint32_t size = PATH_MAX; if (_NSGetExecutablePath(exe_path, &size) == 0) { // 可执行文件路径为Project/build/out.exe,向上跳两级得到根目录 return fs::path(exe_path).parent_path().parent_path(); } return {}; } int main() { fs::path project_root = get_project_root(); fs::path asset_path = project_root / "data" / "assets" / "file1.txt"; std::ofstream myfile(asset_path); myfile << "Writing this to a file.\n"; myfile.close(); return 0; }
这种方式不需要手动配置路径,能自动适配不同的编译输出位置。
方案3:统一Xcode的工作目录
修改Xcode Scheme的工作目录,让其与终端运行时一致:
- 打开Xcode的Scheme设置(Product > Scheme > Edit Scheme);
- 选择"Run"选项卡,切换到"Options"页面;
- 勾选"Use custom working directory",选择项目的
build目录。
这样Xcode运行时的CWD和终端一致,原有的相对路径就能正常工作。
内容的提问来源于stack exchange,提问作者Nitron_707
相关产品推荐
相关产品推荐

