linux使用cmake交叉编译arm32程序


如需转载请标明出处:http://blog.csdn.net/itas109
QQ技术交流群:129518033

环境:
OS : Ubuntu 20.04
GCC:gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)
交叉编译器: arm-linux-gnueabihf-gcc 4.9.4 20151028 (prerelease) (Linaro GCC 4.9-2016.02)
cpr: 1.5.1
libcurl: 7.69.1

前言

x86_64 linux下交叉编译arm的基本程序和静态库cpr(libcurl)

1.下载和安装交叉编译器

免费版目前有三大主流工具商提供:

  • GNU(提供源码,自行编译制作)
  • Codesourcery
  • Linora (提供源码,和已经编译好的release binrary)

arm-linux-gnueabihf(32-bit Armv7 Cortex-A, hard-float, little-endian )
armv8l-linux-gnueabihf(32-bit Armv8 Cortex-A, hard-float, little-endian )
aarch64-linux-gnu(64-bit Armv8 Cortex-A, little-endian )

Linaro,一间非营利性质的开放源代码软件工程公司,主要的目标在于开发不同半导体公司系统单芯片(SoC)平台的共通软件,以促进消费者及厂商的福祉。针对于各个成员推出的 ARM系统单芯片(SoC),它开发了ARM开发工具、Linux内核以及Linux发行版(包括 Android 及 Ubuntu)的主要自动建构系统。

交叉编译器下载地址: https://releases.linaro.org/components/toolchain/binaries/

$ wget https://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz
$ wget https://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/sysroot-linaro-eglibc-gcc4.9-2016.02-arm-linux-gnueabihf.tar.xz

# unzip path /home/dev/toolchain/

$ ./arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/snapshots/gcc-linaro-4.9-2016.02/configure SHELL=/bin/bash --with-bugurl=https://bugs.linaro.org --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libstdcxx-pch --disable-libmudflap --with-cloog=no --with-ppl=no --with-isl=no --disable-nls --enable-c99 --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-multilib --enable-multiarch --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/sysroots/arm-linux-gnueabihf --enable-lto --enable-linker-build-id --enable-long-long --enable-shared --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran,lto --enable-checking=release --disable-bootstrap --with-bugurl=https://bugs.linaro.org --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu
Thread model: posix
gcc version 4.9.4 20151028 (prerelease) (Linaro GCC 4.9-2016.02)

2.编写cmake交叉编译文件toolchain_arm.cmake

toolchain_arm.cmake

# 交叉编译的系统名称
set(CMAKE_SYSTEM_NAME Linux)
# 交叉编译的CPU架构
set(CMAKE_SYSTEM_PROCESSOR arm)

set(USER_PATH "/home/dev")

#代表了一系列的相关文件夹路径的根路径的变更,编译器到指定的根目录下寻找对应的系统库
set(CMAKE_SYSROOT ${USER_PATH}/toolchain/sysroot-linaro-eglibc-gcc4.9-2016.02-arm-linux-gnueabihf)
#set(CMAKE_FIND_ROOT_PATH ${USER_PATH}/)
# 指定主机上要安装的路径
set(CMAKE_STAGING_PREFIX ${USER_PATH}/cross_install)

#指明C和C++编译器
set(tools ${USER_PATH}/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)

#有些开源的库在编译时需要依赖openssl的库,指明openssl的库和头文件
#SET(OPENSSL_LIBRARIES ${USER_PATH}/usr/lib)
#SET(OPENSSL_INCLUDE_DIR ${USER_PATH}/usr/include/openssl)

#对FIND_PROGRAM()起作用,有三种取值,NEVER,ONLY,BOTH,第一个表示不在你CMAKE_FIND_ROOT_PATH下进行查找,第二个表示只在这个路径下查找,第三个表示先查找这个路径,再查找全局路径,对于这个变量来说,一般都是调用宿主机的程序,所以一般都设置成NEVER
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)

3.正常编译x86_64的hello测试程序

a.代码main.c

// main.c

#include <stdio.h>

int main()
{
    printf("hello world\n");
    
    return 0;
}

b.CMakeLists.txt

project(helloDemo)

cmake_minimum_required(VERSION 2.8)

add_executable( ${PROJECT_NAME} main.c)

c.编译批处理build_x86_64.sh

#! /bin/bash

mkdir bin_x86_64
cd bin_x86_64

cmake .. 

make -j8

d.编译和查看应用程序信息

dev@dev:~/toolchain_app$ ./build_x86_64.sh 
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dev/toolchain_app/bin_x86_64
Scanning dependencies of target helloDemo
[ 50%] Building C object CMakeFiles/helloDemo.dir/main.c.o
[100%] Linking C executable helloDemo
[100%] Built target helloDemo

dev@dev:~/toolchain_app$ file bin_x86_64/helloDemo 
bin_x86_64/helloDemo: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=83d8c21407d305e55f43cce132337a04f3917121, for GNU/Linux 3.2.0, not stripped

4.交叉编译arm32的hello测试程序

a.代码main.c

// main.c

#include <stdio.h>

int main()
{
    printf("hello world\n");
    
    return 0;
}

b.CMakeLists.txt

project(helloDemo)

cmake_minimum_required(VERSION 2.8)

add_executable( ${PROJECT_NAME} main.c)

c.编译批处理build_arm32.sh

#! /bin/bash

mkdir bin_arm32
cd bin_arm32

cmake -DCMAKE_TOOLCHAIN_FILE=./toolchain_arm.cmake .. 

make -j8

d.编译和查看应用程序信息

dev@dev:~/toolchain_app$ ./build_arm32.sh 
-- The C compiler identification is GNU 4.9.4
-- The CXX compiler identification is GNU 4.9.4
-- Check for working C compiler: /home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
-- Check for working C compiler: /home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
-- Check for working CXX compiler: /home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dev/toolchain_app/bin_arm32
Scanning dependencies of target helloDemo
[ 50%] Building C object CMakeFiles/helloDemo.dir/main.c.o
[100%] Linking C executable helloDemo
[100%] Built target helloDemo

dev@dev:~/toolchain_app$ file bin_arm32/helloDemo 
bin_arm32/helloDemo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.16, BuildID[sha1]=5e4e705f62045ae9754da2906734ee40c00768ef, with debug_info, not stripped

e.运行

$ sudo apt-get install qemu-user

dev@dev:~/toolchain_app/bin_arm32$ qemu-arm -L /home/dev/toolchain/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc helloDemo 
hello world

5.交叉编译静态库cpr(libcurl)

这里编译的是静态库(http无ssl,设置-fPIC)

$ git clone https://github.com/whoshuu/cpr.git

$ cd cpr
$ touch build_arm32.sh
$ chmod +x build_arm32.sh
$ ./build_arm32.sh

build_arm32.sh内容(只编译http,不包括ssl相关):

mkdir bin_rc_nossl_arm32

cd bin_rc_nossl_arm32

cmake -G "Unix Makefiles"  -DCMAKE_TOOLCHAIN_FILE=./toolchain_arm.cmake -DCMAKE_INSTALL_PREFIX=./_install -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_CURL=OFF -DBUILD_CPR_TESTS=OFF -DUSE_OPENSSL=OFF -DUSE_WINSSL=OFF -DCMAKE_USE_OPENSSL=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_USE_LIBSSH2=OFF ..

make -j8

make install

注意:
a.禁用openssl

-DCMAKE_USE_OPENSSL=OFF 等价于
set(CMAKE_USE_OPENSSL OFF)
message(STATUS "CMAKE_USE_OPENSSL : "${CMAKE_USE_OPENSSL})

# USE_OPENSSL和USE_WINSSL为cpr的配置
# CMAKE_USE_OPENSSL为curl的配置

b.error

libcpr.a(session.cpp.o): relocation R_ARM_THM_MOVW_ABS_NC against `_ZNSs4_Rep20_S_empty_rep_storageE' can not be used when making a shared object; recompile with -fPIC

# cpr和curl的CMakeLists.txt增加
add_compile_options(-fPIC)

c.交叉编译

-DCMAKE_TOOLCHAIN_FILE=./toolchain_arm.cmake
$ tree
.
├── bin
│   └── curl-config
├── include
│   ├── cpr
│   │   ├── ...
│   └── curl
│       ├── ...
└── lib
    ├── cmake
    │   └── CURL
    │       ├── CURLConfig.cmake
    │       ├── CURLConfigVersion.cmake
    │       ├── CURLTargets.cmake
    │       └── CURLTargets-release.cmake
    ├── libcpr.a
    ├── libcurl.a
    └── pkgconfig
        └── libcurl.pc

License

License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎

如需转载请标明出处:http://blog.csdn.net/itas109
QQ技术交流群:129518033


Reference:
NULL

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐