本地编译失败但GitHub Actions成功的原因及本地复现Docker管道方法
问题1:为何本地编译失败但GitHub Actions流水线可正常运行?
问题2:如何在本地运行GitHub Docker流水线,且成功后保留交互式bash终端?
背景
目标是在本地编译ppsat仓库,该仓库的GitHub Actions流水线可成功编译源码并通过所有测试,但本地使用同版本Ubuntu的Docker容器无法复现该结果。
GitHub Actions配置
name: artifact on: [push, pull_request] jobs: functionalities: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v2 - name: Install gtest manually run: ls & pwd & sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp ./lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a - name: install emp run: | ls pwd wget https://raw.githubusercontent.com/emp-toolkit/emp-readme/master/scripts/install.py python3 install.py --deps --tool --ot --sh2pc sudo ldconfig - name: Create Build Environment run: pwd & ls && cmake . && make - name: Test Functionalities working-directory: ./test run: | ls pwd ./runTests.sh
本地复现步骤及错误
- 克隆仓库
- 使用以下Dockerfile构建容器:
FROM ubuntu:22.04 WORKDIR /root RUN apt-get update && apt-get -y install sudo RUN apt-get update && apt-get install -y \ software-properties-common \ build-essential \ cmake \ git \ libssl-dev \ wget \ python3 \ vim
- 执行命令:
docker build .docker run -t -d -v $(pwd):/root [image id]sudo docker exec -it [container id] bash- 安装依赖:
sudo apt install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp ./lib/*.a /usr/lib - 安装emp依赖:
wget https://raw.githubusercontent.com/emp-toolkit/emp-readme/master/scripts/install.py && python3 install.py -install --tool --ot --sh2pc --ag2pc - 执行
cd /root && cmake . && make
执行make时出现链接错误:
root@b2e562f15544:~# make [ 4%] Building CXX object src/CMakeFiles/Ppsat.dir/clause.cpp.o [ 8%] Building CXX object src/CMakeFiles/Ppsat.dir/formula.cpp.o [ 12%] Building CXX object src/CMakeFiles/Ppsat.dir/heuristics.cpp.o [ 16%] Building CXX object src/CMakeFiles/Ppsat.dir/literal.cpp.o [ 20%] Building CXX object src/CMakeFiles/Ppsat.dir/model.cpp.o [ 24%] Building CXX object src/CMakeFiles/Ppsat.dir/parser.cpp.o [ 28%] Building CXX object src/CMakeFiles/Ppsat.dir/ppsat.cpp.o [ 32%] Building CXX object src/CMakeFiles/Ppsat.dir/solver.cpp.o [ 36%] Building CXX object src/CMakeFiles/Ppsat.dir/state.cpp.o [ 40%] Building CXX object src/CMakeFiles/Ppsat.dir/utils.cpp.o [ 44%] Linking CXX static library libPpsat.a [ 44%] Built target Ppsat [ 48%] Building CXX object src/CMakeFiles/ppsat.dir/ppsat.cpp.o [ 52%] Linking CXX executable ppsat /usr/bin/ld: cannot find -lgmp: No such file or directory collect2: error: ld returned 1 exit status make[2]: *** [src/CMakeFiles/ppsat.dir/build.make:98: src/ppsat] Error 1 make[1]: *** [CMakeFiles/Makefile2:180: src/CMakeFiles/ppsat.dir/all] Error 2 make: *** [Makefile:101: all] Error 2
已尝试的解决方案
- 切换Ubuntu 22.04和20.04镜像
- 使用GitHub官方runner镜像(myoung34/github-runner/2.311.0-ubuntu-jammy)
- 尝试README与流水线的多种依赖安装组合
问题1解答
本地编译失败的核心原因是缺少libgmp-dev依赖库:
- GitHub Actions的
ubuntu-latest镜像要么默认预装了libgmp-dev,要么在执行emp安装脚本时使用了--deps参数,该参数会自动安装emp工具链所需的所有依赖(包括gmp)。 - 本地操作时,安装emp的命令用的是
-install --tool --ot --sh2pc --ag2pc,没有添加--deps参数,导致gmp依赖未被安装;同时本地Dockerfile也未包含libgmp-dev的安装步骤,最终编译链接时找不到lgmp库。
问题2解答
要在本地通过Docker复刻GitHub Actions流水线并保留交互式终端,可按以下步骤操作:
方案1:修改Dockerfile,完整复刻流水线步骤
创建包含所有依赖安装和编译步骤的Dockerfile:
FROM ubuntu:22.04 WORKDIR /root # 安装基础工具 RUN apt-get update && apt-get -y install sudo RUN apt-get update && apt-get install -y \ software-properties-common \ build-essential \ cmake \ git \ libssl-dev \ wget \ python3 \ vim \ libgtest-dev # 手动编译安装gtest RUN cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp ./lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a # 安装emp工具链(带--deps参数确保依赖全量安装) RUN wget https://raw.githubusercontent.com/emp-toolkit/emp-readme/master/scripts/install.py && python3 install.py --deps --tool --ot --sh2pc && sudo ldconfig # 克隆仓库(也可在运行时挂载本地目录) RUN git clone https://github.com/evilpoke/ppsat.git && cd ppsat && cmake . && make # 设置默认命令为bash交互式终端 CMD ["/bin/bash"]
然后执行以下命令:
- 构建镜像:
docker build -t ppsat-build . - 运行交互式容器:
docker run -it ppsat-build /bin/bash
若要挂载本地仓库目录替代镜像内克隆的代码,可使用:docker run -it -v $(pwd):/root/ppsat ppsat-build /bin/bash,进入容器后切换到/root/ppsat目录执行编译命令。
方案2:简化流程,在运行时执行流水线步骤
- 用原有Dockerfile构建镜像:
docker build -t ppsat-base . - 直接运行交互式容器并挂载本地仓库:
docker run -it -v $(pwd):/root ppsat-base /bin/bash - 在容器内完全复刻GitHub Actions的命令:
编译完成后,终端会保持交互式状态,可直接测试或操作编译产物。sudo apt-get install libgtest-dev && cd /usr/src/gtest && sudo cmake CMakeLists.txt && sudo make && sudo cp ./lib/*.a /usr/lib && sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a && sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a wget https://raw.githubusercontent.com/emp-toolkit/emp-readme/master/scripts/install.py python3 install.py --deps --tool --ot --sh2pc sudo ldconfig cd /root && cmake . && make
内容的提问来源于stack exchange,提问作者evilquestion
相关产品推荐
相关产品推荐

