工程Makefile中常用符号

Makefile中常见内容

TOPDIR	:= $(shell /bin/pwd)
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
	            else if [ -x /bin/bash ]; then echo /bin/bash; \
	            else echo sh; fi ; fi)
export	CONFIG_SHELL TOPDIR

include Makefile.param

ifeq (y,${cplrec})
	RECFLAGS := >> $(TOPDIR)/$(TARGET_DIR)/$(RECORDFILE) 2>&1
else
	RECFLAGS := 
endif

makefile中 = ,:=,+=有怎么区别?

  = 是最基本的赋值
  := 是覆盖之前的值
  ?= 是如果没有被赋值过就赋予等号后面的值
  += 是添加等号后面的值
  1、“=”
  make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
  x = foo
y = $(x) bar
x = xyz
  在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
  2、“:=”
  “:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
  x := foo
y := $(x) bar
x := xyz
  在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

Makefile_vivi--$$BASH,if -x filename

1、$$BASH 表示BASH完整路径。环境变量指定。

2、if [ -x "$$BASH" ]  then.. else.. fi

3、Makefile中make版export,通常是用来向后起的make进程(这些后起的make进程由当前的make进程启动)传送变量。

make 2>&1

表示的是文件描述符。0 stdin,1 stdout,2 stderr.

2>&1,表示标准错误重定向到标准输出

-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code)  则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

	$(CC) $(CFLAGS) -o $(TOPDIR)/lib/mgi_lib/libiale_custom.so -fPIC -shared $(TOPDIR)/src/custom_minigui.c

PIC使.so文件的代码段变为真正意义上的共享。如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置。

$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。

Makefile.param中的常见内容

交叉编译内核设置

在默认情况下,内核构建系统默认内核是本地编译,即编译的内核是运行在与宿主系统相同的体系架构上。如果是为其他的架构编译内核,即交叉编译,我们需要设置两个变量:ARCH和CROSS_COMPILE。其中:

ARCH指明目标体系架构,即编译好的内核运行在什么平台上,如x86、arm或mips等。

CROSS_COMPILE指定使用的交叉编译器的前缀。对于我们的交叉工具链来说,其前缀是CROSS_COMPILE = arm-hisiv300-linux-

在顶层的Makefile中,我们可以看到工具链中的编译器、链接器等均以$(CROSS_COMPILE)作为前缀:

AS		= $(CROSS_COMPILE)as
LD		= $(CROSS_COMPILE)ld
CC		= $(CROSS_COMPILE)gcc
CP		= $(CC) -E
AR		= $(CROSS_COMPILE)ar
NM		= $(CROSS_COMPILE)nm
STRIP	= $(CROSS_COMPILE)strip
RM		= rm -f

 $(foreach <var>,<list>,<text>)

L_DIR = $(foreach dir,$(LIB_DIR),-L$(TOPDIR)/$(dir))

-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
-L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
 -lworld表示在上面的lib的路径中寻找libworld.so动态库文件(如果gcc编译选项中加入了“-static”表示寻找libworld.a静态库文件)
这个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,然后再执行< text>;所包含的表达式。每一次<text>;会返回一个字符串,循环过程中,<text>;的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>;所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
所以,<var>;最好是一个变量名,<list>;可以是一个表达式,而<text>;中一般会使用<var>;这个参数来依次枚举<list>;中的单词。举个例子:
    names := a b c d
    files := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
注意,foreach中的<var>;参数是一个临时的局部变量,foreach函数执行完后,参数<var>;的变量将不在作用,其作用域只在foreach函数当中。

# standard CFLAGS

CFLAGS := -fPIC 
CFLAGS += -Wall
CFLAGS += $(foreach dir,$(INCL_DIR),-I$(TOPDIR)/$(dir))
CFLAGS += -DHAVE_CONFIG_H -DVOIP

-Wall:选项可以打印出编译时所有的错误或者警告信息。这个选项很容易被遗忘,编译的时候,没有错误或者警告提示,以为自己的程序很完美,其实,里面有可能隐藏着许多陷阱。变量没有初始化,类型不匹配,或者类型转换错误等警告提示需要重点注意,错误就隐藏在这些代码里面。没有使用的变量也需要注意,去掉无用的代码,让整个程序显得干净一点。下次写Makefile的时候,一定加-Wall编译选项。

CFLAGS 表示用于 C 编译器的选项,
CXXFLAGS 表示用于 C++ 编译器的选项。
这两个变量实际上涵盖了编译和汇编两个步骤。

CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include -I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。

# standard LDFLAGS

LDFLAGS := $(LIBS)

LDFLAGS:gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLAGS=-Wl,-rpath,/mnt/system/mtbsystem/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。如果明明安装了某个包,而安装另一个包时,它愣是说找不到,可以抒那个包的lib路径加入的LDFALGS中试一下。

LIBS:告诉链接器要链接哪些库文件,如LIBS = -lrt -lpthread -lm -lstdc++ -lcurl -ldl

简单地说,LDFLAGS是告诉链接器从哪里寻找库文件,而LIBS是告诉链接器要链接哪些库文件。不过使用时链接阶段这两个参数都会加上,所以你即使将这两个的值互换,也没有问题。

有时候LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R"
 

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值