什么是交叉编译?

在某个系统平台下可以产生另一个系统平台的可执行文件

•    编译过程:

•     词法分析、语法分析、汇编器、连接器

•    运行平台 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相关推荐

  1. zlog使用手册,小靠谱啊

    http://hardysimpson.github.io/zlog/UsersGuide-CN.html Chapter 1 zlog是什么? zlog是一个高可靠性.高性能.线程安全.灵活.概念清 ...

  2. 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 ...

  3. 多目录多源文件的驱动Makefile模板

    很多人知道我搞嵌入式,都说我很有前途,对此我表示感谢,希望自己真的会有个好前途.虽然现在还不能说"四举无成 十年不调",但一直无所作为,惭愧得很. 我总徘徊在驱动的门外,迟迟不能掌 ...

  4. ExtJS Panel主要配置列表

    Ext.panel.Panel 属性 值 描述 animCollapse Boolean 设置面板折叠展开是否显示动画,Ext.Fx可用默认true,否则false applyTo Mixed 面板定 ...

  5. Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog

    Android MVVM框架搭建(八)高德地图定位.天气查询.BottomSheetDialog 前言 正文 一.集成SDK 二.基础配置 ① 权限配置 ② 配置Key 三.显示地图 ① MapFra ...

  6. vue 项目中分别使用 vue-pdf 插件和内嵌 iframe 实现 PDF 文件预览,缩放,旋转,下载,保存等功能 ?

    需求:在 vue  和 element-ui 项目中,有点击按钮预览,下载,打印 PDF 文件 需求,要求支持 PDF 的预览,上下页切换,首尾页切换,页码选择跳转,放大缩小,顺时针逆时针旋转,下载, ...

  7. linux完全卸载ffmpeg_RoboMaster视觉教程Linux(四)软件安装和卸载

    一 解压压缩命令一览 在下载各种库进行安装的时候,会发现下载的安装包有各式各样的后缀名.不同的后缀名解压的命令也大不相同.其实我们也没有那么普遍要用到解压的命令,当我们有需要的时候就尽管去搜索对应压缩 ...

  8. 纯C语言日志类库 Zlog

    转自: http://hardysimpson.github.io/zlog/UsersGuide-CN.html 难易 著23 Contents Chapter 1  zlog是什么? 1.1  兼 ...

  9. Makefile详解——从入门到精通

    转自ChinaUnix,作者gunguymadman,陈皓.链接地址:http://www.chinaunix.net/jh/23/408225.html 陈皓 CSDN 博客:http://blog ...

最新文章

  1. win10突然只剩下c盘和d盘了_电脑C盘爆满飘红?系统卡?试试这两种解决办法
  2. mysql不支持addbatch_【MySql】Java 批量插入数据库addBatch
  3. Request的学习笔记(属Servlet学习课程)
  4. 数据链路层:ARP协议详解(绝对经典)
  5. QTP中VBS脚本下FSO、WSH的应用(二)
  6. Visual Studio 2008添加ActiveX控件测试容器(windows 7可用)
  7. 开课吧:电商产品数据分析的核心目标是什么?
  8. log4cpp乱码_log4cxx配置使用(一)
  9. matlab图像画轮毂,轮毂设计及三维造型(全套图纸三维).doc
  10. WORD中设置“选择性粘贴“—“无格式文本”的快捷键
  11. 深色背景黑底白字,蓝底白字课件材料“洗白”打印,ps批处理教程
  12. 解放生产力,CSS3帧动画工具
  13. 电脑控制android 源代码,[源代码]电脑通过adb控制安卓手机
  14. 200万年薪的博士,华为到底看重什么?
  15. 软件系统的多维性能模型
  16. @Value取不到值的原因
  17. Spark RDD API详解
  18. GitHub上这个微信防撤回的开源项目,99%的程序员不知道
  19. [Pandas] 缺失值删除 df.dropna()
  20. 西游记中会七十二变的三个人

热门文章

  1. 交换机,CAM,TCAM,CEF-FIB
  2. SABER 最强大的数模混合信号仿真软件
  3. 超声波气象站和常规气象站的区别
  4. 高斯牛顿法----MATLAB实现
  5. mbedtls安装与入门
  6. Kubernetes(k8s)基础之二:容器编排介绍及概念
  7. 组件容器服务器的关系,什么是docker 容器编排
  8. JavaSE(二)-抽象类
  9. 报错:“export ‘default‘ (imported as ‘mui)‘ was not fount in ‘../lib/mui/js/mui-min.js‘
  10. 程序的可维护性和可扩展性