乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      怎樣編寫Makefile文件 - Moose W. Oler的日志 - 網(wǎng)易博客

       enrol 2010-12-13

      怎樣編寫Makefile文件

      Debian 2009-03-19 15:48:50 閱讀408 評論3   字號: 訂閱

      引言:makefile入門讀本,有些翻譯拿不準的保留原文。原作者的行文結(jié)構(gòu)可能不太好理解,待全部驗證后會根據(jù)自己的使用經(jīng)驗調(diào)整內(nèi)容的布局。
      轉(zhuǎn)載請注明出處。
      ==========================================================================
      怎樣編寫Makefile文件

      原作者 : anonymous
      譯者 : Moose W. Oler (原文部分修改)
      參考 : Make and Makefiles by Reg Quinton
      原文鏈接:http://www.hsrl./ug/make_help.html
      ==========================================================================
      1. 介紹
      在使用Debian GNU/Linux的過程中,我們會經(jīng)常用到(有意或無意識的)make工具。
      make是UNIX自帶的,最初由AT&T貝爾實驗室的S.I. Feldman在1975年完成。
      不過現(xiàn)在也有GNU版本(public domain versions)和其他系統(tǒng)的版本(例如:Vax/VMS)。
      相關(guān)工具有編譯器(如cc,f77,lex,yacc等)和shell編程工具(awk,sed,cp,rm等)
      在閱讀本文之前,作為背景知識,你需要知道如何使用以上工具。

      重要的輔助工具:
      lint(源碼錯誤檢查工具)
      ctags(可在源程序內(nèi)定位函數(shù))
      mkdepand
      它們的功能都很強大,很多優(yōu)秀的程序員在使用它們。

      重要的相關(guān)工具:
      SCCS(Source Code Control System源代碼控制系統(tǒng))
      RCS(Revision Control System軟件修訂控制系統(tǒng),推薦使用)
      使用它們的目的在于自動完成并且優(yōu)化程序/文件的結(jié)構(gòu),也就是說要留下足夠多的信息,以便在其他人閱讀
      源代碼的時候能夠較輕松的理解。

      ==========================================================================
      2.Makefile的命名
      make在運行的時候,默認的是先查找叫做Makefile配置文件,如果沒找到再找叫做makefile的文件。盡量使用
      Makefile這個名字(你不覺得ls的時候,Makefile要比makefile突出嗎?)

      You can get away without any Makefile (but shouldn't)!
      make有它自己默認的"rules"(rules這個關(guān)鍵詞很重要,所以不翻譯)。

      ==========================================================================
      3.Makefile組成部分

      3.1 注釋Comments
      以井號(#)開始的文本部分,被視為注釋。
      注釋可以從一行的任意點開始,直到行尾。
      例如:
      # $Id: slides,v 1.2 1992/02/14 21:00:58 reggers Exp $

      3.2 宏Macros
      make有一個簡單的宏定義和替換系統(tǒng)。
      在Makefile中,宏定義是一個等號對。
      例如:
      MACROS= -me
      PSROFF= groff -Tps
      DITROFF= groff -Tdvi
      CFLAGS= -O -systype bsd43
      系統(tǒng)中有很多默認的宏——你應(yīng)該遵循已有的宏命名約定。
      要查看現(xiàn)有的rules/macros,使用如下命令:
      % make -p
      注意:如果將環(huán)境變量作為宏,export到make里使用,它會覆蓋原有的宏。

      也可以在命令行中定義宏:
      % make "CFLAGS= -O" "LDFLAGS=-s" printenv cc -O printenv.c -s -o printenv

      3.3 目標Targets
      當你make一個特定目標的時候(比如說make all), 如果沒指定make的順序話,將從makefile的第一個開始make:
      paper.dvi: $(SRCS)
      $(DITROFF) $(MACROS) $(SRCS) >paper.dvi
      注意:第二行以TAB開始,而不是空格(雖然看起來一樣)。

      如果target依賴的文件發(fā)生了變化,target就會被執(zhí)行。
      上邊例子中的依賴文件是由$(SRC)語句指定的部分。

      3.4 行的格式Continuation of Lines
      在macros或rules非常長的時候,可以分開多行寫,每行結(jié)尾以“\”結(jié)束。

      3.5 常用宏Conventional Macros
      有很多默認的宏(使用“make -p”查看)。
      Most are pretty obvious from the rules in which they are used:
      AR = ar
      GFLAGS =
      GET = get
      ASFLAGS =
      MAS = mas
      AS = as
      FC = f77
      CFLAGS =
      CC = cc
      LDFLAGS =
      LD = ld
      LFLAGS =
      LEX = lex
      YFLAGS =
      YACC = yacc
      LOADLIBS =
      MAKE = make
      MAKEARGS = 'SHELL=/bin/sh'
      SHELL = /bin/sh
      MAKEFLAGS = b

      3.6 特殊宏Special Macros
      在嘗試寫自己的makefile之前,還需要了解一些特殊的宏:
      1. $@ —— 正在被made的文件名
      2. $? —— 有改動的依賴文件的文件名
      例如,這個rule:
      printenv: printenv.c
      $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@
      也可以這樣寫:
      printenv: printenv.c
      $(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

      還有兩個特殊的宏,它們用在隱式rule中:
      1. $< 引起此行為的相關(guān)文件名
      2. $* 由target和依賴文件共用的前綴

      3.7 Makefile目標規(guī)則Makefile Target Rules
      一個目標規(guī)則的寫法是:
      target [target...] : [dependent ....]
      [ command ...]
      方括號中的是可選項目,省略號代表可以有多項
      注意:在第二行開頭有一個TAB,第一行是頂頭寫的。

      語義相當?shù)暮唵巍?br>The semantics is pretty simple.
      當你輸入“make target”的時候,make就去尋找叫做target的rule。
      如果規(guī)則的依賴文件發(fā)生了變化,make就會一個一個地執(zhí)行第二行的command(發(fā)生在宏替換之后)。
      如果有些依賴必須被made,則先made這些依賴,然后遞歸回去。

      如果某個command返回失敗值,整個make過程就會終止。
      這就是為什么要使用這個rule:
      clean:
      -rm *.o *~ core paper
      如果command行以“-”開頭的話,Make會忽略命令行調(diào)用時返回的提示信息。
      eg. who cares if there is no core file?

      Make會回顯執(zhí)行的commands, 當宏替換后,make會回顯當前的命令,以便讓你知道目前的內(nèi)容和進度。
      有時候,你也許想關(guān)掉這個功能,那么這樣作:
      install:
      @echo You must be root to install

      3.8 示例Example Target Rules
      例如,為了管理在RCS中的源文件,使用如下rule:
      SRCS=x.c y.c z.c
      $(SRCS):
      co $@

      管理SCCS中的源文件 (有時候你希望"get"一個源文件):
      $(SRCS):
      sccs get $@

      為了更有普遍性一些,我們可以將rule修改一下:
      SRCS=x.c y.c z.c
      # GET= sccs get
      GET= co
      $(SRCS):
      $(GET) $@

      又如,下面的rule建立一個對象文件的庫:
      lib.a: x.o y.o z.o
      ar rvu lib.a x.o y.o z.o
      ranlib lib.a

      另外,你也許會喜歡這樣寫:
      OBJ=x.o y.o z.o
      AR=ar

      lib.a: $(OBJ)
      $(AR) rvu $@ $(OBJ)
      ranlib $@
      因為AR是一個默認宏,所以你也可以省略第二行(但是不推薦這樣做)

      如果你習(xí)慣于使用宏,你就能只定義少量的有普遍性的rule,然后反復(fù)的調(diào)用它們。
      例如,在其他的目錄中構(gòu)建一個庫:
      INC=../misc
      OTHERS=../misc/lib.a

      $(OTHERS):
      cd $(INC); make lib.a
      注意:下面這種寫法是錯誤的(雖然看起來沒問題)
      INC=../misc
      OTHERS=../misc/lib.a

      $(OTHERS):
      cd $(INC)
      make lib.a
      因為rule中的command是在各自獨立的shell中執(zhí)行。
      這導(dǎo)致了一些有意思的結(jié)構(gòu),和那種超長行。

      這個rule可以生成多個文件的tags文件:
      SRCS=x.c y.c z.c
      CTAGS=ctags -x >tags

      tags: $(SRCS)
      ${CTAGS} $(SRCS)
      在一個大的工程中,tag文件列出了所有的函數(shù)和它們的定義。
      tags是一個很好的工具。

      可以用lint查找可能的錯誤所在:
      lint:
      lint $(CFLAGS) $(SRCS)
      lint是一個相當不錯的查錯工具,用它檢查那些無意識犯下的小錯誤再好不過了——如拼寫類錯誤,錯誤的
      參數(shù)等等。

      3.9 一些基本的規(guī)則Some Basic Make Rule
      你的Makefile最好具有以下三個target:
      all、install、clean
      1. make all -- 將所有的文件進行編譯以便進行本地調(diào)試。
      2. make install -- 將文件安裝到正確位置。避免破壞安裝文件
      3. make clean -- 清除文件。清楚所有可執(zhí)行的、臨時的和對象文件。

      一些其他的目標也會經(jīng)常用到,比如tags和lint。

      3.10 完整Makefile的示例An Example Makefile for printenv
      # make the printenv command
      #
      OWNER=bin
      GROUP=bin
      CTAGS= ctags -x >tags
      CFLAGS= -O
      LDFLAGS= -s
      CC=cc
      GET=co
      SRCS=printenv.c
      OBJS=printenv.o
      SHAR=shar
      MANDIR=/usr/man/manl/printenv.l
      BINDIR=/usr/local/bin
      DEPEND= makedepend $(CFLAGS)

      all: printenv

      # To get things out of the revision control system
      $(SRCS):
      $(GET) $@
      # To make an object from source
      $(CC) $(CFLAGS) -c $*.c
      # To make an executable
      printenv: $(OBJS)
      $(CC) $(LDFLAGS) -o $@ $(OBJS)

      # To install things in the right place
      install: printenv printenv.man
      $(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 755 printenv $(BINDIR)
      $(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 644 printenv.man $(MANDIR)
      # where are functions/procedures?
      tags: $(SRCS)
      $(CTAGS) $(SRCS)

      # what have I done wrong?
      lint: $(SRCS)
      lint $(CFLAGS) $(SRCS)

      # what are the source dependencies
      depend: $(SRCS)
      $(DEPEND) $(SRCS)

      # to make a shar distribution
      shar: clean
      $(SHAR) README Makefile printenv.man $(SRCS) >shar

      # clean out the dross
      clean:
      -rm printenv *~ *.o *.bak core tags shar

      # DO NOT DELETE THIS LINE -- make depend depends on it.
      printenv.o: /usr/include/stdio.h

      3.11 隱式規(guī)則Makefile Implicit Rules
      假設(shè)有如下rule:
      Consider the rule we used for printenv
      printenv: printenv.c
      $(CC) $(CFLAGS) printenv.c $(LDFLAGS) -o printenv

      可以更一般化些:
      We generalized a bit to get
      printenv: printenv.c
      $(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

      上邊的第二行是普遍適用的,當把.c文件編譯為可執(zhí)行的文件時,就可以用它,而不僅僅限于printenv.c
      這個文件。像這樣的情況,就可以使用隱式rule:
      .c:
      $(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

      這個隱式規(guī)則指明如何將.c文件編譯成可執(zhí)行文件——運行cc進行編譯鏈接,然后命名之。
      之所以稱其為隱式的,因為這個rule沒有確定的指出某一個文件,而是含糊的劃定了一個大的范圍。

      另一個常見的隱式rule是將.c文件生成.o文件(OBJ):
      .o.c:
      $(CC) $(CFLAGS) -c $<

      也可以這樣:
      .o.c:
      $(CC) $(CFLAGS) -c $*.c

      3.12 make依賴Make Dependencies
      使用include在源代碼中很常見。
      比如:
      % cat program.c
      #include
      #include "defs.h"
      #include "glob.h"
      etc....
      main(argc,argv)
      etc...

      隱式rule僅包含了部分的源代碼依賴(它只知道.o文件依賴于.c文件),卻無法解決包含依賴。
      常用的解決辦法是,將詳細的依賴關(guān)系單獨寫出來:
      etc...
      $(CC) $(CFLAGS) -c $*.c
      etc...
      program.o: program.c defs.h glob.h

      一般來說,通過隱式rule和獨立的依賴列表就可以很好的解決所有的依賴問題。

      不過,還有其他的工具可以自動的替你生成依賴關(guān)系列表。
      例如(trivial):
      DEPEND= makedepend $(CFLAGS)
      etc...
      # what are the source dependencies

      depend: $(SRCS)
      $(DEPEND) $(SRCS)
      etc....
      # DO NOT DELETE THIS LINE -- ....
      printenv.o: /usr/include/stdio.h

      使用這些工具(mkdepend,mkmkf等)已經(jīng)很常見了,它們也不是太難理解和使用。
      其實這些工具只是shell腳本,通過運行cpp(或者cc -M等)來查找所有的依賴關(guān)系。
      然后把依賴關(guān)系添加到Makefile的結(jié)尾。
      (EOF)

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多