美文网首页
海思平台配置toolchain.cmake

海思平台配置toolchain.cmake

作者: brownfeng | 来源:发表于2020-02-16 14:23 被阅读0次

交叉编译,在我们的host宿主机器上需要生成target目标机器的程序, 使用CMake的Toolchain管理这里的各种环境变量和配置,就很好.

CMake给交叉编译预留了一个变量--CMAKE_TOOLCHAIN_FILE, 它定义了一个文件的路径, 这个文件就是toolchain,我们可以在里面配置C_COMPILER,CXX_COMPILER,如果用Qt的话需要更改QT_QMAKE_EXECUTABLE以及如果用BOOST的话需要更改的BOOST_ROOT(具体查看相关Findxxx.cmake里面指定的路径), 因此,这个toolchain内嵌了一系列需要改变并且需要set的交叉环境的设置.

下面归纳一些比较重要的:

  1. CMAKE_SYSTEM_NAME: 即你目标机target所在的操作系统名称,比如ARM或者Linux你就需要写Linux,如果Windows平台你就写Windows,如果你的嵌入式平台没有相关OS你即需要写成Generic,只有当CMAKE_SYSTEM_NAME这个变量被设置了,CMake才认为此时正在交叉编译,它会额外设置一个变量CMAKE_CROSSCOMPILING为TRUE.
  2. CMAKE_C_COMPILER: 顾名思义,即C语言编译器,这里可以将变量设置成完整路径或者文件名,设置成完整路径有一个好处就是CMake会去这个路径下去寻找编译相关的其他工具比如linker,binutils等,如果你写的文件名带有arm-elf等等前缀,CMake会识别到并且去寻找相关的交叉编译器。
  3. CMAKE_CXX_COMPILER: 同上,此时代表的是C++编译器。
  4. CMAKE_FIND_ROOT_PATH: 代表了一系列的相关文件夹路径的根路径的变更,比如你设置了/opt/arm/,所有的Find_xxx.cmake都会优先根据这个路径下的/usr/lib,/lib等进行查找,然后才会去你自己的/usr/lib/lib进行查找,如果你有一些库是不被包含在/opt/arm里面的,你也可以显示指定多个值给CMAKE_FIND_ROOT_PATH,比如:
set(CMAKE_FIND_ROOT_PATH /opt/arm /opt/inst)
  1. CMAKE_FIND_ROOT_PATH_MODE_PROGRAM: 对FIND_PROGRAM()起作用,有三种取值,NEVER,ONLY,BOTH,第一个表示不在你CMAKE_FIND_ROOT_PATH下进行查找,第二个表示只在这个路径下查找,第三个表示先查找这个路径,再查找全局路径,对于这个变量来说,一般都是调用宿主机的程序,所以一般都设置成NEVER
  2. CMAKE_FIND_ROOT_PATH_MODE_LIBRARY: 对FIND_LIBRARY()起作用,表示在链接的时候的库的相关选项,因此这里需要设置成ONLY来保证我们的库是在交叉环境中找的.
  3. CMAKE_FIND_ROOT_PATH_MODE_INCLUDE: 对FIND_PATH()FIND_FILE()起作用,一般来说也是ONLY,如果你想改变,一般也是在相关的FIND命令中增加option来改变局部设置,有NO_CMAKE_FIND_ROOT_PATH,ONLY_CMAKE_FIND_ROOT_PATH,BOTH_CMAKE_FIND_ROOT_PATH
  4. BOOST_ROOT: 对于需要boost库的用户来说,相关的boost库路径配置也需要设置,因此这里的路径即ARM下的boost路径,里面有include和lib。
  5. QT_QMAKE_EXECUTABLE: 对于Qt用户来说,需要更改相关的qmake命令切换成嵌入式版本,因此这里需要指定成相应的qmake路径(指定到qmake本身)

下面是一个常规的配置

# cross.toolchain.cmake
# this is required
SET(CMAKE_SYSTEM_NAME Linux)

# specify the cross compiler
SET(CMAKE_C_COMPILER   /opt/arm/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER /opt/arm/usr/bin/ppc_74xx-g++)

# where is the target environment 
SET(CMAKE_FIND_ROOT_PATH /opt/arm/ppc_74xx /home/rickk/arm_inst)

# search for programs in the build host directories (not necessary)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# configure Boost and Qt
SET(QT_QMAKE_EXECUTABLE /opt/qt-embedded/qmake)
SET(BOOST_ROOT /opt/boost_arm)

# OPENSSL_FOUND OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES
SET(OPENSSL_ROOT_DIR /home/brownfeng/haisi/openssl)
SET(OPENSSL_USE_STATIC_LIBS TRUE)

# CURL_FOUND CURL_INCLUDE_DIRS CURL_LIBRARIES

这样就完成了相关toolChain的编写,之后,你可以灵活的选择到底采用宿主机版本还是开发机版本,之间的区别仅仅是一条-DCMAKE_TOOLCHAIN_FILE=./cross.toolChain.cmake,更爽的是,如果你有很多程序需要做转移,但目标平台是同一个,你仅仅需要写一份toolChain放在一个地方,就可以给所有工程使用。

搜索查找外部依赖

稍微大一点的项目都会用到一些外部依赖库或者tool,CMake提供了FIND_PROGRAM(), FIND_LIBRARY(), FIND_FILE(), FIND_PATH() and FIND_PACKAGE() 等命令来进行外部依赖的搜索查找。

但是有个问题,假如我们在给一个ARM处理器的移动设备做交叉编译,其中需要寻找libjpeg.so,假如FIND_PACKAGE(JPEG) 返回的是/usr/lib/libjpeg.so,那么这就会有问题,因为找到的这个so库只是给你的宿主机系统(例如一个x86的Ubuntu主机)服务的,不能用于Arm系统。所以你需要告诉CMake去其它地方去查找,这个时候你就需要配置以下的变量了:

CMAKE_FIND_ROOT_PATH
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE

我的toolchain文件的命名和编译过程

在工程中一般通过如下步骤, 进入工程文件, 创建arm-himix200-linux.cmake文件, 内容是:

#cmake -DCMAKE_MAKE_PROGRAM=/usr/bin/make -DCMAKE_TOOLCHAIN_FILE=../arm-himix200-linux.cmake ..

# this is required
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_MAKE_PROGRAM /usr/bin/make)
# specify the cross compiler
SET(CMAKE_C_COMPILER   /opt/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-gcc)
SET(CMAKE_CXX_COMPILER /opt/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-g++)

#指定交叉编译环境中 FindXXX 搜索的目录...
SET(CMAKE_FIND_ROOT_PATH 
/opt/hisi-linux/x86-arm/arm-himix200-linux/
/home/brownfeng/haisi/openssl
/home/brownfeng/haisi/curl
)

#从来不在指定目录下查找工具程序
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
#只在指定目录下查找库文件
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
#只在指定目录下查找头文件
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# configure Boost and Qt
#SET(QT_QMAKE_EXECUTABLE /opt/qt-embedded/qmake)
#SET(BOOST_ROOT /opt/boost_arm)

# OPENSSL_FOUND OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES
#SET(OPENSSL_ROOT_DIR /home/brownfeng/haisi/openssl)
#SET(OPENSSL_USE_STATIC_LIBS TRUE)

# CURL_FOUND CURL_INCLUDE_DIRS CURL_LIBRARIES

然后创建build文件夹, 进行编译(注意, 需要指定CMAKE_MAKE_PROGRAM, 不指定的话好像编译有问题...):

mkdir build
cd build
cmake -DCMAKE_MAKE_PROGRAM=/usr/bin/make -DCMAKE_TOOLCHAIN_FILE=../arm-himix200-linux.cmake ..

在我的toolchain文件中,我指定:

SET(CMAKE_FIND_ROOT_PATH 
/opt/hisi-linux/x86-arm/arm-himix200-linux/
/home/brownfeng/haisi/openssl
/home/brownfeng/haisi/curl
)

因为我项目中CMakeLists.txt中需要查找OpenSSLcurl, 因此会用到CMake自带的FindOpenSSL.cmakeFindCurl.cmake两个脚本, 他们会用到Findxxx命令, 会去我指定的目录去搜索对应的库

参考

https://www.cnblogs.com/rickyk/p/3875334.html
http://www.cmake.org/Wiki/CMake_Cross_Compiling

相关文章

网友评论

      本文标题:海思平台配置toolchain.cmake

      本文链接:https://www.haomeiwen.com/subject/fripfhtx.html