概述
一般在做項目的時候,都忽略了這個步驟,因爲makefile是別人寫好的,自己只要執行make操作就ok了,
但是真正的項目開發,需要程序員有這項基本技能。
弄明白gcc/g++編譯器的基本參數和使用方法,在編譯make出錯後會有很大的幫助。
GCC使用心得
一個最爲基本的工程,包含一個頭文件.h和一個實現文件.c,還有一個測試文件test.cpp。
那麼如何讓這測試文件能順利編譯?
比如,現在在編寫一個關於string類,那麼會有String.h和String.c這2個文件,最後需要有一個測試文件test_string.cpp
那麼如何編譯這個測試文件呢?
小工具
1、查看Gcc默認查找的目錄
gcc –print-search-dirs
Gcc編譯器,會在搜索路徑下,查找共享庫,若存在,則鏈接它。
若不存在,則查找靜態庫,若只想鏈接靜態庫,可以指定-static選項
共享庫:鏈接時只是指定了動態鏈接器和程序所需的庫文件,沒有做真的鏈接,在運行時做動態鏈接;
靜態庫:鏈接器把靜態庫中的目錄文件取出來和可執行文件真正鏈接到一起
gcc –c xx.c
只編譯或者彙編源文件,但是不鏈接
2、如何編譯出共享庫
gcc -c -g -fPIC stack/stack.c stack/push.cstack/pop.c stack/is_empty.c
gcc -shared -o libstack.so stack.o push.opop.o is_empty.o
gcc main.c -g -L. -lstack -Istack -o main
3、查看可執行文件依賴哪些庫
Ldd /usr/lib64/librados.so.2.0.0.0
[root@lab205 ~]# ldd/usr/lib64/librados.so.2.0.0
linux-vdso.so.1 => (0x00007ffff012c000)
libssl3.so => /usr/lib64/libssl3.so (0x0000003036000000)
libsmime3.so => /usr/lib64/libsmime3.so (0x0000003035c00000)
libnss3.so => /usr/lib64/libnss3.so (0x0000003035000000)
libnssutil3.so =>/usr/lib64/libnssutil3.so (0x0000003034000000)
libplds4.so => /lib64/libplds4.so (0x0000003033800000)
libplc4.so => /lib64/libplc4.so (0x0000003033c00000)
libnspr4.so => /lib64/libnspr4.so (0x0000003034400000)
libpthread.so.0 =>/lib64/libpthread.so.0 (0x0000003030c00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003031000000)
libuuid.so.1 => /lib64/libuuid.so.1 (0x0000003035400000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x0000003036400000)
librt.so.1 => /lib64/librt.so.1 (0x0000003031400000)
libboost_thread-mt.so.5 => /usr/lib64/libboost_thread-mt.so.5(0x00000030c8200000)
libboost_system-mt.so.5 => /usr/lib64/libboost_system-mt.so.5(0x00000030c8e00000)
libleveldb.so.1 =>/usr/lib64/libleveldb.so.1 (0x00000030c8600000)
libsnappy.so.1 => /usr/lib64/libsnappy.so.1 (0x00000030c8a00000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00000030c3e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003031800000)
libc.so.6 => /lib64/libc.so.6 (0x0000003030800000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000030c4600000)
libz.so.1 => /lib64/libz.so.1 (0x0000003031c00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003030000000)
4、共享庫的搜索路徑由動態鏈接器指定
man ld.so
查找順序如下
A、 LD_LIBRARY_PATH (不建議修改)
B、 從緩存文件/etc/ld.so.cache中查找,涉及到ldconfig命令 (常用的方法)
修改/etc/ld.so.conf文件,加入共享庫的路徑,然後運行Ldconfig –v查看
C、 從/usr/lib、/lib中查找
把共享庫文件拷貝到/usr/lib或/lib下便於查找
5、共享庫命名
Real name 共享庫真實名稱,比如/usr/lib64/librados.so.2.0.0,包含完整的共享庫版本號
Soname 符號鏈接的名字,只包含共享庫的主版本號,如/usr/lib64/librados.so.2-> librados.so.2.0.0,
根據soname決定使用哪個共享庫,可以方便升級。比如,有的應用程序依賴librados.so.1,有的依賴librados.so.2,
那麼使用librados.so.1,真正的庫文件不管是librados.so.1.0.1還是librados.so.1.0.2都可以用。
Linker name 在編譯鏈接時使用,/usr/lib64/librados.so-> /usr/lib64/librados.so.2.0.0,因爲編譯器只認linker name,所以如果刪除了/usr/lib64/librados.so但是/usr/lib64/librados.so.2存在,仍然無法通過編譯,編譯器會報錯:找不到共享庫。
gcc的編譯優化選項有-O0、-O、-O1、-O2、-O3、-Os幾種。-O0表示不優化,這是缺省的選項。
-O1、-O2和-O3這幾個選項一個比一個優化得更多,編譯時間也更長。
-O和-O1相同。-Os表示爲縮小目標代碼尺寸而優化。