x86 アーキテクチャは、Docker を使用して arm64 アプリケーションをコンパイルします


x86 アーキテクチャはマルチプラットフォーム システム コードのコンパイルを実現しており、それを実装するにはさまざまな方法があります。

  1. クロスコンパイル: ツールチェーン [新しいサードパーティ ライブラリは扱いにくい]
  2. マウントを隔離する方法【遅い、ファイルシステムに支障をきたす】
    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"]



おすすめ

転載: blog.csdn.net/zyh821351004/article/details/129806776
おすすめ