C++常用库交叉编译方法(一)(环境构建和Qt以及Boost)

原文链接

欢迎大家对于本站的访问 - AsterCasc

前言

首先这里建议从Ubuntu 20.04镜像开始,目前相对最稳定的版本,无论是CentOS还是其他版本的Ubuntu多多少少都会遇到各种很烦的问题,虽然说不是解决不了,但是从Ubuntu 20.04容器镜像开始是最节省时间的方式,Docker默认情况下会让容器使用宿主机的大部分资源,包括CPU和内存,虽然具体的占用情况取决于宿主机的硬件资源和Docker配置,但是容器本身没有严格的资源限制,因此会尽可能地使用宿主机上的所有可用资源,所以不用担心编译性能问题。如果不能直接拉取镜像参考无法使用DockerPull正常拉取镜像解决方案

环境构建

拉取乌班图镜像后,这里给出基本交叉编译的镜像构建:

FROM ubuntu:20.04

RUN apt update && apt upgrade -y \
    && apt install -y build-essential curl wget git vim python python3 libz-dev \
    && apt install -y gcc-arm-linux-gnueabihf \
    && apt install -y g++-arm-linux-gnueabihf \
    && apt install -y g++-8-arm-linux-gnueabihf \
    && apt install -y gcc-8-arm-linux-gnueabihf \
    && apt install -y libc6-dev-armhf-cross \
    && apt install -y libc6-dev-arm64-cross \
    && apt clean 

# 这里请求资源不一定稳定,方便重新获取资源,分开运行,再次build就不需要重新构建处理原生包了
RUN mkdir -p /data/gcc-8.3.0 \
    && cd /data/gcc-8.3.0 \
    && wget -O 1.tar.xz https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz \
    && tar -xf 1.tar.xz -C ./ \
    && rm -rf 1.tar.xz \
    && mv * src 

ENV PATH=/data/gcc-8.3.0/src/bin:$PATH

CMD ["/bin/bash"]

大家根据自己需要自行调整,增加或者删减包,我这里额外处理GCC 8.3.0的交叉编译工具链,因为我的目标机器是这个版本的GLIBC,所以这里增加了对这个部分

如果习惯容器在非交互时也保持活跃状态可以改成CMD ["tail", "-f", "/dev/null"],如果习惯使用交互式的就保持CMD ["/bin/bash"]

Dockerfile写完之后执行构建新镜像,docker build -t cc-ubuntu:20.04 .,然后我们需要定义一个映射目录,方便文件操作,所以这里我们最好再写一个docker-compose.yml处理:

version: "3.9"
services:
  ccu:
    image: cc-ubuntu:20.04
    hostname: 'ccu'
    container_name: 'ccu'
    working_dir: /data
    tty: true
    stdin_open: true
    volumes:
      - /to/your/path/data/src:/data/src

对于stdin_open: truetty: true增加这两个参数可以创建一个为伪终端,让容器保持活跃并能够通过 docker attachdocker exec 进入,允许你将输入流保持打开,使得容器在没有交互的情况下也能接受命令或其他输入,最后docker compose up -d 启动,docker exec -it ccu /bin/bash即可进入

本文以及后续相关内容都在该容器中处理,命令行内容除非特殊说明,否则都在该容器执行

资源限制

前文说了,容器会尽可能使用宿主机的资源,所以如果希望限制的小伙伴,可以通过docker run --cpus="2.0" image限制使用2个CPU核心,使用--memory="4g"限制使用4G内存,对于docker-compose.yml,使用mem_limit: 4gcpus: "2.0"达到相同目的,属性和image同级。通过docker stats观察资源使用情况

Qt

如果你的目标机器本身带Qt库,那么你需要确认下目标机器的版本,然后选择相应的Qt库版本。以5.12.2举例,下载之后tar -xf name.tar.xz进行解压

由于Qt已经将交叉编译的脚本写好,我们这里只需要指定环境,如果需要调整进入qtbase/mkspecs在相应的工具链目录调整。这里我们的目标机器是使用硬件浮点,即linux-arm-gnueabihf-g++,而Qt自带的工具链只有软浮点,不过问题不大基本都是一样,我们只需要进入软浮点目录将内容改成硬浮点即可,vim qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.confgnueabi改为gnueabihf或者你的指定路径。执行./configure -release -opensource -confirm-license -xplatform linux-arm-gnueabi-g++ -prefix /data/src/Qt5.12.2/_install -nomake examples -no-opengl -skip qtlocation

  • ./configure:配置脚本,用于设置Qt的构建选项和环境,生成Makefile
  • -release:相比debug文件更小,性能更高
  • -opensource:开源许可
  • -confirm-license:自动确认开源许可条款
  • -xplatform linux-aarch64-gnu-g++: 指定平台
  • -prefix /path/to/your/qt-app-version:安装路径
  • -nomake examples:不编译example
  • -no-opengl:禁用OpenGL,使用软件渲染而不是硬件渲染
  • -slient:静默,减少输出打印
  • -static:生成静态库。如果不想遇到各种兼容性问题,对于应用程序的大小的不是特别敏感的小伙伴,可以使用静态库,尤其是在初期调试调研功能性方案的时候

Makefile生成完成后,执行make -j 24 && make install即可在/path/to/your/qt-app-version看到arm64架构的指定版本Qt

注意:部分版本可能会编译报错,此时的处理方案有两个。要么换版本,选择更高的稳定的子版本号,要么对于报错的模块取消编译,比如5.15.2版本的qtlocation模块,使用-skip qtlocation跳过该模块的编译

项目使用上举例CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(demo)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(QT5_ROOT /data/src/Qt5.12.2/_install/lib/cmake/Qt5)
set(CMAKE_PREFIX_PATH
    "${QT5_ROOT}"
    )

find_package(Qt5 REQUIRED COMPONENTS Core Widgets)

message(STATUS "C Compiler: ${CMAKE_C_COMPILER}")
message(STATUS "C++ Compiler: ${CMAKE_CXX_COMPILER}")

add_executable(Demo main.cpp)
target_link_libraries(Demo PRIVATE
    Qt5::Core Qt5::Widgets
    )

当然,还需要指定交叉编译工具链:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)

此时就正常构建即可mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake .. && make

Boost

官网地址,这里我们以写作的时候最新版本1.87.0为例,下载源码后解压wget -O boost.tar.gz https://archives.boost.io/release/1.87.0/source/boost_1_87_0.tar.gz && tar -xf boost.tar.gz,命令行位置进入解压后的文件夹下,cd /data/src/boost/boost_1_87_0,这里我们是交叉编译,所以需要先安装B2

cd tools/build
 ./bootstrap.sh 
 ./b2 install --prefix=/data/src/boost/_b2install
 export PATH=/data/src/boost/_b2install/bin:$PATH
 cd /data/src/boost/boost_1_87_0

安装完成之后,配置交叉编译工具echo "using gcc : arm : arm-linux-gnueabihf-g++ ;" >> $HOME/user-config.jam,完成之后执行编译即可,b2 install --toolset=gcc-arm --prefix="/data/src/boost/_install",如果只希望编译某个模块使用b2 install --with-json --toolset=gcc-arm --prefix="/data/src/boost/_install",使用b2 toolset=gcc-arm --show-libraries查看你可构建模块

项目使用上举例CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(demo)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(BOOST_ROOT /data/src/boost/_install)
set(CMAKE_PREFIX_PATH
    "${BOOST_ROOT}"
    )

find_package(Boost REQUIRED COMPONENTS json)

message(STATUS "Boost library dirs: ${Boost_LIBRARY_DIRS}")
message(STATUS "Boost include dirs: ${Boost_INCLUDE_DIRS}")

add_executable(Demo main.cpp)
target_include_directories(Demo PUBLIC
        ${Boost_INCLUDE_DIRS}
        )
target_link_libraries(Demo PRIVATE
    Boost::json
    )

交叉编译工具链配置同上,此时正常构建即可mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake .. && make

原文链接

欢迎大家对于本站的访问 - AsterCasc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值