如何使用 clang 获取标准库 c++ 进行交叉编译
How to get standard library c++ using clang for cross compiling
首先:我已经阅读了所有类似的帖子并且一直在寻找一个多星期。问题不重复了,我查了很多。
基本上,我正在尝试使用 clang 作为 raspberry pi 3.
的交叉编译器,使用 docker 编译一个简单的 helloWorld c++ 程序
我正在使用虚拟机 Ubuntu 18.04
编译器 clang 8
当我使用 clang 交叉编译 docker 中的代码时:
致命错误:'bits/c++config.h' 没有那个文件或目录...
这里是CMakeLists.txt文件
cmake_minimum_required(VERSION 3.7.2)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(triple arm-linux-gnueabihf)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(DCMAKE_CROSSCOMPILING=True)
set(DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf)
set(DLLVM_TARGET_ARCH=ARM)
set(DLLVM_TARGETS_TO_BUILD=ARM)
#executing...
project (arm_cross)
add_executable(hello hello.cpp )
我希望在调用 make 后为 arm 获取可执行文件
我从未处理过docker。但是半年前,我也有一个cross编译树莓派代码的问题,虽然在mac os下。不管怎样,我用clang作为工具链,终于成功了。
关键是要为 clang 提供良好的目标 rootfs。我刚刚通过 sshfs 挂载了真正的树莓派。
另一件事是,我没有将编译器设置放入 CMakeLists.txt,而是为 cmake 提供了工具链文件。
我的 cmake 工具链文件:
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Custom toolchain-specific definitions for your project
set(PLATFORM_ARM "1")
set(PLATFORM_COMPILE_DEFS "COMPILE_GLES")
# There we go!
# Below, we specify toolchain itself!
SET(TARGET_TRIPLE arm-linux-gnueabihf)
# Specify your target rootfs mount point on your compiler host machine
SET(TARGET_ROOTFS /Volumes/rootfs-${TARGET_TRIPLE})
# Specify clang paths
SET(LLVM_DIR /Users/stepan/projects/shared/toolchains/llvm-7.0.darwin-release-x86_64/install)
SET(CLANG ${LLVM_DIR}/bin/clang)
SET(CLANGXX ${LLVM_DIR}/bin/clang++)
# Specify compiler (which is clang)
SET(CMAKE_C_COMPILER ${CLANG})
SET(CMAKE_CXX_COMPILER ${CLANGXX})
# Specify binutils
SET (CMAKE_AR "${LLVM_DIR}/bin/llvm-ar" CACHE FILEPATH "Archiver")
SET (CMAKE_LINKER "${LLVM_DIR}/bin/llvm-ld" CACHE FILEPATH "Linker")
SET (CMAKE_NM "${LLVM_DIR}/bin/llvm-nm" CACHE FILEPATH "NM")
SET (CMAKE_OBJDUMP "${LLVM_DIR}/bin/llvm-objdump" CACHE FILEPATH "Objdump")
SET (CMAKE_RANLIB "${LLVM_DIR}/bin/llvm-ranlib" CACHE FILEPATH "ranlib")
# You may use legacy binutils though.
#SET(BINUTILS /usr/local/Cellar/arm-linux-gnueabihf-binutils/2.31.1)
#SET (CMAKE_AR "${BINUTILS}/bin/${TARGET_TRIPLE}-ar" CACHE FILEPATH "Archiver")
#SET (CMAKE_LINKER "${BINUTILS}/bin/${TARGET_TRIPLE}-ld" CACHE FILEPATH "Linker")
#SET (CMAKE_NM "${BINUTILS}/bin/${TARGET_TRIPLE}-nm" CACHE FILEPATH "NM")
#SET (CMAKE_OBJDUMP "${BINUTILS}/bin/${TARGET_TRIPLE}-objdump" CACHE FILEPATH "Objdump")
#SET (CMAKE_RANLIB "${BINUTILS}/bin/${TARGET_TRIPLE}-ranlib" CACHE FILEPATH "ranlib")
# Specify sysroot (almost same as rootfs)
SET(CMAKE_SYSROOT ${TARGET_ROOTFS})
SET(CMAKE_FIND_ROOT_PATH ${TARGET_ROOTFS})
# Specify lookup methods for cmake
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sometimes you also need this:
# set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# Specify raspberry triple
set(CROSS_FLAGS "--target=${TARGET_TRIPLE}")
# Specify other raspberry related flags
set(RASP_FLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")
# Gather and distribute flags specified at prev steps.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
# Use clang linker. Why?
# Well, you may install custom arm-linux-gnueabihf binutils,
# but then, you also need to recompile clang, with customized triple;
# otherwise clang will try to use host 'ld' for linking,
# so... use clang linker.
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld)
我的详细说明文章是here。
希望对您有所帮助。
我还将这个问题分为两个步骤:
1.通过clang编译。
2.将编译设置整合到docker.
祝你好运!
按照我所做的解决方案
先备份/usr/include 然后把/usr/arm/include 文件移上去。最后 运行 你的 32 位 arm 应用程序。
此步骤可以通过简单的 shell 脚本自动执行。
首先:我已经阅读了所有类似的帖子并且一直在寻找一个多星期。问题不重复了,我查了很多。
基本上,我正在尝试使用 clang 作为 raspberry pi 3.
的交叉编译器,使用 docker 编译一个简单的 helloWorld c++ 程序我正在使用虚拟机 Ubuntu 18.04
编译器 clang 8 当我使用 clang 交叉编译 docker 中的代码时:
致命错误:'bits/c++config.h' 没有那个文件或目录...
这里是CMakeLists.txt文件
cmake_minimum_required(VERSION 3.7.2)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(triple arm-linux-gnueabihf)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(DCMAKE_CROSSCOMPILING=True)
set(DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf)
set(DLLVM_TARGET_ARCH=ARM)
set(DLLVM_TARGETS_TO_BUILD=ARM)
#executing...
project (arm_cross)
add_executable(hello hello.cpp )
我希望在调用 make 后为 arm 获取可执行文件
我从未处理过docker。但是半年前,我也有一个cross编译树莓派代码的问题,虽然在mac os下。不管怎样,我用clang作为工具链,终于成功了。
关键是要为 clang 提供良好的目标 rootfs。我刚刚通过 sshfs 挂载了真正的树莓派。
另一件事是,我没有将编译器设置放入 CMakeLists.txt,而是为 cmake 提供了工具链文件。
我的 cmake 工具链文件:
SET(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Custom toolchain-specific definitions for your project
set(PLATFORM_ARM "1")
set(PLATFORM_COMPILE_DEFS "COMPILE_GLES")
# There we go!
# Below, we specify toolchain itself!
SET(TARGET_TRIPLE arm-linux-gnueabihf)
# Specify your target rootfs mount point on your compiler host machine
SET(TARGET_ROOTFS /Volumes/rootfs-${TARGET_TRIPLE})
# Specify clang paths
SET(LLVM_DIR /Users/stepan/projects/shared/toolchains/llvm-7.0.darwin-release-x86_64/install)
SET(CLANG ${LLVM_DIR}/bin/clang)
SET(CLANGXX ${LLVM_DIR}/bin/clang++)
# Specify compiler (which is clang)
SET(CMAKE_C_COMPILER ${CLANG})
SET(CMAKE_CXX_COMPILER ${CLANGXX})
# Specify binutils
SET (CMAKE_AR "${LLVM_DIR}/bin/llvm-ar" CACHE FILEPATH "Archiver")
SET (CMAKE_LINKER "${LLVM_DIR}/bin/llvm-ld" CACHE FILEPATH "Linker")
SET (CMAKE_NM "${LLVM_DIR}/bin/llvm-nm" CACHE FILEPATH "NM")
SET (CMAKE_OBJDUMP "${LLVM_DIR}/bin/llvm-objdump" CACHE FILEPATH "Objdump")
SET (CMAKE_RANLIB "${LLVM_DIR}/bin/llvm-ranlib" CACHE FILEPATH "ranlib")
# You may use legacy binutils though.
#SET(BINUTILS /usr/local/Cellar/arm-linux-gnueabihf-binutils/2.31.1)
#SET (CMAKE_AR "${BINUTILS}/bin/${TARGET_TRIPLE}-ar" CACHE FILEPATH "Archiver")
#SET (CMAKE_LINKER "${BINUTILS}/bin/${TARGET_TRIPLE}-ld" CACHE FILEPATH "Linker")
#SET (CMAKE_NM "${BINUTILS}/bin/${TARGET_TRIPLE}-nm" CACHE FILEPATH "NM")
#SET (CMAKE_OBJDUMP "${BINUTILS}/bin/${TARGET_TRIPLE}-objdump" CACHE FILEPATH "Objdump")
#SET (CMAKE_RANLIB "${BINUTILS}/bin/${TARGET_TRIPLE}-ranlib" CACHE FILEPATH "ranlib")
# Specify sysroot (almost same as rootfs)
SET(CMAKE_SYSROOT ${TARGET_ROOTFS})
SET(CMAKE_FIND_ROOT_PATH ${TARGET_ROOTFS})
# Specify lookup methods for cmake
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Sometimes you also need this:
# set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# Specify raspberry triple
set(CROSS_FLAGS "--target=${TARGET_TRIPLE}")
# Specify other raspberry related flags
set(RASP_FLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")
# Gather and distribute flags specified at prev steps.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CROSS_FLAGS} ${RASP_FLAGS}")
# Use clang linker. Why?
# Well, you may install custom arm-linux-gnueabihf binutils,
# but then, you also need to recompile clang, with customized triple;
# otherwise clang will try to use host 'ld' for linking,
# so... use clang linker.
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld)
我的详细说明文章是here。
希望对您有所帮助。 我还将这个问题分为两个步骤: 1.通过clang编译。 2.将编译设置整合到docker.
祝你好运!
按照我所做的解决方案 先备份/usr/include 然后把/usr/arm/include 文件移上去。最后 运行 你的 32 位 arm 应用程序。 此步骤可以通过简单的 shell 脚本自动执行。