9/9
第九章:执行make
默认情况,在没有使用“-f ”(“--file ”或者“--makefile ”)指定文件时。make会在工作目录(当前目录)依次搜索命名为“GNUmakefile ”、“makefile”和“Makefile”的文件,最终解析执行的是这三个文件中首先搜索到的哪一个
9.2 指定终极目标
默认情况下,终极目标就是出现在Makefile中,除以点号“. ”(参考 4.9 Makefile的特殊目标 一节)开始的第一个规则中的第一个目标(如果第一个规则存在多个目标)
也可以通过命令行将一个Makefile 中的目标指定为此次make过程的终极目标,替代默认的终极目标,如make clean
部分标准的伪目标和空目标命名:
— all
作为Makefile 的顶层目标,一般此目标作为默认的终极目标。
— clean
这个伪目标定义了一组命令,这些命令的功能是删除所有由make创建的文件。
— mostlyclean
和“clean”伪目标功能相似。区别在于它所定义的删除命令不会全部删除由make
生成的文件。比如说不需要删除某些库文件。
— distclean
— realclean
— clobber
同样类似于伪目标“clean”,但它们所定义的删除命令所删除的文件更多。可以包
含非make创建的文件。例如:编译之前系统的配置文件、链接文件等。
— install
将make成功创建的可执行文件拷贝到shell 环境变量“PATH”指定的某个目录。
典型的,应用可执行文件被拷贝到目录“/usr/local/bin ”,库文件拷贝到目录
“/usr/local/lib”目录下。
打印出所有被更改的源文件列表。
— tar
创建一个tar 文件(归档文件包)。
— shar
创建一个源代码的shell文档(shar 文件)。
— dist
为源文件创建发布的压缩包,可以使各种压缩方式的发布包。
— TAGS
创建当前目录下所有源文件的符号信息(“tags ”)文件,这个文件可被 vim 使用。
— check
— test
Make 编译选项
man make 看去
第十章:make的隐含规则
“隐含规则”为make提供了重建一类目标文件通用方法,就是说你不定义它默认的方法。
10.2 make的隐含规则一览
1. 编译C程序
“N.o”自动由“N.c” 生成,执行命令为“$(CC) -c $(CPPFLAGS) $(CFLAGS)”。就是说什么程序生成什么文件
2. 编译C++ 程序
“N.o”自动由“N.cc”或者“N.C” 生成,执行命令为“$(CXX) -c $(CPPFLAGS) $(CFLAGS)”。建议使用“.cc ”作为C++ 源文件的后缀,而不是“.C”
10.3 隐含变量
内嵌隐含规则的命令中,所使用的变量都是预定义的变量。我们将这些变量称为“隐含变量”。
(就是默认的变量)
编译.c 源文件的隐含规则为:“$(CC) -c $(CFLAGS) $(CPPFLAGS)”。默认的编译命令是“cc”,执行的命令是:“ cc –c”。我们可以同上述的任何一种方式将变量“CC”定义为“ncc”,那么编译.c 源文件所执行的命令将是“ncc -c ”。同样我们可以对变量“CFLAGS”进行重定义。
10.3.1 代表命令的变量
默认变量值
AR
函数库打包程序,可创建静态库.a 文档。默认是“ar ”。
AS
汇编程序。默认是“as”。
CC
C编译程序。默认是“cc”。
CXX
C++ 编译程序。默认是“g++ ”。
CO
从 RCS 中提取文件的程序。默认是“co”。
CPP
C程序的预处理器(输出是标准输出设备)。默认是“$(CC) -E ”。
FC
编译器和预处理Fortran 和 Ratfor 源文件的编译器。默认是“f77 ”。
GET
从SCCS 中提取文件程序。默认是“get”。
LEX
将 Lex 语言转变为 C 或 Ratfo 的程序。默认是“lex ”。
PC
Pascal 语言编译器。默认是“pc”。
YACC
Yacc文法分析器(针对于C程序)。默认命令是“yacc”。
YACCR
Yacc文法分析器(针对于Ratfor程序)。默认是“yacc -r”。
MAKEINFO
转换Texinfo源文件(.texi )到Info 文件程序。默认是“makeinfo”。
TEX
从Te X 源文件创建Te X D V I 文件的程序。默认是“tex ”。
TEXI2DVI
从Texinfo源文件创建Te X D V I 文件的程序。默认是“texi2dvi ”。
WEAVE
转换Web到Te X 的程序。默认是“weave ”。
CWEAVE
转换C Web 到 Te X的程序。默认是“cweave”。
TANGLE
转换Web到Pascal 语言的程序。默认是“tangle ”。
CTANGLE
转换C Web 到 C。默认是“ctangle”。
RM
删除命令。默认是“rm -f”。
10.3.2 命令参数的变量
(参数的默认值)
下边的是代表命令执行参数的变量。如果没有给出默认值则默认值为空。
ARFLAGS
执行“AR”命令的命令行参数。默认值是“rv ”。
ASFLAGS
执行汇编语器“AS”的命令行参数(明确指定“.s ”或“.S ”文件时)。
CFLAGS
执行“CC”编译器的命令行参数(编译.c 源文件的选项)。
CXXFLAGS
执行“g++ ”编译器的命令行参数(编译.cc 源文件的选项)。
COFLAGS
执行“co”的命令行参数(在RCS中提取文件的选项)。
CPPFLAGS
执行C预处理器“cc -E”的命令行参数(C 和 Fortran 编译器会用到)。
FFLAGS
Fortran语言编译器“f77 ”执行的命令行参数(编译Fortran源文件的选项)。
GFLAGS
SCCS “get”程序参数。
LDFLAGS
链接器(如:“ld ”)参数。
LFLAGS
Lex 文法分析器参数。
PFLAGS
Pascal 语言编译器参数。
RFLAGS
Ratfor 程序的Fortran 编译器参数。
YFLAGS
Yacc文法分析器参数。
10.5 模式规则
标名中需要包含有模式字符“% ”(一个),包含有模式字符“% ”的目标被用来匹配一个文件名,“% ”可以匹配任何非空字符串。规则的依赖文件中同样可以使用“% ”,依赖文件中模式字符“% ”的取值情况由目标中的“% ”来决定。
例如:对于模式规则“%.o : %.c”,它表示的含义是:所有的.o 文件依赖于对应的.c 文件。我们可以使用模式规则来定义隐含规则。
10.5.3 自动化变量
模式规则的命令行中表示文件
下面对所有的自动化变量进行说明:
$@
表示规则的目标文件名。如果目标是一个文档文件在多目标模式规则中,它代表的是哪个触发规则被执行的目标文件名。
$%
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则的目标“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。如果目标不静态库文件,其值为空。
$<
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表由隐含规则加入的第一个依赖文件。
$?
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员(.o 文件)。
$^
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
$+
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。
$*
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考 10.5.4 模式的匹配 一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
自动化变量“$* ”需要两点说明:
对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发生改变。此时,如果目标文件名带有一个可识别的后缀(参考 10.7 后缀规则 一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避免使用这个变量。
当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量为空。
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
则实现了只将更新后的.o 文件加入到库中:
lib: foo.o bar.o lose.o win.o
ar r lib $?
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可
参考 8.3 文件名处理函数 一节)。
$(@D)
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函
数“dir”的区别!
$(@F)
目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir $@) ”。
$(*D)
$(*F)
分别代表目标“茎”中的目录部分和文件名部分。
$(%D)
$(%F)
当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。
$(
$(
分别表示规则中第一个依赖文件的目录部分和文件名部分。
$(^D)
$(^F)
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。
$(+D)
$(+F)
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。
$(?D)
$(?F)
分别表示被更新的依赖文件的目录部分和文件名部分。
讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
因为自动化变量本身是一个特殊字符。
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
自动化变量的这个古怪的特性完全是为了兼容Sysv 版本的makefile文件。在使用
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一
特性。
当模式规则的目标只是一个模式字符“% ”(它可以匹配任何文件名)时,我们称这个规则为万用规则
之前的目标文件都是最终目标都是可执行文件,或者是动态库
用gcc -o或-c生成,这一章讲的是生成静态库,那么当然要用ar工具来管理生成
具体的去看下man
1. 所有的Makefile 中应该包含这样一行:
SHELL = /bin/sh
其目的是为了避免变量“SHELL”在有些系统上可能继承同名的系统环境变量而导致错误。
2. 小心处理后缀和隐含规则。不同make 可识别后缀和隐含规则可能不同,它可能会导致混乱或者错误。因此在特定Makefile 中明确限定可识别的后缀是一个不错的主意。在Makefile 中应该这样做:
.SUFFIXES:
.SUFFIXES: .c .o
第一行首先取消掉make默认的可识别后缀列表,第二行重新指定可识别的后缀列表
3. 小心处理规则中的路径。当需要处理指定目录的的文件时,应该明确给出路径。如“./ ”代表当前目录,“$(srcdir) ”代表源代码目录。没有指定明确路径,那么就意味着是当前目录。
目录“./ ”(当前目录, GNU的发布软件包中的“build”目录)和“$(srcdir) ”的区别和重要。 我们可以通过“configure”脚本的选项“--srcdir”指定源代码所在的目录(可参考 GNU发布的软件包中的configure脚本)。当源代码目录和build目录不同时,规则:
foo.1 : foo.man sedscript
sed –e sedscript foo.man > $@
4. 使用GNU make 的变量“VPATH”指定搜索目录。当规则只有一个依赖文件时。
应该使用自动化变量“$<”和“$@ ”代替出现在命令的依赖文件和目标文件
1. 书写Makefile 时,规则的命令(包括其他的脚本文件,如:configure)应该是“sh”而不是“csh ”所支持的。
2. 用于创建和安装的“configure”脚本以及Makefile 中的命令,除使用下面所列出的之外,避免使用其它命令:
cat cmp cp diff echo egrep expr false grep install-info
ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
3. 在目标“dist ”的命令行中可以使用压缩工具“gzip ”。
4. 对于可使用的这些工具命令,尽量使用它的通用选项。不要使用那些只在特定系统上有效的选项。如:“mkdir -p”这个命令在 Linux 系统上能够很好的工作,但是其它很多系统却并不支持“mkdir”的“-p ”选项。
5. 尽量不要在规则的命令行中创建符号连接文件(使用“ln ”命令)。因为有些系统不支持符号连接文件(对于类 Unix的系统我们基本上没有问题,可能这里所说的是MS-DOS系统的系统。我想大家也没有兴趣或者说没有必要在MS-DOS下写Makefile,所以这个限制基本可以不考虑)。
6. 重建或者安装目标(一般是伪目标)的命令行可使用编译器或者相关工具程序,这些命令使用一个变量来表示。这样做的好处是:当修改一个命令时,只需要更改代表命令的变量的值就可以了。对于以下的这些命令程序:
ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc
在规则中的命令中,使用以下这些变量来代表它们:
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG)$(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
prefix
这个变量(通常作为实际文件安装目录的父目录,可以理解为其它实际文件安装目录的前缀)用于构造下列(除这两个安装根目录以外的其它目录变量)变量的缺省值。变量“prefix”缺省值是“/usr/local”
exec_prefix
这个前缀用于构造下列变量的缺省值。变量“exec_prefix”缺省值是“$(prefix) ”
bindir
用于安装一般用户可运行的可执行程序。通常它的值为:“/usr/local/bin ”,使用时应写为:“$(exec_prefix)/bin ”。 (使用“Autoconf ”工具时,应该为“@bindir@”)
sbindir
安装可在shell中直接调用执行的程序。这些命令仅对系统管理员有用(系统管理
工具)。通常它的值为:“/usr/local/sbin ”,要求在使用时应写为:“$(exec_prefix)/sbin”。(使用“Autoconf ”工具时,应该为“@sbindir@”)
ibexecdir
用于安装那些通常不是由用户直接使用,而是由其它程序调用的可执行程序。通常它的值为:“/usr/local/libexec ”,要求在使用时应写为:“$(exec_prefix)/libexec ”。(使用“ Autoconf ”工具时,应该为“ @libexecdir@”)
datadir
用于安装和机器体系结构无关的只读数据文件。通常它的值为:“/usr/local/share ”,使用时应写为:“$(prefix)/share”。(使用“Autoconf ”工具时,应该为“@datadir@”)。“$(infodir) ”和“$(includedir)”作为例外情况,参考后续对它们的详细描述。
sysconfdir
用于安装从属于特定机器的只读数据文件,包括:主机配置文件、邮件服务、网络配置文件、“/etc/passwd”文件等。所有该目录下的文件都应该是普通文本文件(可识别的“ASCII”码文本文件)。通常它的值为:“/usr/local/etc ”,在使用时应写为:“$(prefix)/etc ”。(使用“ Autoconf ”工具时,应该为“@sysconfdir@”)。
sharedstatedir
用于安装那些可由程序运行时修改的文件,这些文件与体系结构无关。通常它的
值为:“/usr/local/com”,要求在使用时应写为:“$(prefix)/com ”。 (使用
“Autoconf ”工具时,应该为“@sharedstatedir@”)
libdir
用于存放编译后的目标文件(.o )文件库文件(文档文件或者执行的共享库文件)。不要在此目录下安装可执行文件(可执行文件应该安装在目录“$(libexecdir)”下)。变量libdir值通常为:“/usr/local/lib”,使用时应写为:“ $(exec_prefix)/lib ”。(使用“Autoconf ”工具时,应该为“@libdir@”)
infodir
用于安装软件包的 Info 文件。它的缺省值为:“/usr/local/info ”,使用时应写为:“$(prefix)/info”。(使用“Autoconf ”工具时,应该为“@infodir@”)
lispdir
用于安装软件包的Emacs Lisp 文件的目录。它的缺省值为:“ /usr/local/share/emacs/site-lisp ”,使用时应写为:“$(prefix)/share/ emacs/site-lisp ”。
includedir
用于安装用户程序源代码使用“#include ”包含的头文件。它的缺省值为:
“/usr/local/include ”,使用时应写为:“ $(prefix)/include”。 (使用“Autoconf ”
工具时,应该为“@includedir@”)。
除gcc外的大多数编译器不会在目录“/usr/local/include ”中搜寻头文件,因此这种方式只适用gcc编译器。这一点应该不是一个问题,因为很多情况下一些库需要gcc才能工作。对那些依靠其它编译器的库文件,需要将头文件安装在两个地方,一个由变量 “includedir ”指定,另一个由变量“oldincludedir ”指定。
oldincludedir
它所指定的目录也同样用于安装头文件,这些头文件用于非gcc的编译器。它的
缺省值为:“/usr/include ”。(使用“ Autoconf ”工具时,应该为
“@oldincludedir@”)。
mandir
安装该软件包的帮助文档(如果有)的顶层目录。它的缺省值为:“/usr/local/man”,要求在使用时应写为:“ $(prefix)/man ”。 (使用“Autoconf ”工具时,应该为“@@mandir@@”)
man1dir
用于安装帮助文档的第一节(man 1)。它的缺省值为:“$(mandir)/man1”。
man2dir
用于安装帮助文档的第二节(man 2)。它的缺省值为:“$(mandir)/man2”。
manext
文件名扩展字,它是对安装手册的扩展。以点号(. )开始的十进制数。缺省值为:“.1 ”。
man1ext
帮助文档的第一节(man 1)的文件名扩展字。
man2ext
帮助文档的第二节(man 2)的文件名扩展字。
...
当一个软件包的帮助手册有多个章节时,使用这些变量代替“manext”。(第一节“man1ext”,第二节“man2ext”,第三节“man3ext”……)
srcdir
此变量指定的目录是需要编译的源文件所在的目录。该变量的值在使用“configure”脚本对软件包进行配置时产生的。(使用“Autoconf ”工具,应该书写为“srcdir = @srcdir@”)
例如:
# 安装的普通目录路径前缀。
# 注意:该目录在开始安装前必须存在
prefix = /usr/local
exec_prefix = $(prefix)
# 放置“gcc ”命令使用的可执行程序
bindir = $(exec_prefix)/bin
# 编译器需要的目录
libexecdir = $(exec_prefix)/libexec
# 软件包的Info 文件所在目录
infodir = $(prefix)/info
在用户标准指定的目录下安装大量文件时,可以将这些文件分类安装在指定目录的多个子目录下。可以在 Makefile 中实现一个“install ”伪目标来描述安装这些文件的命令(包括创建子目录,安装文件到对应的子目录中)。 在发布的软件包中,不能强制要求用户必须指定这些安装目录的变量。使用一套标准的安装目录变量来指定安装目录,当用户需要指定安装目录时,通过修改变量定义来指定具体的目录,在用户没有指定的情况下,使用默认的目录。
all
此目标的动作是编译整个软件包。
install
此目标的动作是完成程序的编译并将最终的可执行程序、库文件等拷贝到安装的目录。如果只是验证这些程序是否可被正确安装,它的动作应该是一个测试安装动作。
uninstall
删除所有已安装文件——由install 创建的文件拷贝。规则所定义的命令不能修改编译目录下的文件,仅仅是删除安装目录下的文件
install-strip
和目标install 的动作类似,但是install-strip 指定的命令在安装时对可执行文件进行strip (去掉程序内部的调试信息)。它的定义如下:
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
一般不建议安装时对可执行文件进行strip ,因为去掉可执行文件的调试信息后,如果在程序中存在bug ,就不能通过gdb 对程序进行调试。
clean
清除当前目录下编译生成的所有文件,这些文件在make过程中产生。注意,clean动作不能删除软件包的配置文件
distclean
类似于目标clean,但增加删除当前目录下的的配置文件、build过程产生的文件。(Android里以前用到)目标“distclean ”指定的删除命令应该删除软件包中所有非发布文件。
mostlyclean
类似于目标“clean”,但是可保留一些编译生成的文件,避免在下次编译时对这些文件重建。例如,对于gcc 来说,此目标指定的命令不删除文件“libgcc.a ”,因为在绝大多数情况下它都不需要重新编译。
maintainer-clean
此目标所定义的命令几乎会删除所有当前目录下能够由Makefile重建的文件。典型的,包括目标“distclean ”删除的文件、由Bison生成的.c 源文件、tags 记录文件、Ifon 文件等。但是有一个例外,就是执行“make maintainer-clean”不能删除“configure”这个配置脚本文件
TAGS
此目标所定义的命令完成对该程序的tags 记录文件的更新。tags 文件通常可被编辑器作为符号记录文件,例如vim ,Emacs等。
info
产生必要的Info 文档。此目标应该按照如下书写:
info: foo.info
foo.info: foo.texi chap1.texi chap2.texi
$(MAKEINFO) $(srcdir)/foo.texi
必须在Makefile中定义变量“MAKEINFO”,代表命令工具makeinfo,该工具是发布软件Te x i n f o的一部分。
dvi
为所有的Te x i n f o文件创建对应的DVI文件。例如:
dvi: foo.dvi
foo.dvi: foo.texi ch ap1.texi chap2.texi
$(TEXI2D VI) $(srcdir)/foo.texi
必须在Makefile中定义变量“TEXI2DVI”。它代表命令工具texi2dvi ,该工具是发布软件Texinfo一部分。
dist
此目标指定的命令创建发布程序的tar文件。创建的tar文件应该是这个软件包的目录,文件名中也可以包含版本号
check
此目标指定的命令完成所有的自检功能。在执行检查之前,应确保所有程序已经被创建,可以不安装。为了对它们进行测试,需要实现在程序没有安装的情况下被执行的规则命令
installcheck
执行安装检查。在执行安装检查之前,确保所有程序已经被创建并且被安装。需要注意的是:安装目录“$(bindir) ”是否在搜索路径中
installdirs
使用目标“installdirs”创建安装目录以及它的子目录在很多场合是非常有用的。脚本“mkinstalldirs”就是为了实现这个目的而编写的;发布的Texinfo软件包中就包含了这个脚本文件。Makefile中的规则可以这样书写:
# 确保所有安装目录(例如 $(bindir))存在,如有必要则创建这些目录
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
$(libdir) $(infodir) \
$(mandir)
在为Makefile 书写“install ”目标时,需要将其命令分为三类:正常命令、安装前命令和安装后命令。
种可能的分类行,以及它们的解释:
$(PRE_INSTALL) # 以下是安装前命令
$(POST_INSTALL) # 以下是安装后命令
$(NORMAL_INSTALL) # 以下是正常命令
对应的,以下这三个是“uninstall ”命令的分类行:
$(PRE_UNINSTALL) # 以下是卸载前命令
$(POST_UNINSTALL) # 以下是卸载后命令
$(NORMAL_UNINSTALL) # 以下是正常命令
10.5.5 万用规则
第十一章:使用make更新静态库文件
第十四章 Makefile的约定
14.1 基本的约定
14.2 规则命令行的约定
14.4 安装目录变量
文件(包括可执行程序、说明文档等)的安装目录:
在Makefile 中应该使用以下变量为不同类型的文件指定对应的安装目录:
Unix 风格的帮助文件需要安装在以下目录中:
下列这些变量也应该在Makefile 中定义:
14.5 Makefile的标准目标名
14.6 安装命令分类