Makefile的几则实用技巧
来源:互联网 发布:波动大的数据预测方法 编辑:程序博客网 时间:2024/06/02 07:06
转载时请注明出处和作者联系方式
作者联系方式:会飞的鱼 <parker30_liu at hotmail dot com>
GNU的Makefile有强大的功能,我们一直都用Makefile控制整个项目的构建过程。在使用Makefile的过程中有些有时用了些技巧,记录在此,以备以后参考。
技巧一:根据Makefile的内容自动生成Makefile的变量。
在我们的工程中有着众多的模块,根据我们的使用和分析,大部分的模块使用同样的优化参数即可,但有些模块需要用另外的优化参数。因此可以在Makefile中设定一个Makefile变量,该变量保存了缺省的优化参数,赋值给每个模块的CFLAGS变量,给少数的几个模块的CFLAGS变量单独赋值。但我们的模块时常会有增加和减少,若手工维护这些变量很容易出错,导致有些模块的优化参数设置不对,影响性能和系统测试的结果。若能依赖Makefile自己根据模块列表自动生成每个模块的CFLAGS变量,并赋值为缺省的优化参数,就省事了。
我查看了GNU的Makefile手册,没有发现可以通过Makefile自身产生变量给自己用的方法。看来只好用文件的方法了,通过一个脚本文件根据模块生成变量及赋值表达式,将其写入一个新的Makefile中,然后在原来这个Makefile中通过include命令包含新的Makefile。
Makefile中的实现如下所示。
GEN_MODULES_FLAGS:=`. ./genmodflags.sh "$(ALL_MODULES)" > hw_defaultflags.mk`
include hw_defaultflags.mk
include com.mk
hw_defaultflags.mk: hw.mk
@eval $(GEN_MODULES_FLAGS);
脚本文件如下所示。
for MODULE in $1; do
MODULE=`echo $MODULE | tr [a-z]- [A-Z]_`
echo "${MODULE}_OPTIM_FLAGS?=$(BRONCHO_DEFAULT_OPTIM_FLAGS)"
done
因为GNU的Makefile具有两遍执行的特性,因此当第一遍执行时若没有hw_defaultflags.mk时,只是会报告错误,但仍然会根据规则产生hw_defaultflags.mk文件。在第二遍执行时将hw_defaultflags.mk包含进来,执行com.mk中的编译过程。
技巧二:使用Makefile的片断文件定制构建过程。
gcc的构建系统可以为多个目标构建gcc编译器,多种体系架构(ARM,X86,ALPHA,POWER,SPARC)和操作系统(linux,unix,BSD,cygwin,ecos,symbian)的目标现在都可以得到支持,具体的目标列表可以查看gcc的相关网站。每个目标的编译器都有一些和其他目标不同的构建过程的设置,如包含目标特定的文件、定义特定的编译条件等,这就需要有一个对各个目标的构建过程进行定制的方法。gcc 的构建系统是通过包含各个具体目标相关的Makefile片断文件的方法来实现的。
gcc的配置目录(gcc/config/)下保存了各个目标系统相关的Makefile片断文件,这些片断文件重新设置了构建过程的变量和独有的构建过程规则。下面是支持intel的iwmmx指令的gcc构建的Makefile片断文件(gcc/config/arm/t-iwmmxt-elf),这里的$(T)crti.o的规则就是该目标独有的构建过程规则。
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func
_call_via_rX _interwork_call_via_rX
_lshrdi3 _ashrdi3 _ashldi3
_negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi
_truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2
_fixsfsi _fixunssfsi _floatdidf _floatdisf _floatundidf _floatundisf
_unwind
MULTILIB_OPTIONS += mcpu=iwmmxt
MULTILIB_DIRNAMES += iwmmxt
MULTILIB_REDUNDANT_DIRS += interwork/thumb/iwmmxt=thumb
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
# If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here
# EXTRA_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
# Currently there is a bug somewhere in GCC's alias analysis
# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
# Disabling function inlining is a workaround for this problem.
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
# Assemble startup files.
$(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES)
-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/arm/crti.asm
$(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
gcc的configure(路径是gcc/configure)会执行gcc/config.gcc收集目标系统的具体规格信息,在该shell文件中,将目标系统使用的Makefile片断文件名加入到变量tmake_file中。然后gcc的Makefile用include指令将tmake_file中所有的Makefile片断文件包含进来,片断文件的变量设置和构建过程规则将在执行make命令时生效,从而构建出特定目标系统使用的gcc编译器。config.gcc中armlinux目标系统的相关代码如下所示。
tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h"
case ${target} in
arm*-iwmmxt-*)
tmake_file="${tmake_file} arm/t-iwmmxt-elf"
tm_file="${tm_file} arm/iwmmxt-linux-elf.h"
;;
*)
tmake_file="${tmake_file} arm/t-arm-elf"
tm_file="${tm_file} arm/linux-elf.h"
;; esac
tmake_file="${tmake_file} t-linux arm/t-arm"
case ${target} in
arm*-*-linux-gnueabi)
tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h"
tmake_file="$tmake_file arm/t-bpabi arm/t-linux-eabi"
# The BPABI long long divmod functions return a 128-bit value in
# registers r0-r3. Correctly modeling that requires the use of
# TImode.
need_64bit_hwint=yes
# The EABI requires the use of __cxa_atexit.
default_use_cxa_atexit=yes
;;
*)
tmake_file="$tmake_file arm/t-linux"
;;
esac
tm_file="$tm_file arm/aout.h arm/arm.h"
;;
- Makefile的几则实用技巧
- VIM的几则实用技巧
- iOS开发之NSString的几条实用技巧
- iOS开发之NSString的几条实用技巧
- 几步搞定makefile文件的编写
- Makefile 的几种赋值方式
- (杂记)Makefile的几种规则
- Makefile 的几种赋值方式
- DBGrid的实用技巧
- DBGrid的实用技巧
- mysql的几种超实用技巧
- vi的几个实用技巧
- Source Insight 的实用技巧
- SourceInsight的实用技巧
- SourceInsight的实用技巧
- 光电耦合器的实用技巧
- UltraEdit的实用技巧
- Source Insight 的实用技巧
- MBA案例分析(行销与营销之营销七)
- String 与 UTF8 之间的转换
- 《红雪莲》
- 不能说的秘密结局分析
- 2008瑞星杀毒软件试用板
- Makefile的几则实用技巧
- 软件维护大有文章
- CSDN会因我而更精彩!
- .Net常用快捷键收集
- 读“淘宝与禅”小记
- 五大内存分区
- sping+struts+hibernate+ajax配置
- C++中extern “C”含义深层探索
- 写给一家公司选型企业,希望这家公司能真正看到自己的不足