CrossCompiler And Auto tools
2014-04-15 11:14
567 查看
什么是交叉编译?
在某个系统平台下可以产生另一个系统平台的可执行文件
•
编译过程:
•
词法分析、语法分析、汇编器、连接器
•
运行平台 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命令选项就有许多不同
•
应对不同需求能力,不同目标系统需要不同,难以
4000
统一
解决可移植性及交叉编译方案
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文件对交叉编译路径有所不同,内容中的包含路径要准确
在某个系统平台下可以产生另一个系统平台的可执行文件
•
编译过程:
•
词法分析、语法分析、汇编器、连接器
•
运行平台 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命令选项就有许多不同
•
应对不同需求能力,不同目标系统需要不同,难以
4000
统一
解决可移植性及交叉编译方案
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文件对交叉编译路径有所不同,内容中的包含路径要准确
相关文章推荐
- 基于JSP编译器基本语法的使用详解
- 跨平台python异步回调机制实现和使用方法
- 跨平台音频项目
- [转]C++强大背后
- [游戏资讯][转]《反恐精英:全球攻势》要实现跨平台对战
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- g++编译 参数 .
- vim中的杀手级插件: YouCompleteMe
- Android 内核源代码交叉编译
- Android内核源码交叉编译
- Google C++ unit test 在ARM Android 2.3 上的编译与使用
- 从代码示例了解ECMAScript5新特性
- Java的可移植性受到广泛使用
- C++ .H .CPP
- Windows Server 2003远程桌面多用户连接问题
- centos下安装nginx
- C++对象的内存分析(1)
- C++对象的内存分析(2)
- C++对象的内存分析(4)
- ARM Linux 交叉编译 工具链 制作攻略