自動產生Linux下Makefile全攻略(下)

來源:互聯網
上載者:User

    下面再來看看多個源檔案的例子。

     如何寫用code1.c, code2.c產生 prog1的configure.in和Makefile.am。首先建立一個專案檔夾testproj。在testproj下建立dir1目錄。

    [kang@node16 kang]$ mkdir testproj
    [kang@node16 kang]$ mkdir dir1

    然後在dir1目錄中分別建立code1.c, code1.h, code2.c, code2.h,下面原始碼都只由幾個簡單的語句組成,以便說明問題。
   下面是code1.h:

    #include <stdlib.h>

    void foo_a();

    下面是code1.c:

    #include "code1.h"

    void foo_a()
    {
        printf("This is code1./n");
    }

    下面是code2.h:

    #include <stdlib.h>

    void foo_b();

    下面是code2.c,這裡讓code.c作為prog1的進入點:

    #include "code1.h"
    #include "code2.h"

    void foo_b()
    {
        printf("This is code2./n");
    }

    int main()
    {
        foo_a();
        foo_b();
    }

    建立好這幾個檔案之後,下面就可以正式建立configure.in和Makefile.am了。
首先在testproj目錄下建立configure.in檔案:

    #指定項目的一個源檔案
    AC_INIT(dir1/code2.c)

    #指定項目名稱和版本號碼
    AM_INIT_AUTOMAKE(prog1, 0.0.1)

    #檢查編譯器
    AC_PROG_CC

    #輸出Makefile檔案
    AC_OUTPUT(Makefile dir1/Makefile) 

    同時建立testproj目錄下的Makefile.am檔案,這個檔案很簡單,就一句話:

    SUBDIRS=dir1

    然後建立dir1目錄下的Makefile.am檔案,這才是真正起作用的Makefile.am檔案: 

    bin_PROGRAMS=prog1
    prog1_SOURCES=code1.c code2.c 

    完成之後,為了方便操作,再寫一個autogen.sh檔案,儲存在testproj目錄下。 

    #!/bin/sh
    aclocal
    automake --add-missing
    autoconf 

    ./autogen.sh即可在testproj目錄下產生configure和makefile檔案,同時在dir1目錄下也會產生一個makefile檔案。現在在testproj目錄下執行make,螢幕將顯示如下資訊: 

    [kang@node16 testproj]$ make
    Making all in dir1
    make[1]: Entering directory `/home/kang/testproj/dir1'
    gcc -DPACKAGE=/"prog1/" -DVERSION=/"0.0.1/"  -I. -I.      -g -O2 -c code1.c
    code1.c:6:2: warning: no newline at end of file
    gcc -DPACKAGE=/"prog1/" -DVERSION=/"0.0.1/"  -I. -I.      -g -O2 -c code2.c
    code2.c:13:2: warning: no newline at end of file
    gcc  -g -O2  -o prog1  code1.o code2.o
    make[1]: Leaving directory `/home/kang/testproj/dir1'
    make[1]: Entering directory `/home/kang/testproj'
    make[1]: Nothing to be done for `all-am'.
    make[1]: Leaving directory `/home/kang/testproj' 

    進入dir1目錄,就可以看到產生的prog1程式。如果再執行make install,prog1將被安裝到預設的/usr/local/bin目錄下去。
    這就是一個最簡單的configure.in和Makefile.am的編寫情況。你如果不熟悉,最好自己動手做一遍,複雜的configure.in和Makefile.am都是在這個基礎上擴充的。

    在此基礎上,如果要同時實現code1.c, code2.c產生 prog1, 而 code3.c產生prog2。由於code1.c,code2.c,code3.c都在同一個目錄,只要改寫dir1目錄下的Makefile.am就可以了。
    為了便於說明問題,首先要在dir1目錄下增加一個code3.h 和code3.c檔案。
下面是code3.h: 

    #include <stdlib.h>

    void foo_c();

下面是code3.c: 

    #include "code3.h"

    void foo_c()
   {
       printf("This is code3./n");
   }

   int main()
   {
       foo_c();
   }

    然後修改dir1目錄下的Makefile.am檔案: 

    bin_PROGRAMS=prog1 prog2
    prog1_SOURCES=code1.c code2.c
    prog2_SOURCES=code3.c 

    再重新執行一次autogen.sh。make之後,在dir1目錄下就會同時存在prog1和prog2兩個程式。

     那麼,兩個處在不同子目錄下的檔案如何共同產生一可執行檔呢?一般互相引用的來源程式都是放在同一個目錄下的,如果要放在不同的目錄,可以把要引用的源檔案編譯成靜態庫檔案。為便於說明問題,準備了如下檔案:
    在testproj目錄下建立dir2目錄,儲存code4.h和code4.c檔案。
    下面是code4.h:

    #include <stdlib.h>

    void foo_d();

    下面是code4.c: 

    #include "code1.h"
    #include "code4.h"

    void foo_d()
    {
        printf("This is code4./n");
    }

    int main()
    {
        foo_a();
        foo_d();
    } 

    修改testproj目錄下的configure.in檔案。 

    #指定項目的一個源檔案
    AC_INIT(dir2/code4.c)

    #指定項目名稱和版本號碼
    AM_INIT_AUTOMAKE(myproject, 0.0.1)

    #檢查編譯器
    AC_PROG_CC

    #檢查ranlib
    AC_PROG_RANLIB

    #輸出Makefile檔案
    AC_OUTPUT(Makefile dir1/Makefile dir2/Makefile) 

    同時修改testproj目錄下的Makefile.am檔案。 

    SUBDIRS = dir1 dir2 

    在dir1目錄下修改Makefile.am檔案。這時是將code1.c編譯成一個不安裝(noinst)的靜態庫檔案。 

    noinst_LIBRARIES=libcode1.a

    libcode1_a_SOURCES=code1.c 

    在dir2目錄下添加一個Makefile.am檔案。 

    INCLUDES= -I../dir1
    bin_PROGRAMS=prog4

    prog4_SOURCES=code4.c
    prog4_LDADD=../dir1/libcode1.a 

    然後執行autogen.sh就可以了。

    補充問答。
    問題1:如何指定特定的編譯器(AC_PROG_CC只會檢查C編譯器?)?

    答:首先在configure.in中加上對特殊編譯器的檢查,如果檢查不到,則configure時會停止並給出“Couldn't find mpicc.”的出錯資訊: 

    #檢查mpicc編譯器
    AC_CHECK_PROG(MPICC,mpicc,yes,no)

    if test "$MPICC" = no; then 
        AC_MSG_ERROR([Couldn't find mpicc.])  
    fi 

    然後把需要用mpicc編譯的來源程式放在一個目錄下面。在這個目錄中先用上面的方法寫Makefile.am檔案。然後再加上下面這部分: 

    CC=mipcc
    CFLAGS= 

    這樣用自己定義的編譯器和編譯標誌取代系統定義的編譯器和編譯標誌。

    問題2:因為有部分程式不能公開發布,所以我想將它們產生庫,(*.la, 通過libtool 產生),但我解開產生的壓縮檔,發現庫檔案沒在壓縮檔裡面,所以make的時候會有些函數找不到,產生錯誤。請問如何能讓帶庫檔案的檔案夾也一起包括的壓縮檔裡去呢?

    答:如果代碼中用了庫檔案,要先編譯安裝庫檔案,再編譯代碼。你可以把編譯成庫檔案的代碼獨立出來單獨打包,這樣也便於管理。前面給的例子中庫檔案是只編譯不安裝的。下面給一個動態庫安裝的例子。

     問題3:我做的Makefile安裝時預設安裝在/usr/local/bin底下,而我想安裝在/usr/sbin下,不知道該怎麼改?

    答:這個問題不需要修改configure.in或者Makefile.am檔案。用./configure --help可以看到有一個bindir參數可以指定可執行檔的安裝目錄。你只需要執行./configure --bindir=/usr/sbin就可以了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.