makefile FAQ——跟着陈皓写makefile

***********************************************

local OS :xp(SP3) 

VM OS: ubuntu-10.04.2

kernel: 2.6.32-41-generic

VM:VMware-workstation-7.1.4

***********************************************


Q1. =  , :=, +=, ?= 的区别

 Q:在看mk脚本的时候经常有看到 := ,+=,容易混淆,这四者间什么区别呢。

 A:   稍微解释一下,在结合实例看看

      = 是最基本的赋值
:= 是覆盖之前的值 ?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值

对于“=”,make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:

equal.mk

            x = foo
            y = $(x) bar
            x = xyz

对于    “:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。只用于已经定义过的变量,否则这个变量将会不存在。

colonequal.mk
            x := foo
            y := $(x) bar
            x := xyz

对于最终y的值来说:equal.mk 来说 y的结果就是xyzbar     colonequal.mk中有的结果是foobar 


Q2. missing separator.  Stop.

跟着大牛的博文敲了一遍makefile 的template,

 edit : main.o kbd.o command.o display.o /
	insert.o search.o files.o utils.o
	cc -o edit main.o kbd.o command.o display.o /
	insert.o search.o files.o utils.o

    main.o : main.c defs.h
	cc -c main.c
    kbd.o : kbd.c defs.h command.h
	cc -c kbd.c
    command.o : command.c defs.h command.h
	cc -c command.c
    display.o : display.c defs.h buffer.h
	cc -c display.c
    insert.o : insert.c defs.h buffer.h
	cc -c insert.c
    search.o : search.c defs.h buffer.h
	cc -c search.c
    files.o : files.c defs.h buffer.h command.h
	cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
	rm edit main.o kbd.o command.o display.o /
	insert.o search.o files.o utils.o


结果运行了一下,很多的文件找不到,当然了我的test1文件夹下只有一个main。和Makefile,所以找不到其他的文件了,于是我的改改

Makefile

OBJS = main.o 
edit : $(OBJS) 
	cc -o edit $(OBJS)
#OBJS = main.o kdb.o command.o display.o insert.o /
#	 search.o file.o util.o 
#edit : $(OBJS)
#        cc -o edit main.o kdb.o command.o display.o /
#        insert.o search.o file.o util.o
main.o : main.c defs.h
	cc -c main.c

kdb.o : kdb.c defs.h
	cc -c kdb.c

command.o : command.c defs.h command.h
	cc -c kdb.c

display.o : display.c defs.h buffer.h
	cc -c display.c

search.o : search.c defs.h buffer.h
	cc -c search.c

file.o : file.c defs.h buffer.h command.h
	cc -c files.c

utils.o : utils.c defs.h
	cc -c utils.c

.PHONY:clean
	clean :
	rm edit $(OBJS) 


main.c

#include

int main()
{
	printf("hello, my makefile study \n");
	return 0;
}

另外加个defs.h,好了,运行make 在执行 edit完可以显示了

hello, my makefile study


Q2: missing separator.  Stop

A2 :好吧,第二行没有没有分隔符,加上,再运行一次,额问题二出现

Makefile:4: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.

Q3:did you mean TAB instead of 8 spaces

A3: 好吧是我贱,一定要用VIM编辑,换其他编辑器多好,没把Tab 退格设置成4位。 :set tabstop=4

Q4:make: `edit' is up to date.

分析: edit是我的target ,之前好好的怎么会提示呢。我看了一下生成的时间,好像edit有问题!!!之前做的操作有(1)修改Makefile中内容,(2)修改Makefile 名字为makefile,因为ubuntu下终端中好像对大小写感冒。每次要切换输入"M"着实难受呀,就给改了。

A:于是做了几个实验发现结论:

如果之前没删除的生成的文件的话,修改Makefile文件内容,在执行时会提示文件更新的问题,这一点本来在使用伪目标文件.PHONY应该会解决(GNU官网解释:A phony target should not be a prerequisite of a real target file; if it is, its recipe will be run every time make goes to update that file. As long as a phony target is never a prerequisite of a real target, the phony target recipe will be executed only when the phony target is a specified goal (see Arguments to Specify the Goals)),好像并没有解决。


Q5:makefile 的注释

A5:makefile的注释只有“#” 不要去用// 。

 

Q6:$(subst \,/ ,$(PATH))      

A6:经常看到这样一句,subst是makefile中的替换函数,原型是 $(subst

,, ),将text中的“from”字符替换为“to"字符。$(subst \,/ ,$(PATH))    是将PATH中的路径分隔符改成"/".makefile中的路径分隔符是 “/”


Q7:输出$(shell echo "error error..." >&2)

A7: 在shell下 

0:标准输入
1:标准输出
2:标准错误
>&2
将前面的重定向为标准错误,也就是把“ error error ...”作为错误来输出。


Q8 :make: `edit' is up to date.

分析:我按着Q2的脚本改过之后虽然能运行了,但是发现我在没有修改任何文件的情况下,重复执行

make
这个时候总会很扫兴的给出提示。

make: `edit' is up to date.
A8:



你可能感兴趣的:([编程语言]脚本语言)