如何在Makefile不可改且直接传入*.c的场景下并行构建C程序
结论
纯GCC本身未提供单命令编译多个输入源文件的内置并行选项,上游设计逻辑为将并行调度交由构建工具实现,因此仅通过GCC原生参数无法满足需求。但可以通过重写CC标准变量的方式,在完全不修改现有Makefile、不生成持久化目标文件污染缓存的前提下实现并行编译,完全符合你的约束条件。
实现方案
该方案通过自定义包装脚本作为CC变量的取值,自动拆分编译与链接流程、调度并行编译任务,临时目标文件存放于内存文件系统,执行完成后自动清理,完全匹配原有Makefile的设计初衷。
- 第一步:在执行make的工作目录下创建
parallel_gcc.sh脚本,赋予执行权限:
#!/bin/bash # 拆分输入参数中的源文件与编译/链接标记 src_list=() gcc_flags=() for arg in "$@"; do [[ $arg == *.c ]] && src_list+=("$arg") || gcc_flags+=("$arg") done # 创建内存级临时目录存放中间目标文件,退出时自动清理 tmp_dir=$(mktemp -d -p /dev/shm gcc_build.XXXXXX) trap 'rm -rf "$tmp_dir"' EXIT # 并行编译所有源文件,-P参数指定并行度,此处默认使用全部CPU核心 printf "%s\n" "${src_list[@]}" | xargs -P $(nproc) -I {} \ gcc -c {} -o "$tmp_dir/$(basename {} .c).o" ${CFLAGS} ${CPPFLAGS} # 链接生成最终可执行文件 gcc "$tmp_dir"/*.o ${gcc_flags} ${LDFLAGS}
权限设置命令:chmod +x parallel_gcc.sh
- 第二步:执行make时直接指定CC变量为该脚本即可,无需修改Makefile任何内容:
make CC=./parallel_gcc.sh
方案优势
- 完全兼容原有Makefile的配置规则,不需要做任何改动
- 中间目标文件全部存放于内存文件系统
/dev/shm,执行完成后自动删除,不会污染本地缓存 - 并行度可自由调整,修改xargs的
-P参数即可,编译速度接近原生make -j的水平
如果受环境限制无法使用自定义脚本,仅能使用GCC原生参数,那么目前没有可用的并行编译方案。
内容的提问来源于stack exchange,提问作者Cyan
相关产品推荐
相关产品推荐

