x86 アーキテクチャはマルチプラットフォーム システム コードのコンパイルを実現しており、それを実装するにはさまざまな方法があります。
- クロスコンパイル: ツールチェーン [新しいサードパーティ ライブラリは扱いにくい]
- マウントを隔離する方法【遅い、ファイルシステムに支障をきたす】
3. 実際にdockerを実行するQEMUなどのエミュレータ【推奨】
1. クロスコンパイル: ツールチェーン
https://github.com/dockcross/dockcross.git
ツールチェーン-aarch64.cmake
# DO NOT EDIT THIS FILE
#
# To set up cross-compilation, create the file
# $(ROS_ROOT)/rostoolchain.cmake. It gets read first, prior to
# any of cmake's system tests.
#############################################################
#
# An example for using the gumstix arm-linux toolchain is below.
# Copy these lines to $(ROS_ROOT)/rostoolchain.cmake to try them out.
#
#set(CMAKE_SYSTEM_NAME Linux)
#set(CMAKE_C_COMPILER /opt/arm-linux/bin/arm-linux-gcc)
#set(CMAKE_CXX_COMPILER /opt/arm-linux/bin/arm-linux-g++)
#set(CMAKE_FIND_ROOT_PATH /opt/arm-linux)
# Have to set this one to BOTH, to allow CMake to find rospack
#set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
#set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
#set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
#File rostoolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm64)
set(CMAKE_SYSROOT /arm64)
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH /opt/ros/melodic /arm64)
set(CMAKE_LIBRARY_PATH /arm64/usr/lib/aarch64-linux-gnu /arm64/usr/lib /arm64/lib /arm64/usr/local/lib)
set(CMAKE_INCLUDE_PATH /arm64/usr/include /arm64/usr/local/include)
set(LD_LIBRARY_PATH /arm64/usr/lib/aarch64-linux-gnu /arm64/usr/lib /arm64/lib /arm64/usr/local/lib)
set(PYTHON_EXECUTABLE /usr/bin/python)
set(PCL_ROOT /arm64/usr)
set(CMAKE_CROSSCOMPILING true)
# Have to set this one to BOTH, to allow CMake to find rospack
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
catkin_make install -DCMAKE_TOOLCHAIN_FILE=/xx/toolchain-aarch64.cmake -j4
2. 分離実装の方法:
ch-mount.sh -m arm64
ch-mount.sh -u arm64
arm64 マシンにある対応するライブラリ ファイルをコピーし、分離のために x86 コンピュータに置きます。
$ ls arm64/
Arm64Env arm64_xc.gz bin boot dev etc home lib lost+found mnt opt proc root sbin snap srv sys system tmp usr var
chマウント.sh
#!/bin/bash
#
function mnt() {
echo "MOUNTING"
sudo mount -t proc /proc ${2}/proc
sudo mount -t sysfs /sys ${2}/sys
sudo mount -o bind /dev ${2}/dev
sudo mount -o bind /dev/pts ${2}/dev/pts
# sudo mount -o bind /run ${2}/run
# sudo mount -o bind /proc ${2}/proc
# sudo mount -o bind /sys ${2}/sys
sudo chroot ${2}
}
function umnt() {
echo "UNMOUNTING"
sudo umount ${2}/proc
sudo umount ${2}/sys
sudo umount ${2}/dev/pts
sudo umount ${2}/dev
# sudo umount ${2}/run
}
if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
umnt $1 $2
else
echo ""
echo "Either 1'st, 2'nd or both parameters were missing"
echo ""
echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
echo ""
echo "For example: ch-mount -m /media/sdcard/"
echo ""
echo 1st parameter : ${1}
echo 2nd parameter : ${2}
fi
3. 実際に docker を実行するための QEMU またはその他のエミュレーター
x86 コンピューター上で実行する Docker イメージがすでに arm64 アーキテクチャをターゲットにしている場合 (たとえば、FROM arm64v8/ubuntu をベース イメージとして使用する)、クロスコンパイルを構成する必要はありません。これは、Docker イメージ自体に arm64 用のライブラリとツールがすでに含まれているためです。
この場合、arm64 プログラムを Docker イメージ内で直接コンパイルできます。ただし、x86 マシン上で arm64 Docker イメージを実際に実行するには、ホスト マシン上で QEMU または別のエミュレータを構成する必要がある場合があることに注意してください。そうしないと、x86 ホスト上で arm64 コードを実行しようとするため、互換性の問題が発生する可能性があります。
arm64 Docker イメージを実行すると、Docker は arm64 アーキテクチャをエミュレートするために QEMU を自動的にセットアップします。これらのイメージを正しく実行するには、ホスト マシンに QEMU がインストールされていることを確認し、対応するバイナリ形式のサポートを有効にしてください。
安装QEMU和支持库:
sudo apt-get install qemu-user-static binfmt-support
将QEMU的ARM64静态二进制文件复制到Dockerfile的当前目录:
cp /usr/bin/qemu-aarch64-static .
在Dockerfile中添加以下指令以包含QEMU二进制文件:
COPY qemu-aarch64-static /usr/bin/
要确保您的宿主机上安装了 QEMU 并启用了对应的二进制格式支持,请按照以下步骤操作:
首先,安装 QEMU。在基于 Debian 的系统(如 Ubuntu)上,您可以使用以下命令进行安装:
sudo apt-get update
sudo apt-get install qemu qemu-user-static binfmt-support
在基于 RHEL 的系统(如 CentOS、Fedora)上,您可以使用以下命令进行安装:
sudo yum install qemu qemu-user-static
接下来,验证 QEMU 是否已安装:
qemu-system-aarch64 --version
如果成功安装,您应该会看到 QEMU 版本信息。
确认 binfmt-support 服务是否启用:
sudo systemctl status binfmt-support
如果服务未启用,请使用以下命令启用并启动服务:
sudo systemctl enable binfmt-support
sudo systemctl start binfmt-support
最后,确保您的系统已注册了 ARM64 架构的二进制格式支持。运行以下命令:
cat /proc/sys/fs/binfmt_misc/qemu-aarch64
如果已启用支持,您应该会看到包含 "flags: F" 和 "interpreter /usr/bin/qemu-aarch64-static" 的输出。
完成这些步骤后,您的宿主机应已准备好运行 ARM64 架构的 Docker 镜像。这意味着您可以在这些镜像中直接编译 ARM64 程序,而无需配置交叉编译。
Dockerfile.arm64_melodic
FROM arm64v8/ros:melodic-perception
ENV WS=/home/xx/yy
COPY start.sh /home/xx/yy/
COPY qemu-aarch64-static /usr/bin/
COPY sources.list.arm /etc/apt/sources.list
COPY ros.asc /etc/
RUN apt-get install -y build-essential
RUN sh -c '. /etc/lsb-release && echo "deb http://mirrors.sjtug.sjtu.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list' && \
apt-key add /etc/ros.asc
#RUN apt-key adv --keyserver keys.gnupg.net --recv-key 6F3EFCDE
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7EA0A9C3F273FCD8
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8B3A55A6F3EFCDE
RUN apt update
RUN apt-get install -y ros-melodic-desktop-full
RUN apt-get install -y python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential python-catkin-tools python3-vcstool
RUN apt-get install -y ros-melodic-ecl libgoogle-glog-dev libgflags-dev libbullet-dev libsdl2-dev zstd libsdl-image1.2-dev libsdl-dev
RUN apt-get install -y ros-melodic-tf2-geometry-msgs ros-melodic-tf2-sensor-msgs ros-melodic-urdf \
ros-melodic-usb-cam ros-melodic-rgbd-launch ros-melodic-libuvc ros-melodic-libuvc-camera ros-melodic-libuvc-ros \
ros-melodic-move-base-msgs ros-melodic-kobuki-msgs libfcl-dev ros-melodic-bfl ros-melodic-pcl-ros libpcl-dev
RUN mv /usr/include/flann/ext/lz4.h /usr/include/flann/ext/lz4.h.bak && \
mv /usr/include/flann/ext/lz4hc.h /usr/include/flann/ext/lz4.hc.bak && \
ln -s /usr/include/lz4.h /usr/include/flann/ext/lz4.h && \
ln -s /usr/include/lz4hc.h /usr/include/flann/ext/lz4hc.h
RUN echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
RUN apt-get install -y ros-melodic-qt-build libevent-dev gcc g++ gfortran git cmake liblapack-dev pkg-config swig ipython python-dev python-numpy python-scipy python-matplotlib --install-recommends
RUN apt-get install -y tmux ros-melodic-dynamic-reconfigure libzstd-dev
RUN apt-get install -y \
clang \
cmake \
g++ \
git \
google-mock \
libboost-all-dev \
libcairo2-dev \
libcurl4-openssl-dev \
libeigen3-dev \
libgflags-dev \
libgoogle-glog-dev \
liblua5.2-dev \
libsuitesparse-dev \
lsb-release \
ninja-build \
stow
RUN apt-get install -y vim net-tools git ssh
RUN apt-get install -y python-sphinx
RUN apt-get install -y libceres-dev tar
WORKDIR /home/xx/carto_libs
#git clone http://gitlab.csjbot.com/RenBot/abseil-cpp.git
#git clone http://gitlab.csjbot.com/RenBot/ceres-solver.git
#git clone http://gitlab.csjbot.com/RenBot/protobuf.git
#ADD abseil-cpp.tar.gz /home/xx/carto_libs/abseil-cpp.tar.gz
#ADD ceres-solver.tar.gz /home/xx/carto_libs/ceres-solver.tar.gz
#ADD protobuf.tar.gz /home/xx/carto_libs/protobuf.tar.gz
COPY abseil-cpp.tar.gz /home/xx/carto_libs/
COPY ceres-solver.tar.gz /home/xx/carto_libs/
COPY protobuf.tar.gz /home/xx/carto_libs/
WORKDIR /home/xx/carto_libs/
RUN tar -xzvf /home/xx/carto_libs/abseil-cpp.tar.gz abseil-cpp && \
tar -xzvf /home/xx/carto_libs/ceres-solver.tar.gz && \
tar -xzvf /home/xx/carto_libs/protobuf.tar.gz
RUN echo "Start ceres"
WORKDIR /home/xx/carto_libs/ceres-solver
RUN cd /home/xx/carto_libs/abseil-cpp && \
#git checkout tags/carto && \
mkdir -p build && \
cd build && \
cmake .. -DCXX11=ON && \
make -j16 && \
make install >> ../install.info && \
echo "Finish ceres"
RUN echo "Start abseil"
WORKDIR /home/xx/carto_libs/abseil-cpp/
#RUN cd abseil-cpp
RUN cd /home/xx/carto_libs/abseil-cpp && \
#git checkout tags/carto && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DCXX11=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl .. && \
make -j12 && \
make install >> ../install.info
RUN cd /usr/local/stow && \
stow --replace absl && \
echo "Finish abseil"
WORKDIR /home/xx/carto_libs
RUN echo "Start protobuf"
RUN cd /home/xx/carto_libs/protobuf && \
#git checkout tags/carto && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release -Dprotobuf_BUILD_TESTS=OFF ../cmake && \
make -j12 && \
sudo make install >> ../install.info && \
echo "Finish protobuf"
RUN echo "export DISABLE_AUTO_TITLE=true" >> ~/.bashrc
RUN echo 'LC_NUMERIC="en_US.UTF-8"' >> ~/.bashrc
RUN echo "source /usr/share/gazebo/setup.sh" >> ~/.bashrc
RUN echo 'alias cinstall="catkin_make install -j12"' >> ~/.bashrc
RUN echo 'alias cbuild="catkin_make -j12"' >> ~/.bashrc
RUN echo "bashrc"
RUN echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
RUN echo "source /opt/ros/melodic/setup.bash" >> /home/xx/.bashrc
RUN echo "source /home/xx/yy/install/setup.bash" >> /home/xx/.bashrc
RUN echo "source /home/xx/yy/install/setup.bash" >> ~/.bashrc
RUN pwd
WORKDIR $WS
CMD ["bash","-c","/home/xx/yy/start.sh"]