You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI运行C++程序时切换工作目录行为不符合预期

问题原因

你代码里的工作目录切换逻辑本身有缺陷,和GitLab Runner的配置没有直接关系:

  1. 全程使用相对路径(child/、../)做目录切换,路径解析完全依赖程序启动时的初始工作目录,只要启动目录和预期不一致,切换就会失效。你本地能跑通只是因为本地启动程序时刚好处于child的父级目录,属于巧合。
  2. 没有对std::filesystem::current_directory的调用结果做任何校验,切换目录失败(比如目标路径不存在)时会直接静默跳过,你完全感知不到错误,后续命令自然会在初始目录执行。
  3. 你在CI脚本里写的cd build/tests是shell层面的目录切换,如果你的child目录不是放在build/tests路径下,而是放在项目根目录或者其他位置,程序启动后自然找不到对应的child文件夹,切换直接失败。
解决方案

优先修复代码(根治方案,所有环境通用)

不要用相对路径+../的方式切换目录,全程用绝对路径,加上错误校验,参考实现:

#include <filesystem>
#include <stdexcept>
#include <cstdlib>

namespace fs = std::filesystem;

void run_cmd_in_child_dir(const std::string& cmd) {
    // 先保存启动时的绝对工作目录,不要靠../回退
    const fs::path original_workdir = fs::current_path();
    try {
        // 拼接目标目录的绝对路径,消除相对路径解析歧义
        const fs::path target_workdir = original_workdir / "child";
        // 先校验目标路径是否存在
        if (!fs::is_directory(target_workdir)) {
            throw std::runtime_error("Target directory not found: " + target_workdir.string());
        }
        // 切换目录
        fs::current_path(target_workdir);
        // 执行命令
        int exit_code = std::system(cmd.c_str());
        if (exit_code != 0) {
            throw std::runtime_error("Command exit with code: " + std::to_string(exit_code));
        }
    } catch (...) {
        // 无论成功失败,强制切回原工作目录
        fs::current_path(original_workdir);
        throw;
    }
    fs::current_path(original_workdir);
}

如果你的child目录是和可执行文件放在同一路径,而不是和启动目录绑定,那先拿到可执行文件的绝对路径再拼接:

fs::path exe_path = fs::read_symlink("/proc/self/exe");
fs::path target_workdir = exe_path.parent_path() / "child";

这种写法完全不依赖启动时的工作目录,不管是本地、CI还是其他部署环境都能正常运行。

CI配置临时适配(仅临时验证用,不推荐长期用)

如果暂时不想改代码,可以在CI脚本里先确认路径,保证程序启动时的工作目录和你本地完全一致:

testing:
  stage: testing
  image: myhub/archlinux
  script:
    - export BOOST_INCLUDEDIR="/usr/include/boost/"
    - export BOOST_LIBRARYDIR="/usr/lib/"
    - cd $CI_PROJECT_DIR/build/tests
    - pwd  # 打印当前路径,确认和本地启动路径一致
    - ls -la  # 打印当前目录文件,确认child文件夹确实存在
    - ./buildUStests

绝大多数这类CI路径问题,加了pwd和ls -la之后立刻就能定位到——基本都是实际目录结构和你预期的不一致,导致切换目录的调用失败。

内容的提问来源于stack exchange,提问作者Scary Monsters

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:48:14