• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            makefile info!

            Posted on 2008-06-28 00:05 T.S Liu 閱讀(2066) 評論(0)  編輯 收藏 引用 所屬分類: makefile
            Make工程管理器
            到此為止,讀者已了解了如何在Linux下使用編輯器編寫代碼,如何使用Gcc把代碼編譯成可執行文檔,還學習了如何使用Gdb來調試程式,那么,任何的工作看似已完成了,為什么還需要Make這個工程管理器呢?
            所謂工程管理器,顧名思義,是指管理較多的文檔的。讀者能夠試想一下,有一個上百個文檔的代碼構成的項目,假如其中只有一個或少數幾個文檔進行了修改,按照之前所學的Gcc編譯工具,就不得不把這任何的文檔重新編譯一遍,因為編譯器并不知道哪些文檔是最近更新的,而只知道需要包含這些文檔才能把源代碼編譯成可執行文檔,于是,程式員就不能不再重新輸入數目如此龐大的文檔名以完成最后的編譯工作。
            但是,請讀者仔細回想一下本書在3.1.2節
            中所闡述的編譯過程,編譯過程是分為編譯、匯編、鏈接不同階段的,其中編譯階段僅檢查語法錯誤連同函數和變量的聲明是否正確聲明了,在鏈接階段則主要完成
            是函數鏈接和全局變量的鏈接。因此,那些沒有改變的源代碼根本無需重新編譯,而只要把他們重新鏈接進去就能夠了。所以,人們就希望有一個工程管理器能夠
            自動識別更新了的文檔代碼,同時又無需重復輸入冗長的命令行,這樣,Make工程管理器也就應運而生了。
            實際上,Make工程管理器也就是個“自動編譯管理器”,這里的“自動”是指他能夠根據文檔時間戳自動發現更新過的文檔而減少編譯的工作量,同時,他通過讀入Makefile文檔的內容來執行大量的編譯工作。用戶只需編寫一次簡單的編譯語句就能夠了。他大大提高了實際項目的工作效率,而且幾乎任何Linux下的項目編程均會涉及到他,希望讀者能夠認真學習本節內容。
            3.6.1  Makefile基本結構
            Makefile是Make讀入的惟一配置文檔,因此本節的內容實際就是講述Makefile的編寫規則。在一個Makefile中通常包含如下內容:
            ·  需要由make工具創建的目標體(target),通常是目標文檔或可執行文檔;
            ·  要創建的目標體所依賴的文檔(dependency_file);
            ·  創建每個目標體時需要運行的命令(command)。
            他的格式為:

            target: dependency_files
                   command

            例如,有兩個文檔分別為hello.c和hello.h,創建的目標體為hello.o,執行的命令為gcc編譯指令:gcc –c hello.c,那么,對應的Makefile就能夠寫為:

            #The simplest example
            hello.o: hello.c hello.h
                   gcc –c hello.c –o hello.o

            接著就能夠使用make了。使用make的格式為:make target,這樣make就會自動讀入Makefile(也能夠是首字母小寫makefile)并執行對應target的command語句,并會找到相應的依賴文檔。如下所示:

            [root@localhost makefile]# make hello.o
            gcc –c hello.c –o hello.o
            [root@localhost makefile]# ls
            hello.c  hello.h  hello.o  Makefile

            能夠看到,Makefile執行了“hello.o”對應的命令語句,并生成了“hello.o”目標體。


            注意
            在Makefile中的每一個command前必須有“Tab”符,否則在運行make命令時會出錯。
            3.6.2  Makefile變量
            上面示例的Makefile在實際中是幾乎不存在的,因為他過于簡單,僅包含兩個文檔和一個命令,在這種情況下完全不必要編寫Makefile而只需在Shell中直接輸入即可,在實際中使用的Makefile往往是包含很多的文檔和命令的,這也是Makefile產生的原因。下面就可給出稍微復雜一些的Makefile進行講解:

            sunq:kang.o yul.o
            Gcc kang.o bar.o -o myprog
            kang.o : kang.c kang.h head.h
            Gcc –Wall –O -g –c kang.c -o kang.o
            yul.o : bar.c head.h
            Gcc - Wall –O -g –c yul.c -o yul.o

            在這個Makefile中有三個目標體(target),分別為sunq、kang.o和yul.o,其中第一個目標體的依賴文檔就是后兩個目標體。假如用戶使用命令“make sunq”,則make管理器就是找到sunq目標體開始執行。
            這時,make會自動檢查相關文檔的時間戳。首先,在檢查“kang.o”、“yul.o”和“sunq”三個文檔的時間戳之前,他會向下查找那些把“kang.o”或“yul.o”做為目標文檔的時間戳。比如,“kang.o”的依賴文檔為:“kang.c”、“kang.h”、“head.h”。假如這些文檔中任何一個的時間戳比“kang.o”新,則命令“gcc –Wall –O -g –c kang.c -o kang.o”將會執行,從而更新文檔“kang.o”。在更新完“kang.o”或“yul.o”之后,make會檢查最初的“kang.o”、“yul.o”和“sunq”三個文檔,只要文檔“kang.o”或“yul.o”中的任比文檔時間戳比“sunq”新,則第二行命令就會被執行。這樣,make就完成了自動檢查時間戳的工作,開始執行編譯工作。這也就是Make工作的基本流程。
            接下來,為了進一步簡化編輯和維護Makefile,make允許在Makefile中創建和使用變量。變量是在Makefile中定義的名字,用來代替一個文本字符串,該文本字符串稱為該變量的值。在具體需要下,這些值能夠代替目標體、依賴文檔、命令連同makefile文檔中其他部分。在Makefile中的變量定義有兩種方式:一種是遞歸展開方式,另一種是簡單方式。
            遞歸展開方式定義的變量是在引用在該變量時進行替換的,即假如該變量包含了對其他變量的應用,則在引用該變量時一次性將內嵌的變量全部展開,雖然這種類型的變量能夠很好地完成用戶的指令,但是他也有嚴重的缺點,如不能在變量后追加內容(因為語句:CFLAGS = $(CFLAGS) -O在變量擴展過程中可能導致無窮循環)。
            為了避免上述問題,簡單擴展型變量的值在定義處展開,并且只展開一次,因此他不包含任何對其他變量的引用,從而消除變量的嵌套引用。
            遞歸展開方式的定義格式為:VAR=var
            簡單擴展方式的定義格式為:VAR:=var
            Make中的變量使用均使用格式為:$(VAR)


            注意
            變量名是不包括“:”、“#”、“=”結尾空格的任何字符串。同時,變量名中包含字母、數字連同下劃線以外的情況應盡量避免,因為他們可能在將來被賦予特別的含義。
            變量名是大小寫敏感的,例如變量名“foo”、“FOO”、和“Foo”代表不同的變量。
            推薦在makefile內部使用小寫字母作為變量名,預留大寫字母作為控制隱含規則參數或用戶重載命令選項參數的變量名。

            下面給出了上例中用變量替換修改后的Makefile,這里用OBJS代替kang.o和yul.o,用CC代替Gcc,用CFLAGS代替“-Wall -O –g”。這樣在以后修改時,就能夠只修改變量定義,而無需修改下面的定義實體,從而大大簡化了Makefile維護的工作量。
            經變量替換后的Makefile如下所示:

            OBJS = kang.o yul.o
            CC = Gcc
            CFLAGS = -Wall -O -g
            sunq : $(OBJS)
                   $(CC) $(OBJS) -o sunq
            kang.o : kang.c kang.h
                   $(CC) $(CFLAGS) -c kang.c -o kang.o
            yul.o : yul.c yul.h
                   $(CC) $(CFLAGS) -c yul.c -o yul.o

            能夠看到,此處變量是以遞歸展開方式定義的。
            Makefile中的變量分為用戶自定義變量、預定義變量、自動變量及環境變量。如上例中的OBJS就是用戶自定義變量,自定義變量的值由用戶自行設定,而預定義變量和自動變量為通常在Makefile都會出現的變量,其中部分有默認值,也就是常見的設定值,當然用戶能夠對其進行修改。
            預定義變量包含了常見編譯器、匯編器的名稱及其編譯選項。下表3.14列出了Makefile中常見預定義變量及其部分默認值。
            表3.14                                                  Makefile中常見預定義變量
            命 令 格 式
            含    義
            AR
            庫文檔維護程式的名稱,默認值為ar
            AS
            匯編程式的名稱,默認值為as
            CC
            C編譯器的名稱,默認值為cc
            CPP
            C預編譯器的名稱,默認值為$(CC) –E
            CXX
            C++編譯器的名稱,默認值為g++
            FC
            FORTRAN編譯器的名稱,默認值為f77
            RM
            文檔刪除程式的名稱,默認值為rm –f
            ARFLAGS
            庫文檔維護程式的選項,無默認值
            ASFLAGS
            匯編程式的選項,無默認值
            CFLAGS
            C編譯器的選項,無默認值
            CPPFLAGS
            C預編譯的選項,無默認值
            CXXFLAGS
            C++編譯器的選項,無默認值
            FFLAGS
            FORTRAN編譯器的選項,無默認值

            能夠看出,上例中的CC和CFLAGS是預定義變量,其中由于CC沒有采用默認值,因此,需要把“CC=Gcc”明確列出來。
            由于常見的Gcc編譯語句中通常包含了目標文檔和依賴文檔,而這些文檔在Makefile文檔中目標體的一行已有所體現,因此,為了進一步簡化Makefile的編寫,就引入了自動變量。自動變量通常能夠代表編譯語句中出現目標文檔和依賴文檔等,并且具備本地含義(即下一語句中出現的相同變量代表的是下一語句的目標文檔和依賴文檔)。下表3.15列出了Makefile中常見自動變量。
            表3.15                                                    Makefile中常見自動變量
            命令格式
            含    義
            $*
            不包含擴展名的目標文檔名稱
            $+
            任何的依賴文檔,以空格分開,并以出現的先后為序,可能包含重復的依賴文檔
            $
            第一個依賴文檔的名稱
            $?
            任何時間戳比目標文檔晚的依賴文檔,并以空格分開
            命令格式
            含    義
            $@
            目標文檔的完整名稱
            $^
            任何不重復的依賴文檔,以空格分開
            $%
            假如目標是歸檔成員,則該變量表示目標的歸檔成員名稱

            自動變量的書寫比較難記,但是在熟練了之后會很的方便,請讀者結合下例中的自動變量改寫的Makefile進行記憶。

            OBJS = kang.o yul.o
            CC = Gcc
            CFLAGS = -Wall -O -g
            sunq : $(OBJS)
                  $(CC) $^ -o $@
            kang.o : kang.c kang.h
                  $(CC) $(CFLAGS) -c $
            yul.o : yul.c yul.h
                  $(CC) $(CFLAGS) -c $

            另外,在Makefile中還能夠使用環境變量。使用環境變量的方法相對比較簡單,make在啟動時會自動讀取系統當前已定義了的環境變量,并且會創建和之具備相同名稱和數值的變量。但是,假如用戶在Makefile中定義了相同名稱的變量,那么用戶自定義變量將會覆蓋同名的環境變量。
            3.6.3  Makefile規則
            Makefile的規則是Make進行處理的依據,他包括了目標體、依賴文檔及其之間的命令語句。一般的,Makefile中的一條語句就是個規則。在上面的例子中,都顯示地指出了Makefile中的規則關系,如“$(CC) $(CFLAGS) -c $”,但為了簡化Makefile的編寫,make還定義了隱式規則和模式規則,下面就分別對其進行講解。
            1.隱式規則
            隱含規則能夠告訴make怎樣使用傳統的技術完成任務,這樣,當用戶使用他們時就不必周詳指定編譯的具體細節,而只需把目標文檔列出即可。Make會自動搜索隱式規則目錄來確定如何生成目標文檔。如上例就能夠寫成:

            OBJS = kang.o yul.o
            CC = Gcc
            CFLAGS = -Wall -O -g
            sunq : $(OBJS)
                  $(CC) $^ -o $@

            為什么能夠省略后兩句呢?因為Make的隱式規則指出:任何“.o”文檔都可自動由“.c”文檔使用命令“$(CC) $(CPPFLAGS) $(CFLAGS) -c file.c –o file.o”生成。這樣“kang.o”和“yul.o”就會分別調用“$(CC) $(CFLAGS) -c kang.c -o kang.o”和“$(CC) $(CFLAGS) -c yul.c -o yul.o”生成。


            注意
            在隱式規則只能查找到相同文檔名的不同后綴名文檔,如”kang.o”文檔必須由”kang.c”文檔生成。

            下表3.16給出了常見的隱式規則目錄:
            表3.16                                                Makefile中常見隱式規則目錄
            對應語言后綴名
            規    則
            C編譯:.c變為.o
            $(CC) –c $(CPPFLAGS) $(CFLAGS)
            C++編譯:.cc或.C變為.o
            $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
            Pascal編譯:.p變為.o
            $(PC) -c $(PFLAGS)
            Fortran編譯:.r變為-o
            $(FC) -c $(FFLAGS)
            2.模式規則
            模式規則是用來定義相同處理規則的多個文檔的。他不同于隱式規則,隱式規則僅僅能夠用make默認的變量來進行操作,而模式規則還能引入用戶自定義變量,為多個文檔建立相同的規則,從而簡化Makefile的編寫。
            模式規則的格式類似于普通規則,這個規則中的相關文檔前必須用“%”標明。使用模式規則修改后的Makefile的編寫如下:

            OBJS = kang.o yul.o
            CC = Gcc
            CFLAGS = -Wall -O -g
            sunq : $(OBJS)
                  $(CC) $^ -o $@
            %.o : %.c
                  $(CC) $(CFLAGS) -c $

            3.6.4  Make使用
            使用make管理器很簡單,只需在make命令的后面鍵入目標名即可建立指定的目標,假如直接運行make,則建立Makefile中的第一個目標。
            此外make更有豐富的命令行選項,能夠完成各種不同的功能。下表3.17列出了常用的make命令行選項。
            表3.17                                                        make的命令行選項
            命令格式
            含    義
            -C dir
            讀入指定目錄下的Makefile
            -f file
            讀入當前目錄下的file文檔作為Makefile
            命令格式
            含    義
            -i
            忽略任何的命令執行錯誤
            -I dir
            指定被包含的Makefile所在目錄
            -n
            只打印要執行的命令,但不執行這些命令
            -p
            顯示make變量數據庫和隱含規則
            -s
            在執行命令時不顯示命令
            -w
            假如make在執行過程中改變目錄,則打印當前目錄名
            3.7  使用autotools
            在上一小節,讀者已了解到了make項目管理器的強大功能。的確,Makefile能夠幫助make完成他的使命,但要承認的是,編寫Makefile確實不是一件輕松的事,尤其對于一個較大的項目而言更是如此。那么,有沒有一種輕松的手段生成Makefile而同時又能讓用戶享受make的優越性呢?本節要講的autotools系列工具正是為此而設的,他只需用戶輸入簡單的目標文檔、依賴文檔、文檔目錄等就能夠輕松地生成Makefile了,這無疑是廣大用戶的所希望的。另外,這些工具還能夠完成系統配置信息的收集,從而能夠方便地處理各種移植性的問題。也正是基于此,現在Linux上的軟件研發一般都用autotools來制作Makefile,讀者在后面的講述中就會了解到。
            3.7.1  autotools使用流程
            正如前面所言,autotools是系列工具,讀者首先要確認系統是否裝了以下工具(能夠用which命令進行查看)。
            ·  aclocal
            ·  autoscan
            ·  autoconf
            ·  autoheader
            ·  automake
            使用autotools主要就是利用各個工具的腳本文檔以生成最后的Makefile。其總體流程是這樣的:
            ·  使用aclocal生成一個“aclocal.m4”文檔,該文檔主要處理本地的宏定義;
            ·  改寫“configure.scan”文檔,并將其重命名為“configure.in”,并使用autoconf文檔生成configure文檔。
            接下來,筆者將通過一個簡單的hello.c例子帶領讀者熟悉autotools生成makefile的過程,由于在這過程中有涉及到較多的腳本文檔,為了更清楚地了解相互之間的關系,強烈建議讀者實際動手操作以體會其整個過程。
            1.autoscan
            他會在給定目錄及其子目錄樹中檢查源文檔,若沒有給出目錄,就在當前目錄及其子目錄樹中進行檢查。他會搜索源文檔以尋找一般的移植性問題并創建一個文檔“configure.scan”,該文檔就是接下來autoconf要用到的“configure.in”原型。如下所示:

            [root@localhost automake]# autoscan
            autom4te: configure.ac: no such file or directory
            autoscan: /usr/bin/autom4te failed with exit status: 1
            [root@localhost automake]# ls
            autoscan.log  configure.scan  hello.c

            如上所示,autoscan首先會嘗試去讀入“configure.ac”(同configure.in的配置文檔)文檔,此時還沒有創建該配置文檔,于是他會自動生成一個“configure.in”的原型文檔“configure.scan”。
            2.autoconf
            configure.in是autoconf的腳本配置文檔,他的原型文檔“configure.scan”如下所示:

            #                                               -*- Autoconf -*-
            # Process this file with autoconf to produce a configure script.
            AC_PREREQ(2.59)
            #The next one is modified by sunq
            #AC_INIT(FULL-PACKAGE-NAME,VERSION,BUG-REPORT-ADDRESS)
            AC_INIT(hello,1.0)
            # The next one is added by sunq
            AM_INIT_AUTOMAKE(hello,1.0)
            AC_CONFIG_SRCDIR([hello.c])
            AC_CONFIG_HEADER([config.h])
            # Checks for programs.
            AC_PROG_CC
            # Checks for libraries.
            # Checks for header files.
            # Checks for typedefs, structures, and compiler characteristics.
            # Checks for library functions.
            AC_CONFIG_FILES([Makefile])
            AC_OUTPUT

            下面對這個腳本文檔進行解釋:
            ·  以“#”號開始的行為注釋。
            ·  AC_PREREQ宏聲明本文檔需要的autoconf版本,如本例使用的版本2.59。
            · AC_INIT宏用來定義軟件的名稱和版本等信息,在本例中省略了BUG-REPORT-ADDRESS,一般為作者的e-mail。
            ·  AM_INIT_AUTOMAKE是筆者另加的,他是automake所必備的宏,也同前面相同,PACKAGE是所要產生軟件套件的名稱,VERSION是版本編號。
            ·  AC_CONFIG_SRCDIR宏用來偵測所指定的源碼文檔是否存在,來確定源碼目錄的有
            效性。在此處為當前目錄下的hello.c。
            ·  AC_CONFIG_HEADER宏用于生成config.h文檔,以便autoheader使用。
            ·  AC_CONFIG_FILES宏用于生成相應的Makefile文檔。
            ·  中間的注釋間能夠添加分別用戶測試程式、測試函數庫、測試頭文檔等宏定義。
            接下來首先運行aclocal,生成一個“aclocal.m4”文檔,該文檔主要處理本地的宏定義。如下所示:

            [root@localhost automake]# aclocal

            再接著運行autoconf,生成“configure”可執行文檔。如下所示:

            [root@localhost automake]# autoconf
            [root@localhost automake]# ls
            aclocal.m4  autom4te.cache  autoscan.log  configure  configure.in  hello.c
            3.autoheader
            接著使用autoheader命令,他負責生成config.h.in文檔。該工具通常會從“acconfig.h”文檔中復制用戶附加的符號定義,因此此處沒有附加符號定義,所以無需創建“acconfig.h”文檔。如下所示:

            [root@localhost automake]# autoheader
            4.automake
            這一步是創建Makefile很重要的一步,automake要用的腳本配置文檔是Makefile.am,用戶需要自己創建相應的文檔。之后,automake工具轉換成Makefile.in。在該例中,筆者創建的文檔為Makefile.am如下所示:

            AUTOMAKE_OPTIONS=foreign
            bin_PROGRAMS= hello
            hello_SOURCES= hello.c

            下面對該腳本文檔的對應項進行解釋。
            ·  其中的AUTOMAKE_OPTIONS為配置automake的選項。由于GNU(在第1章中已有所介紹)對自己發布的軟件有嚴格的規范,比如必須附帶許可證聲明文檔COPYING等,否則automake執行時會報錯。automake提供了三種軟件等級:foreign、gnu和gnits,讓用戶選擇采用,默認等級為gnu。在本例使用foreign等級,他只檢測必須的文檔。
            ·  bin_PROGRAMS定義要產生的執行文檔名。假如要產生多個執行文檔,每個文檔名用空格隔開。
            ·  hello_SOURCES定義“hello”這個執行程式所需要的原始文檔。假如”hello”這個程式是由多個原始文檔所產生的,則必須把他所用到的任何原始文檔都列出來,并用空格隔開。例如:若目標體“hello”需要“hello.c”、“sunq.c”、“hello.h”三個依賴文檔,則定義hello_SOURCES=hello.c sunq.c hello.h。要注意的是,假如要定義多個執行文檔,則對每個執行程式都要定義相應的file_SOURCES。
            接下來能夠使用automake對其生成“configure.in”文檔,在這里使用選項“—adding-missing”能夠讓automake自動添加有一些必需的腳本文檔。如下所示:

            [root@localhost automake]# automake --add-missing
            configure.in: installing './install-sh'
            configure.in: installing './missing'
            Makefile.am: installing 'depcomp'
            [root@localhost automake]# ls
            aclocal.m4      autoscan.log  configure.in  hello.c     Makefile.am  missing
            autom4te.cache  configure     depcomp    install-sh  Makefile.in  config.h.in

            能夠看到,在automake之后就能夠生成configure.in文檔。
            5.運行configure
            在這一步中,通過運行自動配置配置文檔configure,把Makefile.in變成了最終的Makefile。如下所示:

            [root@localhost automake]# ./configure
            checking for a BSD-compatible install... /usr/bin/install -c
            checking whether build enVironment is sane... yes
            checking for gawk... gawk
            checking whether make sets $(MAKE)... yes
            checking for Gcc... Gcc
            checking for C compiler default output file name... a.out
            checking whether the C compiler works... yes
            checking whether we are cross compiling... no
            checking for suffix of executables...
            checking for suffix of object files... o
            checking whether we are using the GNU C compiler... yes
            checking whether Gcc accepts -g... yes
            checking for Gcc option to accept ANSI C... none needed
            checking for style of include used by make... GNU
            checking dependency style of Gcc... Gcc3
            configure: creating ./config.status
            config.status: creating Makefile
            config.status: executing depfiles commands
            能夠看到,在運行configure時收集了系統的信息,用戶能夠在configure命令中對其進行方便地配置。在./configure的自定義參數有兩種,一種是開關式(--enable-XXX或--disable-XXX),另一種是開放式,即后面要填入一串字符(--with-XXX=yyyy)參數。讀者能夠自行嘗試其使用方法。另外,讀者能夠查看同一目錄下的”config.log”文檔,以方便調試之用。
            到此為止,makefile就能夠自動生成了?;貞浾麄€步驟,用戶不再需要定制不同的規則,而只需要輸入簡單的文檔及目錄名即可,這樣就大大方便了用戶的使用。下面的圖3.9總結了上述過程:

            圖3.9  autotools生成Makefile流程圖
            3.7.2  使用autotools所生成的Makefile
            autotools生成的Makefile除具備普通的編譯功能外,還具備以下主要功能(感興趣的讀者能夠查看這個簡單的hello.c程式的makefile):
            1.make
            鍵入make默認執行”make all”命令,即目標體為all,其執行情況如下所示:

            [root@localhost automake]# make
            if Gcc
            -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\"
            -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hello\"
            -DVERSION=\"1.0\"  -I. -I.     -g -O2 -MT hello.o -MD -MP -MF
            ".deps/hello.Tpo" -c -o hello.o hello.c; \
            then mv -f ".deps/hello.Tpo" ".deps/hello.Po"; else rm -f ".deps/hello.Tpo"; exit 1; fi
            Gcc  -g -O2   -o hello  hello.o
            此時在本目錄下就生成了可執行文檔“hello”,運行“./hello”能出現正常結果,如下所示:

            [root@localhost automake]# ./hello
            Hello!Autoconf!
            2.make install
            此時,會把該程式安裝到系統目錄中去,如下所示:

            [root@localhost automake]# make install
            if Gcc
            -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\"
            -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hello\"
            -DVERSION=\"1.0\"  -I. -I.     -g -O2 -MT hello.o -MD -MP -MF
            ".deps/hello.Tpo" -c -o hello.o hello.c; \
            then mv -f ".deps/hello.Tpo" ".deps/hello.Po"; else rm -f ".deps/hello.Tpo"; exit 1; fi
            Gcc  -g -O2   -o hello  hello.o
            make[1]: Entering directory '/root/workplace/automake'
            test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"
              /usr/bin/install -c 'hello' '/usr/local/bin/hello'
            make[1]: Nothing to be done for 'install-data-am'.
            make[1]: LeaVing directory '/root/workplace/automake'

            此時,若直接運行hello,也能出現正確結果,如下所示:

            [root@localhost automake]# hello
            Hello!Autoconf!
            3.make clean
            此時,make會清除之前所編譯的可執行文檔及目標文檔(object file, *.o),如下所示:

            [root@localhost automake]# make clean
            test -z "hello" || rm -f hello
            rm -f *.o
            4.make dist
            此時,make將程式和相關的文檔打包為一個壓縮文檔以供發布,如下所示:

            [root@localhost automake]# make dist
            [root@localhost automake]# ls hello-1.0-tar.gz
            hello-1.0-tar.gz

            可見該命令生成了一個hello-1.0-tar.gz的壓縮文檔。
            由上面的講述讀者不難看出,autotools確實是軟件維護和發布的必備工具,也鑒于此,如今GUN的軟件一般都是由automake來制作的。


            想一想
            對于automake制作的這類軟件,應如何安裝呢?
            3.8.3  編寫包含多文檔的Makefile
            1.實驗目的
            通過對包含多文檔的Makefile的編寫,熟悉各種形式的Makefile,并且進一步加深對Makefile中用戶自定義變量、自動變量及預定義變量的理解。
            2.實驗過程
            (1)用Vi在同一目錄下編輯兩個簡單的Hello程式,如下所示:

            #hello.c
            #include "hello.h"
            int main()
            {
                   printf("Hello everyone!\n");
            }
            #hello.h
            #include

            (2)仍在同一目錄下用Vi編輯Makefile,且不使用變量替換,用一個目標體實現(即直接將hello.c和hello.h編譯成hello目標體)。然后用make驗證所編寫的Makefile是否正確。
            (3)將上述Makefile使用變量替換實現。同樣用make驗證所編寫的Makefile是否正確
            (4)用編輯另一Makefile,取名為Makefile1,不使用變量替換,但用兩個目標體實現(也就是首先將hello.c和hello.h編譯為hello.o,再將hello.o編譯為hello),再用make的”-f”選項驗證這個Makefile1的正確性。
            (5)將上述Makefile1使用變量替換實現。
            3.實驗步驟
            (1)用Vi打開上述兩個代碼文檔“hello.c”和“hello.h”。
            (2)在shell命令行中用Gcc嘗試編譯,使用命令:”Gcc hello.c –o hello”,并運行hello可執行文檔查看結果。
            (3)刪除此次編譯的可執行文檔:rm hello。
            (4)用Vi編輯Makefile,如下所示:

            hello:hello.c hello.h
                   Gcc hello.c -o hello

            (5)退出保存,在shell中鍵入:make,查看結果。
            (6)再次用Vi打開Makefile,用變量進行替換,如下所示:

            OBJS :=hello.o
            CC :=Gcc
            hello:$(OBJS)
                   $(CC) $^ -o $@

            (7)退出保存,在shell中鍵入:make,查看結果。
            (8)用Vi編輯Makefile1,如下所示:

            hello:hello.o
                   Gcc hello.o -o hello
            hello.o:hello.c hello.h
                   Gcc -c hello.c -o hello.o

            (9)退出保存,在shell中鍵入:make -f Makefile1,查看結果。
            (10)再次用Vi編輯Makefile1,如下所示:

            OBJS1 :=hello.o
            OBJS2 :=hello.c hello.h
            CC :=Gcc
            hello:$(OBJS1)
                   $(CC) $^ -o $@
            $(OBJS1):$(OBJS2)
                   $(CC) -c $

            在這里請注意區別“$^”和“$”。
            (11)退出保存,在shell中鍵入:make -f Makefile1,查看結果
            4.實驗結果
            各種不同形式的makefile都能完成其正確的功能。
            3.8.4  使用autotools生成包含多文檔的Makefile
            1.實驗目的
            通過使用autotools生成包含多文檔的Makefile,進一步掌控autotools的正確使用方法。同時,掌控Linux下安裝軟件的常用方法。
            2.實驗過程
            (1)在原目錄下新建文檔夾auto。
            (2)利用上例的兩個代碼文檔“hello.c”和“hello.h”,并將他們復制到該目錄下。
            (3)使用autoscan生成configure.scan。
            (4)編輯configure.scan,修改相關內容,并將其重命名為configure.in。
            (5)使用aclocal生成aclocal.m4。
            (6)使用autoconf生成configure。
            (7)使用autoheader生成config.in.h。
            (8)編輯Makefile.am。
            (9)使用automake生成Makefile.in。
            (10)使用configure生成Makefile。
            (11)使用make生成hello可執行文檔,并在當前目錄下運行hello查看結果。
            (12)使用make install將hello安裝到系統目錄下,并運行,查看結果。
            (13)使用make dist生成hello壓縮包。
            (14)解壓hello壓縮包。
            (15)進入解壓目錄。
            (16)在該目錄下安裝hello軟件。
            3.實驗步驟
            (1)mkdir ./auto。
            (2)cp hello.* ./auto(假定原先在“hello.c”文檔目錄下)。
            (3)命令:autoscan。
            (4)使用Vi編輯configure.scan為:

            #                                               -*- Autoconf -*-
            # Process this file with autoconf to produce a configure script.

            AC_PREREQ(2.59)
            AC_INIT(hello, 1.0)
            AM_INIT_AUTOMAKE(hello,1.0)
            AC_CONFIG_SRCDIR([hello.h])
            AC_CONFIG_HEADER([config.h])
            # Checks for programs.
            AC_PROG_CC
            # Checks for libraries.
            # Checks for header files.
            # Checks for typedefs, structures, and compiler characteristics.
            # Checks for library functions.
            AC_OUTPUT(Makefile)

            (5)保存退出,并重命名為configure.in。
            (6)運行:aclocal。
            (7)運行:autoconf,并用ls查看是否生成了configure可執行文檔。
            (8)運行:autoheader。
            (9)用Vi編輯Makefile.am文檔為:

            AUTOMAKE_OPTIONS=foreign
            bin_PROGRAMS=hello
            hello_SOURCES=hello.c hello.h

            (10)運行:automake。
            (11)運行:./configure。
            (12)運行:make。
            (13)運行:./hello,查看結果是否正確。
            (14)運行:make install。
            (15)運行:hello,查看結果是否正確。
            (16)運行:make dist。
            (17)在當前目錄下解壓hello-1.0.tar.gz:tar –zxvf hello-1.0.tar.gz。
            (18)進入解壓目錄:cd ./hello-1.0。
            (19)下面開始Linux下常見的安裝軟件步驟:./configure。
            (20)運行:make。
            (21)運行:./hello(在正常安裝時這一步可省略)。
            (22)運行:make install。
            (23)運行:hello,查看結果是否正確。
            4.實驗結果
            能夠正確使用autotools生成Makefile,并且能夠安裝成功短小的Hello軟件。
            日本高清无卡码一区二区久久| 亚洲色大成网站WWW久久九九| 久久九九有精品国产23百花影院| 精品久久久久久亚洲精品 | 亚洲va久久久久| 少妇久久久久久被弄高潮| 99麻豆久久久国产精品免费| 精品久久久久中文字幕一区| 亚洲精品无码成人片久久| 99久久免费只有精品国产| 精品久久久久久国产| 精品一久久香蕉国产线看播放| 国产精品久久久久久久人人看| 久久免费小视频| 久久亚洲精品成人AV| 一本综合久久国产二区| 99久久综合狠狠综合久久| 久久亚洲日韩精品一区二区三区| 美女久久久久久| 久久se这里只有精品| 中文字幕亚洲综合久久2| 少妇精品久久久一区二区三区| 久久婷婷五月综合色99啪ak| 久久精品视频免费| 久久99精品国产自在现线小黄鸭 | 99久久免费国产精品热| 伊人久久大香线蕉综合网站| 99久久精品无码一区二区毛片 | 91精品国产91久久久久久青草 | 香蕉久久夜色精品升级完成| 亚洲精品无码久久久| 久久人人爽人人澡人人高潮AV| 国产精品va久久久久久久| 久久国产精品-国产精品| 久久青青草原国产精品免费| 2020久久精品国产免费| 91久久精品91久久性色| 亚洲午夜久久久精品影院| 国产69精品久久久久99| 久久se精品一区二区影院| 久久久久国色AV免费看图片|