当前位置: 首页 > 编程日记 > 正文

Cmake 交叉编译

转载自 http://zhixinliu.com/2016/02/01/2016-02-01-cmake-cross-compile/

CMake交叉编译

CMake的使用,以及如何将一个项目移植到Android。

CMake的用法

先让我们简单学习回顾一下cmake的基本知识:

基本流程

以linux平台为例,使用 CMake 生成 Makefile 并编译的流程如下:

编写 CMake 配置文件 CMakeLists.txt 。
执行命令 cmake Path-to-Cmakelist/CMakeLists.txt 生成 Makefile。
使用 make 命令进行编译。
语法
CMakeLists文件可以包含comments,commands,以及 空行。
注释以#开头
command:包含命令名字,括号,用空格分开的参数 comand(arg1 arg2 …)
所有的空白行都会被忽略。

基本的命令
project
project:用来声明项目的名字,也可以指定项目的开发语言
project(projectname [cxx] [c] [java] [none])
如果没有指定语言,那么CMake默认指定为c和c++
在每一个project出现的CMakeLists.txt,CMake都会创建一个top level的IDE project文件。这个project会包括出现在该CMakeLists.txt中的所有的targets,以及它所有的subdirecotry, 用add_subdirectory命令来指定。

set
set命令用来定义或者修改变量或者lists
和set对应的remove命令

add_executable / add_library
用来定义what executable/libs to build, 并且指定source 文件。

另外一些命令可以从这里找到:
https://cmake.org/cmake/help/v3.0/manual/cmake-variables.7.html
https://cmake.org/Wiki/CMake_Useful_Variables

关于cmake在普通项目中的用法,请参考这篇文章:cmake入门实践

交叉编译

现在移动开发越老越火,我们免不了会将一些项目porting到Android/iOS平台,这个时候就要用到交叉编译:即在你host宿主机上(例如你用的Ubuntu电脑)要生成target目标机(例如Android手机)的程序。在编译的过程中会涉及到相关头文件的切换和编译器的选择以及环境变量的改变等,今天就来看看CMake是如何来做交叉编译的。

首先需要明确以下几点:

CMake不能自动判断出目标机系统,需要我们指定。
一般情况下Build出来的可执行文件是不能直接运行在宿主机上。
编译过程中不能用宿主机上的原声头文件和库,而是需要用到一套不同的头文件和库。
CMAKE_TOOLCHIAIN_FILE

这个应该是CMake交叉编译中最重要的概念。正如前面提到过的,CMake不知道你的目标平台是什么、用什么编译起、如何编译等等,所以你需要提供预设一些变量到CMake,其中最为方便的一个方法就是将相关的变量设置都放进一个文件(cmake脚本)中去,然后将该文件通过CMAKE_TOOLCHIAIN_FILE传递给CMake, 例如:

cmake -D CMAKE_TOOLCHIAIN_FILE="/path/to/my-cmake-toolchain-file" …
此处我们假设要执行的CMakeLists file在上一级目录中。

下面将要在这个文件中需要设置的几个重要的变量分两大类依次介绍一下。

设置目标系统以及Toolchain
CMAKE_SYSTEM_NAME:
在toolchain脚本中必须要设置的变量,只有当CMAKE_SYSTEM_NAME这个变量被设置了,CMake才认为此时正在交叉编译,它会额外设置一个变量CMAKE_CROSSCOMPILING为TRUE。

CMAKE_SYSTEM_NAME即目标机target所在的操作系统名称,比如ARM或者Linux你就需要写”Linux”,如果Android平台你就写”Android”,如果你的嵌入式平台没有相关OS你即需要写成”Generic”.

CMAKE_SYSTEM_PROCESSOR:
这个是可选项,但是在移动开发中很重要,代表目标系统的硬件或者CPU型号,例如ARM,X86 etc。

CMAKE_C_COMPILER:
即C语言编译器,这里可以将变量设置成完整路径或者文件名

CMAKE_CXX_COMPILER:
C++编译器。

搜索查找外部依赖
稍微大一点的项目都会用到一些外部依赖库或者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:
代表了一系列的相关文件夹路径的根路径的变更,比如你设置了/opt/arm/,所有的Find_xxx.cmake都会优先根据这个路径下的/usr/lib,/lib等进行查找,然后才会去你自己的/usr/lib和/lib进行查找.

CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:
对FIND_PROGRAM()起作用,有三种取值,NEVER,ONLY,BOTH,第一个表示不在你CMAKE_FIND_ROOT_PATH设置的目录下进行查找,第二个表示只在这个路径下查找,第三个表示先查找这个路径,再查找全局路径

CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
对FIND_LIBRARY()起作用,表示在链接的时候的库的相关选项,因此这里需要设置成ONLY来保证我们的库是在交叉环境中找的.

一个小例子

附上一个CMake官方文档中的toolchian file的小例子,这样我们就会对如何写toolchain文件有了感性认识:

# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)# specify the cross compiler
SET(CMAKE_C_COMPILER   /opt/eldk-2007-01-19/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER /opt/eldk-2007-01-19/usr/bin/ppc_74xx-g++)# where is the target environment 
SET(CMAKE_FIND_ROOT_PATH  /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)# search for programs in the build host directories
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)

执行起来也很简单,如下:

~/src$ cd build
~/src/build$ cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-eldk-ppc74xx.cmake …

相关文章:

利用System.Uri转URL为绝对地址

在使用ASPOSE.Word生成Word文档时可以通过InsertHtml(html)来将图文信息写入Word文档(图片内嵌),但要求html里图片的src是绝对全路径,所以需要对html进行转化。 获取html可以来自数据库数据或者通过网络抓取,得到之后使用System.Uri来进行替换…

idea上java接口自动化_Java接口自动化之IDEA创建及运行maven项目

本文2564字阅读约需7分钟第195次推送Maven作为一个项目管理工具,是一组标准集合,一个项目的生命周期、一个依赖管理系统,以下主要介绍IDEA创建及运行maven项目。01创建maven项目①打开IDEA,顶部菜单栏依次选择File-->New-->…

.NET面向上下文、AOP架构模式(实现)

.NET面向上下文、AOP架构模式(实现) 1.上下文Context、面向切面编程AOP模型分析 在本人的.NET面向上下文、AOP架构模式(概述)一文中,我们大概了解了上下文如何辅助对象在运行时的管理。在很多时候我们急需在运行时能把…

英语之弱元音Schwa

IELTS Speaking - 学会英语Schwa弱元音,你的口语也将充满英伦味 https://baijiahao.baidu.com/s?id1596905156544848616&wfrspider&forpc http://blog.sina.com.cn/s/blog_95e5f8a601017jr4.html https://www.guokr.com/blog/440820/ 打傻方进 百家号04-05…

工厂方法模式和抽象工厂模式

工厂方法模式和抽象工厂模式工厂方法模式抽象工厂模式总结:工厂方法模式 #include <string> #include <iostream>// Abstract class Splitter { private:/* data */ public:Splitter(/* args */);virtual ~Splitter(); public:virtual void split() 0; };Splitte…

关于JQuery中的ajax请求或者post请求的回调方法中的操作执行或者变量修改没反映的问题...

前段时间做一个项目&#xff0c;而项目中所有的请求都要用jquery 中的ajax请求或者post请求&#xff0c;但是开始处理一些简单操作还好&#xff0c;但是自己写了一些验证就出现问题了&#xff0c;比如表单提交的时候&#xff0c;要验证帐号的唯一性&#xff0c;所以要在submit前…

下列关于Java多线程并发控制_下列关于Java多线程并发控制机制的叙述中,错误的是...

下列叙述成都望江楼的造景手法有()。竹文化景观应体现科学性与艺术性的和谐统一&#xff0c;关于既要满足植物的生态习性&#xff0c;又能体现美学价值。在中国传统的审美趣味、多线伦理道德上&#xff0c;竹在造园中被拟人化为( )的代表。程并错误下列不属于竹文化旅游的发展趋…

一.vtun源码学习笔记

1.守护进程 &#xff08;1&#xff09;守护进程简介 守护进程,也就是我们通常所说的Daemon进程。它是一个生存期较长的进程&#xff0c;它通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。 它与普通进程相比有下面这些特殊性&#xff1a;守护进程最重要的…

获取data 数据

export function getData(el, name, val) {const prefix data-if (val) {return el.setAttribute(prefix name, val)}return el.getAttribute(prefix name) } 转载于:https://www.cnblogs.com/hss-blog/p/9781816.html

java jwks_Java SpringBoot 如何使用 IdentityServer4 作为验证服务器学习笔记

这边记录下如何使用IdentityServer4 作为 Java SpringBoot 的 认证服务器和令牌颁发服务器。本人也是新手&#xff0c;所以理解不足的地方请多多指教。另外由于真的很久没有写中文了&#xff0c;用词不太恰当的地方也欢迎新手大佬小伙伴指出&#xff0c;一起进步。另外这边令牌…

git 快速复制一个新项目

gitlab创建项目a及一个主分支master 本地整体复制已有项目b 本地克隆gitlab上新创建的项目a&#xff08;git clone gitlab地址&#xff09; 将本地克隆过来的a文件夹下的.git目录拷贝到b项目下&#xff08;cp -r .git …/b&#xff0c;注意是两个点&#xff0c;不是三个点,写两…

微信公众平台消息接口星标功能

【微信公众平台星标功能接口被撤销】微信公众平台消息接口中的星标功能&#xff0c;被悄悄的去掉了。 原因应该是有的账号在程序中大量使用星标功能&#xff0c;造成微信服务器存储记录过于宠大。 现在要继续使用星标功能&#xff0c;只能在后台手工操作。 <xml> <ToU…

国庆双节长假旅游出行必装的手机软件

长假即将来临&#xff0c;如果打算出去溜达溜达&#xff0c;透透气的朋友&#xff0c;本文可千万别错过了。今天将介绍几款应用是旅途中绝对不能缺少的&#xff0c;这些应用都非常好用、功能全面&#xff0c;是出行必备的手机软件&#xff0c;希望可以伴你度过快乐的十一长假。…

Windbg双机调试环境配置(Windows7/Windows XP+VirtualBox/VMware+WDK7600)

简介&#xff1a;Windbg双机调试内核、驱动 下载软件&#xff1a; 下载Windbg(GRMWDK_EN_7600_1.ISO)下载VirtualBox 5.2/VMware 12一、安装WDK&#xff0c;这里要提一点的是Debugging Tools for Windows一定要打勾&#xff0c;因为我们后面就是要通过这个工具来进行双机调试的…

哈夫曼树的java实现_java实现哈夫曼树

哈夫曼译码,就是将输入的译码还原成对应的字符。 抽象的算法描述:将建立哈夫曼树、实现哈夫曼编码、哈夫曼译码都定义成 子函数的的形式, 然后在主函数中调用它们......数据结构课程设计设计题目: 哈夫曼树及其应用学 院:计算机科学与技术 专业:网络...用哈夫曼树实现图像压缩_…

on-my-zsh git 仓库下运行卡顿

在 oh-my-zsh 进入 包含 git 仓库目录时&#xff0c;执行 ls 时会比较卡顿 原因&#xff1a; oh-my-zsh 要获取 git 更新信息 解决办法&#xff1a; 设置 oh-my-zsh 不读取文件变化信息&#xff08;在 git 项目目录执行下列命令&#xff09; $ git config --add oh-my-zsh…

oracle, group by, having, where

选择列表中如果包含有列、表达式时&#xff0c;这个列、表达式必须包含在Group By子句中。另外&#xff0c;如果采用了表达式的话&#xff0c;则数据库管理员即使在选择列表中采用了别名&#xff0c;但是在Group By子句中仍然必须采用表达式的完整表达方式&#xff0c;而不能够…

[转载] CSS模块化【封装-继承-多态】

第一次听到“CSS模块化”这个词是在WebReBuild的第四届“重构人生”年会上&#xff0c;当时我还想&#xff0c;“哈&#xff0c;CSS也有模块化&#xff0c;我没听错吧&#xff1f;”事实上&#xff0c;我没听错&#xff0c;你也没看错&#xff0c;早就有CSS模块化这个概念了。之…

用jQuery写的一个翻页,并封装为插件,

用jQuery写的一个翻页&#xff0c;并封装为插件&#xff0c; 1 *{2 margin:0;3 padding: 0;4 list-style: none;5 text-decoration: none;6 }7 .page{8 width:500px;9 margin:100px auto; 10 color: #ccc; 11 } 12 .page a{ 13 display: inlin…

Ubuntu 将 /home 或 /var 目录挂载到新的分区

背景 在使用 docker 的过程中&#xff0c;docker 会将某些产物放到 /var/lib/docker/volumes 这会占用很大的跟目录磁盘空间&#xff0c;于是想办法将 /var 目录挂载到另一个一个单独的磁盘上面。 参考链接如下&#xff1a;Ubuntu将var目录挂载到新硬盘 步骤 1. 查看当前磁…

php 500 内部服务器错误,php 500 - 内部服务器错误的解决方法

php 500 - 内部服务器错误的解决方法发布时间&#xff1a;2020-11-04 09:55:31来源&#xff1a;亿速云阅读&#xff1a;71作者&#xff1a;小新小编给大家分享一下php 500 - 内部服务器错误的解决方法&#xff0c;相信大部分人都还不怎么了解&#xff0c;因此分享这篇文章给大家…

网游生命周期在百度指数曲线上呈“M”形分布,各阶段搜索行为呈一定特征

&#xff08;本文转载自&#xff1a;http://data.baidu.com/youxi3/part1.html&#xff09; 产品生命周期就是一种新产品从开始进入市场到被市场淘汰的整个过程&#xff0c;进人和退出市场分别标志着周期的开始和结束。网络游戏的生命周期一般可以划分成测试期、成长期、成熟期…

配置Open***使用User/Pass方式验证登录

Open***和PPTP ***相比存在诸多的优势&#xff0c;最明显的是Open***支持NAT穿越&#xff0c;也就是说在nat环境下使用open***只需要一个在路由器上做一个端口映射即可&#xff01;不需要其他路由的支持&#xff0c;要知道不是所有的路由器都支持配置NAT穿越&#xff0c;只有高…

常惠琢 201771010102《面向对象程序设计(java)》第七周学习总结

实验七 继承附加实验 实验时间 2018-10-11 1、实验目的与要求 &#xff08;1&#xff09;进一步理解4个成员访问权限修饰符的用途&#xff1b; &#xff08;2&#xff09;掌握Object类的常用API用法&#xff1b; &#xff08;3&#xff09;掌握ArrayList类用法与常用API&#…

nginx php站点配置文件,php网站修改默认访问文件的nginx配置

搭建好lnmp后&#xff0c;有时候并不需要直接访问index.php&#xff0c;配置其他的默认访问文件比如index.html这时候需要配置一下nginx才能访问到你想要设置的文件直接上代码&#xff0c;如下是我的配置的一份简单的nginx到php-fpm的站点&#xff0c;该站点默认访问目录/ecmob…

CMake 打包已经存在的动态库生成 target

一. 背景 在 CMakeLists.txt 中&#xff0c;某模块 A 通过 add_subdirectory 引入模块 B &#xff0c;模块 B 通过 add_subdirectory 引入模块 C。模块 C 里面本身就是一个开源的动态库&#xff0c;比如 libtask。目的想要将 C 模块打包成一个 Target &#xff0c;以便在 A 模…

Ruby: Ruby脚本在测试中的使用

如果存在以下的场景&#xff1a;1. 放置在公司的读报机服务器&#xff0c;每天都是开启的&#xff1b;2. 读报机每天下载报纸&#xff0c;一旦成功/失败&#xff0c;就会有相应的记录生成在某个xml文件中&#xff1b;3. 现在有过去一年的读报机下载xml&#xff0c;大约有200多份…

cocos2d-xna for win8源代码轻松移植cocos-xna for wp游戏

无意间看到杨哥弄了一个cocos2d-xna for win8出来可惜没有放出源代码&#xff0c;我试着要了一下结果他没理我&#xff0c;各种画圈圈。 那我只好自己弄一个了&#xff0c;源代码放出大家供交流学习使用&#xff0c;像杨哥说的一样就是一点小bug很容易该成把wp改成win8版的&…

Oct 2018

Tasks motion planning code in Autonomous DrivingUdacity RoboticsNDCoursera RoboticsMotion PlanningEstimationF1/10 racecarProject Overview 1. Mooc Udacity RoboticsND: project 3 Coursera Robotics Motion Planning HomeworkNote --> Post  2. Leetcode ☆☆ …

Springboot+mybatisplus搭建新闻管理系统

模块化实现&#xff0c;一周轻松搭建 前端 后端 项目源码及其教程回复已三连备注邮箱领取