如何使用Maven编译C程序生成Linux二进制并打包到Docker镜像
方案解答
最优实现思路
不需要修改父项目原有<packaging>pom</packaging>配置,有两种可落地的方案,按需选择即可:
方案1:独立子模块集成native插件(适合C代码需要复用/迭代的场景)
该方案符合Maven多模块职责拆分的最佳实践,完全不影响父项目原有配置:
- 新增一个专门用于编译C代码的子模块,仅在该子模块的pom.xml中配置
<packaging>nar</packaging>,父项目仅需在<modules>列表中添加该子模块即可,原有配置保持不变 - 子模块中
nar-maven-plugin核心配置参数如下:- 配置
<output>executable</output>指定输出为可执行二进制文件,而非动态链接库 - 配置
<target>x86_64-Linux</target>指定目标运行平台为Linux x86_64架构,适配openSUSE环境 - 绑定插件执行目标到Maven的
compile生命周期,指定编译产物输出到统一的目录,方便后续fabric8 docker-maven-plugin读取复制
- 配置
- 父项目的镜像构建配置中直接引用子模块输出的二进制文件路径即可
注意:该方案需要本地开发环境安装对应Linux平台的交叉编译链,才能在Windows/Mac环境下编译出符合要求的Linux二进制
方案2:容器化编译(推荐,适合跨构建环境场景)
因为你本身需要构建Docker镜像,该方案不需要额外安装本地编译环境、不需要新增子模块、不需要修改项目packaging配置,全平台通用:
- 用
exec-maven-plugin绑定到Maven的compile阶段,执行Docker命令临时启动openSUSE容器,挂载本地C代码目录和构建输出目录到容器内,在容器内完成编译,直接输出可用的二进制到项目target目录 - 核心配置示例如下:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>compile</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>docker</executable> <arguments> <argument>run</argument> <argument>--rm</argument> <argument>-v</argument> <argument>${project.basedir}/src/main/c:/build</argument> <argument>-v</argument> <argument>${project.build.directory}:/output</argument> <argument>opensuse/leap:latest</argument> <argument>bash</argument> <argument>-c</argument> <argument>zypper install -y gcc && gcc -o /output/update-ca-cert /build/update-ca-cert.c && chmod +s /output/update-ca-cert</argument> </arguments> </configuration> </execution> </executions> </plugin>
- 后续fabric8插件直接将
${project.build.directory}/update-ca-cert复制到镜像对应路径即可使用
子模块必要性说明
如果仅需要编译这段固定的简单C代码,不需要复用,优先选方案2,不需要新增子模块;如果C代码后续会频繁迭代、需要给多个模块复用,选方案1新增子模块更便于维护。
内容的提问来源于stack exchange,提问作者rmf
相关产品推荐
相关产品推荐

