构建一个可以使用LLVM编译ROS项目的docker镜像
build a docker image that can use LLVM to compile ROS projects
我打算构建一个可以使用 LLVM 编译 ROS 项目代码的 Docker 映像。根据Docker的官方文档https://docs.docker.com/config/containers/multi-service_container/,最好避免在一个容器中使用多个服务。 LLVM 和 ROS 都得到了它们的 Docker 图像,如何将它们合二为一并一起发布?
更新(2019.12.13):
如果您想在官方 ROS docker 图像中使用 clang
,您可以这样做:
FROM ros:melodic
RUN apt-get -y install clang-6.0
RUN update-alternatives --install /usr/bin/c++ c++ $(command -v clang++-6.0) 1000
RUN update-alternatives --install /usr/bin/cc cc $(command -v clang-6.0) 1000
您可以这样做,因为官方 ROS 图像继承自 Ubuntu 图像,这些图像使用 update-alternatives
来管理通用命令(例如,C/C++ 编译器)如何映射到包提供它们。简而言之,对 update-alternatives
的调用将安装各种符号链接,使得 /usr/bin/cc
和 /usr/bin/c++
都(最终)分别指向 clang-6.0
和 clang++-6.0
。
有关 update-alternatives
工作原理的详细信息,请参阅其 man page。
原回答如下。
您有一些可用的策略:
合并 Dockerfile
s
如果您可以访问两个 Dockerfile
,请尝试将其中的内容合并为一个Dockerfile
。您必须选择一条 FROM
指令,但可以按照您选择的方式组合其他指令。
在一个
上更改FROM
如果您只能访问 一个 Dockerfile
,请尝试更改其 FROM
指令以从另一个图像继承。例如,ros:kinetic-ros-core-xenial
图像继承自 ubuntu:xenial
;尝试将其更改为继承自 reaverproject/llvm
.
ADD
两个压缩包
如果您无法访问 Dockerfile
,那么您将不得不进行一些逆向工程。首先从每个图像创建一个 "noop" 容器并从中 export
ing 一个文件系统 tarball。即,做...
$ docker container run --name noop-foobar foobar sh -c 'exit 0'
$ docker container export --output foobar.tar noop-foobar
$ docker container rm noop-foobar
...根据需要替换 "foobar"。
导出两个文件系统 tarball 后,通过 ADD
将它们转成 scratch
图像来创建 "base image":
FROM scratch
ADD llvm.tar
ADD ros.tar
...
您很可能必须手动解决文件系统 tarball 之间的冲突才能使基本映像按预期工作。
参考文献:
我打算构建一个可以使用 LLVM 编译 ROS 项目代码的 Docker 映像。根据Docker的官方文档https://docs.docker.com/config/containers/multi-service_container/,最好避免在一个容器中使用多个服务。 LLVM 和 ROS 都得到了它们的 Docker 图像,如何将它们合二为一并一起发布?
更新(2019.12.13):
如果您想在官方 ROS docker 图像中使用 clang
,您可以这样做:
FROM ros:melodic
RUN apt-get -y install clang-6.0
RUN update-alternatives --install /usr/bin/c++ c++ $(command -v clang++-6.0) 1000
RUN update-alternatives --install /usr/bin/cc cc $(command -v clang-6.0) 1000
您可以这样做,因为官方 ROS 图像继承自 Ubuntu 图像,这些图像使用 update-alternatives
来管理通用命令(例如,C/C++ 编译器)如何映射到包提供它们。简而言之,对 update-alternatives
的调用将安装各种符号链接,使得 /usr/bin/cc
和 /usr/bin/c++
都(最终)分别指向 clang-6.0
和 clang++-6.0
。
有关 update-alternatives
工作原理的详细信息,请参阅其 man page。
原回答如下。
您有一些可用的策略:
合并 Dockerfile
s
如果您可以访问两个 Dockerfile
,请尝试将其中的内容合并为一个Dockerfile
。您必须选择一条 FROM
指令,但可以按照您选择的方式组合其他指令。
在一个
上更改FROM
如果您只能访问 一个 Dockerfile
,请尝试更改其 FROM
指令以从另一个图像继承。例如,ros:kinetic-ros-core-xenial
图像继承自 ubuntu:xenial
;尝试将其更改为继承自 reaverproject/llvm
.
ADD
两个压缩包
如果您无法访问 Dockerfile
,那么您将不得不进行一些逆向工程。首先从每个图像创建一个 "noop" 容器并从中 export
ing 一个文件系统 tarball。即,做...
$ docker container run --name noop-foobar foobar sh -c 'exit 0'
$ docker container export --output foobar.tar noop-foobar
$ docker container rm noop-foobar
...根据需要替换 "foobar"。
导出两个文件系统 tarball 后,通过 ADD
将它们转成 scratch
图像来创建 "base image":
FROM scratch
ADD llvm.tar
ADD ros.tar
...
您很可能必须手动解决文件系统 tarball 之间的冲突才能使基本映像按预期工作。
参考文献: