使用CMake搭建樹莓派交叉編譯環(huán)境

1.環(huán)境

  • PC
    Ubuntu 16.04
  • Raspberry PI4B
    Ubuntu 18.04

2.交叉工具鏈接

cd ~
mkdir -p toolchain/raspberrypi
git clone git://github.com/raspberrypi/tools.git
cd tools/arm-bcm2708
ls -al

可以看到有幾套工具鏈

arm-bcm2708hardfp-linux-gnueabi
arm-bcm2708-linux-gnueabi
arm-linux-gnueabihf -> arm-rpi-4.9.3-linux-gnueabihf
arm-rpi-4.9.3-linux-gnueabihf
gcc-linaro-arm-linux-gnueabihf-raspbian
gcc-linaro-arm-linux-gnueabihf-raspbian-x64

在這里我們使用的是 arm-linux-gnueabihf 版本

3.安裝cmake

sudo apt-get install cmake
cmake --version

如需升級(jí)cmake可以自行查找升級(jí)方法

4. 配置toolchain

復(fù)制下面文件保存至toolchain/raspberrypi_32.cmake

set(CMAKE_SYSTEM_NAME Linux)

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)

set(LINUX_COMPILER_FLAGS)
set(LINUX_COMPILER_FLAGS_CXX)
set(LINUX_COMPILER_FLAGS_DEBUG)
set(LINUX_COMPILER_FLAGS_RELEASE)
set(LINUX_LINKER_FLAGS)
set(LINUX_LINKER_FLAGS_EXE)

# STL.
set(LINUX_TOOLCHAIN_PATH $ENV{RASPBERRYPI_32_TOOLCHAIN})
list(APPEND CMAKE_FIND_ROOT_PATH "${LINUX_TOOLCHAIN_PATH}")

# Sysroot.
set(CMAKE_SYSROOT ${LINUX_TOOLCHAIN_PATH}/arm-linux-gnueabihf/sysroot)

# Toolchain.
set(LINUX_C_COMPILER   "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-gcc")
set(LINUX_CXX_COMPILER "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-g++")
set(LINUX_ASM_COMPILER "${LINUX_TOOLCHAIN_PATH}/bin/arm-linux-gnueabihf-as")

set(CMAKE_C_COMPILER_ID_RUN TRUE)
set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
set(CMAKE_C_COMPILER_ID Clang)
set(CMAKE_CXX_COMPILER_ID Clang)
set(CMAKE_C_COMPILER_VERSION 3.8)
set(CMAKE_CXX_COMPILER_VERSION 3.8)
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT 11)
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 98)
set(CMAKE_CXX_STANDARD 11)
# Generic flags.
list(APPEND LINUX_COMPILER_FLAGS
    -DLINUX
    -ffunction-sections
    -funwind-tables
    -fstack-protector-strong
    -no-canonical-prefixes)
list(APPEND LINUX_LINKER_FLAGS
    -Wl,--build-id
    -Wl,--warn-shared-textrel
    -Wl,--fatal-warnings)
list(APPEND LINUX_LINKER_FLAGS_EXE
    -Wl,--gc-sections
    -Wl,-z,nocopyreloc)

# Debug and release flags.
list(APPEND LINUX_COMPILER_FLAGS_DEBUG
    -g
    -O0)

list(APPEND LINUX_COMPILER_FLAGS_RELEASE
    -O2)

list(APPEND LINUX_COMPILER_FLAGS_RELEASE
    -DNDEBUG)
    
# Toolchain and ABI specific flags.
# Configuration specific flags.
# if(LINUX_PIE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
list(APPEND LINUX_LINKER_FLAGS_EXE
    -pie
    -fPIE)
# endif()

list(APPEND LINUX_LINKER_FLAGS
-Wl,--no-undefined)

# Convert these lists into strings.
string(REPLACE ";" " " LINUX_COMPILER_FLAGS         "${LINUX_COMPILER_FLAGS}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_CXX     "${LINUX_COMPILER_FLAGS_CXX}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_DEBUG   "${LINUX_COMPILER_FLAGS_DEBUG}")
string(REPLACE ";" " " LINUX_COMPILER_FLAGS_RELEASE "${LINUX_COMPILER_FLAGS_RELEASE}")
string(REPLACE ";" " " LINUX_LINKER_FLAGS           "${LINUX_LINKER_FLAGS}")
string(REPLACE ";" " " LINUX_LINKER_FLAGS_EXE       "${LINUX_LINKER_FLAGS_EXE}")

set(CMAKE_C_COMPILER        "${LINUX_C_COMPILER}")
set(CMAKE_CXX_COMPILER      "${LINUX_CXX_COMPILER}")

# Set or retrieve the cached flags.
# This is necessary in case the user sets/changes flags in subsequent
# configures. If we included the Android flags in here, they would get
# overwritten.
set(CMAKE_C_FLAGS ""
    CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_CXX_FLAGS ""
    CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_ASM_FLAGS ""
    CACHE STRING "Flags used by the compiler during all build types.")
set(CMAKE_C_FLAGS_DEBUG ""
    CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_CXX_FLAGS_DEBUG ""
    CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_ASM_FLAGS_DEBUG ""
    CACHE STRING "Flags used by the compiler during debug builds.")
set(CMAKE_C_FLAGS_RELEASE ""
    CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_CXX_FLAGS_RELEASE ""
    CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_ASM_FLAGS_RELEASE ""
    CACHE STRING "Flags used by the compiler during release builds.")
set(CMAKE_MODULE_LINKER_FLAGS ""
    CACHE STRING "Flags used by the linker during the creation of modules.")
set(CMAKE_SHARED_LINKER_FLAGS ""
    CACHE STRING "Flags used by the linker during the creation of dll's.")
set(CMAKE_EXE_LINKER_FLAGS ""
    CACHE STRING "Flags used by the linker.")

set(CMAKE_C_FLAGS             "${LINUX_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS           "${LINUX_COMPILER_FLAGS} ${LINUX_COMPILER_FLAGS_CXX} ${CMAKE_CXX_FLAGS}")
set(CMAKE_ASM_FLAGS           "${LINUX_COMPILER_FLAGS} ${CMAKE_ASM_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG       "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_DEBUG     "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_ASM_FLAGS_DEBUG     "${LINUX_COMPILER_FLAGS_DEBUG} ${CMAKE_ASM_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_RELEASE     "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELEASE   "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_ASM_FLAGS_RELEASE   "${LINUX_COMPILER_FLAGS_RELEASE} ${CMAKE_ASM_FLAGS_RELEASE}")
set(CMAKE_SHARED_LINKER_FLAGS "${LINUX_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${LINUX_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS    "${LINUX_LINKER_FLAGS} ${LINUX_LINKER_FLAGS_EXE} ${CMAKE_EXE_LINKER_FLAGS}")

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__=\"./$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))\"'")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-builtin-macro-redefined -D'__FILE__=\"./$(subst $(realpath ${CMAKE_SOURCE_DIR})/,,$(abspath $<))\"'")

5. 測(cè)試

  • ~/test/main.c
// main.c
#include <stdio.h>

int main()
{
  printf("hello pibot\n");
  return 0;
}
  • ~/test/CMakeList.txt
add_executable(test main.c)

本機(jī)測(cè)試

編譯本機(jī)PC執(zhí)行程序只需要直接執(zhí)行cmake即可,如下

cd ~/test
rm -rf build
mkdir build
cd build
cmake ..
make

交叉編譯

export RASPBERRYPI_32_TOOLCHAIN=$HOME/toolchains/raspberrypi/tools/arm-bcm2708/arm-linux-gnueabihf
cd ~/test/
rm -rf build
mkdir build
cd build
cmake ..  -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchains/raspberrypi_32.cmake
make

6. 擴(kuò)展

可以看到我們只需要編寫CMAKE_TOOLCHAIN_FILE就可以完成,對(duì)于其他平臺(tái)也是類似
下面介紹下Android平臺(tái)下用NDK如何編譯

NDK的cmake交叉環(huán)境配置

首先下在ndk環(huán)境, 這里我們使用的android-ndk-r14b具體
可以發(fā)現(xiàn)android-ndk-r14b/build/cmake命令中已經(jīng)有配置好的CMAKE_TOOLCHAIN_FILE文件, 打開該文件可以看到可以支持gcc/clang, 支持不同的Android Platform, 下面我們看看如何編譯上面的測(cè)試程序

  • 使用gcc編譯32的版本
cd ${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
ln -sf /opt/android-ndk-r14b/platforms/android-22/arch-arm sysroot
cd ~/test/
rm -rf build
mkdir build
cd build
cmake  ..    -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
                    -DANDROID_TOOLCHAIN=gcc \
                    -DANDROID_ABI=armeabi-v7a \
                    -DANDROID_UNIFIED_HEADERS=1 \
                    -DANDROID_PLATFORM=android-21 \
                    -DCMAKE_ANDROID_STANDALONE_TOOLCHAIN=${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
                    -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=gcc
make
  • 使用clang編譯64的版本
cd ~/test/
rm -rf build
mkdir build
cd build
cmake  .. -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
                -DANDROID_TOOLCHAIN=clang \
                -DANDROID_ABI=arm64-v8a \
                -DANDROID_PLATFORM=android-21 \
                -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
                -DANDROID_STL=c++_static
make

可以使用make VERBOSE=1查看是否使用指定編譯器編譯, 例如

[ 50%] Building C object CMakeFiles/test.dir/main.c.o
/opt/android-ndk-r14b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=aarch64-none-linux-android --gcc-toolchain=/opt/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 --sysroot=/opt/android-ndk-r14b/platforms/android-21/arch-arm64  -isystem /opt/android-ndk-r14b/platforms/android-21/arch-arm64/usr/include -isystem /opt/android-ndk-r14b/platforms/android-21/arch-arm64/usr/include/aarch64-linux-android  -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info  -fPIE   -o CMakeFiles/test.dir/main.c.o   -c /home/david/test/main.c
[100%] Linking C executable test
/opt/clion-2018.3.4/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
/opt/android-ndk-r14b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=aarch64-none-linux-android --gcc-toolchain=/opt/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 --sysroot=/opt/android-ndk-r14b/platforms/android-21/arch-arm64 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fno-limit-debug-info -O0 -fno-limit-debug-info   -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -L/opt/android-ndk-r14b/sources/cxx-stl/llvm-libc++/libs/arm64-v8a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--gc-sections -Wl,-z,nocopyreloc -pie -fPIE -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -L/opt/android-ndk-r14b/sources/cxx-stl/llvm-libc++/libs/arm64-v8a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -Wl,--gc-sections -Wl,-z,nocopyreloc -pie -fPIE  CMakeFiles/test.dir/main.c.o  -o test -lm 
make[2]: Leaving directory '/home/david/test/build'
[100%] Built target test
make[1]: Leaving directory '/home/david/test/build'
/opt/clion-2018.3.4/bin/cmake/linux/bin/cmake -E cmake_progress_start /home/david/test/build/CMakeFiles 0

可以看到詳細(xì)的編譯信息

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钠龙,一起剝皮案震驚了整個(gè)濱河市派草,隨后出現(xiàn)的幾起案子鸽嫂,更是在濱河造成了極大的恐慌,老刑警劉巖赂乐,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異坏逢,居然都是意外死亡毒租,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門衰伯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)铡羡,“玉大人,你說(shuō)我怎么就攤上這事意鲸》持埽” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵怎顾,是天一觀的道長(zhǎng)读慎。 經(jīng)常有香客問我,道長(zhǎng)槐雾,這世上最難降的妖魔是什么夭委? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮募强,結(jié)果婚禮上闰靴,老公的妹妹穿的比我還像新娘。我一直安慰自己钻注,他們只是感情好蚂且,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幅恋,像睡著了一般杏死。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捆交,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天淑翼,我揣著相機(jī)與錄音,去河邊找鬼品追。 笑死玄括,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肉瓦。 我是一名探鬼主播遭京,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼泞莉!你這毒婦竟也來(lái)了哪雕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鲫趁,失蹤者是張志新(化名)和其女友劉穎斯嚎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡堡僻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年糠惫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钉疫。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡硼讽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陌选,到底是詐尸還是另有隱情理郑,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布咨油,位于F島的核電站您炉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏役电。R本人自食惡果不足惜赚爵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望法瑟。 院中可真熱鬧冀膝,春花似錦、人聲如沸霎挟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)酥夭。三九已至赐纱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間熬北,已是汗流浹背疙描。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讶隐,地道東北人起胰。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像巫延,于是被迫代替她去往敵國(guó)和親效五。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容