亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

linux 編程技術(shù)No.1前期準(zhǔn)備工作

系統(tǒng) 2213 0

原創(chuàng)博文,轉(zhuǎn)載請注明出處。

GCC的編譯過程分為預(yù)處理、生成匯編代碼、生成目標(biāo)代碼和鏈接成可執(zhí)行文件等4個步驟。

使用vim編寫C 文件 : [lining@localhost program]$ vim hello.c 這樣就會在program文件夾生成hello.c文件

編譯C代碼:使用如下命令“gcc 代碼文件名”? 如: [lining@localhost program]$ gcc hello.c 這樣就會生成二進(jìn)制可執(zhí)行文件名稱位a.out。

????????? 如果需要指定輸出的文件名稱,使用 “gcc -o 代碼文件名” 如:[lining@localhost program]$ gcc -o hello hello.c 這樣就會生存名稱為hello的可執(zhí)行文件。

???????? [lining@localhost program]$ gcc -v -o hello hello.c 使用參數(shù)v可以顯示GCC的工作整個過程。

編譯C ++代碼:與編譯C 代碼類似,只不過要把gcc換成g++。

使用GCC控制編譯過程:

  1、預(yù)處理

??????????? 該步驟完成宏和include展開工作。在GCC 中使用參數(shù)E可控制GCC完成預(yù)處理。

?????????? [lining@localhost program]$ gcc -E -o hello.pre.c hello.c 可通過查看hello.pre.c文件內(nèi)容驗(yàn)證

?????? 2、生成匯編代碼

?????????? 編譯器將預(yù)處理生成的代碼進(jìn)行處理,并根據(jù)編譯參數(shù)進(jìn)行優(yōu)化,最后生成匯編代碼。使用參數(shù)S。

????????? [lining@localhost program]$ gcc -S hello.c 將生成名為hello.s的匯編代碼。

  3、生成目標(biāo)代碼

?????????? 目標(biāo)代碼生成階段是把中間代碼變換成特定機(jī)器上的絕對指令代碼、可重定位的指令代碼或匯編指令代碼。GCC中使用參數(shù)c完成預(yù)編譯、生成匯編代碼和生成目標(biāo)代碼。

?????????? [lining@localhost program]$ gcc -c hello.c 將生成名為hello.o的目標(biāo)代碼。

  4、鏈接生成最終可執(zhí)行代碼

??????????? 這一步相當(dāng)與前面的程序編譯。

  補(bǔ)充知識 :gcc -shared -fPIC -o 1.so 1.c

   這里有一個-fPIC參數(shù),PIC就是position independent code,PIC使.so文件的代碼段變?yōu)檎嬲饬x上的共享.
   如果不加-fPIC,則加載.so文件的代碼段時,代碼段引用的數(shù)據(jù)對象需要重定位, 重定位會修改代碼段的內(nèi)容,這就造成每個使用這個.so文件代碼段的進(jìn)程在內(nèi)核里都會生成這個.so文件代碼段的copy.每個copy都不一樣,取決于 這個.so文件代碼段和數(shù)據(jù)段內(nèi)存映射的位置. 不加fPIC編譯出來的so,是要再加載時根據(jù)加載到的位置再次重定位的.(因?yàn)樗锩娴拇a并不是位置無關(guān)代碼)
如果你的.so被多個應(yīng)用程序共同使用,那么它們必須每個程序維護(hù)一份so的代碼副本了.(因?yàn)閟o被每個程序加載的位置都不同,顯然這些重定位后的代碼也不同,當(dāng)然不能共享)
我們總是用fPIC來生成so,也從來不用fPIC來生成a. fPIC與動態(tài)鏈接可以說基本沒有關(guān)系,libc.so一樣可以不用fPIC編譯,只是這樣的so必須要在加載到用戶程序的地址空間時重定向所有表目.
????????? 比如我們使用C在擴(kuò)展python的時候 最好使用gcc -shared -fPIC -o來生成.so文件供python調(diào)用。

GNU Make項(xiàng)目管理

??????? Make按照一定的規(guī)則對項(xiàng)目的源文件進(jìn)行編譯,并生成可執(zhí)行的二進(jìn)制文件。在使用gcc編譯項(xiàng)目文件時,由于項(xiàng)目源文件代碼很多,每次修改任何一個源代碼文件都要重新編譯和鏈接。

?Make通過讀入配置好的文本文件,并根據(jù)文本文件中預(yù)先定義的規(guī)則和步驟,完成代碼的編譯和鏈接工作,最終生成所需要的項(xiàng)目文件。這個文本文件在缺省情況下文件名為makefile或Makefile。Make程序的命令形式是 “make[選項(xiàng)]、[目標(biāo)]...”,可通過make -h 查看所支持選項(xiàng)。

??????? Make 在進(jìn)行項(xiàng)目編譯時會讀makefile文件,比較該目標(biāo)所依賴的源文件額日期和時間,以確定要編譯的代碼和相關(guān)的編譯規(guī)則。當(dāng)用戶輸入make命令后,Make將首先搜索該目錄下是否存在makefile。如果沒找到,則搜索名為makefile的文件,最后查找名為Makefile的文件。用戶可通過 -f參數(shù)來指定makefile配置文件。

makefile的語法

  makefile文件由一組依賴關(guān)系和規(guī)則構(gòu)成。每個依賴關(guān)系由一個目標(biāo)(即將要創(chuàng)建的文件)和一組該目標(biāo)所依賴的源文件組成。makefile的內(nèi)容包含5個部分:顯式規(guī)則,隱式規(guī)則,變量定義,指令和注釋。

?????? 這里主要介紹變量和指令這兩個主要的部分。

?????? 變量:區(qū)分大小寫,與C/C++不同,定義變量不需要先聲明。在定義變量后,如果要引用該變量,可以使用$(變量名)的形式訪問該變量。

?????????? ? ? ?? 對上面的hello.c 編寫帶有變量定義的makefile ???

      CC =
      
         gcc

hello : hello.c

          $(CC) 
      
      -o hello hello.c ? ?//這兒需要注意,第二行的開頭是tab字符,如果使用空格會在make命令下出現(xiàn)提示
    

???????????????? 完成編輯后,將其保存為makefile文件。在shell命令下輸入make命令,編輯文件。

???????????????? makefile中有一些預(yù)先設(shè)定的變量:

  ?????????????????? $@?? 表示當(dāng)前規(guī)則中的目標(biāo)文件名

????????????????????????? $????? 新修改過的依賴文件列表

????????????????????????? $*????? 不包含擴(kuò)展名的目標(biāo)文件名

????????????????????????? $<????? 當(dāng)前規(guī)則中的第一個依賴文件名

????????????????????????? $%???? 當(dāng)目標(biāo)文件為庫文件時,該變量為庫文件名;如果不是庫文件,該變量為空值

????????????????????????? $^????? 當(dāng)前規(guī)則中的所有文件列表

????????????????????????? AR???? 歸檔程序名稱,默認(rèn)為AR

????????????????????????? ARFLAGS????? 歸檔程序選項(xiàng)

???????????????????????? CC????? C編譯器命令名,默認(rèn)為CC

???????????????????????? CFLAGS???? C編譯器編譯參數(shù)

   基于依賴關(guān)系的指定區(qū):

?????????????? 依賴關(guān)系定義了最終應(yīng)用程序里的每個文件與源文件之間的關(guān)系。規(guī)則的寫法如下

?????????????????????? 目標(biāo)(可能存在多個目標(biāo))... :空格或tab鍵 依賴條件(可能存在多個依賴條件,以空格或tab隔開)...

  舉例如下:

      myapp:    main.o 
      
        2
      
      .o 
      
        3
      
      
        .o

main.o:    main.c a.h


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h


      
      
        3
      
      .o:    
      
        3
      
      .c b.h c.h
    

它表示目標(biāo)myapp依賴于main.o,2.o和3.o, 而main.o依賴于 main.c和a.h,等等。如果你沒有指定目標(biāo)的名字作為make命令的一個參數(shù),make命令將第一個目標(biāo)定義為all。

      myapp:    main.o 
      
        2
      
      .o 
      
        3
      
      
        .o

      gcc 
      
      -o myapp main.o 
      
        2
      
      .o 
      
        3
      
      
        .o     

main.o:    main.c a.h

      gcc 
      
      -
      
        c main.c


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h

      gcc 
      
      -c 
      
        2
      
      
        .c


      
      
        3
      
      .o:    
      
        3
      
      
        .c b.h c.h

      gcc 
      
      -c 
      
        3
      
      .c 
    

當(dāng)我們執(zhí)行make -f makefile1(我們把創(chuàng)建的第一個makefile自定義命名),首先會檢查其他的依賴關(guān)系,最終確定需要有一個文件main.c。在這里我們令頭文件都是空文件,我們可以用touch命令來創(chuàng)建它們:

[lining@localhost program]$ touch a.h
[lining@localhost program]$ touch b.h
[lining@localhost program]$ touch c.h

      
        1
      
       #include <stdlib.h>

  
      
        2
      
       #include <stdio.h>

  
      
        3
      
       #include 
      
        "
      
      
        a.h
      
      
        "
      
      
        4
      
      
        extern
      
      
        void
      
      
         function_two();

  
      
      
        5
      
      
        extern
      
      
        void
      
      
         function_three();

  
      
      
        6
      
      
        void
      
      
         main()

  
      
      
        7
      
      
         {

  
      
      
        8
      
      
                 function_two();

  
      
      
        9
      
      
                 function_three();

 
      
      
        10
      
               printf(
      
        "
      
      
        %s\n
      
      
        "
      
      ,
      
        "
      
      
        This is a test
      
      
        "
      
      
        );

 
      
      
        11
      
       }
    

2.c 和3.c

      
        /*
      
      
         2.c 
      
      
        */
      
      
        1
      
       #include 
      
        "
      
      
        a.h
      
      
        "
      
      
        2
      
       #include 
      
        "
      
      
        b.h
      
      
        "
      
      
        3
      
      
        void
      
      
         function_two(){

  
      
      
        4
      
      
         }


      
      
        /*
      
      
         3.c 
      
      
        */
      
      
        1
      
       #include 
      
        "
      
      
        b.h
      
      
        "
      
      
        2
      
       #include 
      
        "
      
      
        c.h
      
      
        "
      
      
        3
      
      
        void
      
      
         function_three(){

  
      
      
        4
      
       }
    

然后執(zhí)行make命令:make -f makefile1生成目標(biāo)文件myapp,再執(zhí)行如下命令:

[lining@localhost program]$ ./myapp
This is a test
如果我們使用變量將使得我們在以后的維護(hù)過程中更加方面,我們把上面的makefile文件改造

      CC=
      
        gcc

CFLAGS1
      
      =-
      
        o

CFLAGS2
      
      =-
      
        c

myapp:    main.o 
      
      
        2
      
      .o 
      
        3
      
      
        .o

      $(CC) $(CFLAGS1) $@ main.o 
      
      
        2
      
      .o 
      
        3
      
      
        .o     

main.o:    main.c a.h

      $(CC) $(CFLAGS2) main.c


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h

      $(CC) $(CFLAGS2) 
      
      
        2
      
      
        .c


      
      
        3
      
      .o:    
      
        3
      
      
        .c b.h c.h

      $(CC) $(CFLAGS2) 
      
      
        3
      
      
        .c 

clean:

      rm main.o

      rm 
      
      
        2
      
      
        .o

      rm 
      
      
        3
      
      .o
    

使用 clean 可將中間生成的文件做必要的清理,這樣目標(biāo)就沒有依賴關(guān)系了。在正常情況下,如果沒有告訴Make執(zhí)行clean命令(make -f makefile1 clean),clean將永遠(yuǎn)不被執(zhí)行。

Make在makefile中沒有指明具體處理規(guī)則時會采用慣例來處理。例如,將后綴.c的文件編譯為.o文件,也就說說我們不必寫出將后綴.c的文件編譯為.o文件的規(guī)則,Make命令就自動識別并執(zhí)行。常見的隱含規(guī)則如下:

?????? C 程序編譯: .o文件自動由同名的.c文件生成,編譯命令為: $(CC) -c $(CPPFLAGS) $(CFLAGS)

?????? C++程序編譯: .o文件自動由同名的.c文件或.cc文件生成,編譯命令為:$(CXX) -c $(CPPFLAGS) $(CFLAGS)

  Pascal程序編譯: .o文件自動由同名的.p生成,編譯命令為:$(PC) -c $(PFLAGS)

makefile的模式規(guī)則:

?????? Make支持編寫模式規(guī)則來定義用戶自己的隱含規(guī)則。相比于一般的規(guī)則,模式規(guī)則在形式上只是含有“%”的通配符(其功能類似于shell中的“*”)。如果確定了依賴關(guān)系中的“%”模式,Make就會按要求去匹配當(dāng)前目錄下的所有文件名,一旦找到符合規(guī)則的文件,Make就會執(zhí)行該規(guī)則下的命令。如

      %.o : %
      
        .c

               $(CC) 
      
      -c $(CFLAGS) $(CPPFLAGS) $< -o $@
    

該模式規(guī)則表示當(dāng)前目錄下的所有以.c結(jié)尾的文件編譯成以.o結(jié)尾的目標(biāo)文件。宏$<將被擴(kuò)展為起始文件的名字。而$@將被替換成生成的目標(biāo)文件。

?關(guān)于調(diào)試的知識將在以后的章節(jié)中介紹。

?



linux 編程技術(shù)No.1前期準(zhǔn)備工作


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲视频在线观看免费视频 | 日本在线一卡二卡毛片 | 黄色小视频在线免费观看 | 黄页网址大全免费观看美女 | 日干夜操 | 成人综合婷婷国产精品久久免费 | 美日韩中文字幕 | 一区二区手机视频 | 日韩精品欧美成人 | 欧美日韩成人高清色视频 | 欧美激情一区 | 福利视频自拍 | 天天透天天插 | 欧美人牲囗毛片 | 欧美成人手机在线视频 | 久久久网 | 最新狠狠色狠狠色综合 | 一及毛片 | 91在线小视频 | 中文字幕亚洲高清综合 | 精品国产成人综合久久小说 | 一区二区三区四区国产 | 国产精品原创永久在线观看 | 成人久久18免费游戏网站 | 免费人成在线观看网站品爱网 | 日本黄色免费一级片 | 91精品国产免费久久久久久 | 国产一级淫片a | 一区二区中文字幕 | 深夜在线看 | 久久久久久久国产a∨ | 亚洲五月综合缴情婷婷 | 九九九久久久久久久爱 | 免费视频一区二区性色 | 亚洲欧美日韩国产精品影院 | 香蕉成人 | 欧美 日韩 国产在线 | 青青青青久久精品国产一百度 | 大杳焦伊人久久综合热 | 国产在热线精品视频国产一二 | 国内视频自拍 |