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

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

    • 分享

      gcc總結(jié)【基本用法】【選項(xiàng)】【動靜態(tài)庫】

       昵稱15515903 2014-02-11

      gcc總結(jié)【基本用法】【選項(xiàng)】【動靜態(tài)庫】

      1.////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      linuxc編程起步一:掌握gcc基本用法

       初學(xué)時(shí)最好從命令行入手,這樣可以熟悉從編寫程序、編譯、調(diào)試和執(zhí)行的整個過程。編寫程序可以用vi或其它編輯器編寫。

      編譯則使用gcc命令。要往下學(xué)習(xí)首先就得熟悉gcc命令的用法。

      gcc命令提供了非常多的命令選項(xiàng),但并不是所有都要熟悉,初學(xué)時(shí)掌握幾個常用的就可以了,到后面再慢慢學(xué)習(xí)其它選項(xiàng),免得因選項(xiàng)太多而打擊了學(xué)習(xí)的信心。


      .常用編譯命令選項(xiàng)

      假設(shè)源程序文件名為test.c。


      1.無選項(xiàng)編譯鏈接

      用法:#gcctest.c

      作用:將test.c預(yù)處理、匯編、編譯并鏈接形成可執(zhí)行文件。這里未指定輸出文件,默認(rèn)輸出為a.out。


      2.選項(xiàng)-o

      用法:#gcctest.c -o test

      作用:將test.c預(yù)處理、匯編、編譯并鏈接形成可執(zhí)行文件test。-o選項(xiàng)用來指定輸出文件的文件名。


      3.選項(xiàng)-E

      用法:#gcc-E test.c -o test.i

      作用:將test.c預(yù)處理輸出test.i文件。


      4.選項(xiàng)-S

      用法:#gcc-S test.i

      作用:將預(yù)處理輸出文件test.i匯編成test.s文件。


      5.選項(xiàng)-c

      用法:#gcc-c test.s

      作用:將匯編輸出文件test.s編譯輸出test.o文件。


      6.無選項(xiàng)鏈接

      用法:#gcctest.o -o test

      作用:將編譯輸出文件test.o鏈接成最終可執(zhí)行文件test。


      7.選項(xiàng)-O

      用法:#gcc-O1 test.c -o test

      作用:使用編譯優(yōu)化級別1編譯程序。級別為1~3,級別越大優(yōu)化效果越好,但編譯時(shí)間越長。


      .多源文件的編譯方法


      如果有多個源文件,基本上有兩種編譯方法:

      [假設(shè)有兩個源文件為test.ctestfun.c]


      1.多個文件一起編譯

      用法:#gcctestfun.c test.c -o test

      作用:將testfun.ctest.c分別編譯后鏈接成test可執(zhí)行文件。


      2.分別編譯各個源文件,之后對編譯后輸出的目標(biāo)文件鏈接。

      用法:

      #gcc-c testfun.c //testfun.c編譯成testfun.o

      #gcc-c test.c //test.c編譯成test.o

      #gcc-o testfun.o test.o -o test //testfun.otest.o鏈接成test


      以上兩種方法相比較,第一中方法編譯時(shí)需要所有文件重新編譯,而第二種方法可以只重新編譯修改的文件,未修改的文件不用重新編譯。


      gcc編程環(huán)境基礎(chǔ)5--編譯時(shí)頭文件和庫文件路徑指定


      預(yù)處理(preprocessing),編譯(compilation),匯編(assembly)和連接(linking)
      include
      header文件,連結(jié)數(shù)據(jù)庫,系統(tǒng)定義,總共有下列來源指定gcc去那找.
      當(dāng)初在編譯時(shí)指定的(~gcc/gcc/collect2.c:locatelib()
      寫在specs內(nèi)的
      后來用-D-I -L指定的
      gcc
      環(huán)境變量設(shè)定(編譯的時(shí)候)
      ld.so
      的環(huán)境變量(這是runtime的時(shí)候)
      =======================================
        1
      =======================================
      1.
      頭文件
      gcc
      在編譯時(shí)怎么去尋找所需要的頭文件
      所以headerfile的搜尋會從-I開始
      然后找gcc的環(huán)境變量C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
      再找內(nèi)定目錄
      /usr/include
      /usr/local/include
      /usr/lib/gcc-lib/i386-linux/2.95.2/include
      /usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
      /usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
      庫文件不過如果裝gcc的時(shí)候,是有給定的prefix的話,那么就是
      /usr/include
      prefix/include
      prefix/xxx-xxx-xxx-gnulibc/include
      prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include

      2.庫文件
      cos()
      等函式庫的選項(xiàng)要多加-lm
      編譯的時(shí)候:
      gcc
      會去找-L
      再找gcc的環(huán)境變量LIBRARY_PATH
      再找內(nèi)定目錄/lib/usr/lib /usr/local/lib這是當(dāng)初compilegcc時(shí)寫在程式內(nèi)的
      =======================================
          2
      =======================================

      2.利用Linux系統(tǒng)上已有的研發(fā)庫
      (1).
      查看庫文件提供了哪些調(diào)用
      能用nm命令自己查看庫文件提供了哪些調(diào)用
      (2).
      通過頭文件查看函數(shù)的定義
      =======================================
          3
      =======================================
      3.gcc
      選項(xiàng)
      總體選項(xiàng)(OverallOption)         :(-c(生成目標(biāo)但不連接)-S(匯編)-E(預(yù)處理)  -ofile(生成指定的文件)-pipe-v(顯示過程)    -xlanguage(設(shè)定文件所使用的語言,使后綴名無效`c’,可用參數(shù)`objective-c’,`c-header’, `c++’, `cpp-output’, `assembler’, and`assembler-with-cpp’))
      語言選項(xiàng)(LANGUAGEOPTIONS) :(-ansi只支持ANSI標(biāo)準(zhǔn)的C語法.這一選項(xiàng)將禁止GNU C的某些特色)
      預(yù)處理器選項(xiàng)(PreprocessorOption):(-Aassertion-C -dD -dM -dN -Dmacro[=defn] -E -H -idirafter dir -include file-imacros file -iprefix file -iwithprefix dir -M -MD -MM -MMD-nostdinc -P -Umacro相當(dāng)于C語言中的#undefmacro -undef -DMACRO以字符串1”定義MACRO, -DMACRO=DEFN以字符串DEFN”定義MACRO宏)
      匯編器選項(xiàng)(ASSEMBLEROPTION)     :(-Wa,option
      連接器選項(xiàng)(LINKEROPTION)        :(-llibrary-nostartfiles -nostdlib -static -shared -symbolic -Xlinker option-Wl,option -u symbol 
      目錄選項(xiàng)(DIRECTORYOPTION)       :(-Bprefix-Idir -I- -Ldir) 
      警告選項(xiàng)(WARNINGOPTION)  :(-w不生成所有警告信息,-Wall生成所有警告信息)
      調(diào)試選項(xiàng)(DEBUGGINGOPTION)       :(-a-dletters -fpretend-float -g -glevel -gcoff -gxcoff -gxcoff+ -gdwarf-gdwarf+ -gstabs -gstabs+ -ggdb  -p -pg -save-temps-print-file-name=library -print-libgcc-file-name-print-prog-name=program 
      優(yōu)化選項(xiàng)(OPTIMIZATIONOPTION)    :(-O0不進(jìn)行優(yōu)化處理,-O-O1優(yōu)化生成代碼-O2進(jìn)一步優(yōu)化 -O3-O2更進(jìn)一步優(yōu)化,包括inline函數(shù))
      目標(biāo)機(jī)選項(xiàng)(TARGETOPTION)  :(-bmachine -V version
      機(jī)器相關(guān)選項(xiàng)(MACHINEDEPENDENT OPTION):(-m486針對486進(jìn)行代碼優(yōu)化)
      代碼生成選項(xiàng)(CODEGENERATION OPTION)  (-fpic-fPIC)





      2.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////GCC選項(xiàng)
      GCC
      有超過100個的編譯選項(xiàng)可用.這些選項(xiàng)中的許多你可能永遠(yuǎn)都不會用到,但一些主要的選項(xiàng)將會頻繁用到.很多的GCC選項(xiàng)包括一個以上的字符.因此你必須為每個選項(xiàng)指定各自的連字符,并且就象大多數(shù)Linux命令一樣你不能在一個單獨(dú)的連字符后跟一組選項(xiàng).例如,下面的兩個命令是不同的:
      gcc -p -g test.c

      gcc -pg test.c
      第一條命令告訴GCC編譯test.c時(shí)為prof命令建立剖析(profile)信息并且把調(diào)試信息加入到可執(zhí)行的文件里.第二條命令只告訴GCCgprof命令建立剖析信息.

      當(dāng)你不用任何選項(xiàng)編譯一個程序時(shí),GCC將會建立(假定編譯成功)一個名為a.out的可執(zhí)行文件.例如,下面的命令將在當(dāng)前目錄下產(chǎn)生一個叫a.out的文件:
      gcc test.c
      你能用-o編譯選項(xiàng)來為將產(chǎn)生的可執(zhí)行文件指定一個文件名來代替a.out.例如,將一個叫count.cC程序編譯為名叫count的可執(zhí)行文件,你將輸入下面的命令:
      gcc -o count count.c

      注意:當(dāng)你使用-o選項(xiàng)時(shí),-o后面必須跟一個文件名.

      -c只編譯并生成目標(biāo)文件。

      --------------------------------------------------------------------------------
      gcc and g++
      分別是gnuc& c++編譯器gcc/g++在執(zhí)行編譯工作的時(shí)候,總共需要4

      1.
      預(yù)處理,生成.i的文件[預(yù)處理器cpp]
      2.
      將預(yù)處理后的文件不轉(zhuǎn)換成匯編語言,生成文件.s[編譯器egcs]
      3.
      有匯編變?yōu)槟繕?biāo)代碼(機(jī)器代碼)生成.o的文件[匯編器as]
      4.
      連接目標(biāo)代碼,生成可執(zhí)行程序[鏈接器ld]
      [
      參數(shù)詳解]
      -x language filename
       設(shè)定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根據(jù)約定C語言的后
      綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個性,決定你的C代碼文件的后綴
      名是.pig哈哈,那你就要用這個參數(shù),這個參數(shù)對他后面的文件名都起作用,除非到了
      下一個參數(shù)的使用。
        可以使用的參數(shù)嗎有下面的這些
        `c',`objective-c', `c-header', `c++', `cpp-output', `assembler', and `a
      ssembler-with-cpp'.
        看到英文,應(yīng)該可以理解的。
        例子用法:
        gcc-x c hello.pig
        
      -xnone filename
        關(guān)掉上一個選項(xiàng),也就是讓gcc根據(jù)文件名后綴,自動識別文件類型
        例子用法:
        gcc-x c hello.pig -x none hello2.c
        
      -c
        只激活預(yù)處理,編譯,和匯編,也就是他只把程序做成obj文件
        例子用法:
        gcc-c hello.c
        他將生成.oobj文件
      -S
        只激活預(yù)處理和編譯,就是指把文件編譯成為匯編代碼。
        例子用法
        gcc-S hello.c
        他將生成.s的匯編代碼,你可以用文本編輯器察看
      -E
        只激活預(yù)處理,這個不生成文件,你需要把它重定向到一個輸出文件里面.
        例子用法:
        gcc-E hello.c > pianoapan.txt
        gcc-E hello.c | more
        慢慢看吧,一個helloword也要與處理成800行的代碼
      -o
        制定目標(biāo)名稱,缺省的時(shí)候,gcc編譯出來的文件是a.out,很難聽,如果你和我有同感
      ,改掉它,哈哈
        例子用法
        gcc-o hello.exe hello.c (,windows用習(xí)慣了)
        gcc-o hello.asm -S hello.c
      -pipe
        使用管道代替編譯中臨時(shí)文件,在使用非gnu匯編工具的時(shí)候,可能有些問題
        gcc-pipe -o hello.exe hello.c
      -ansi
        關(guān)閉gnuc中與ansic不兼容的特性,激活ansic的專有特性(包括禁止一些asminl
      ine typeof
      關(guān)鍵字,以及UNIX,vax等預(yù)處理宏,
      -fno-asm
        此選項(xiàng)實(shí)現(xiàn)ansi選項(xiàng)的功能的一部分,它禁止將asm,inlinetypeof用作關(guān)鍵字。
          
      -fno-strict-prototype
        只對g++起作用,使用這個選項(xiàng),g++將對不帶參數(shù)的函數(shù),都認(rèn)為是沒有顯式的對參數(shù)
      的個數(shù)和類型說明,而不是沒有參數(shù).
        而gcc無論是否使用這個參數(shù),都將對沒有帶參數(shù)的函數(shù),認(rèn)為城沒有顯式說明的類型

        
      -fthis-is-varialble
        就是向傳統(tǒng)c++看齊,可以使用this當(dāng)一般變量使用.
        
      -fcond-mismatch
        允許條件表達(dá)式的第二和第三參數(shù)類型不匹配,表達(dá)式的值將為void類型
        
      -funsigned-char
      -fno-signed-char
      -fsigned-char
      -fno-unsigned-char
        這四個參數(shù)是對char類型進(jìn)行設(shè)置,決定將char類型設(shè)置成unsignedchar(前兩個參
      數(shù))或者signedchar(后兩個參數(shù))
        
      -includefile
        包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時(shí)候,就可以用它設(shè)
      ,功能就相當(dāng)于在代碼中使用#include<filename>
        例子用法:
        gcchello.c -include /root/pianopan.h
        
      -imacrosfile
        將file文件的宏,擴(kuò)展到gcc/g++的輸入文件,宏定義本身并不出現(xiàn)在輸入文件中
        
      -Dmacro
        相當(dāng)于C語言中的#definemacro
        
      -Dmacro=defn
        相當(dāng)于C語言中的#definemacro=defn
        
      -Umacro
        相當(dāng)于C語言中的#undefmacro
      -undef
        取消對任何非標(biāo)準(zhǔn)宏的定義
        
      -Idir
        在你是用#include"file"的時(shí)候,gcc/g++會先在當(dāng)前目錄查找你所制定的頭文件,
      果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,
        回先在你所制定的目錄查找,然后再按常規(guī)的順序去找.
        對于#include<file>,gcc/g++會到-I制定的目錄查找,查找不到,然后將到系統(tǒng)的缺
      省的頭文件目錄查找
        
      -I-
        就是取消前一個參數(shù)的功能,所以一般在-Idir之后使用
        
      -idirafterdir
        在-I的目錄里面查找失敗,講到這個目錄里面查找.
        
      -iprefixprefix
      -iwithprefix dir
        一般一起使用,當(dāng)-I的目錄查找失敗,會到prefix+dir下查找
        
      -nostdinc
        使編譯器不再系統(tǒng)缺省的頭文件目錄里面找頭文件,一般和-I聯(lián)合使用,明確限定頭
      文件的位置
        
      -nostdinC++
        規(guī)定不在g++指定的標(biāo)準(zhǔn)路經(jīng)中搜索,但仍在其他路徑中搜索,.此選項(xiàng)在創(chuàng)libg++
      使用
        
      -C
        在預(yù)處理的時(shí)候,不刪除注釋信息,一般和-E使用,有時(shí)候分析程序,用這個很方便的

        
      -M
        生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴的所有源代碼你可以用gcc-M hello.c
      來測試一下,很簡單。
        
      -MM
        和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關(guān)系。
        
      -MD
        和-M相同,但是輸出將導(dǎo)入到.d的文件里面
        
      -MMD
        和-MM相同,但是輸出將導(dǎo)入到.d的文件里面
        
      -Wa,option
        此選項(xiàng)傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選項(xiàng),
      后傳遞給會匯編程序
        
      -Wl.option
        此選項(xiàng)傳遞option給連接程序;如果option中間有逗號,就將option分成多個選項(xiàng),
      后傳遞給會連接程序.
        
      -llibrary
        制定編譯的時(shí)候使用的庫
        例子用法
        gcc-lcurses hello.c
        使用ncurses庫編譯程序
        
      -Ldir
        制定編譯的時(shí)候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然
        編譯器將只在標(biāo)準(zhǔn)庫的目錄找。這個dir就是目錄的名稱。
        
      -O0
      -O1
      -O2
      -O3
        編譯器的優(yōu)化選項(xiàng)的4個級別,-O0表示沒有優(yōu)化,-O1為缺省值,-O3優(yōu)化級別最高 
         
      -g
        只是編譯器,在編譯的時(shí)候,產(chǎn)生調(diào)試信息。
        
      -gstabs
        此選項(xiàng)以stabs格式聲稱調(diào)試信息,但是不包括gdb調(diào)試信息.
        
      -gstabs+
        此選項(xiàng)以stabs格式聲稱調(diào)試信息,并且包含僅供gdb使用的額外調(diào)試信息.
        
      -ggdb
        此選項(xiàng)將盡可能的生成gdb的可以使用的調(diào)試信息.
      -static
        此選項(xiàng)將禁止使用動態(tài)庫,所以,編譯出來的東西,一般都很大,也不需要什么
      動態(tài)連接庫,就可以運(yùn)行.
      -share
        此選項(xiàng)將盡量使用動態(tài)庫,所以生成文件比較小,但是需要系統(tǒng)由動態(tài)庫.
      -traditional
        試圖讓編譯器支持傳統(tǒng)的C語言特性
      [
      參考資料]
      -Linux/UNIX
      高級編程
        中科紅旗軟件技術(shù)有限公司編著.清華大學(xué)出版社出版
      -Gccman page
        
      [ChangeLog]
      -2002-08-10
        ver0.1發(fā)布最初的文檔
      -2002-08-11
        ver0.11修改文檔格式
      -2002-08-12
        ver0.12加入了對靜態(tài)庫,動態(tài)庫的參數(shù)
      -2002-08-16
        ver0.16增加了gcc編譯的4個階段的命令
      運(yùn)行gcc/egcs
      **********
      運(yùn)行gcc/egcs***********************
        GCCGNUCC++編譯器。實(shí)際上,GCC能夠編譯三種語言:CC++O
      bject C
      C語言的一種面向?qū)ο髷U(kuò)展)。利用gcc命令可同時(shí)編譯并連接CC++
      源程序。
        如果你有兩個或少數(shù)幾個C源文件,也可以方便地利用GCC編譯、連接并生成可
      執(zhí)行文件。例如,假設(shè)你有兩個源文件main.cfactorial.c兩個源文件,現(xiàn)在要編
      譯生成一個計(jì)算階乘的程序。
      代碼:
      -----------------------
      清單factorial.c
      -----------------------
      int factorial (int n)
      {
        if(n <= 1)
         return1;
        else
         returnfactorial (n - 1) * n;
      }
      -----------------------
      清單main.c
      -----------------------
      #include
       <stdio.h>
      #include
       <unistd.h>
      int factorial (int n);
      int main (int argc, char **argv)
      {
        intn;
        if(argc < 2)
        {
          printf("Usage: %s n\n", argv [0]);
          return-1;
        }
        else
        {
         n= atoi (argv[1]);
         printf("Factorial of %d is %d.\n", n, factorial (n));
        }
        return0;
      }
      -----------------------
      利用如下的命令可編譯生成可執(zhí)行文件,并執(zhí)行程序:
      $gcc -o factorial main.c factorial.c
      $ ./factorial 5
      Factorialof 5 is 120.
        GCC可同時(shí)用來編譯C程序和C++程序。一般來說,C編譯器通過源文件的后綴
      名來判斷是C程序還是C++程序。在Linux中,C源文件的后綴名為.c,而C++
      文件的后綴名為.C.cpp。但是,gcc命令只能編譯C++源文件,而不能自動和C
      ++
      程序使用的庫連接。因此,通常使用g++命令來完成C++程序的編譯和連接,該程
      序會自動調(diào)用gcc實(shí)現(xiàn)編譯。假設(shè)我們有一個如下的C++源文件(hello.C):
      #include<iostream>
      void main (void)
      {
        cout<< "Hello, world!" << endl;
      }
      則可以如下調(diào)用g++命令編譯、連接并生成可執(zhí)行文件:
      $g++ -o hello hello.C
      $ ./hello
      Hello, world!
      **********************gcc/egcs
      的主要選項(xiàng)*********
      gcc
      命令的常用選項(xiàng)
      選項(xiàng)解釋
      -ansi
      只支持ANSI標(biāo)準(zhǔn)的C語法。這一選項(xiàng)將禁止GNUC的某些特色,
      例如asmtypeof關(guān)鍵詞。
      -c
      只編譯并生成目標(biāo)文件。
      -DMACRO
      以字符串1”定義MACRO宏。
      -DMACRO=DEFN
      以字符串DEFN”定義MACRO宏。
      -E
      只運(yùn)行C預(yù)編譯器。
      -g
      生成調(diào)試信息。GNU調(diào)試器可利用該信息。
      -IDIRECTORY
      指定額外的頭文件搜索路徑DIRECTORY。
      -LDIRECTORY
      指定額外的函數(shù)庫搜索路徑DIRECTORY。
      -lLIBRARY
      連接時(shí)搜索指定的函數(shù)庫LIBRARY
      -m486
      針對486進(jìn)行代碼優(yōu)化。
      -oFILE
      生成指定的輸出文件。用在生成可執(zhí)行文件時(shí)。
      -O0
      不進(jìn)行優(yōu)化處理。
      -O
      -O1優(yōu)化生成代碼。
      -O2
      進(jìn)一步優(yōu)化。
      -O3
      -O2更進(jìn)一步優(yōu)化,包括inline函數(shù)。
      -shared
      生成共享目標(biāo)文件。通常用在建立共享庫時(shí)。
      -static
      禁止使用共享連接。
      -UMACRO
      取消對MACRO宏的定義。
      -w
      不生成任何警告信息。
      -Wall
      生成所有警告信息。

      3./////////////////////////////////////////////////動態(tài)靜態(tài)庫制作////////////////////////////////////////////////////////////////

      我們通常把一些公用函數(shù)制作成函數(shù)庫,供其它程序使用。函數(shù)庫分為靜態(tài)庫和動態(tài)庫兩種。靜態(tài)庫在程序編譯時(shí)會被連接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要該靜態(tài)庫。動態(tài)庫在程序編譯時(shí)并不會被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入,因此在程序運(yùn)行時(shí)還需要動態(tài)庫存在。本文主要通過舉例來說明在Linux中如何創(chuàng)建靜態(tài)庫和動態(tài)庫,以及使用它們。

             在創(chuàng)建函數(shù)庫前,我們先來準(zhǔn)備舉例用的源程序,并將函數(shù)庫的源程序編譯成.o文件。

             第1步:編輯得到舉例的程序--hello.h、hello.cmain.c;

             hello.c(見程序2)是函數(shù)庫的源程序,其中包含公用函數(shù)hello,該函數(shù)將在屏幕上輸出"HelloXXX!"hello.h(見程序1)為該函數(shù)庫的頭文件。main.c(見程序3)為測試庫文件的主程序,在主程序中調(diào)用了公用函數(shù)hello

               #ifndefHELLO_H
               #defineHELLO_H

               voidhello(const char *name);

               #endif//HELLO_H
              
      程序1:hello.h

               #include

               voidhello(const char *name)
              {
               printf("Hello %s!\n", name);
              }
              
      程序2:hello.c

               #include"hello.h"

               intmain()
              {
               hello("everyone");
               return 0;
              }
              
      程序3:main.c

              第2步:將hello.c編譯成.o文件;

             無論靜態(tài)庫,還是動態(tài)庫,都是由.o文件創(chuàng)建的。因此,我們必須將源程序hello.c通過gcc先編譯成.o文件。

              在系統(tǒng)提示符下鍵入以下命令得到hello.o文件。

              #gcc -c hello.c

              #

             (1:本文不介紹各命令使用和其參數(shù)功能,若希望詳細(xì)了解它們,請參考其他文檔。)

             (2:首字符"#"是系統(tǒng)提示符,不需要鍵入,下文相同。)

              我們運(yùn)行ls命令看看是否生存了hello.o文件。

              #ls

              hello.chello.h hello.o main.c

              #

              (3:首字符不是"#"為系統(tǒng)運(yùn)行結(jié)果,下文相同。)

             在ls命令結(jié)果中,我們看到了hello.o文件,本步操作完成。

              下面我們先來看看如何創(chuàng)建靜態(tài)庫,以及使用它。

              第3步:由.o文件創(chuàng)建靜態(tài)庫;

             靜態(tài)庫文件名的命名規(guī)范是以lib為前綴,緊接著跟靜態(tài)庫名,擴(kuò)展名為.a。例如:我們將創(chuàng)建的靜態(tài)庫名為myhello,則靜態(tài)庫文件名就是libmyhello.a。在創(chuàng)建和使用靜態(tài)庫時(shí),需要注意這點(diǎn)。創(chuàng)建靜態(tài)庫用ar命令。

             在系統(tǒng)提示符下鍵入以下命令將創(chuàng)建靜態(tài)庫文件libmyhello.a。

              #ar cr libmyhello.a hello.o

              #

              我們同樣運(yùn)行ls命令查看結(jié)果:

              #ls

              hello.chello.h hello.o libmyhello.a main.c


             #

              ls命令結(jié)果中有libmyhello.a。

              4步:在程序中使用靜態(tài)庫;

             靜態(tài)庫制作完了,如何使用它內(nèi)部的函數(shù)呢?只需要在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明靜態(tài)庫名,gcc將會從靜態(tài)庫中將公用函數(shù)連接到目標(biāo)文件中。注意,gcc會在靜態(tài)庫名前加上前綴lib,然后追加擴(kuò)展名.a得到的靜態(tài)庫文件名來查找靜態(tài)庫文件。

      在程序3:main.c中,我們包含了靜態(tài)庫的頭文件hello.h,然后在主程序main中直接調(diào)用公用函數(shù)hello。下面先生成目標(biāo)程序hello,然后運(yùn)行hello程序看看結(jié)果如何。

              #gcc -o hello main.c -L. -lmyhello

              #./hello

              Helloeveryone!

              #

             我們刪除靜態(tài)庫文件試試公用函數(shù)hello是否真的連接到目標(biāo)文件hello中了。

              #rm libmyhello.a

              rm:remove regular file `libmyhello.a'? y

              #./hello

              Helloeveryone!

              #

             程序照常運(yùn)行,靜態(tài)庫中的公用函數(shù)已經(jīng)連接到目標(biāo)文件中了。

             我們繼續(xù)看看如何在Linux中創(chuàng)建動態(tài)庫。我們還是從.o文件開始。

              5步:由.o文件創(chuàng)建動態(tài)庫文件;

             動態(tài)庫文件名命名規(guī)范和靜態(tài)庫文件名命名規(guī)范類似,也是在動態(tài)庫名增加前綴lib,但其文件擴(kuò)展名為.so。例如:我們將創(chuàng)建的動態(tài)庫名為myhello,則動態(tài)庫文件名就是libmyhello.so。用gcc來創(chuàng)建動態(tài)庫。

             在系統(tǒng)提示符下鍵入以下命令得到動態(tài)庫文件libmyhello.so。

              #gcc -shared -fPCI -o libmyhello.so hello.o

              #

              我們照樣使用ls命令看看動態(tài)庫文件是否生成。

              #ls

              hello.chello.h hello.o libmyhello.so main.c

              #

              6步:在程序中使用動態(tài)庫;

             在程序中使用動態(tài)庫和使用靜態(tài)庫完全一樣,也是在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明動態(tài)庫名進(jìn)行編譯。我們先運(yùn)行gcc命令生成目標(biāo)文件,再運(yùn)行它看看結(jié)果。

              #gcc -o hello main.c -L. -lmyhello

              #./hello

              ./hello:error while loading shared libraries: libmyhello.so: cannot openshared object file: No such file or directory

              #

             哦!出錯了??炜纯村e誤提示,原來是找不到動態(tài)庫文件libmyhello.so。程序在運(yùn)行時(shí),會在/usr/lib/lib等目錄中查找需要的動態(tài)庫文件。若找到,則載入動態(tài)庫,否則將提示類似上述錯誤而終止程序運(yùn)行。我們將文件libmyhello.so復(fù)制到目錄/usr/lib中,再試試?;蛘咴O(shè)置環(huán)境變量LD_LIBRARY_PATH到動態(tài)庫所在目錄

              #mv libmyhello.so /usr/lib

              #./hello

              Helloeveryone!

              #

             成功了。這也進(jìn)一步說明了動態(tài)庫在程序運(yùn)行時(shí)是需要的。

             我們回過頭看看,發(fā)現(xiàn)使用靜態(tài)庫和使用動態(tài)庫編譯成目標(biāo)程序使用的gcc命令完全一樣,那當(dāng)靜態(tài)庫和動態(tài)庫同名時(shí),gcc命令會使用哪個庫文件呢?抱著對問題必究到底的心情,來試試看。

             先刪除除.c.h外的所有文件,恢復(fù)成我們剛剛編輯完舉例程序狀態(tài)。

              #rm -f hello hello.o /usr/lib/libmyhello.so

              #ls

              hello.chello.h main.c

              #

             在來創(chuàng)建靜態(tài)庫文件libmyhello.a和動態(tài)庫文件libmyhello.so。

              #gcc -c hello.c

              #ar cr libmyhello.a hello.o

              #gcc -shared -fPCI -o libmyhello.so hello.o

              #ls

             hello.chello.h hello.o libmyhello.a libmyhello.so main.c

             #

             通過上述最后一條ls命令,可以發(fā)現(xiàn)靜態(tài)庫文件libmyhello.a和動態(tài)庫文件libmyhello.so都已經(jīng)生成,并都在當(dāng)前目錄中。然后,我們運(yùn)行gcc命令來使用函數(shù)庫myhello生成目標(biāo)文件hello,并運(yùn)行程序hello。

              #gcc -o hello main.c -L. -lmyhello

              #./hello

              ./hello:error while loading shared libraries: libmyhello.so: cannot openshared object file: No such file or directory

              #

             從程序hello運(yùn)行的結(jié)果中很容易知道,當(dāng)靜態(tài)庫和動態(tài)庫同名時(shí),gcc命令將優(yōu)先使用動態(tài)庫。


      4.///////////////////////////////////////////////////////////////////////動態(tài)庫編寫

      C語言中有一些函數(shù)不需要進(jìn)行編譯,有一些函數(shù)也可以在多個文件中使用。一般來說,這些函數(shù)都會執(zhí)行一些標(biāo)準(zhǔn)任務(wù),如數(shù)據(jù)庫輸入/輸出操作或屏幕控制等。可以事先對這些函數(shù)進(jìn)行編譯,然后將它們放置在一些特殊的目標(biāo)代碼文件中,這些目標(biāo)代碼文件就稱為庫。庫文件中的函數(shù)可以通過連接程序與應(yīng)用程序進(jìn)行連接。這樣就不必在每次開發(fā)程序時(shí)都對這些通用的函數(shù)進(jìn)行編譯了。

        不同類型的應(yīng)用程序?qū)褂貌煌暮瘮?shù)庫。例如:libdbm庫中組包含了對數(shù)據(jù)庫文件進(jìn)行訪問的dbm函數(shù),需要對數(shù)據(jù)庫進(jìn)行操作的程序就會與該庫進(jìn)行連接。數(shù)學(xué)應(yīng)用程序?qū)⑹褂脭?shù)學(xué)庫libm,X-Windows應(yīng)用程序?qū)⑹褂?/SPAN>Xlib庫,libX11。另外,所有的程序都將使用標(biāo)準(zhǔn)的C函數(shù)庫。libc,該庫中包含了諸好內(nèi)存管理或輸入輸出操作的基本函數(shù),這些庫都存放在/usr/lib這些系統(tǒng)公用的目錄中,系統(tǒng)中的任何用戶都可以利用這些庫。當(dāng)然用戶也可以建立自己專用的庫函數(shù),供自己或其它指定的人員使用。

        庫可以有三種使用的形式:靜態(tài)、共享和動態(tài)。靜態(tài)庫的代碼在編譯時(shí)就已連接到開發(fā)人員開發(fā)的應(yīng)用程序中,而共享庫只是在程序開始運(yùn)行時(shí)才載入,在編譯時(shí),只是簡單地指定需要使用的庫函數(shù)。動態(tài)庫則是共享庫的另一種變化形式。動態(tài)庫也是在程序運(yùn)行時(shí)載入,但與共享庫不同的是,使用的庫函數(shù)不是在程序運(yùn)行開始,而是在程序中的語句需要使用該函數(shù)時(shí)才載入。動態(tài)庫可以在程序運(yùn)行期間釋放動態(tài)庫所占用的內(nèi)存,騰出空間供其它程序使用。由于共享庫和動態(tài)庫并沒有在程序中包括庫函數(shù)的內(nèi)容,只是包含了對庫函數(shù)的引用,因此代碼的規(guī)模比較小。

        已經(jīng)開發(fā)的大多數(shù)庫都采取共享庫的方式。ELF格式的可執(zhí)行文件使得共享庫能夠比較容易地實(shí)現(xiàn),當(dāng)然使用舊的a.out模式也可以實(shí)現(xiàn)庫的共享。Linux系統(tǒng)中目前可執(zhí)行文件的標(biāo)準(zhǔn)格式為ELF格式。

        GNU庫的使用必須遵守LibraryGNU PublicLicense(LGPL許可協(xié)議)。該協(xié)議與GNU許可協(xié)議略有不同,開發(fā)人員可以免費(fèi)使用GNU庫進(jìn)行軟件開發(fā),但必須保證向用戶提供所用的庫函數(shù)的源代碼。

        系統(tǒng)中可用的庫都存放在/usr/lib/lib目錄中。庫文件名由前綴lib和庫名以及后綴組成。根據(jù)庫的類型不同,后綴名也不一樣。共享庫的后綴名由.so和版本號組成,靜態(tài)庫的后綴名為.a。采用舊的a.out格式的共享庫的后綴名為.sa。
        libname.so.major.minor
        libname.a

        這里的name可以是任何字符串,用來唯一標(biāo)識某個庫。該字符串可以是一個單字、幾個字符、甚至一個字母。數(shù)學(xué)共享庫的庫名為libm.so.5,這里的標(biāo)識字符為m,版本號為5。libm.a則是靜態(tài)數(shù)學(xué)庫。X-Windows庫名為libX11.so.6,這里使用X11作為庫的標(biāo)識,版本號為6。

        使用gcc編譯器就可以將庫與自己開發(fā)的程序連接起來,例如:libc.so.5中包含了標(biāo)準(zhǔn)的輸入輸出函數(shù),當(dāng)連接程序進(jìn)行目標(biāo)代碼連接時(shí)會自動搜索該程序并將其連接到生成的可執(zhí)行文件中。標(biāo)準(zhǔn)的輸入輸出庫中包含了許多基本的輸入輸出函數(shù),如printf函數(shù)等。也可以連接其它的一些系統(tǒng)函數(shù)庫,如數(shù)學(xué)庫等,但與libc.so.5不同,大部分其它的系統(tǒng)庫需要在命令行中顯式指定所用的庫名。

        在/usr/lib/lib目錄中可以找到絕大多數(shù)的共享庫。連接時(shí)將首先搜索這兩個目錄。有一些庫也可能存放在特定的目錄中,在/etc/ld.conf配置文件中給出了這些目錄的列表。連接程序也會對列出的這些目錄進(jìn)行搜索。在默認(rèn)情況下,Linux將首先搜索指定庫的共享版本,如果找不到,才會去搜索靜態(tài)版本。在對共享庫進(jìn)行更新或安裝新庫后,必須運(yùn)行ldconfig命令更新/etc/ld.conf文件中相應(yīng)的項(xiàng)(如果使用RPM進(jìn)行安裝,一般會自動進(jìn)行更新,不過也不能保證這一點(diǎn))。

        在gcc編譯器中引用可搜索到的目錄中的庫文件時(shí),需要使用-l選項(xiàng)和庫名。在gcc命令行上輸入-lm可以在程序中連接標(biāo)準(zhǔn)算術(shù)庫,-l將首先使用libname.so進(jìn)行搜索,這里是libm.so。下面的例子將使用算術(shù)庫創(chuàng)建bookrecs程序,請注意這里的-lm選項(xiàng)。
        $gccmain.c io.c -o bookrecs -lm

        系統(tǒng)中還有一些其它可用的庫,常用的是libncurses.a庫,包含了一些簡單的鼠標(biāo)移動例程。在命令行中使用-lncurses選項(xiàng)引用libncurses.so庫。下面的例子同時(shí)調(diào)用了數(shù)學(xué)和光標(biāo)庫。
        $gccmian.c io.c -o bookrecs -lm -lncurses

        在引用其它目錄中的庫時(shí),需要使用-ldir選項(xiàng)指定該目錄。該選項(xiàng)指定了搜索庫函數(shù)時(shí)其它路徑。在下面的例子中,用戶在連接時(shí)使用了mydir目錄中的myio.so庫文件。
        $gccmain.c -o bookrecs -lmydir -lmyio

        .a的是為了支持較老的a.out格式的可執(zhí)行文件的
        .so的是支持elf格式的可執(zhí)行文件的庫。

        靜態(tài)庫是指編譯連接時(shí),把庫文件的代碼全部加入到可執(zhí)行文件中,所以生成的文件較大,但運(yùn)行時(shí),就不再需要庫文件了。動態(tài)庫正好相反,在編譯連接時(shí),沒有把庫文件的代碼加入到可執(zhí)行文件中,所以生成的文件較小,但運(yùn)行時(shí),仍需要加載庫文件

        .a是靜態(tài)庫文件,可以用ar命令生成。
        .so是動態(tài)庫文件,編譯時(shí)加上指定的選項(xiàng)即可生成,具體選項(xiàng)看相應(yīng)的系統(tǒng)文檔了。。。。

        IBMAIX下如下:
        $(CC)(SHOPT)(SHLIBS)a.o b.o -o lib@(DBBUILDTAIL)

        假設(shè)你有test1.ctest2.c test3.c ,編寫成動態(tài)鏈接庫
        1.先編譯成test1.otest2.o test3.o
        2.gcc -shared -W1, -soname,libvTest.so.1 -o libvTest.so.1.0*.o





      二、正確編譯與命名動態(tài)鏈接庫:  g++   -shared   -fPIC   -Wall  -o   libMy.so   getdate.cc  gettime.cc  


          ###########    Makefile   ############  
         obj   =   libmy.so  
         CC   =   g++  
         all   :  
      (obj)  
         SRC   =   getdate.cc   gettime.cc  
         TGT   =  
      (SRC:.cc=.o)  
         
      (SRC)  :   adatetime.h  
                         @touch  
      @  
         %.o   :   %.c  
                         
      (CC)  -c  ?  
         
      (obj)  :  (TGT)  
                         
      (CC)  -shared   -fPIC   -Wall   -o  @  (TGT)  

      gcc  -shared   -fPIC   -o   libjcmpp.so  JCMPP.c   libtssx_cmpp.a   -I.  -I/opt/jdk142/include/   -I/opt/jdk142/include/linux
        

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多