文章目录
本机是 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/"