2022年2月21日 星期一

【暫存】gcc筆記

gcc signal_emit_demo.c -o signal_emit_demo -D_REENTRANT -lpthread `pkg-config --cflags --libs gtk+-2.0`

-c 編譯但不連結,將程式碼變成.o的object檔

-D 定義常數,表示有定義,在程式碼裡可以用#ifdef來判斷

-l 使用程式庫,以上例來說是使用pthread程式庫

-S 輸出組譯碼

-E 顯示預處理 (define, macro) 的結果

-o filename 指定輸出檔名

-ansi 只支持 ANSI 標準的 C 語法。這一選項將禁止 GNU C 的某些特色 例如 asm 或 typeof 關鍵詞。

-Dmacro 定義指定巨集為有效

-Dmarco=defn 定義指定巨集為 defn

-Wa,option 將選項 (option) 傳給組譯器

-wl,option 將選項 (option) 傳給連結器

-I 增加 include header 檔案的搜尋路徑

-L 增加 library 檔案的搜尋路徑

-l 指定連結的函式庫

-Wall 顯示所有的警告訊息

-g 編入除錯資訊 (使用 GDB 除錯時用)

-shared 生成共享目標文件。通常用在建立共享庫時。

-static 禁止使用共享連接。

-UMACRO 取消對 MACRO 宏的定義。

-w的意思是關閉編譯時的警告,也就是編譯後不顯示任何warning,因為有時在編譯之後編譯器會顯示一些例如數據轉換之類的警告,這些警告是我們平時可以忽略的。

-Wall選項意思是編譯後顯示所有警告。

-W選項類似-Wall,會顯示警告,但是只顯示編譯器認為會出現錯誤的警告。

-Wl… 是 gcc 傳給 static linker 的參數,參閱 man ld。在gcc中使用ld鏈接選項時,需要在選項前面加上前綴-Wl,以區別不是編譯器的選項。

沒加 -Wl… 是 gcc 用的參數,參閱 man gcc

-L: 「鏈接」的時候,去找的目錄,也就是所有的 -lFOO 選項裡的庫,都會先從 -L 指定的目錄去找,然後是默認的地方。 編譯時的-L選項並不影響環境變量LD_LIBRARY_PATH,-L只是指定了程序編譯連接時庫的路徑,並不影響程序執行時庫的路徑,系統還是會到默認路徑下查找該程序所需要的庫,如果找不到,還是會報錯,類似cannot open shared object file。

-rpath-link:這個也是用於「鏈接」的時候的,例如你顯示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,後者你並沒有指定,而是 FOO.so 引用到它,這個時候,會先從 -rpath-link 給的路徑裡找。

-rpath: 「運行」的時候,去找的目錄。運行的時候,要找 .so 文件,會從這個選項裡指定的地方去找。對於交叉編譯,交叉編譯鏈接器需已經配置 –with-sysroot 選項才能起作用。也就是說,-rpath指定的路徑會被記錄在生成的可執行程序中,用於運行時查找需要加載的動態庫。-rpath-link 則只用於鏈接時查找。

跨平臺編譯的時候時常會出現,rpath-link與rpath這兩個參數,簡單來說:

  • rpath-link用途用來連結編譯的路徑與-L相同
  • rpath用途為編譯完成後執行環境的路徑指定


最佳化

-Os, -O0, -O1, -O2, -O3,

-O0 表示沒有優化,-O1 為缺省值,-O3 優化級別最高


The linker uses the following search paths to locate required shared libraries:

1.  Any directories specified by -rpath-link options.

2.  Any directories specified by -rpath options.  The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option.

3.  On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH".

4.  On SunOS, if the -rpath option was not used, search any directories specified using -L options.

5.  For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH".

6.  For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist.

7.  The default directories, normally /lib and /usr/lib.

8.  For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file.

If the required shared library is not found, the linker will issue a warning and continue with the link.


檢查gcc搜尋哪些路徑

gcc -print-search-dirs


The linking is actually done by ld but it has its paths passed down to it by gcc. Probably the quickest way to find out what's going on is compile a helloworld.c program and strace it to see what is getting passed to ld and see what's going on.

檢查gcc傳什麼給ld

strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test


關閉某個warning message

-Wno-error=date-time 


Linux標頭檔案和庫檔案新增環境變數與GCC編譯器新增INCLUDE與LIB環境變數

對所有使用者有效在/etc/profile增加以下內容。只對當前使用者有效在Home目錄下的

.bashrc或.bash_profile裡增加下面的內容:

(注意:等號前面不要加空格,否則可能出現 command not found)


#在PATH中找到可執行檔案程式的路徑。

export PATH =$PATH:$HOME/bin


#gcc找到標頭檔案的路徑

C_INCLUDE_PATH=/usr/include/libxml2:/MyLib

export C_INCLUDE_PATH


#g++找到標頭檔案的路徑

CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/libxml2:/MyLib

export CPLUS_INCLUDE_PATH


#找到動態連結庫的路徑

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib

export LD_LIBRARY_PATH


#找到靜態庫的路徑

LIBRARY_PATH=$LIBRARY_PATH:/MyLib

export LIBRARY_PATH

沒有留言:

張貼留言