makefile吧 关注:105贴子:186
  • 13回复贴,共1

【新手必看】Makefile大百科

只看楼主收藏回复

1L空白


1楼2013-12-26 10:53回复
    一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。


    2楼2013-12-26 10:53
    回复
      2025-06-15 14:52:23
      广告
      1定义和概述
      Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix程序员。在 Linux(unix )环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。所要完成的Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要得可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。而且在Makefile 中可以使用系统shell所提供的任何命令来完成想要的工作。Makefile(在其它的系统上可能是另外的文件名)在绝大多数的IDE 开发环境中都在使用,已经成为一种工程的编译方法。


      3楼2013-12-26 10:54
      回复
        2.自动化编译
        makefile(3张) makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。


        4楼2013-12-26 10:55
        回复
          3主要功能
          Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。在 UNIX 系统中,习惯使用 Makefile 作为 makefile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:


          5楼2013-12-26 10:55
          回复
            Makefile的规则
            让我们先来粗略地看一看Makefile的规则。[2]target ... : prerequisites ...command......目标:依赖执行指令 ...target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。① prerequisites就是,要生成那个target所需要的文件或是目标。② command也就是make需要执行的命令。(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行(command一定要以Tab键开始,否者编译器无法识别command),减少重复编译,提高了其软件工程管理效率。


            7楼2013-12-26 10:57
            回复
              文件定义与命令Makefile文件作为一种描述文档一般需要包含以下内容:◆宏定义
              ◆ 源文件之间的相互依赖关系◆ 可执行的命令Makefile中允许使用简单的宏指代源文件及其相关编译信息,在Linux中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。


              8楼2013-12-26 10:58
              回复
                有效的宏引用$(CFLAGS)$Z$(Z)其中最后两个引用是完全一致的。需要注意的是一些宏的预定义变量,在Unix系统中,$*、$@、$?和$<四个特殊宏的值在执行命令的过程中会发生相应的变化,而在GNU make中则定义了更多的预定义变量。关于预定义变量的详细内容,宏定义的使用可以使我们脱离那些冗长乏味的编译选项,为编写makefile文件带来很大的方便。# Define a macro for the object filesOBJECTS= filea.o fileb.o filec.o# Define a macro for the library fileLIBES= -LS# use macros rewrite makefileprog: $(OBJECTS)cc $(OBJECTS) $(LIBES) -o prog……---------------------------------------------------------


                9楼2013-12-26 10:58
                回复
                  2025-06-15 14:46:23
                  广告
                  此时如果执行不带参数的make命令,将连接三个目标文件和库文件LS;但是如果在make命令后带有新的宏定义:make "LIBES= -LL -LS" #如何实现?则命令行后面的宏定义将覆盖makefile文件中的宏定义。若LL也是库文件,此时make命令将连接三个目标文件以及两个库文件LS和LL。在Unix系统中没有对常量NULL作出明确的定义,因此我们要定义NULL字符串时要使用下述宏定义:STRINGNAME= //这里有待考证makefile 中的变量(宏)GNU 的 make 工具除提供有建立目标的基本功能之外,还有许多便于表达依赖性关系以及建立目标的命令的特色。其中之一就是变量或宏的定义能力。如果你要以相同的编译选项同时编译十几个 C 源文件,而为每个目标的编译指定冗长的编译选项的话,将是非常乏味的。但利用简单的变量定义,可避免这种乏味的工作:# Define macros for name of compilerCC = gcc# Define a macr o for the CC flagsCCFLAGS = -D_DEBUG -g -m486# A rule for building a object filetest.o: test.c test.h$(CC) -c $(CCFLAGS) test.c在上面的例子中,CC 和 CCFLAGS 就是 make 的变量。GNU make 通常称之为变量,而其他 UNIX 的 make 工具称之为宏,实际是同一个东西。在 makefile 中引用变量的值时,只需变量名之前添加 $ 符号,如上面的 $(CC) 和 $(CCFLAGS)。GNU make 有许多预定义的变量,这些变量具有特殊的含义,可在规则中使用。表 13-2给出了一些主要的预定义变量,除这些变量外,GNU make 还将所有的环境变量作为自己的预定义变量。表 13-2 GNU make 的主要预定义变量


                  10楼2013-12-26 10:58
                  回复
                    预定义变量含义$*不包含扩展名的目标文件名称。$+所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。$<第一个依赖文件的名称。$?所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。$@目标的完整名称。$^所有的依赖文件,以空格分开,不包含重复的依赖文件。$%如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为(image.o),则 $@ 为 ,而 $% 为 image.o。AR归档维护程序的名称,默认值为 ar。ARFLAGS归档维护程序的选项。AS汇编程序的名称,默认值为 as。ASFLAGS汇编程序的选项。CCC编译器的名称,默认值为 cc。CFLAGSC编译器的选项。CPPC 预编译器的名称,默认值为 $(CC) -E。CPPFLAGSC预编译的选项。CXXC++编译器的名称,默认值为 g++。CXXFLAGSC++编译器的选项。FCFORTRAN编译器的名称,默认值为 f77。FFLAGSFORTRAN编译器的选项。


                    11楼2013-12-26 10:59
                    回复
                      Makefile以文件名:文件名的形式比较冒号右边的文件是不是较左边的文件有更新,如果有更新则执行下一行的程序代码。因此Makefile可以把文件关联起来


                      12楼2013-12-26 10:59
                      回复





                        ----------------------------------以上内容来自百科Makefile词条-------------------------------------


                        13楼2013-12-26 11:01
                        回复
                          高一狗路过


                          IP属地:浙江来自Android客户端14楼2015-02-28 19:18
                          回复
                            楼主问你一个Makefile的问题呀?
                            # sample Makefile
                            PROGRAMS = server client
                            server_OBJS = server.o server_priv.o server_access.o
                            server_LIBS = priv protocol
                            client_OBJS = client.o client_api.o client_mem.o
                            client_LIBS = protocol
                            # Everything after this is generic
                            .PHONY: all
                            all: $(PROGRAMS)
                            define PROGRAM_template
                            $(1): $$($(1)_OBJ) $$($(1)_LIBS:%=-l%)
                            ALL_OBJS += $$($(1)_OBJS)
                            endef
                            $(1): $$($(1)_OBJ) $$($(1)_LIBS:%=-l%)
                            理面的$(1)是指哪个呀?大侠,请赐教呀?求呀!!!!!!!


                            15楼2015-10-08 15:10
                            回复