gcc 優化選項 -O1 -O2 -O3 -Os 優先級,-fomit-frame-pointer

少優化->多優化:

O0 -->> O1 -->> O2 -->> O3

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


英文解析:

`-O '
`-O1 '
? ? ? ? ? ? ? ? Optimize.? ? ? Optimizing ? compilation ? takes ? somewhat ? more ? time, ? and ? a
? ? ? ? ? ? ? ? lot ? more ? memory ? for ? a ? large ? function.
?
? ? ? ? ? ? ? ? With ? `-O ', ? the ? compiler ? tries ? to ? reduce ? code ? size ? and ? execution
? ? ? ? ? ? ? ? time, ? without ? performing ? any ? optimizations ? that ? take ? a ? great ? deal
? ? ? ? ? ? ? ? of ? compilation ? time.
?
? ? ? ? ? ? ? ? `-O ' ? turns ? on ? the ? following ? optimization ? flags:
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fdefer-pop? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fdelayed-branch? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fguess-branch-probability? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fcprop-registers? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -floop-optimize? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fif-conversion? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fif-conversion2? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-ccp? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-dce? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-dominator-opts? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-dse? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-ter? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-lrs? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-sra? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-copyrename? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-fre? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-ch? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -funit-at-a-time? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fmerge-constants
?
? ? ? ? ? ? ? ? `-O ' ? also ? turns ? on ? `-fomit-frame-pointer ' ? on ? machines ? where ? doing
? ? ? ? ? ? ? ? so ? does ? not ? interfere ? with ? debugging.
?
? ? ? ? ? ? ? ? `-O ' ? doesn 't ? turn ? on ? `-ftree-sra ' ? for ? the ? Ada ? compiler.? ? ? This
? ? ? ? ? ? ? ? option ? must ? be ? explicitly ? specified ? on ? the ? command ? line ? to ? be
? ? ? ? ? ? ? ? enabled ? for ? the ? Ada ? compiler.
?
`-O2 '
? ? ? ? ? ? ? ? Optimize ? even ? more.? ? ? GCC ? performs ? nearly ? all ? supported
? ? ? ? ? ? ? ? optimizations ? that ? do ? not ? involve ? a ? space-speed ? tradeoff.? ? ? The
? ? ? ? ? ? ? ? compiler ? does ? not ? perform ? loop ? unrolling ? or ? function ? inlining ? when
? ? ? ? ? ? ? ? you ? specify ? `-O2 '.? ? ? As ? compared ? to ? `-O ', ? this ? option ? increases
? ? ? ? ? ? ? ? both ? compilation ? time ? and ? the ? performance ? of ? the ? generated ? code.
?
? ? ? ? ? ? ? ? `-O2 ' ? turns ? on ? all ? optimization ? flags ? specified ? by ? `-O '.? ? ? It ? also
? ? ? ? ? ? ? ? turns ? on ? the ? following ? optimization ? flags:
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fthread-jumps? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fcrossjumping? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -foptimize-sibling-calls? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fcse-follow-jumps? ? ? -fcse-skip-blocks? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fgcse? ? ? -fgcse-lm ? ? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fexpensive-optimizations? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fstrength-reduce? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -frerun-cse-after-loop? ? ? -frerun-loop-opt? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fcaller-saves? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fpeephole2? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fschedule-insns? ? ? -fschedule-insns2? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fsched-interblock? ? ? -fsched-spec? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fregmove? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fstrict-aliasing? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -fdelete-null-pointer-checks? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -freorder-blocks? ? ? -freorder-functions? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -falign-functions? ? ? -falign-jumps? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -falign-loops? ? ? -falign-labels? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-vrp? ?
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -ftree-pre
?
? ? ? ? ? ? ? ? Please ? note ? the ? warning ? under ? `-fgcse ' ? about ? invoking ? `-O2 ' ? on
? ? ? ? ? ? ? ? programs ? that ? use ? computed ? gotos.
?
`-O3 '
? ? ? ? ? ? ? ? Optimize ? yet ? more.? ? ? `-O3 ' ? turns ? on ? all ? optimizations ? specified ? by
? ? ? ? ? ? ? ? `-O2 ' ? and ? also ? turns ? on ? the ? `-finline-functions ',
? ? ? ? ? ? ? ? `-funswitch-loops ' ? and ? `-fgcse-after-reload ' ? options.
?
`-O0 '
? ? ? ? ? ? ? ? Do ? not ? optimize.? ? ? This ? is ? the ? default.?


///==================另外還有個Os選項==========================

http://hi.baidu.com/ah__fu/blog/item/cc9fd19b801948bdc9eaf4b3.html

在研究編譯驅動的makefile的時候,發現GCC的命令行里面有一個-Os的優化選項。
? ? 遍查GCC文檔,發現了-O0, -O1, -O2, -O3,就是沒有發現-Os
? ? 祭出GOOGLE***搜了一下,終于發現這篇文章說明了-Os的作用:
http://www.linuxjournal.com/article/7269

?? 原來-Os相當于-O2.5。是使用了所有-O2的優化選項,但又不縮減代碼尺寸的方法。
?? 詳細的說明如下:
Level 2.5 (-Os)

The special optimization level (-Os or size) enables all -O2 optimizations that do not increase code size; it puts the emphasis on size over speed. This includes all second-level optimizations, except for the alignment optimizations. The alignment optimizations skip space to align functions, loops, jumps and labels to an address that is a multiple of a power of two, in an architecture-dependent manner. Skipping to these boundaries can increase performance as well as the size of the resulting code and data spaces; therefore, these particular optimizations are disabled. The size optimization level is enabled as:

gcc -Os -o test test.c

In gcc 3.2.2, reorder-blocks is enabled at -Os, but in gcc 3.3.2 reorder-blocks is disabled.

==============================
補充:在GCC的官方文檔里又發現了關于-Os的說明:
http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Optimize-Options.html#Optimize-Options

?



//=============================================

http://blog.csdn.net/ison81/archive/2009/05/07/4158576.aspx

?

backtracefomit-frame-pointer選項

?

事實上gcc的所有級別的優化(-O, -O2, -O3等)都會打開-fomit-frame-pointer,該選項的功能是函數調用時不保存frame指針,在ARM上就是fp,故我們無法按照APCS中的約定來回溯調用棧。但是GDB中仍然可以使用bt命令看到調用棧,為什么?得知GDB v6之后都是支持DWARF2的,也就意味著它可以不依賴fp來回溯調用棧(詳見http://gcc.gnu.org/ml/gcc/2003-10/msg00322.html)。

看來想在代碼中動態顯示調用棧而又不希望使用GDB的朋友,只能在編譯時關掉-fomit-frame-pointer了。

?

//==================gcc參數大全:===========================

?


[介紹]
gcc and g++
分別是gnuc & c++編譯器 gcc/g++在執行編譯工作的時候,總共需要4
1.
預處理,生成.i的文件[預處理器cpp]
2.
將預處理后的文件不轉換成匯編語言,生成文件.s[編譯器egcs]
3.
有匯編變為目標代碼(機器代碼)生成.o的文件[匯編器as]
4.
連接目標代碼,生成可執行程序[鏈接器ld]

[參數詳解]
-x language filename
 設定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根據約定C語言的后綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個性,決定你的C代碼文件的后綴名是.pig哈哈,那你就要用這個參數,這個參數對他后面的文件名都起作用,除非到了下一個參數的使用。
  可以使用的參數嗎有下面的這些
  `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `assembler-with-cpp'.
  看到英文,應該可以理解的。
  例子用法:
  gcc -x c hello.pig
  
-x none filename
  關掉上一個選項,也就是讓gcc根據文件名后綴,自動識別文件類型
  例子用法:
  gcc -x c hello.pig -x none hello2.c
  
-c
  只激活預處理,編譯,和匯編,也就是他只把程序做成obj文件
  例子用法:
  gcc -c hello.c
  他將生成.oobj文件

-S
  只激活預處理和編譯,就是指把文件編譯成為匯編代碼。
  例子用法
  gcc -S hello.c
  他將生成.s的匯編代碼,你可以用文本編輯器察看

-E
  只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件里面.
  例子用法:
  gcc -E hello.c > pianoapan.txt
  gcc -E hello.c | more
  慢慢看吧,一個hello word也要與處理成800行的代碼

-o
  制定目標名稱,缺省的時候,gcc編譯出來的文件是a.out,很難聽,如果你和我有同感,改掉它,哈哈
  例子用法
  gcc -o hello.exe hello.c (,windows用習慣了)
  gcc -o hello.asm -S hello.c

-pipe
  使用管道代替編譯中臨時文件,在使用非gnu匯編工具的時候,可能有些問題
  gcc -pipe -o hello.exe hello.c

-ansi
  關閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一些asm inline typeof關鍵字,以及UNIX,vax等預處理宏,

-fno-asm
  此選項實現ansi選項的功能的一部分,它禁止將asm,inlinetypeof用作關鍵字。    
-fno-strict-prototype
  只對g++起作用,使用這個選項,g++將對不帶參數的函數,都認為是沒有顯式的對參數的個數和類型說明,而不是沒有參數.
  而gcc無論是否使用這個參數,都將對沒有帶參數的函數,認為城沒有顯式說明的類型
  
-fthis-is-varialble
  就是向傳統c++看齊,可以使用this當一般變量使用.
  
-fcond-mismatch
  允許條件表達式的第二和第三參數類型不匹配,表達式的值將為void類型
  
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
  這四個參數是對char類型進行設置,決定將char類型設置成unsigned char(前兩個參數)或者 signed char(后兩個參數)
  
-include file
  包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以用它設定,功能就相當于在代碼中使用#include<filename>
  例子用法:
  gcc hello.c -include /root/pianopan.h
  
-imacros file
  將file文件的宏,擴展到gcc/g++的輸入文件,宏定義本身并不出現在輸入文件中
  
-Dmacro
  相當于C語言中的#define macro
  
-Dmacro=defn
  相當于C語言中的#define macro=defn
  
-Umacro
  相當于C語言中的#undef macro

-undef
  取消對任何非標準宏的定義
  
-Idir
  在你是用#include"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭文件,如果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,
  回先在你所制定的目錄查找,然后再按常規的順序去找.
  對于#include<file>,gcc/g++會到-I制定的目錄查找,查找不到,然后將到系統的缺省的頭文件目錄查找
  
-I-
  就是取消前一個參數的功能,所以一般在-Idir之后使用
  
-idirafter dir
  在-I的目錄里面查找失敗,講到這個目錄里面查找.
  
-iprefix prefix
-iwithprefix dir
  一般一起使用,-I的目錄查找失敗,會到prefix+dir下查找
  
-nostdinc
  使編譯器不再系統缺省的頭文件目錄里面找頭文件,一般和-I聯合使用,明確限定頭文件的位置
  
-nostdin C++
  規定不在g++指定的標準路經中搜索,但仍在其他路徑中搜索,.此選項在創libg++庫使用
  
-C
  在預處理的時候,不刪除注釋信息,一般和-E使用,有時候分析程序,用這個很方便的
  
-M
  生成文件關聯的信息。包含目標文件所依賴的所有源代碼你可以用gcc -M hello.c來測試一下,很簡單。
  
-MM
  和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關系。
  
-MD
  和-M相同,但是輸出將導入到.d的文件里面
  
-MMD
  和-MM相同,但是輸出將導入到.d的文件里面
  
-Wa,option
  此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選項,然后傳遞給會匯編程序
  
-Wl.option
  此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選項,然后傳遞給會連接程序.

-llibrary
  制定編譯的時候使用的庫
  例子用法
  gcc -lcurses hello.c
  使用ncurses庫編譯程序
  
-Ldir
  制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然
  編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。
  
-O0
-O1
-O2
-O3
  編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高    
-g
  只是編譯器,在編譯的時候,產生調試信息。
  
-gstabs
  此選項以stabs格式聲稱調試信息,但是不包括gdb調試信息.
  
-gstabs+
  此選項以stabs格式聲稱調試信息,并且包含僅供gdb使用的額外調試信息.
  
-ggdb
  此選項將盡可能的生成gdb的可以使用的調試信息.

-static
  此選項將禁止使用動態庫,所以,編譯出來的東西,一般都很大,也不需要什么
動態連接庫,就可以運行.

-share
  此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.

-traditional
  試圖讓編譯器支持傳統的C語言特性

[參考資料]
-Linux/UNIX高級編程
  中科紅旗軟件技術有限公司編著.清華大學出版社出版
-Gcc man page
  
[ChangeLog]
-2002-08-10
  ver 0.1 發布最初的文檔
-2002-08-11
  ver 0.11 修改文檔格式
-2002-08-12
  ver 0.12 加入了對靜態庫,動態庫的參數
-2002-08-16
  ver 0.16 增加了gcc編譯的4個階段的命令

運行 gcc/egcs

**********運行 gcc/egcs***********************
  GCC GNU C C++編譯器。實際上,GCC 能夠編譯三種語言:CC++ Object CC語言的一種面向對象擴展)。利用 gcc命令可同時編譯并連接 C C++ 源程序。
  如果你有兩個或少數幾個 C 源文件,也可以方便地利用 GCC 編譯、連接并生成可執行文件。例如,假設你有兩個源文件 main.c factorial.c 兩個源文件,現在要編譯生成一個計算階乘的程序。
代碼:

-----------------------
清單 factorial.c
-----------------------
int factorial (int n)
{
  if (n <= 1)
   return 1;
  else
   return factorial (n - 1) * n;
}
-----------------------
清單 main.c
-----------------------
#include <stdio.h>
#include <unistd.h>

int factorial (int n);
int main (int argc, char **argv)
{
  int n;

  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));
   }
  return 0;
}


-----------------------
利用如下的命令可編譯生成可執行文件,并執行程序:
$ gcc -o factorial main.c factorial.c
$ ./factorial 5
Factorial of 5 is 120.

  GCC 可同時用來編譯 C 程序和 C++程序。一般來說,C 編譯器通過源文件的后綴名來判斷是 C 程序還是 C++ 程序。在 Linux中,C 源文件的后綴名為 .c,而 C++源文件的后綴名為 .C .cpp。但是,gcc命令只能編譯 C++ 源文件,而不能自動和 C++ 程序使用的庫連接。因此,通常使用 g++ 命令來完成 C++ 程序的編譯和連接,該程序會自動調用 gcc實現編譯。假設我們有一個如下的 C++源文件(hello.C):
#include <iostream>
void main (void)
{
  cout << "Hello, world!" << endl;
}

則可以如下調用 g++ 命令編譯、連接并生成可執行文件:
$ g++ -o hello hello.C
$ ./hello
Hello, world!


**********************gcc/egcs 的主要選項*********
gcc 命令的常用選項
選項 解釋
-ansi 只支持 ANSI標準的 C 語法。這一選項將禁止 GNU C 的某些特色,
例如 asm typeof 關鍵詞。
-c 只編譯并生成目標文件。
-DMACRO 以字符串“1”定義 MACRO宏。
-DMACRO=DEFN 以字符串“DEFN”定義 MACRO宏。
-E 只運行 C 預編譯器。
-g 生成調試信息。GNU 調試器可利用該信息。
-IDIRECTORY 指定額外的頭文件搜索路徑DIRECTORY
-LDIRECTORY 指定額外的函數庫搜索路徑DIRECTORY
-lLIBRARY 連接時搜索指定的函數庫LIBRARY
-m486 針對 486 進行代碼優化。
-o FILE 生成指定的輸出文件。用在生成可執行文件時。
-O0 不進行優化處理。
-O -O1 優化生成代碼。
-O2 進一步優化。
-O3 -O2 更進一步優化,包括 inline 函數。
-shared 生成共享目標文件。通常用在建立共享庫時。
-static 禁止使用共享連接。
-UMACRO 取消對 MACRO宏的定義。
-w 不生成任何警告信息。
-Wall 生成所有警告信息。





Linux GCC常用命令

1簡介

2簡單編譯

2.1預處理

2.2編譯為匯編代碼(Compilation)

2.3匯編(Assembly)

2.4連接(Linking)

3多個程序文件的編譯

4檢錯

5庫文件連接

5.1編譯成可執行文件

5.2鏈接

5.3強制鏈接時使用靜態鏈接庫

1簡介

GCC 的意思也只是 GNU C Compiler 而已。經過了這么多年的發展,GCC 已經不僅僅能支持 C 語言;它現在還支持 Ada 語言、C++ 語言、Java 語言、Objective C 語言、Pascal 語言、COBOL語言,以及支持函數式編程和邏輯編程的 Mercury 語言,等等。而 GCC 也不再單只是 GNU C 語言編譯器的意思了,而是變成了 GNU Compiler Collection 也即是 GNU 編譯器家族的意思了。另一方面,說到 GCC 對于操作系統平臺及硬件平臺支持,概括起來就是一句話:無所不在。

2簡單編譯

示例程序如下:

//test.c

#include <stdio.h>

int main(void)

{

? ? printf("Hello World!\n");

? ? return 0;

}

這個程序,一步到位的編譯指令是:

gcc test.c -o test



實質上,上述編譯過程是分為四個階段進行的,即預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、匯編 (Assembly)和連接(Linking)

2.1預處理

gcc -E test.c -o test.i gcc -E test.c

?

可以輸出test.i文件中存放著test.c經預處理之后的代碼。打開test.i文件,看一看,就明白了。后面那條指令,是直接在命令行窗口中輸出預處理后的代碼.

gcc-E選項,可以讓編譯器在預處理后停止,并輸出預處理結果。在本例中,預處理結果就是將stdio.h 文件中的內容插入到test.c中了。

2.2編譯為匯編代碼(Compilation)

預處理之后,可直接對生成的test.i文件編譯,生成匯編代碼:

gcc -S test.i -o test.s

gcc-S選項,表示在程序編譯期間,在生成匯編代碼后,停止,-o輸出匯編代碼文件。

2.3匯編(Assembly)

對于上一小節中生成的匯編代碼文件test.sgas匯編器負責將其編譯為目標文件,如下:

gcc -c test.s -o test.o

2.4連接(Linking)

gcc連接器是gas提供的,負責將程序的目標文件與所需的所有附加的目標文件連接起來,最終生成可執行文件。附加的目標文件包括靜態連接庫和動態連接庫。

對于上一小節中生成的test.o,將其與C標準輸入輸出庫進行連接,最終生成程序test

gcc test.o -o test

?

在命令行窗口中,執行./test, 讓它說HelloWorld吧!

3多個程序文件的編譯

通常整個程序是由多個源文件組成的,相應地也就形成了多個編譯單元,使用GCC能夠很好地管理這些編譯單元。假設有一個由test1.c test2.c兩個源文件組成的程序,為了對它們進行編譯,并最終生成可執行程序test,可以使用下面這條命令:

gcc test1.c test2.c -o test

如果同時處理的文件不止一個,GCC仍然會按照預處理、編譯和鏈接的過程依次進行。如果深究起來,上面這條命令大致相當于依次執行如下三條命令:

gcc -c test1.c -o test1.o

gcc -c test2.c -o test2.o

gcc test1.o test2.o -o test



4檢錯

gcc -pedantic illcode.c -o illcode

-pedantic編譯選項并不能保證被編譯程序與ANSI/ISO C標準的完全兼容,它僅僅只能用來幫助Linux程序員離這個目標越來越近。或者換句話說,-pedantic選項能夠幫助程序員發現一些不符合 ANSI/ISO C標準的代碼,但不是全部,事實上只有ANSI/ISO C語言標準中要求進行編譯器診斷的那些情況,才有可能被GCC發現并提出警告。

除了-pedantic之外,GCC還有一些其它編譯選項也能夠產生有用的警告信息。這些選項大多以-W開頭,其中最有價值的當數-Wall了,使用它能夠使GCC產生盡可能多的警告信息。

gcc -Wall illcode.c -o illcode

GCC給出的警告信息雖然從嚴格意義上說不能算作錯誤,但卻很可能成為錯誤的棲身之所。一個優秀的Linux程序員應該盡量避免產生警告信息,使自己的代碼始終保持標準、健壯的特性。所以將警告信息當成編碼錯誤來對待,是一種值得贊揚的行為!所以,在編譯程序時帶上-Werror選項,那么GCC會在所有產生警告的地方停止編譯,迫使程序員對自己的代碼進行修改,如下:

gcc -Werror test.c -o test

?


5庫文件連接

開發軟件時,完全不使用第三方函數庫的情況是比較少見的,通常來講都需要借助許多函數庫的支持才能夠完成相應的功能。從程序員的角度看,函數庫實際上就是一些頭文件(.h)和庫文件(so、或libdll)的集合。。雖然Linux下的大多數函數都默認將頭文件放到/usr/include/目錄下,而庫文件則放到/usr/lib/目錄下;Windows所使用的庫文件主要放在Visual Stido的目錄下的includelib,以及系統文件夾下。但也有的時候,我們要用的庫不再這些目錄下,所以GCC在編譯時必須用自己的辦法來查找所需要的頭文件和庫文件。

例如我們的程序test.c是在linux上使用c連接mysql,這個時候我們需要去mysql官網下載MySQL ConnectorsC庫,下載下來解壓之后,有一個include文件夾,里面包含mysql connectors的頭文件,還有一個lib文件夾,里面包含二進制so文件libmysqlclient.so

其中inclulde文件夾的路徑是/usr/dev/mysql/include,lib文件夾是/usr/dev/mysql/lib

?

5.1編譯成可執行文件

首先我們要進行編譯test.c為目標文件,這個時候需要執行

gcc –c –I /usr/dev/mysql/include test.c –o test.o

5.2鏈接

最后我們把所有目標文件鏈接成可執行文件:

gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test

Linux下的庫文件分為兩大類分別是動態鏈接庫(通常以.so結尾)和靜態鏈接庫(通常以.a結尾),二者的區別僅在于程序執行時所需的代碼是在運行時動態加載的,還是在編譯時靜態加載的。

5.3強制鏈接時使用靜態鏈接庫

默認情況下, GCC在鏈接時優先使用動態鏈接庫,只有當動態鏈接庫不存在時才考慮使用靜態鏈接庫,如果需要的話可以在編譯時加上-static選項,強制使用靜態鏈接庫。

/usr/dev/mysql/lib目錄下有鏈接時所需要的庫文件libmysqlclient.solibmysqlclient.a,為了讓GCC在鏈接時只用到靜態鏈接庫,可以使用下面的命令:

gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test

?

靜態庫鏈接時搜索路徑順序:

1. ld會去找GCC命令中的參數-L
2. 再找gcc的環境變量LIBRARY_PATH
3. 再找內定目錄 /lib /usr/lib /usr/local/lib 這是當初compile gcc時寫在程序內的

動態鏈接時、執行時搜索路徑順序:

1. 編譯目標代碼時指定的動態庫搜索路徑
2.
環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑
3.
配置文件/etc/ld.so.conf中指定的動態庫搜索路徑
4.
默認的動態庫搜索路徑/lib
5.
默認的動態庫搜索路徑/usr/lib

有關環境變量:
LIBRARY_PATH
環境變量:指定程序靜態鏈接庫文件搜索路徑
LD_LIBRARY_PATH
環境變量:指定程序動態鏈接庫文件搜索路徑



本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383339.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383339.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383339.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

const 和 #define 區別總結

const有類型&#xff0c;可進行編譯器安全檢查&#xff0c;#define 無類型&#xff0c;不可進行類型檢查const 有作用域&#xff0c;而#define 不重視作用域&#xff0c;默認定義在指定作用域下有效的常量&#xff0c;那么#define 就不能用&#xff08;可以用#undef結束宏定義生…

Eclipse : Unresolved inclusion

Eclipse 中新建C 或C 到項目時&#xff0c;頭文件報警&#xff0c;顯示“Unresolved inclusion:<stdio.h>” 雖然不影響項目到編譯和運行&#xff0c;確也無法查看頭文件&#xff0c;讓人感覺實在不爽。下面是在國外到網站上看到解決方案&#xff0c;自己整理了一下拿來分…

c++對const增強 和cosnt分配內存情況

const增強 c語言中const是偽常量&#xff0c;可以通過指針修改 c中const會放到符號表中 c語言中const默認是外部連接&#xff0c;c中const默認是內部鏈接 #include<iostream> using namespace std;const int m_a 10; //在全局區域里&#xff0c;受到保護&…

Linux下crontab命令的用法

任務調度的crond常駐命令 crond 是linux用來定期執行程序的命令。當安裝完成操作系統之后&#xff0c;默認便會啟動此任務調度命令。crond命令每分鍾會定期檢查是否有要執行的工作&#xff0c;如果有要執行的工作便會自動執行該工作。而linux任務調度的工作主要分為以下兩類&am…

c++中引用的作用

引用的基本語法 用途起別名 Type &別名原名 引用必須初始化 一旦初始化后&#xff0c;不能修改 對數組建立引用 #include<iostream>using namespace std;//1.引用基本語法 Type &別名原名void test01(){int a 10;int &b a;cout << "a"…

LVM (Logic Volume Management,邏輯卷管理)

是傳統商業Unix就帶有的一項高級磁盤管理工具&#xff0c;異常強大。后來LVM移植到了Linux操作系統上&#xff0c;盡管不像原來Unix版本那么強大&#xff0c;但瘦死的駱駝比馬大&#xff0c;Linux的LVM仍然非常強大&#xff0c;可以在生產運行系統上面直接在線擴展硬盤分區&…

cpu中的MMU的作用

虛擬內存與物理內存之間的映射 用戶空間映射到物理內存是獨立的&#xff0c;提高安全性修改內存訪問級別 &#xff08;0是最高級&#xff09;

Linux命令行與Shell腳本編程大全讀書筆記

Linux內核4大主要功能&#xff1a; 內存管理 進程管理 設備管理 文件系統管理 Linux系統啟動的進程和腳本管理 1./etc/inittab 管理系統開機時會自動啟動的進程 2./etc/init.d 管理開機時啟動或停止某個應用的腳本放在這個目錄下&#xff0c;/etc/rcX.d目錄在啟動時&…

拷貝構造函數的總結

構造函數的分類及調用 按照參數分類 1.無參構造&#xff08;默認構造&#xff09; 2.有參構造按照類型分類 1.普通構造函數2.拷貝構造函數無參構造寫法和調用 Person p1; 注意不能寫Person (),因為編譯器認為這個是函數聲明有參構造函數寫法 和調用 Person p2(10) 或者Per…

技術與技巧札記

Linux常用命令及技巧&#xff1a; &#xff08;1&#xff09;cat /proc/version 查看當前內核的版本 (2) 掛載nfs文件夾&#xff1a;需要先確認在&#xff0f;etc&#xff0f;exports文件&#xff0c;可以用于開發板掛載的文件夾 mount -o nolock 10.0.22.30:/root/sharednfs …

c++中new的總結(動態管理,malloc存在的問題,malloc與new的區別)

c中使用malloc出現的問題 程序員必須確定對象的長度malloc 返回一個&#xff08;void *&#xff09;指針 &#xff0c;c不允許將&#xff08;void*) 賦值給其它指針&#xff0c;必須強轉malloc可能申請內存失敗&#xff0c;所以必須判斷返回值來保存內存分配成功用戶在使用對象…

Linux中變量#,@,0,1,2,*,$$,$?的含義

$# 是傳給腳本的參數個數 $0 是腳本本身的名字 $1 是傳遞給該shell腳本的第一個參數 $2 是傳遞給該shell腳本的第二個參數 $ 是傳給腳本的所有參數的列表 $* 是以一個單字符串顯示所有向腳本傳遞的參數&#xff0c;與位置變量不同&#xff0c;參數可超過9個 $$ 是腳本運行的當前…

Volatile的陷阱

最近寫的關于在嵌入式開發中常遇到的關于volatile關鍵字使用的短文&#xff0c;都是些通用的技術&#xff0c;貼上來share。 對于volatile關鍵字&#xff0c;大部分的C語言教材都是一筆帶過&#xff0c;并沒有做太過深入的分析&#xff0c;所以這里簡單整理了一些關于volatile的…

c++中靜態成員變量和靜態成員函數

靜態成員變量 在一個類中&#xff0c;若將一個成員變量聲明為static,這種成員成為靜態成員變量&#xff0c;與一般的數據成員不同&#xff0c;無論建立了多少個對象&#xff0c;都只想有一個靜態數據的拷貝&#xff0c;靜態成員變量&#xff0c;屬于某個類&#xff0c;所有對象…

單列模式(餓漢)

單例模式案例 目的&#xff1a;為了讓類中只有一個實例&#xff0c;實例不需要自己釋放將 默認構造 和 拷貝構造 私有化內部維護一個 對象的指針私有化唯一指針對外提供getinstance方法來訪問這個指針保證類中只能實例化唯一 一個對象 主席案例 #include<iostream>usin…

Makefile札記

Makefile中: ? 的區別 在Makefile中我們經常看到 : ? 這幾個賦值運算符&#xff0c;那么他們有什么區別呢&#xff1f;我們來做個簡單的實驗 新建一個Makefile&#xff0c;內容為&#xff1a; ifdef DEFINE_VRE VRE “Hello World!” else endif ifeq ($(OPT),define) VRE…

c++中this指針基本概念和使用

class Person { public:int m_A;//非靜態成員變量&#xff0c;屬于對象上void func(/*Person * this*/){}; //非靜態成員函數 不屬于對象身上static int m_B;//靜態成員函數&#xff0c;不屬于對象上static void fun2(){};//靜態成員函數 &#xff0c;不屬于對象身上//double …

通用Makefile實現

Makefile是Linux下程序開發的自動化編譯工具&#xff0c;一個好的Makefile應該準確的識別編譯目標與源文件的依賴關系&#xff0c;并且有著高效的編譯效率&#xff0c;即每次重新make時只需要處理那些修改過的文件即可。Makefile擁有很多復雜的功能&#xff0c;這里不可能也沒必…

c++中空指針訪問成員函數

如果成員函數沒有用到this &#xff0c;那么空指針可以直接訪問 如果成員函數用到this 指針&#xff0c;就要注意&#xff0c;要判斷是否為空&#xff0c;防止程序崩潰 #include<iostream>using namespace std;class Person{public:void show(){//沒有 用到this指針&am…

從0開始python學習-35.allure報告企業定制

目錄 1. 搭建allure環境 2. 生成報告 3. logo定制 4. 企業級報告內容或層級定制 5. allure局域網查看 1. 搭建allure環境 1.1 JDK&#xff0c;使用PyCharm 找到pycharm安裝目錄找到java.exe記下jbr目錄的完整路徑&#xff0c;eg: C:\Program Files\JetBrains\PyCharm Com…