C/C++ 交叉编译方法

文章目录

本机是 x86_64 架构的,使用 Ubuntu 22.04.4 LTS 作为 WSL 虚拟机

Update APT

开启 universe 源,

bash 复制代码
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update

x86

Toolchain

bash 复制代码
sudo apt install gcc-multilib g++-multilib
sudo apt install linux-libc-dev-i386-cross libc6-dev-i386

toolchain-x86-linux.cmake

cmake 复制代码
# 指定交叉编译工具链
set(TARGET_TRIPLE x86_64-linux-gnu)
set(TOOLCHAIN_BIN /usr/bin)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-gcc        CACHE FILEPATH "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-g++        CACHE FILEPATH "" FORCE)
set(CMAKE_AR           ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ar         CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB       ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ranlib     CACHE FILEPATH "" FORCE)

# 指定目标 OS 和 CPU
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "" FORCE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR i686)

# 告知 CMake 交叉搜索根目录
include_directories(SYSTEM /usr/i686-linux-gnu/include)
set(CMAKE_FIND_ROOT_PATH /usr/lib32)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 编译目标 32-bit
add_compile_options(-m32 -maes -mavx -mavx2)
add_link_options(-m32)

# 指定产物的输出目录
set(ARCH_OUTPUT_NAME "x86")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/lib
    CACHE PATH "" FORCE
)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/
    CACHE PATH "" FORCE
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/bin
    CACHE PATH "" FORCE
)

x86_64

Toolchain

bash 复制代码
sudo apt install gcc g++ make cmake

toolchain-x86_64-linux.cmake

cmake 复制代码
# 指定交叉编译工具链
set(TARGET_TRIPLE x86_64-linux-gnu)
set(TOOLCHAIN_BIN /usr/bin)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-gcc        CACHE FILEPATH "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-g++        CACHE FILEPATH "" FORCE)
set(CMAKE_AR           ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ar         CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB       ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ranlib     CACHE FILEPATH "" FORCE)

# 指定目标 OS 和 CPU
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "" FORCE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

# 告知 CMake 交叉搜索根目录
include_directories(SYSTEM /usr/include)
set(CMAKE_FIND_ROOT_PATH /usr/lib64)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 编译目标 64-bit
add_compile_options(-m64 -maes -mavx -mavx2)
add_link_options(-m64)

# 指定产物的输出目录
set(ARCH_OUTPUT_NAME "x86_64")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/lib
    CACHE PATH "" FORCE
)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/
    CACHE PATH "" FORCE
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/bin
    CACHE PATH "" FORCE
)

ARMv7

Toolchain

bash 复制代码
sudo apt install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi
sudo apt install linux-libc-dev-armel-cross

sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
sudo apt install linux-libc-dev-armhf-cross

toolchain-armv7abi-linux.cmake

cmake 复制代码
# 指定交叉编译工具链
set(TARGET_TRIPLE arm-linux-gnueabi)
set(TOOLCHAIN_BIN /usr/bin)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-gcc        CACHE FILEPATH "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-g++        CACHE FILEPATH "" FORCE)
set(CMAKE_AR           ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ar         CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB       ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ranlib     CACHE FILEPATH "" FORCE)

# 指定目标 OS 和 CPU
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "" FORCE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 告知 CMake 交叉搜索根目录
set(CMAKE_FIND_ROOT_PATH /usr/${TARGET_TRIPLE})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 指定目标架构为 ARMv7-a, 采用软浮点 ABI
add_compile_options(-march=armv7-a)

# 指定产物的输出目录
set(ARCH_OUTPUT_NAME "armv7abi")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/lib
    CACHE PATH "" FORCE
)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/
    CACHE PATH "" FORCE
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/bin
    CACHE PATH "" FORCE
)

toolchain-armv7abihf-linux.cmake

cmake 复制代码
# 指定交叉编译工具链
set(TARGET_TRIPLE arm-linux-gnueabihf)
set(TOOLCHAIN_BIN /usr/bin)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-gcc        CACHE FILEPATH "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-g++        CACHE FILEPATH "" FORCE)
set(CMAKE_AR           ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ar         CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB       ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ranlib     CACHE FILEPATH "" FORCE)

# 指定目标 OS 和 CPU
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "" FORCE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 告知 CMake 交叉搜索根目录
set(CMAKE_FIND_ROOT_PATH /usr/${TARGET_TRIPLE})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 指定目标架构为 ARMv7-a, 适配带 NEON 浮点的硬件
add_compile_options(-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard)

# 指定产物的输出目录
set(ARCH_OUTPUT_NAME "armv7abihf")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/lib
    CACHE PATH "" FORCE
)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/
    CACHE PATH "" FORCE
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/bin
    CACHE PATH "" FORCE
)

ARMv8

Toolchain

bash 复制代码
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt install linux-libc-dev-arm64-cross

toolchain-armv8a-linux.cmake

cmake 复制代码
# 指定交叉编译工具链
set(TARGET_TRIPLE aarch64-linux-gnu)
set(TOOLCHAIN_BIN /usr/bin)
set(CMAKE_C_COMPILER   ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-gcc        CACHE FILEPATH "" FORCE)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-g++        CACHE FILEPATH "" FORCE)
set(CMAKE_AR           ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ar         CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB       ${TOOLCHAIN_BIN}/${TARGET_TRIPLE}-ranlib     CACHE FILEPATH "" FORCE)

# 指定目标 OS 和 CPU
set(CMAKE_CROSSCOMPILING ON CACHE BOOL "" FORCE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

# 告知 CMake 交叉搜索根目录
set(CMAKE_FIND_ROOT_PATH /usr/${TARGET_TRIPLE})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 指定目标架构为 ARMv8-a
add_compile_options(-march=armv8-a)

# 指定产物的输出目录
set(ARCH_OUTPUT_NAME "armv8a")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/lib
    CACHE PATH "" FORCE
)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/
    CACHE PATH "" FORCE
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${CMAKE_SOURCE_DIR}/build_out/${ARCH_OUTPUT_NAME}/bin
    CACHE PATH "" FORCE
)

build

CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(MULTI_TOOLCHAIN VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# 检查工具链情况
message(">>> CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
message(">>> CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}")
message(">>> CMAKE_CXX_FLAGS_DEBUG = ${CMAKE_CXX_FLAGS_DEBUG}")
message(">>> CMAKE_CXX_FLAGS_RELEASE = ${CMAKE_CXX_FLAGS_RELEASE}")
message(">>> COMPILE_OPTIONS GLOBAL = ${CMAKE_CURRENT_LIST_DIR} : ${CMAKE_COMPILE_OPTIONS}")

# 指定头文件目录
include_directories(
    ${PROJECT_SOURCE_DIR}/include
)

# 编译子目录
add_subdirectory(src)

build.sh

bash 复制代码
#!/bin/bash

set -euo pipefail

# 项目根目录(脚本所在目录)
PROJ_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

# 并发线程数
BUILD_JOBS=$(nproc)

# 格式: 工具链配置文件; 构建目录; 产物输出目录 (在各个 toolchain-xxx.cmake 中定义)
ARCH_LIST=(
    "toolchain-x86-linux.cmake;build_x86;x86"
    "toolchain-x86_64-linux.cmake;build_x86_64;x86_64"
    "toolchain-armv7abi-linux.cmake;build_armv7abi;armv7abi"
    "toolchain-armv7abihf-linux.cmake;build_armv7abihf;armv7abihf"
    "toolchain-armv8a-linux.cmake;build_armv8a;armv8"
)

# 循环遍历所有架构
for entry in "${ARCH_LIST[@]}"; do
    IFS=';' read -r TC_FILE BUILD_DIR ARCH_OUT <<< "$entry"

    FULL_TC_PATH="${PROJ_ROOT}/cmake/${TC_FILE}"
    FULL_BUILD_PATH="${PROJ_ROOT}/${BUILD_DIR}"

    echo "========================================"
    echo "Start build arch: ${ARCH_OUT}"
    echo "Toolchain file:  ${FULL_TC_PATH}"
    echo "Build directory: ${FULL_BUILD_PATH}"
    echo "========================================"

    # 0. 安全清理旧数据
    # if [[ -z "${FULL_BUILD_PATH}" ]]; then
    #     exit 1
    # fi

    # if [[ "${FULL_BUILD_PATH}" == "/" ]]; then
    #     exit 1
    # fi

    # if [[ "${FULL_BUILD_PATH}" != "${PROJ_ROOT}/"* ]]; then
    #     exit 1
    # fi

    # if [[ -d "${FULL_BUILD_PATH}" ]]; then
    #     echo "Clean old build dir: ${FULL_BUILD_PATH}"
    #     rm -rf "${FULL_BUILD_PATH}"
    # fi

    # 1. 创建构建目录
    mkdir -p "${PROJ_ROOT}/build_out"
    mkdir -p "${FULL_BUILD_PATH}"

    # 2. 加载工具链
    cmake -C "${FULL_TC_PATH}" -S "${PROJ_ROOT}" -B "${FULL_BUILD_PATH}" 
    
    # 3. 并发编译
    cmake --build "${FULL_BUILD_PATH}" -j"${BUILD_JOBS}"

    echo "==== Finish ${ARCH_OUT} ===="
    echo ""
done

echo "All architectures compile finished!"
echo "Output dir: ${PROJ_ROOT}/build_out/"
相关推荐
benbenAItalk2 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
sunshine22 girl2 小时前
Java学习二 基本语法2, 算术运算符
java·学习
niucloud-admin2 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
2601_962885722 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
anew___2 小时前
蜂鸣器播放音乐——让 Arduino 唱出旋律
c++·stm32·单片机·嵌入式硬件·c
滕州市燕猫虎计算机科技工作室个体工商户2 小时前
Java锁
java·开发语言
派葛穆3 小时前
Lerobot -飞特舵机ST-3215双舵机联动(ESP_NOW)
c语言
零依赖极客4 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm
stolentime4 小时前
洛谷P10515 转圈题解
c++·算法·数学建模·贪心算法
shehuiyuelaiyuehao4 小时前
1计算机是如何工作的
java·计算机网络