嵌入式Linux的QT项目CMake工程模板分享及使用指南

在嵌入式linux开发板上跑QT应用,不同于PC上的开发过程。最大的区别就是需要交叉编译,才能在板子上运行。 这里总结下嵌入式linux环境下使用CMake,嵌入式QT的CMake工程模板配置及如何使用,分享给有需要的小伙伴,有用到的可以点击收藏。

CMake简介

CMake 是一个项目构建工具,并且是跨平台的。关于项目构建我们所熟知的还有Makefile(通过 make 命令进行项目的构建),大多的IDE软件都集成了make,比如:VS 的 nmake、linux 下的 GNU make、Qt 的 qmake等,如果自己动手写 makefile,会发现makefile 通常依赖于当前的编译平台,而且编写 makefile 的工作量比较大,解决依赖关系时也容易出错。

而 CMake 恰好能解决上述问题, 其允许开发者指定整个工程的编译流程,在根据编译平台,自动生成本地化的Makefile和工程文件,最后用户只需make编译即可,所以可以把CMake看成一款自动生成 Makefile工具。而且一旦习惯了CMake,再也不想回到手写makefile的时代了。

cmake的编译流程,执行原理如下图所示:

环境准备

CMake安装

Download | CMake

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

sudo apt-get install cmake

交叉编译工具链gcc

这个一般的开发板都会提供,这里不在详细介绍。

下面介绍下工具链的配置:

(目的是指定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")

工程模板

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

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

首先我们要创建一个CMakeLists.txt文件,名称大小写一定不能错

需要注意的是,在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_PREFIX_PATH,它是一个分号分隔的路径列表,用来指明软件/库安装路径前缀,以供find_package()find_program()find_library()find_file()find_path()命令搜索使用,这样就方便搜索可执行文件、头文件、库文件及相关配置文件等。 

可以在编译时,在命令行指定它,如:


#在项目根目录,cd build,先进入build目录
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 ../

或者嫌它太长,可以写到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")

完整的CMakeLists.txt文件工程模板: 

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})

如何使用

执行以下命令即可。

#先加载环境变量
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 ../
#执行make,开始编译
make

最后,编译成功!可以在嵌入式环境下愉快的使用cmake来编译qt的工程。 

总结一下CMake的优点:

1.跨平台;

2.能够管理大型项目;

3.简化编译构建过程和编译过程;

4.可扩展:可以为 cmake 编写特定功能的模块,扩充 cmake 功能。

5.可以集成CI/CD,自动化构建与部属。

其他资源

cmake的使用_cmake使用-CSDN博客

cmake使用详细教程(日常使用这一篇就足够了)-CSDN博客

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

https://www.cnblogs.com/Fitanium/p/16181605.html

什么是 CI/CD ?5分钟让你明白 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/322140.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】---继承

【C】---继承 一、继承的概念及定义1、继承的概念2、定义语法格式3、继承基类成员访问方式的变化 二、基类 和 派生类 的对象之间的赋值转换1、赋值规则2、切片&#xff08;1&#xff09;子类对象 赋值 给 父类对象&#xff08;2&#xff09;子类对象 赋值 给 父类指针&#xf…

数据结构-线性表-链表-2.3-1

设计一个递归算法&#xff0c;删除不带头结点的单链表L中所有值为x的结点。 void del(Linkllist &L&#xff0c;int x){LNode *p;if(LNULL){return;}if(L->datax){pL;LL->next;;free(p);del(L,x);}else{del(L->next,x);} } 时间复杂度为O(n)

【项目学习01_2024.05.08_Day06】

学习笔记 5 新增课程5.1 需求分析5.1.1 业务流程5.1.2 数据模型 5.2 接口定义5.3 接口开发5.3.1 保存课程基本信息5.3.2 保存营销信息 5.4 接口测试 5 新增课程 5.1 需求分析 5.1.1 业务流程 5.1.2 数据模型 5.2 接口定义 5.3 接口开发 根据需求分析&#xff0c;新增课程表…

模型智能体开发之metagpt-多智能体实践

参考&#xff1a; metagpt环境配置参考模型智能体开发之metagpt-单智能体实践 需求分析 之前有过单智能体的测试case&#xff0c;但是现实生活场景是很复杂的&#xff0c;所以单智能体远远不能满足我们的诉求&#xff0c;所以仍然还需要了解多智能体的实现。通过多个role对动…

NSSCTF中的web

目录 [第五空间 2021]WebFTP [LitCTF 2023]PHP是世界上最好的语言&#xff01;&#xff01; [SWPUCTF 2021 新生赛]PseudoProtocols [LitCTF 2023]导弹迷踪 [NISACTF 2022]easyssrf [第五空间 2021]WebFTP 1.进入页面&#xff0c;发现是登录页面&#xff0c;想到 弱口令&…

《MySQL45讲》读书笔记

重建表 alter table t engine InnoDB&#xff08;也就是recreate&#xff09;&#xff0c;而optimize table t 等于recreateanalyze&#xff0c;让表大小变小 重建表的执行流程 建立一个临时文件&#xff0c;扫描表 t 主键的所有数据页&#xff1b;用数据页中表 t 的记录生…

六步轻松打造创新文化和领导力的技术团队

引言 在当今快速变化的商业环境中&#xff0c;构建一个支持创新的文化和领导力至关重要。通过实施创新激励机制、建立失败的容忍度、领导层的示范作用、开放和透明的沟通、促进多样性和包容性以及持续学习和适应&#xff0c;公司可以培养出一支能够不断创新的员工队伍&#xf…

6层板学习笔记2

说明:笔记基于6层全志H3消费电子0.65MM间距BGA 67、多层板的电源建议直接大面积铺铜,不建议走线,铺铜充分满足其载流能力 68、凡亿推荐表层1OZ的铜厚线宽20MIL能承载1A的电流,内层0.5OZ的铜厚线宽为40MIL能承载1A的电流,过孔直径20MIL(0.5MM)能承载1A左右的电流,实际设…

QT实战百度语音识别

前言 随着学习的深入&#xff0c;感觉愈发缺乏满足感。刚好看到微信语音转文字的功能&#xff0c;经网上查询&#xff0c;发现可以使用 QT 百度语音识别技术 实现这一功能。当然&#xff0c;由于使用的 QT 和 百度语音识别&#xff0c;那么看不到一些具体的底层实现&#xff…

C++初识多态(1)

1.多态要解决的问题&#xff08;引入&#xff09; 任何一种机制的存在&#xff0c;必然是有其存在的意义的&#xff0c;例如我们前面学过的函数重载&#xff0c;运算符重载&#xff0c;以及引用等等&#xff0c;都是解决一些特殊问题的&#xff1b; 下面通过一些具体的例子&a…

Echarts散点图的29个配置项,散点图可以随心所欲啦。

1-9 当使用 ECharts 绘制散点图时&#xff0c;可以配置以下一些常用的选项&#xff1a; 1. tooltip&#xff1a;配置提示框组件&#xff0c;用于显示鼠标悬停在散点上时的提示信息。 2. legend&#xff1a;配置图例组件&#xff0c;用于展示不同散点的标识和名称。 3. xAxis…

目录页码右对齐快速解决

选择目录–段落–制表符&#xff0c;按图中设置即可

merge函数占用内存过大

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

USB3.0接口——(1)基础知识

1.背景 USB 3.0是一种USB规范&#xff0c;该规范由英特尔等公司发起。 USB协议版本 命名约定 USB-IF组织引入命名约定&#xff0c;将端口列为 USB 5 Gbps、USB 10 Gbps、USB 20 Gbps 、USB 40 Gbps&#xff0c;而不使用版本号。获得 USB-IF 认证的 USB 产品的制造商会获得带…

WM Shell多动画场景处理

Shell导致的内存泄漏 基本上都是某个动画未正常结束&#xff0c;执行时间太久导致后续动画堆积或被merge到异常动画导致相关Surface得不到释放导致的。 某个Transition执行时间太久导致后续动画堆积 Visible layers 中有1558 个Transition Root相关layer Visible layers (c…

Java毕业设计 基于SpringBoot vue社区智慧养老监护管理平台

Java毕业设计 基于SpringBoot vue社区智慧养老监护管理平台 SpringBoot 社区智慧养老监护管理平台 功能介绍 登录注册 个人中心 修改密码 个人信息 房间信息管理 房间入住信息管理 反馈信息管理 留言管理 老人信息管理 公告管理 物资申请管理 管理员管理 护工管理 体检员管理…

C++多态(全)

多态 概念 调用函数的多种形态&#xff0c; 多态构成条件 1&#xff09;父子类完成虚函数的重写&#xff08;三同&#xff1a;函数名&#xff0c;参数&#xff0c;返回值相同&#xff09; 2&#xff09;父类的指针或者引用调用虚函数 虚函数 被virtual修饰的类成员函数 …

React:Router-1.BrowserRouter组件式

使用步骤 安装 react-router-dom 依赖 $ npm install react-router-dom6导入 BrowserRouter, Link, Routes, Route 对象 import {BrowserRouter, Link, Routes, Route} from react-router-dom;3.BrowserRouter&#xff1a;history模式路由&#xff1b; HashRouter&#xff1…

代码随想录算法训练营第二十二天|654.最大二叉树 、617.合并二叉树 、700.二叉搜索树中的搜索 、 98.验证二叉搜索树

654.最大二叉树 文档讲解&#xff1a;代码随想录 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 递归的三要素&#xff1a; 第一要素&#xff1a;明确这个函数想要干什么 传入一个数组&#xff0c;针对这个数组构造一个最大二叉树 第二要素&#xff1a;寻…

跟TED演讲学英文:What moral decisions should driverless cars make by Iyad Rahwan

What moral decisions should driverless cars make? Link: https://www.ted.com/talks/iyad_rahwan_what_moral_decisions_should_driverless_cars_make Speaker: Iyad Rahwan Date: September 2016 文章目录 What moral decisions should driverless cars make?Introduct…