日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 昵稱15515903 2014-02-11

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

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

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

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

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

gcc命令提供了非常多的命令選項(xiàng),但并不是所有都要熟悉,初學(xué)時(shí)掌握幾個(gè)常用的就可以了,到后面再慢慢學(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)化級(jí)別1編譯程序。級(jí)別為1~3,級(jí)別越大優(yōu)化效果越好,但編譯時(shí)間越長(zhǎng)。


.多源文件的編譯方法


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

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


1.多個(gè)文件一起編譯

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

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


2.分別編譯各個(gè)源文件,之后對(duì)編譯后輸出的目標(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的搜尋會(huì)從-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
會(huì)去找-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針對(duì)486進(jìn)行代碼優(yōu)化)
代碼生成選項(xiàng)(CODEGENERATION OPTION)  (-fpic-fPIC)





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

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

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

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

-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è)定文件所使用的語言,使后綴名無效,對(duì)以后的多個(gè)有效.也就是根據(jù)約定C語言的后
綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個(gè)性,決定你的C代碼文件的后綴
名是.pig哈哈,那你就要用這個(gè)參數(shù),這個(gè)參數(shù)對(duì)他后面的文件名都起作用,除非到了
下一個(gè)參數(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)掉上一個(gè)選項(xiàng),也就是讓gcc根據(jù)文件名后綴,自動(dòng)識(shí)別文件類型
  例子用法:
  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ù)處理,這個(gè)不生成文件,你需要把它重定向到一個(gè)輸出文件里面.
  例子用法:
  gcc-E hello.c > pianoapan.txt
  gcc-E hello.c | more
  慢慢看吧,一個(gè)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
  只對(duì)g++起作用,使用這個(gè)選項(xiàng),g++將對(duì)不帶參數(shù)的函數(shù),都認(rèn)為是沒有顯式的對(duì)參數(shù)
的個(gè)數(shù)和類型說明,而不是沒有參數(shù).
  而gcc無論是否使用這個(gè)參數(shù),都將對(duì)沒有帶參數(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
  這四個(gè)參數(shù)是對(duì)char類型進(jìn)行設(shè)置,決定將char類型設(shè)置成unsignedchar(前兩個(gè)參
數(shù))或者signedchar(后兩個(gè)參數(shù))
  
-includefile
  包含某個(gè)代碼,簡(jiǎn)單來說,就是便以某個(gè)文件,需要另一個(gè)文件的時(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
  取消對(duì)任何非標(biāo)準(zhǔn)宏的定義
  
-Idir
  在你是用#include"file"的時(shí)候,gcc/g++會(huì)先在當(dāng)前目錄查找你所制定的頭文件,
果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,
  回先在你所制定的目錄查找,然后再按常規(guī)的順序去找.
  對(duì)于#include<file>,gcc/g++會(huì)到-I制定的目錄查找,查找不到,然后將到系統(tǒng)的缺
省的頭文件目錄查找
  
-I-
  就是取消前一個(gè)參數(shù)的功能,所以一般在-Idir之后使用
  
-idirafterdir
  在-I的目錄里面查找失敗,講到這個(gè)目錄里面查找.
  
-iprefixprefix
-iwithprefix dir
  一般一起使用,當(dāng)-I的目錄查找失敗,會(huì)到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í)候分析程序,用這個(gè)很方便的

  
-M
  生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴的所有源代碼你可以用gcc-M hello.c
來測(cè)試一下,很簡(jiǎn)單。
  
-MM
  和上面的那個(gè)一樣,但是它將忽略由#include<file>造成的依賴關(guān)系。
  
-MD
  和-M相同,但是輸出將導(dǎo)入到.d的文件里面
  
-MMD
  和-MM相同,但是輸出將導(dǎo)入到.d的文件里面
  
-Wa,option
  此選項(xiàng)傳遞option給匯編程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),
后傳遞給會(huì)匯編程序
  
-Wl.option
  此選項(xiàng)傳遞option給連接程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),
后傳遞給會(huì)連接程序.
  
-llibrary
  制定編譯的時(shí)候使用的庫
  例子用法
  gcc-lcurses hello.c
  使用ncurses庫編譯程序
  
-Ldir
  制定編譯的時(shí)候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然
  編譯器將只在標(biāo)準(zhǔn)庫的目錄找。這個(gè)dir就是目錄的名稱。
  
-O0
-O1
-O2
-O3
  編譯器的優(yōu)化選項(xiàng)的4個(gè)級(jí)別,-O0表示沒有優(yōu)化,-O1為缺省值,-O3優(yōu)化級(jí)別最高 
   
-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)將禁止使用動(dòng)態(tài)庫,所以,編譯出來的東西,一般都很大,也不需要什么
動(dòng)態(tài)連接庫,就可以運(yùn)行.
-share
  此選項(xiàng)將盡量使用動(dòng)態(tài)庫,所以生成文件比較小,但是需要系統(tǒng)由動(dòng)態(tài)庫.
-traditional
  試圖讓編譯器支持傳統(tǒng)的C語言特性
[
參考資料]
-Linux/UNIX
高級(jí)編程
  中科紅旗軟件技術(shù)有限公司編著.清華大學(xué)出版社出版
-Gccman page
  
[ChangeLog]
-2002-08-10
  ver0.1發(fā)布最初的文檔
-2002-08-11
  ver0.11修改文檔格式
-2002-08-12
  ver0.12加入了對(duì)靜態(tài)庫,動(dòng)態(tài)庫的參數(shù)
-2002-08-16
  ver0.16增加了gcc編譯的4個(gè)階段的命令
運(yùn)行gcc/egcs
**********
運(yùn)行gcc/egcs***********************
  GCCGNUCC++編譯器。實(shí)際上,GCC能夠編譯三種語言:C、C++O
bject C
C語言的一種面向?qū)ο髷U(kuò)展)。利用gcc命令可同時(shí)編譯并連接CC++
源程序。
  如果你有兩個(gè)或少數(shù)幾個(gè)C源文件,也可以方便地利用GCC編譯、連接并生成可
執(zhí)行文件。例如,假設(shè)你有兩個(gè)源文件main.cfactorial.c兩個(gè)源文件,現(xiàn)在要編
譯生成一個(gè)計(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++源文件,而不能自動(dòng)和C
++
程序使用的庫連接。因此,通常使用g++命令來完成C++程序的編譯和連接,該程
序會(huì)自動(dòng)調(diào)用gcc實(shí)現(xiàn)編譯。假設(shè)我們有一個(gè)如下的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
針對(duì)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
取消對(duì)MACRO宏的定義。
-w
不生成任何警告信息。
-Wall
生成所有警告信息。

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

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

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

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

       hello.c(見程序2)是函數(shù)庫的源程序,其中包含公用函數(shù)hello,該函數(shù)將在屏幕上輸出"HelloXXX!"。hello.h(見程序1)為該函數(shù)庫的頭文件。main.c(見程序3)為測(cè)試庫文件的主程序,在主程序中調(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)庫,還是動(dòng)態(tài)庫,都是由.o文件創(chuàng)建的。因此,我們必須將源程序hello.c通過gcc先編譯成.o文件。

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

        #gcc -c hello.c

        #

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

       (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將會(huì)從靜態(tài)庫中將公用函數(shù)連接到目標(biāo)文件中。注意,gcc會(huì)在靜態(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)建動(dòng)態(tài)庫。我們還是從.o文件開始。

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

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

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

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

        #

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

        #ls

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

        #

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

       在程序中使用動(dòng)態(tài)庫和使用靜態(tài)庫完全一樣,也是在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明動(dòng)態(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

        #

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

        #mv libmyhello.so /usr/lib

        #./hello

        Helloeveryone!

        #

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

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

       先刪除除.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和動(dòng)態(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和動(dòng)態(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)庫和動(dòng)態(tài)庫同名時(shí),gcc命令將優(yōu)先使用動(dòng)態(tài)庫。


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

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

  不同類型的應(yīng)用程序?qū)?huì)使用不同的函數(shù)庫。例如:libdbm庫中組包含了對(duì)數(shù)據(jù)庫文件進(jìn)行訪問的dbm函數(shù),需要對(duì)數(shù)據(jù)庫進(jìn)行操作的程序就會(huì)與該庫進(jìn)行連接。數(shù)學(xué)應(yīng)用程序?qū)⑹褂脭?shù)學(xué)庫libmX-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)、共享和動(dòng)態(tài)。靜態(tài)庫的代碼在編譯時(shí)就已連接到開發(fā)人員開發(fā)的應(yīng)用程序中,而共享庫只是在程序開始運(yùn)行時(shí)才載入,在編譯時(shí),只是簡(jiǎn)單地指定需要使用的庫函數(shù)。動(dòng)態(tài)庫則是共享庫的另一種變化形式。動(dòng)態(tài)庫也是在程序運(yùn)行時(shí)載入,但與共享庫不同的是,使用的庫函數(shù)不是在程序運(yùn)行開始,而是在程序中的語句需要使用該函數(shù)時(shí)才載入。動(dòng)態(tài)庫可以在程序運(yùn)行期間釋放動(dòng)態(tài)庫所占用的內(nèi)存,騰出空間供其它程序使用。由于共享庫和動(dòng)態(tài)庫并沒有在程序中包括庫函數(shù)的內(nèi)容,只是包含了對(duì)庫函數(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和版本號(hào)組成,靜態(tài)庫的后綴名為.a。采用舊的a.out格式的共享庫的后綴名為.sa。
  libname.so.major.minor
  libname.a

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

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

  在/usr/lib/lib目錄中可以找到絕大多數(shù)的共享庫。連接時(shí)將首先搜索這兩個(gè)目錄。有一些庫也可能存放在特定的目錄中,在/etc/ld.conf配置文件中給出了這些目錄的列表。連接程序也會(huì)對(duì)列出的這些目錄進(jìn)行搜索。在默認(rèn)情況下,Linux將首先搜索指定庫的共享版本,如果找不到,才會(huì)去搜索靜態(tài)版本。在對(duì)共享庫進(jìn)行更新或安裝新庫后,必須運(yùn)行ldconfig命令更新/etc/ld.conf文件中相應(yīng)的項(xiàng)(如果使用RPM進(jìn)行安裝,一般會(huì)自動(dòng)進(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程序,請(qǐng)注意這里的-lm選項(xiàng)。
  $gccmain.c io.c -o bookrecs -lm

  系統(tǒng)中還有一些其它可用的庫,常用的是libncurses.a庫,包含了一些簡(jiǎn)單的鼠標(biāo)移動(dòng)例程。在命令行中使用-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í),就不再需要庫文件了。動(dòng)態(tài)庫正好相反,在編譯連接時(shí),沒有把庫文件的代碼加入到可執(zhí)行文件中,所以生成的文件較小,但運(yùn)行時(shí),仍需要加載庫文件

  .a是靜態(tài)庫文件,可以用ar命令生成。
  .so是動(dòng)態(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 ,編寫成動(dòng)態(tài)鏈接庫
  1.先編譯成test1.otest2.o test3.o
  2.gcc -shared -W1, -soname,libvTest.so.1 -o libvTest.so.1.0*.o





二、正確編譯與命名動(dòng)態(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
  

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多