linux程序设计笔记9:make,makefile

 

第九章:开发工具。
1.多个源文件带来的问题:改动头文件后,就必须重新编译包含其的所有源文件。而make工具可以解决上述问题,它会在必要使重新编译所有受改动影响的文体。(没改动的就不编译)
2.make 命令需要配合 makefile来结合使用,才能达到最强大的功能。
3.如果是大型项目,我们可以通过多个不同的makefile文件来分别管理不同部分。
4.makefile的语法:
  1.makefile由一组依赖关系和规则构成。
  2.make命令会读取makefile文件的内容,它先确定目标文件或要创建的文件,然后比较该目标文件所依赖的源文件的日期和时间以决定该采取用哪条规则来构造目标。通常在建立最终目标之前,它需要建立一些中间目标。
 make命令选项和参数:
  1.make -k :make时,发现错误仍然继续执行,而不是检测到第一个错误时就停下来。你可以利用这个选项在一次操作中发现所有未编译成功的源文件。
  2.make -n :他的作用是要Make输出将要执行的步骤,而不是真正执行这些操作。
  3.make -f :指明要make的makefile文件名.不指明就默认找makefile or Makefile(大写可以排列在前面方便找)
  4.make xxx:为了指示make命令创建一个特定的目标,你可以把该目标的名字作为make命令的一个参数。make ab.o
  5.all:myobj all表示在没有指定的目标名的make命令上默认最终会生成什么目标。(其实默认就是第一个目标)

5.依赖关系写法:(写法是从最终目标生成写到最初目标建立)
  先写目标的名称,然后紧跟一个冒号,接着空格或tab制表符,最后是用空格分隔的依赖文件列表。mapp: main.o
6.规则写法:
  规则所在的行必须以制表符tab开头,用空格是不行的。(这是历史遗留问题,因为现在已经有大量的makefile文件存在),  如果Makefile文件中的某行以空格结尾,他也可能会导致make命令执行失败。
(make命令读取makefile文件,确定重建myapp所需的最少命令:最少命令哦。)
7.注释:#开头。
8.makefile中的宏:ABC=abc 通过$(ABC) or ${ABC} 来解开宏,如果要置空,那么=后面留空即可。
  宏经常用于设置编译器的选项:比如 gcc g++ cc 等。通过宏,然后往后只需要修改宏定义即可。改一改多。
  宏定义也是可以从文件外部传出来的:make CC=gcc or make "CC = gg"
9.一个模版:
 all: myapp

 #which compiler 哪个编译器
 CC = gcc

 #where are include files kept 当前目标
 INCLUDE = . 
 
 CFLAGS = -g -Wall -ansi
 
 myapp: main.o 2.o 3.o
 $(CC) -o myapp main.o 2.o 3.o

 main.o: main.c a.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c

 2.o: 2.c a.h b.h
 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
 .......

 clean:
  -rm main.o 2.o 3.o

 install: myapp
 @if [  ] &&\  # \表示使这些语句在同一个shell下执行,一起传递给shell,而非分行传过去。
  then &&\
  .....&&\  #  &&表示shell中的“与”:每个命令的前一个命令执行成功的情况下才会执行。
 fi

//调用: make -f Makefile3 ; make -f Makefile3 clean ; make -f Makefile3 install

10.make命令内置的宏定义:
 $?比目标文件还要新的文件  $@目标文件名 $<依赖文件名 $*不包括后缀的依赖文件名
11. makefile中用于行首的2个特殊符号:
 -:告诉make命令忽略所有错误。
 @: 告诉make在执行某条命令前不要将该命令显示在标准输出上面。
12.增加一个clean选项来删除不需要的目标文件,增加一个instll选择来将编译成功的应用程序安装到另一个目标下。

13.make内置推到规则: make -p 打印出所有内置规则。
 1. make foo : 则会自动去找foo.c文件,然后自动gcc -ofoo foo.c  考虑到这些规则,那么我们可以删去目标制作的规则,只需要定义目标依赖关系即可。
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h
 2.后缀和模式规则
 后缀:通过.c生成.o,这个规则。
    自定义后缀规则: .old.new ==> .cpp.o: 告诉了编译器,紧随其后的规则是用于将后缀为.cpp的文件
.cpp.o:
 $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<转换为后缀名为.o的文件。
 模式:%.cpp: %o 和上面的效果一致哦。
%.cpp: %o
 $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<

 3.用make管理函数苦:.a  .o 库文件
 .c.a:
   $(CC) -c $(CFLAGS) $<
   $(AR) $(ARFLAGS) $@ $* .o      // ar rv  这行则用ar命令将新的目标文件添加到函数库中。
告诉Make,从.c文件得到.a库文件。

例子:lib(file.o) 含义:是目标文件file.o是存储在函数库lib.a中的。
 MYLIB = mylib.a
 myapp: main.o $(MYLIB)
 $(CC) -o myapp main.o $(MYLIB)
 $(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h

二:高级主题:makefile文件的子目录
有时我们希望把构成一个函数库的几个文件从主文件中分离出来,并将他们保存到一个子目录中。
方法一:
mylib.a:
 (cd mydir;$(MAKE))
用()括起来,表示这2个命令在同一个shell中执行,因为第二个命令依赖于第一个切换好了目录的命令。
(在这个目录中找到Makefile文件,执行make命令,来生成mylib.a文件。)
或者:
方法二:通过宏,把文件名字给宏起来,达到替换效果。
mylib.a: mydir/2.o mydir/3.o
 ar -rv mylib.a $?


2.gnu make 和 gcc
1.make命令的-jN命令,它允许make命令同时执行N条命令。
 make -j3 自己试试呗。如果有许多源文件,那么值得一试。
2.gcc -MM选项
 产生一个适用于make命令的依赖关系清单。如果某个项目包含非常多的源文件,头文件相互包含,晕死了,那么我们使用这个东西,重定向到一个文件中,然后copy到makefile中,以保证包含正常和避免多次包含的效果。
gcc -MM main.c 2.c 3.c
 main.o: main.c a.h
 2.o: 2.c a.h b.h
 3.o: 3.c b.h c.h
 

你可能感兴趣的:(IT书籍笔记,makefile,linux,include,gcc,编译器,shell)