gcc常用選項

 

  -Idir   將dir中頭文件添加到工程中(注意是大寫的 i 加上路徑),這個路徑可以是相對路徑,也可以是絕對路徑,相對路徑就是表示以當前Makefile來做相對
-lname                                                                                         (注意是小寫的 L加上庫名)這種方式是鏈接程序時,使用到了名字爲name的庫(靜態或者動態)。如果你在鏈接時使用到了動態庫,那麼需要將這個動態庫導入到系統lib中(有興趣的可以查找下ldconfig這個命令)。或者修改LD_LIBRARY_PATH環境變量。如果使用的是靜態庫,那麼程序運行時不需要將靜態庫導入到系統lib中。當然使用動態庫編譯出來的程序體積要小。
-Ldir1 將指定目錄中的動態鏈接庫加入到編譯環境中,如果鏈接時,會從這個加入的目錄中尋找動態庫。
-g 表示編譯時,程序中帶調試信息,支持gdb調試,如果不加-g,那麼gdb是無法調試你的程序的。
-Wall   表示開啓gcc能夠提供的警告信息。
-On  其中n表示一個數值,表示優化級別,通常用-O2。
static 表示鏈接時,只使用靜態庫,如果需要鏈接的庫名只有動態庫而沒有靜態庫,那麼會報錯。
-share 我在使用這個命令的時候,gcc報錯,說無法識別這個參數。網上看到很多人說gcc有這個參數,反正我是沒用上。有待考證
-shared   表示生成動態庫,如gcc test.c -fPIC -shared -o libtest.so 。 如果test.c用到了別的庫,那麼在編譯動態庫時,還需要指定動態庫名稱。
如test.c中調用了libhello.so中的函數。那麼使用下面命令編譯(假設libhello.so就在test.c目錄中)
gcc test.c -fPIC  -shared -o libtest.so -L. -lhello
-DBT_DEBUG  表示給這個工程定義一個宏,宏的名字是 BT_DEBUG。這個很有用,在程序開發中會加入很多log信息,但是在產品中卻不需要那麼多log信息,藉助編譯器這個參數,可以編譯出帶log和不帶log的程序。


下面使用3個簡單的源文件進行測試,三個文件的位置關係是:

[root@AY140517072824856a84Z test]# ls -l
total 12
-rw-r--r-- 1 root root   63 Jun 14 20:51 add.c
-rw-r--r-- 1 root root  155 Jun 14 19:51 hello.c
drwxr-xr-x 2 root root 4096 Jun 14 20:57 static
[root@AY140517072824856a84Z test]# ls -l ./static/
total 4
-rw-r--r-- 1 root root 40 Jun 14 19:52 del.c

明白了吧。hello.c和add.c是文件,static是目錄,這三個在同級目錄,而static目錄中有個文件時del.c。

源文件hello.c:

#include <stdio.h>

int main()
{
        printf("1 + 2 = %d\n",add(1,2));
        printf("5 - 8 = %d\n",del(5,10));
        return 0;
}

源文件add.c:

#ifdef BT_DEBUG
int add(int a,int b)
{
        return (a-b);
}
#endif

源文件del.c:

int del(int a,int b)
{
        return (a-b);
}

如上面3個文件所示,main函數在hello.c中。而add.c文件中有個預處理指令用來測試-D參數。

首先將add.c編譯成動態庫,不使用-D參數:

#gcc -fPIC -shared add.c -o libadd.so

帶-D參數再次編譯add.c。生成的庫名爲libdadd.so

#gcc -fPIC -shared add.c -o libdadd.so -DBT_DEBUG

接下來編譯static目錄中的del.c。將其編譯成靜態庫,方法如下:

#gcc -c static/del.c  -o ./static/del.o
#ar cr ./static/libdel.a ./static/del.o

接下來編譯hello.c文件,並做鏈接生成可執行程序。首先使用libadd.so作爲鏈接(這個不帶-D參數編譯出來的動態庫),執行結果如下:
[root@AY140517072824856a84Z test]# gcc hello.c -L. -L./static -ladd -ldel
/tmp/ccc3mopN.o: In function `main':
hello.c:(.text+0x14): undefined reference to `add'
collect2: ld returned 1 exit status
[root@AY140517072824856a84Z test]# 
如上面所示,找不到add這個函數。爲什麼?因爲沒有帶-DBT_DEBUG。導致沒有這個宏,那麼add.c中就不會編譯add這個函數了。接下來使用libdadd.so庫做鏈接。

#gcc hello.c -L. -L./static -ldadd -ldel

這次順利通過。執行結果如下:

[root@AY140517072824856a84Z test]# ./a.out 
./a.out: error while loading shared libraries: libdadd.so: cannot open shared object file: No such file or directory
[root@AY140517072824856a84Z test]# 

提示找不到libdadd.so這個動態庫。使用動態庫作連接的,需要將動態庫導入系統lib中,或者設置LD_LIBRARY_PATH。下面設置這個變量:

export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

再次運行:

[root@AY140517072824856a84Z test]# ./a.out 
1 + 2 = -1
5 - 8 = -5
[root@AY140517072824856a84Z test]# 

如上面所示,del爲靜態庫,dadd爲動態庫。那麼如果在編譯hello.c時,加上-static會出現什麼情況?

[root@AY140517072824856a84Z test]# gcc hello.c -L. -L./static -ldadd -ldel -static
/usr/bin/ld: cannot find -ldadd
collect2: ld returned 1 exit status
[root@AY140517072824856a84Z test]# 
如上面信息所示.-ldadd是動態庫,所以加上-static後,鏈接時不會尋找動態庫。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章