iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用

习惯了使用cmake,再也不想回到手写makefile的年代了。相比手写makefile,使用cmake则像是实现了机动化,管理项目工程的编译变得很简单了。况且cmake很流行,linux下的很多软件源码包,很多也都使用了cmake的方式编译。因此这里总结下嵌入式linux环境下如何使用cmake,以及嵌入式qt的cmake配置。

CMake简介

什么是CMake
你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作,手写makefile也不是个很容易的事。

CMake就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等 。

在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
1、编写 CMake 配置文件 CMakeLists.txt 。
2、执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(ccmake 和 cmake 的区别在于前者提供了一个交互式的界面),其中 PATH 是 CMakeLists.txt 所在的目录。
3、使用 make 命令进行编译。

cmake安装

Download | CMake

linux下的cmake安装很简单。以ubuntu为例,可以直接sudo apt-get install cmake。当然也可以手工下载最新源码包来安装。这里选择了一种最简单的方式。

sudo apt-get install cmake

cmake交叉编译环境下的配置

指定cmake使用的交叉编译工具链(选项:DCMAKE_TOOLCHAIN_FILE)。

在项目根目录下新建个toolchains目录,在此目录下,参照其它开发板的配置文件,添加一个该开发板的配置文件arm-poky-linux-gnueabi.cmake。

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-poky-linux-gnueabi-gcc")
set(CMAKE_CXX_COMPILER "arm-poky-linux-gnueabi-g++")
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_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi")
set(CMAKE_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi")

# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")

cmake使用

新建个cmake_test项目文件夹,内部新建hello.c文件源码。

#include 

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

编写CMakeLists.txt文件,注释掉的内容可以不用管,其实内容很少。

cmake_minimum_required(VERSION 3.12)

project(HELLO)

#add_definitions(
 #   -D_ENABLE_LOGGING
#)

set(SRC_LIST hello.c)

#add library(libhello SHARED hello.c)
#set_target_properties(libhello PROPERTIES OUTPUT NAME "hello")
add_executable(hello ${SRC_LIST})
#target_link_libraries(hello libhello)

开始编译 

在项目根目录下创建build目录,然后cd build,先进入build目录。注意,需要指定-DCMAKE_TOOLCHAIN_FILE。

#先加载环境变量
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi 

#在项目根目录,cd build,先进入build目录
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-poky-linux-gnueabi.cmake ../

iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用_第1张图片

最终生成了可以在板子上执行的可执行文件。

QT交叉编译环境下的cmake脚本

示例demo,main.cpp:

#include 
#include
#include 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "hello QT test";
    return a.exec();
}

QT项目的交叉编译环境下的cmake脚本:

cmake_minimum_required(VERSION 3.12)

project(helloqt)

add_definitions(
    -D_ENABLE_LOGGING
)

#set(CMAKE_PREFIX_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake")

set(BUILD_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build_out)
get_filename_component(ABSOLUTE_PATH ${BUILD_DIRECTORY} ABSOLUTE)
set(BUILD_DIRECTORY ${ABSOLUTE_PATH})


####################  QT dependencies ####################
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(QT_VERSION 5)
set(CMAKE_CROSSCOMPILING TRUE)
set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin)

set(REQUIRED_LIBS Core Quick Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Quick Qt5::Widgets)

####################  set output directory ####################
set(BUILD_DIR ${BUILD_DIRECTORY})
set(LIB_DIR ${BUILD_DIR}/lib/Release)
#set(LIB_FIX)
#if (CMAKE_BUILD_TYPE MATCHES "Debug")
#    set(LIB_DIR ${BUILD_DIR}/lib/Debug)
#    set(LIB_FIX _d)
#endif ()

#get_filename_component(ABSOLUTE_PATH ${LIB_DIR} ABSOLUTE)
#set(LIB_DIR ${ABSOLUTE_PATH})

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_PDB_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIB_DIR})

#set(LIB_DIR_FIX ${LIB_DIR})
#option(USE_VS_BUILD "use visual studio build." OFF)
#if (USE_VS_BUILD)
#    set(LIB_DIR_FIX ${LIB_DIR}/bin/Debug)
#endif ()
###########set include path ####################
include_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}/
        ${BUILD_DIR}/include
)

####################  scan source files ####################
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/ SRC_FILES)
#aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/test2 SRC_FILES)

#set(SRC_LIST hello.c)

#add library(libhello SHARED hello.c)
#set_target_properties(libhello PROPERTIES OUTPUT NAME "hello")
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)
#find_package(Qt5 COMPONENTS Widgets)

add_executable(${PROJECT_NAME}  ${SRC_FILES})
#target_link_libraries(hello libhello)


####################  set target dependencies ####################

set(THIRD_LIBS "")

target_link_libraries(${PROJECT_NAME} PRIVATE ${REQUIRED_LIBS_QUALIFIED} ${THIRD_LIBS})

报错信息

iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用_第2张图片

报错解决办法

根据错误提示,提示表明在CMake中找不到OE_QMAKE_PATH_EXTERNAL_HOST_BINS变量。这是因为您的交叉编译环境中没有设置正确的OpenEmbedded(OE)环境变量。

可以在CMakeLists.txt文件中添加以下行来设置OE_QMAKE_PATH_EXTERNAL_HOST_BINS变量。它的目的是为了找到qmake的位置。因此可以设置如下:

set(QT_VERSION 5)
set(CMAKE_CROSSCOMPILING TRUE)
set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin)

开始编译 

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-poky-linux-gnueabi.cmake -DCMAKE_PREFIX_PATH=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake ../

如果嫌上面这串命令有点儿长,可以把-DCMAKE_PREFIX_PATH写固定到CMakeLists.txt文件里。如下(带不带""都行):

set(CMAKE_PREFIX_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake")

最后,编译成功啦!终于可以在嵌入式环境下愉快的使用cmake来编译qt的工程。如果不想安装使用qtcreater这个庞大IDE的话。或者想使用脚本的方式编译qt项目,使用cmake是个不错的选择。

iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用_第3张图片

iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用_第4张图片

经过以上操作,成功生成helloqt可执行文件。把该文件放置到开发板上,可以看到执行效果。生成的可执行文件的位置在build_out/lib/Release/路径下。

其他资源

https://m.elecfans.com/article/2012326.html

CMAKE介绍和使用(Linux平台)_cmake linux_L888666Q的博客-CSDN博客

【cmake实战一】linux下安装cmake的两个方法_cmake安装_郑同学的笔记的博客-CSDN博客

cmake超详细入门教程_cmake编译流程_yygr的博客-CSDN博客

利用VSCode+cmake+GDB+gdbserver调试IMX6ULL的Linux C应用程序_imx6ull cmake_生啃枸杞的博客-CSDN博客

你可能感兴趣的:(嵌入式应用开发实战,Qt,linux,运维,服务器,cmake,交叉编译)