cmake交叉编译的使用

2019-12-14     10:51:06

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。本文主要如何利用cmake实现交叉编译。在Linux中有在X_86上和ARM上运行的可执行程序。对应的就有不同的编译方式,X_86上通常都是gcc编译代码,ARM上通常都是交叉编译的方式。下面来介绍cmake在linux交叉编译的使用。

1、编写交叉编译的配置文件

  文件命名为toolchain.cmake,配置文件中主要是对编译器的说明,指明编译器的sysroot,CC,CXX以及其他的选项设置,不同的交叉工具链配置略有不同,基本配置都是相同的。

#目标机target所在的操作系统名称,比如ARM或者Linux你就需要写"Linux",如果Windows平台你就写"Windows",如果你的嵌入式平台没有相关OS你即需要写成"Generic",只有当CMAKE_SYSTEM_NAME这个变量被设置了,CMake才认为此时正在交叉编译,它会额外设置一个变量
#CMAKE_CROSSCOMPILING为TRUE
#this is required
set(CMAKE_SYSTEM_NAME Linux)

set(USER_PATH ".....")

#代表了一系列的相关文件夹路径的根路径的变更,编译器到指定的根目录下寻找对应的系统库
set(CMAKE_SYSROOT ${USER_PATH}/gcc-eglibc-locale-internal-arm-oe-linux-gnueabi-6.4.0/mdm9607)
set(CMAKE_FIND_ROOT_PATH ${USER_PATH}/gcc-eglibc-locale-internal-arm-oe-linux-gnueabi-6.4.0/mdm9607)

#指明C和C++编译器
set(tools ${USER_PATH}/gcc-eglibc-locale-internal-arm-oe-linux-gnueabi-6.4.0/x86_64-linux/usr/bin/arm-oe-linux-gnueabi)

set(CMAKE_C_COMPILER ${tools}/arm-oe-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${tools}/arm-oe-linux-gnueabi-g++)

#有些开源的库在编译时需要依赖openssl的库,指明openssl的库和头文件
SET(OPENSSL_LIBRARIES ${USER_PATH}/gcc-eglibc-locale-internal-arm-oe-linux-gnueabi-6.4.0/mdm9607/usr/lib)
SET(OPENSSL_INCLUDE_DIR ${USER_PATH}/gcc-eglibc-locale-internal-arm-oe-linux-gnueabi-6.4.0/mdm9607/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)

在编译的时候需要指明配置文件    cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain.cmake ../    CMAKE_TOOLCHAIN_FILE这个指明是使用的配置文件。../ 选择要编译的CMakeLists.txt文件。

2、交叉编译curl代码

在调用curl的CMakeLists.txt时,需要对CMakeLists.txt配置。这些配置通过上层的CMakeLists.txt传进去。下面看看上层的库如何编写。ADD_SUBDIRECTORY(curl)来调用下面的CMakeLists.txt,通常我们把第三方的库用外部编译的方式。

cmake_minimum_required(VERSION 3.10.0)                                  

#指明头文件,生成的库,可执行程序的安装路径
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}")
set(CMAKE_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")

#做打印调试
message(STATUS "-------------------------in curl-------------------")
message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}")
message(STATUS "CMAKE_INSTALL_BINDIR: ${CMAKE_INSTALL_BINDIR}")
message(STATUS "CMAKE_INSTALL_INCLUDEDIR: ${CMAKE_INSTALL_INCLUDEDIR}")
message(STATUS "CMAKE_CROSSCOMPILING: ${CMAKE_CROSSCOMPILING}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "VERBOSE_MESSAGES: ${VERBOSE_MESSAGES}")
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
message(STATUS "-------------------------in curl-------------------")
#指明外部工程编译
include(ExternalProject)

set(CURL_BUILD_DIR ${CMAKE_BINARY_DIR}/source)

#对编译的命令配置
if (CMAKE_CROSSCOMPILING)
#交叉编译,在指明交叉编译时,CMAKE_CROSSCOMPILING被置为TRUE
message(STATUS "CURL CMAKE_CROSSCOMPILING: ${CMAKE_CROSSCOMPILING}----------------------------------")
set(CMAKE_CONFIGURE_COMMAND
    cmake
    -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} 
    -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR} 
    -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR}      #指明依赖的openssl的库路径
    -DOPENSSL_ROOT_DIR=${OPENSSL_LIBRARIES}
    -DOPENSSL_LIBRARIES=${OPENSSL_LIBRARIES}
    -DOPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR}
    -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
    -DVERBOSE_MESSAGES=${VERBOSE_MESSAGES}
    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
    -DNROFF_USEFUL=0
    --enable-ftp
    --enable-tftp
    -DBUILD_CURL_EXE=0
    -DENABLE_ARES=0
    -DUSE_ARES=0
    -DBUILD_TESTING=0
    -DENABLE_MANUAL=0
    -DBUILD_SHARED_LIBS=0
    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
)
else ()
#gcc编译
message(STATUS "CURL GCC: ${CMAKE_CROSSCOMPILING}----------------------------------")
set(CMAKE_CONFIGURE_COMMAND
    cmake
    -DDAMS_ROOT_DIR=${CMAKE_SOURCE_DIR}
    -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
    -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
    -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_BINDIR}
    -DOPENSSL_ROOT_DIR=/usr/local/ssl
    -DOPENSSL_LIBRARIES=/usr/local/ssl/lib
    -DOPENSSL_INCLUDE_DIR=/usr/local/ssl/include
    -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
    -DVERBOSE_MESSAGES=${VERBOSE_MESSAGES}
    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
    -DNROFF_USEFUL=0
    --enable-ftp
    --enable-tftp
    -DBUILD_CURL_EXE=0
    -DENABLE_ARES=0
    -DUSE_ARES=0
    -DBUILD_TESTING=0
    -DENABLE_MANUAL=0
    -DBUILD_SHARED_LIBS=0
)
endif ()

ExternalProject_Add(
    CURL
    PREFIX ${CURL_BUILD_DIR}
    TMP_DIR curl
    DOWNLOAD_DIR ${CURL_BUILD_DIR}
    DOWNLOAD_COMMAND cp -rf ${CMAKE_SOURCE_DIR}/packages/curl/curl-7.64.0 ${CURL_BUILD_DIR}
    SOURCE_DIR ${CURL_BUILD_DIR}/curl-7.64.0
    CONFIGURE_COMMAND ${CMAKE_CONFIGURE_COMMAND} ${CURL_BUILD_DIR}/curl-7.64.0
    BUILD_ALWAYS 1
    BINARY_DIR ${CURL_BUILD_DIR}/curl-7.64.0
    BUILD_COMMAND make 
    INSTALL_COMMAND make install
    LOG_CONFIGURE ${LOG_LEVEL}
    LOG_BUILD ${LOG_LEVEL}
    LOG_INSTALL ${LOG_LEVEL}
)

相关推荐