CrossCompiler And Auto tools
什么是交叉编译?
在某个系统平台下可以产生另一个系统平台的可执行文件
• 编译过程:
• 词法分析、语法分析、汇编器、连接器
• 运行平台 vs 编译平台
• gcc –dumpmachine:
• i486-linux-gnu:32bit linux
• i686-apple-darwin11:MacOS
• arm-linux-androideabi:Android
• arm-apple-darwin10: IOS
如何支持交叉编译?
支持交叉编译,首先要选择对的编译器,其次对编译过程引用的头文件、库要使用目标系统而不是运行系统的,最后还要明确支持系统机器类型
• 编译器:
• Android使用arm-linux-androideabi-gcc
• IOS使用的是arm-apple-darwin10-llvm-gcc
• 选择目标系统路径
• gcc –sysroot platforms/android-9/arch-arm
• gcc –sysroot iPhoneOS.platform/Developer
• 选择目标系统机器(machine)类型
• IOS和Android是arm的,但不同版本arm指令集不同,armv7s、armv5tej……
一个简单交叉编译的例子
• 文件main.c:
• int main(int argc, char** argc) { printf(“ok\n”); }
• 编译:
• gcc main.c –o test
• arm-apple-darwin10-llvm-gcc-4.2 main.c –o test.arm –sysroot=…/SDKs/iPhoneOS6.0.sdk –b armv7s
• file test: Mach-0 64-bit executable x86_64
• file test.arm: Mach-0 executable arm
编译器与目标系统相关选项
• --sysroot=${root}: 定义包含标准路径的prefix,如${root}/usr/include
• -b <machine>: 定义目标机器型号,一般编译器支持多种CPU及汇编,需要选择正确的型号,如arm5te、arm5tej、arm946e-s、armv7s等
交叉编译的困难是什么?
本系统编译,所有路径都是以文件系统根路径为起点,在不同机器上是固定的,而交叉编译,编译器无法预知系统位置,编译器中在spec中预置的变量是不对的,需要逐一指定。
本机编译,CPU等机器选项是可以测试得到,而交叉编译是无法指定,只能逐一指定。
• 系统路径:
• libgcc_s crt1.o等gcc需要库路径
• libc及其头文件的路径
• 目标系统路径,如IOS预置库及头文件路径
• 安装的模块路径,如依赖库及图文件路径
• 多机器选项:
• 支持ios5-7 simulator(i386),CPU选项不同
• andriod指令集种类繁多的问题。
自己写Makefile的困难
如何检查编译器的能力,检查目标系统版本及能力、检查依赖模块及其版本,检查引用库支持所需功能情况,检查所需头文件情况……
• 需要大量脚本:看看生成的configure有多大
• 跨平台脚本能力,如BSD和Linux命令选项就有许多不同
• 应对不同需求能力,不同目标系统需要不同,难以统一
解决可移植性及交叉编译方案
Automake工具
可移植性
检查系统
检查编译器
检查路径
生成Makefile
Auto-tools工具组
• Autoconf
– ‘autoconf’:用configure.ac产生configure.
– ‘autoheader’:用configure.ac产生config.h
– ‘autoreconf’ :运行autoconf重新产生configure
– ‘autoscan’: 扫描常见的移植问题.
– ‘autoupdate’: 升级configure.ac中的废弃宏.
– ‘ifnames’: 收集条件宏#if/#ifdef/.
– ‘autom4te’:m4宏收集和实施,真正的code生成器
• Automake
– ‘automake’:用configure.ac 和Makefile.am产生Makefile.in.
– ‘aclocal’: 扫描configure.ac并将第三方宏定义放入aclocal.m4.
• Libtools
– ‘libtoolize’:用于生产系统相关libtool
– ‘libtool’:库管理命令行工具
Auto-tools 工作过程
如何编写configure.ac?
初始化
dnl Process this file with autoconf to produce a configure script.
define([svnversion], esyscmd([sh -c "LANG= LANGUAGE= svnversion|sed s/:/./g |tr -d '\n'"]))
dnl Initialization
AC_INIT([demo], [1.0.svnversion], [yantao.li@gnetis.com])
AC_CONFIG_AUX_DIR(auxdir)
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
dnl Package information
AC_CONFIG_MACRO_DIR([m4])
编译器检查
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_HEADER_STDC
库、函数、类型检查
dnl Checks for libraries.
dnl AC_CHECK_LIB([LIBRARY{> < = >= <= version}], [desc], [ACT-IF-FOUND], [ACT-IF-NOT])
dnl Check header
dnl AC_CHECK_HEADERS(HEADERS...)
dnl Checks for typedefs, structures, function and compiler characteristics.
dnl AC_CHECK_FUNCS([function], [if-found], [if-not-found])
dnl AC_CHECK_TYPES([struct aaa], [if-found], [if-not-found])
dnl Check related tools or programs.
dnl AC_CHECK_PROG(variable, program-name, value-if-found, [value-if-not-found], [path], [reject])
dnl tang check, keep it anyway, our prefix=/tang
构造命令行选项
dnl –enable-feature
dnl AC_ARG_ENABLE([feature], [help-text], [if-given], [if-not-given])
dnl –with-feature
dnl AC_ARG_WITH([package], [help-text], [if-given], [if-not-given])
dnl help string with format
dnl AS_HELP_STRING([--enable-feature],[describe])
定义autoheader和automake宏
dnl 定义automake宏,在Makefile.am中以@macro@引用
macro=test
AC_SUBST([macro])
dnl 定义autoheader宏macro
AC_DEFINE([macro], [value], [macro description])
AC_DEFINE_UNQUOTED([macro],[value],[macro description])
dnl 对于automake条件
AM_CONDITIONAL([condition],[test sss])
自定义m4宏
dnl 定义宏AC_SET_DEFAULT_LOGLEVEL([level]), 缺省log level为level,可命令设定
AC_DEFUN([AC_SET_DEFAULT_LOGLEVEL], [
if test -z "$1"; then LOG_LEVEL=7; else LOG_LEVEL=$1; fi
AC_ARG_WITH([log],[AS_HELP_STRING([--with-log:],[
set log level for debugging purpose, (default is set log level to $1)])], [
echo "set log level to $enableval"
AC_DEFINE_UNQUOTED([LOG_LEVEL], [$withval], [set the log level])],
[ echo "set log level to $LOG_LEVEL"
AC_DEFINE_UNQUOTED(LOG_LEVEL, $LOG_LEVEL, [set the log level $LOG_LEVEL to disable log])
]) ])
定义输出文件
dnl Final Output
AC_OUTPUT([
Makefile
src/Makefile
lib/Makefile
test/Makefile
lib/test.pc
])
语法规则与Makefile相同
DATA:
数据文档,一般无需编译,需要包含或安装的数据文件
HEADERS:
头文件,包含需要安装或不需要安装的头文件
SCRIPTS:
脚本,包含build需要的脚本或是需要安装的脚本
MANS:
手册,是需要安装的程序说明书
TEXINFOS:
提供info程序显示的手册,一般是程序说明书
PROGRAMS :
要编译的可执行程序定义
LIBRARIES :
要编译的库程序,一般是内部使用的静态库
LTLIBRARIES:
需要libtool编译的程序库,一般是动态库程序,也支持静态库
实现可执行文件编译
# 定义可执行文件,安装到bindir下,命令参数--bindir=DIR,还有sbin_PROGRAMS,安装到sbindir
bin_PROGRAMS = test
#定义test的源文件,可以包含不安装的头文件
test_SOURCES = main.c
#定义连接test需要的库文件及附加的object文件,
test_LDADD = @FOO_OBJ@
# 定义编译test所依赖的目标
test_DEPENDENCIES = @FOO_OBJ@
# 定义附加的源文件
EXTRA_foo_SOURCES = foo.c
# 定义编译test说需要的编译选项, 对c编译器有效
test_CFLAGS=-Iaaa
# 定义编译test说需要的编译选项, 对c++编译器有效
test_CXXFLAGS=-O2
# 定义编译test说需要的编译选项, 对c和c++编译器都有效
test_CPPFLAGS=-O0
# 定义连接test说需要的选项
test_LDFLAGS=-lppp
实现静态库文件编译
# 定义可执行文件,安装到libdir下,命令参数--libdir=DIR
lib_LIBRARIES = libzlib.a
#定义zlib的源文件,可以包含不安装的头文件
libzlib_a_SOURCES = main.c
#定义连接需要的库文件及附加的object文件,LIBADD仅仅对LIBRARIES有效
libzlib_a_LIBADD = @FOO_OBJ@
# 定义编译zlib所依赖的目标
libzlib_a_DEPENDENCIES = @FOO_OBJ@
# 定义附加的源文件, 一般是生成源文件
EXTRA_libzlib_a_SOURCES = foo.c
# 定义编译zlib说需要的编译选项, 对c编译器有效
libzlib_a_CFLAGS=-Iaaa
# 定义连接zlib说需要的选项
libzlib_a_LDFLAGS=-lppp
实现动态库文件编译
# 定义可执行文件,安装到libdir下,命令参数--libdir=DIR
lib_LTLIBRARIES = libzlib.la
#定义zlib的源文件,可以包含不安装的头文件l
libzlib_la_SOURCES = main.c
#定义连接需要的库文件及附加的object文件
libzlib_la_LDADD = @FOO_OBJ@
# 定义编译zlib所依赖的目标
libzlib_la_DEPENDENCIES = @FOO_OBJ@
# 定义附加的源文件, 一般是生成源文件
EXTRA_libzlib_la_SOURCES = foo.c
# 定义编译zlib说需要的编译选项, 对c编译器有效
libzlib_la_CFLAGS=-Iaaa
# 定义连接zlib说需要的选项
libzlib_la_LDFLAGS=-lppp
库文件版本定义原则
…_LDFALGS = -version-info Current : Revision : Age
– 初始值 0:0:0,除非确有代码修改,不要修改该值,且只在发布时修改
– 如果有接口改变或增加,但二进制兼容,即原来程序可以不编译使用该库,改变原则是: current+1:0:age+1
– 如果接口改变或删除接口,破坏了二进制兼容,原来程序需要修改编译才能使用该库,改变原则是:current+1:0:0
– 如果接口没有变化,但内部有修改,改变原则是:current:revision+1:age
库输出版本:so. major. minor .build=(Current- Age).(Age).(Revision )
– 兼容修改接口,major不变,minor增加,build归零
– 不兼容修改,major增加,minor归零,build归零
– 接口没有修改,但内部修改, major不变,minor不变,build增加
– 发布、安装相关问题
– 发布dist包含以下文件
– 所有SOURCES、HEADERS、TEXINFOS、 SCRIPTS、DATA、MANS定义文件,缺省进入dist包,除非是有nodist_前缀排除
– EXTRA_DIST 用于定义额外的发布文件列表
– 对于其它如PROGRAMS,增加前缀dist_,可以用于增加到发布列表
– 安装文件
– HEADERS、TEXINFOS、 SCRIPTS、DATA、MANS、 PROGRAMS、LTLIBRARIES和LIBRARIES都会进入安装,安装路径是以前缀定义,如bin_表名安装到bindir
– 排除安装方式是noinst_前缀
Autoreconf
• autoreconf –fiv
-v, --verbose
verbosely report processing
-f, --force
consider all files obsolete
-i, --install
copy missing auxiliary files
-m, --make
when applicable, re-run ./configure && make
如何使用configure脚本?
使用环境变量
• 支持一下环境变量替换:
• CC、CXX编译器设置
• CFLAGS、CPPFLAGS、CXXFLAGS初始化值替换
• LDFLAGS、LIBS初始化值替换
• 使用环境变量:
• PATH
• PKG_CONFIG_PATH
• 常规命令行参数
• 安装目录相关:
• --prefix:所有architecture无关文件安装路径
• --exec-prefix: architecture无关文件安装路径,缺省是prefix
• --bindir、--sbindir、--libexecdir定义相关安装路径
• 交叉编译相关
• --build定义build运行的主机系统,缺省会自动判断
• --host定义编译目标运行的系统,以前使用—target,缺省使用编译器猜测
• 使用依赖模块:
• --with-xxxx
• 使用相关功能
• --enable-xxxx
• 帮助
• --help
• 检查输出结果
• 输出Makefile文件
• 输出config.h文件
Automake产生Makefile有什么不同?
Make的目标
• all:build target
• check:build test program and running it
• Install:install target to ${DESTDIR}$bindir, …
• clean: clean all build result
• dist: distribute the source code
• distclean: clean make and configure script results
• make target DESTDIR=xxxx CFLAGS=xxxx
示例和问题
• 对于交叉编译,特别是多目标交叉编译,autotools是如何支持,如何实现的呢?
支持不了多host?
使用多build路径支持多host
• Makefile.am中可以使用@srcdir@和@builddir@来区分源文件路径和build中间文件路径
• 同一个srcdir可以支持多个builddir,各自完成自己的任务
• Install是可以将不同builddir的路径安装到一个路径下,实现同一个包支持多个host
• 实例:
• RabbitMQ client支持,iphone5、6、7及simulator
• 实现脚本一次构建完成
支持不了动态构建目标?
使用automake条件
• configure.ac定义条件CONDITION
• AM_CONDITIONAL([CONDITION], [test x$p = xtrue])
• Makefile.am使用条件:
• if CONDITION
tools=dbgtool
else
tools=
bin_PROGRAMS=foo $(tools)
• 实例:
• 客户端测试程序,对不同目标有不同程序
• 对于Tang客户端,对OC和Java有不同分装代码需要编译
支持不了模块检查?
pkg-config
Autotools之外单独工具
定义m4宏:
PKG_CHECK_MODULES([GLIB_THREADS], gthread-2.0 >= 2.2, have_glib_threads=yes, have_glib_threads=no)
Makefile.am中使用GLIB_THREAD_CFLAGS和GLIB_THREAD_LIBS宏引用module库和头文件,避免升级引起的麻烦
模块查找路径由PKG_CONFIG_PATH决定
模块描述文件是.pc(package configure)文件
注意.pc文件对交叉编译路径有所不同,内容中的包含路径要准确
CrossCompiler And Auto tools相关推荐
- zlog使用手册,小靠谱啊
http://hardysimpson.github.io/zlog/UsersGuide-CN.html Chapter 1 zlog是什么? zlog是一个高可靠性.高性能.线程安全.灵活.概念清 ...
- Qt / SIGNAL、SLOT、signals、slots、emit 关键字含义
一.SIGNAL.SLOT 源码路径:/home/(name)/Qt5.14.2/5.14.2/Src/qtbase/src/corelib/kernel/qobjectdefs.h Q_CORE_E ...
- 多目录多源文件的驱动Makefile模板
很多人知道我搞嵌入式,都说我很有前途,对此我表示感谢,希望自己真的会有个好前途.虽然现在还不能说"四举无成 十年不调",但一直无所作为,惭愧得很. 我总徘徊在驱动的门外,迟迟不能掌 ...
- ExtJS Panel主要配置列表
Ext.panel.Panel 属性 值 描述 animCollapse Boolean 设置面板折叠展开是否显示动画,Ext.Fx可用默认true,否则false applyTo Mixed 面板定 ...
- Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
Android MVVM框架搭建(八)高德地图定位.天气查询.BottomSheetDialog 前言 正文 一.集成SDK 二.基础配置 ① 权限配置 ② 配置Key 三.显示地图 ① MapFra ...
- vue 项目中分别使用 vue-pdf 插件和内嵌 iframe 实现 PDF 文件预览,缩放,旋转,下载,保存等功能 ?
需求:在 vue 和 element-ui 项目中,有点击按钮预览,下载,打印 PDF 文件 需求,要求支持 PDF 的预览,上下页切换,首尾页切换,页码选择跳转,放大缩小,顺时针逆时针旋转,下载, ...
- linux完全卸载ffmpeg_RoboMaster视觉教程Linux(四)软件安装和卸载
一 解压压缩命令一览 在下载各种库进行安装的时候,会发现下载的安装包有各式各样的后缀名.不同的后缀名解压的命令也大不相同.其实我们也没有那么普遍要用到解压的命令,当我们有需要的时候就尽管去搜索对应压缩 ...
- 纯C语言日志类库 Zlog
转自: http://hardysimpson.github.io/zlog/UsersGuide-CN.html 难易 著23 Contents Chapter 1 zlog是什么? 1.1 兼 ...
- Makefile详解——从入门到精通
转自ChinaUnix,作者gunguymadman,陈皓.链接地址:http://www.chinaunix.net/jh/23/408225.html 陈皓 CSDN 博客:http://blog ...
最新文章
- win10突然只剩下c盘和d盘了_电脑C盘爆满飘红?系统卡?试试这两种解决办法
- mysql不支持addbatch_【MySql】Java 批量插入数据库addBatch
- Request的学习笔记(属Servlet学习课程)
- 数据链路层:ARP协议详解(绝对经典)
- QTP中VBS脚本下FSO、WSH的应用(二)
- Visual Studio 2008添加ActiveX控件测试容器(windows 7可用)
- 开课吧:电商产品数据分析的核心目标是什么?
- log4cpp乱码_log4cxx配置使用(一)
- matlab图像画轮毂,轮毂设计及三维造型(全套图纸三维).doc
- WORD中设置“选择性粘贴“—“无格式文本”的快捷键
- 深色背景黑底白字,蓝底白字课件材料“洗白”打印,ps批处理教程
- 解放生产力,CSS3帧动画工具
- 电脑控制android 源代码,[源代码]电脑通过adb控制安卓手机
- 200万年薪的博士,华为到底看重什么?
- 软件系统的多维性能模型
- @Value取不到值的原因
- Spark RDD API详解
- GitHub上这个微信防撤回的开源项目,99%的程序员不知道
- [Pandas] 缺失值删除 df.dropna()
- 西游记中会七十二变的三个人
热门文章
- 交换机,CAM,TCAM,CEF-FIB
- SABER 最强大的数模混合信号仿真软件
- 超声波气象站和常规气象站的区别
- 高斯牛顿法----MATLAB实现
- mbedtls安装与入门
- Kubernetes(k8s)基础之二:容器编排介绍及概念
- 组件容器服务器的关系,什么是docker 容器编排
- JavaSE(二)-抽象类
- 报错:“export ‘default‘ (imported as ‘mui)‘ was not fount in ‘../lib/mui/js/mui-min.js‘
- 程序的可维护性和可扩展性