修改gcc/g++默認include路徑
轉自:
http://www.network-theory.co.uk/docs/gccintro/gccintro_23.html
http://ilewen.com/questions/692
GCC: GNU C Complier(GNU C 編譯器)
不僅僅能支持C語言,它現在還支持 Ada、C++、Java、Objective-C、Pascal、COBOL 以及函數式編程和邏輯編程的
Mercury 語言等。因此,現在的 gcc 已經變成了 GNU Compiler Collection,也即是 GNU 編譯器套件.
g++: gcc 的一個版木,默認語言設置為C++,而且在連接的時候自動包含標准 C++ 庫。
GCC 使用的軟件工具:
1)addr2line
給出一個可執行文件的內部地址,addr2line使用文件中的調試信息將地址翻譯成源碼文件名和行號。該程序是binutils包的一部分。
2)ar
是一個程序,可以從文檔中增加、刪除和析取文件來維護庫文件。通常使用該工具是為了創建和管理連接程序使用的目標庫文檔。該程序是binutils包的一部分
3)as
GNU 匯編器。binutils包的一部分
4)autoconf
產生的 shell 腳本自動配置源代碼包去編譯某個特定版本的 UNIX
5)c++filt
程序接受被 C++ 編譯程序轉換過的名字(不是被重載的),而且將該名字翻澤成初始形式。 該程序是 binutils 包的一部分
6) gcov
gprof使用的配置工具,來確定程序運行時哪一部分耗時最大
7)gdb
GNU調試器,用於檢查程序運行時的值和行為
8)GNATS
GNU的調試跟蹤系統(GNU Bug Tracking System),一個跟蹤GCC和其他GNU軟件問題的在線系統
9)gprof
該程序會監督編譯程序的執行過程,並報告程序中各個函數的運行時間,可以根據所提供的配置文件來優化程序。該程序是 binutils 包的一部分
10)ld
GNU連接程序,該程序將目標文件的集合組合成可執行程序。binutils包的一部分
11) libtool
一個基本庫,支持make程序的描述文件使用的簡化共享庫用法的腳本
12) make
一個工具程序,它會讀makefile腳本來確定程序中的哪個部分需要編澤和連接,然后發布必要的命令。它讀出的腳本(叫做makefile或Makefile)定義了文件關系和依賴關系
13) nlmconv
將可重定位的目標文件轉換成NetWare可加載模塊(NetWare Loadable Module, NLM)。該程序是 binutils 的一部分
14) nm
列出目標文件中定義的符號。該程序是 binutils 包的一部分
15) objcopy
將目標文件從一種二進制格式復制和翻譯到另外一種。該程序是 binutils 包的一部分
16) objdump
顯示一個或多個目標文件中保存的多種不同信息。該程序是 binutils 包的一部分
17) ranlib
創建和添加到 ar 文檔的索引。該索引被ld使用來定位庫中的模塊, binutils包的一部分
18)ratfor
預處理程序可由 GCC激活,但不是標准GCC發布版的一部分
19)readelf
從 ELF 格式的目標文件顯示信息。該程序是 binutils 包的一部分
20) size
列出目標文件中每個部分的名字和尺寸。該程序是 binutils 包的一部分
21) strings
瀏覽所有類型的文件,析取出用於顯示的字符串。該程序是 binutils 包的一部
22) strip
從目標文件或文檔庫中去掉符號表,以及其他調試所需的信息。該程序是 binutils 包的一部
23) vcg
Ratfor 瀏覽器從文木文件中讀取信息,並以圖表形式顯示它們。而 vcg 工具並不是 GCC 發布中的一部分,但 -dv 選項可被用來產生 vcg 可以理解的優化數據的格式
24) windres
Window 資源文件編澤程序。該程序是 binutils 包的一部分
GCC 編譯器在編譯一個C語言程序時需要經過以下 4 步:
1) 將C語言源程序預處理,生成.i文件。
2) 預處理后的.i文件編譯成為匯編語言,生成.s文件。
3) 將匯編語言文件經過匯編,生成目標文件.o文件。
4) 將各個模塊的.o文件鏈接起來生成一個可執行程序文件。
過程如下:
c語言源文件----(預處理)--->預處理后的文件.i----(編譯)--->匯編文件.s----(匯編)--->目標文件.o----(鏈接)--->可執行程序
GCC常用選項:
1)-c
編譯、匯編指定的源文件,但是不進行鏈接
2) -S
編譯指定的源文件,但是不進行匯編
3) -E
預處理指定的源文件,但不進行編譯
4) -o [file1] [file2]
將文件2編譯成可執行文件file1
5) -I directory
指定include包含文件的搜索目錄
6) -g
生成調試信息,該程序可以被調試器調試
注意: 編譯選項區分大小寫
GCC 預處理器階段常用的選項:
1) -Dname[=definition]
在處理源文件之前,先定義宏name。宏name必須是在源文件和頭文件中都沒有被定義過的。將該選項搭配源代碼中的#ifdef name命令使用,可以實現條件式編譯。
如果沒有指定一個替換的值,該宏被定義為值 1。
2) -Uname
如果在命令行或 GCC 默認設置中定義過宏 name,則“取消”name 的定義。-D和-U選項會依據在命令行中出現的先后順序進行處理。
3) -Idirectory[:directory[...]]
當通過 #include 命令把所需的頭文件包括進源代碼中時,除系統標准 include 目錄之外,指定其他的目錄對這些頭文件進行搜索
4) -iquote directory[:directory[...]]
這是在最近 GCC 版本中新增的選項,它為在 #include 命令中采用引號而非尖括號指定的頭文件指定搜索目錄
5) -isystem directory[:directory[...]]
該選項在標准系統include目錄以外為系統頭文件指定搜索目錄,且它指定的目錄優先於標准系統include目錄被搜索。在目錄說明開頭位置的等號,被視作系統根目錄的占位符,
可以使用--sysroot或-isysroot選項來修改它。
6) -isysroot directory
該選項指定搜索頭文件時的系統根目錄。例如,如果編譯器通常在/usr/include目錄及其子目錄下搜索系統頭文件,則該選項將引導到 directory/usr/include 及其子目錄下進行搜索。
7) -I-
在較新版本的GCC中,該選項被-iquote替代。在舊版本中,該選項用於將命令行的所有-Idirectory選項分割為兩組。所有在-I-左邊加上-I選項的目錄,被視為等同於采用-iquote選項;
這指的是,它們只對 #include 命令中采用引號的頭文件名進行搜索。所有在-I-右邊加上-I選項的目錄,將對所有 #include 命令中的頭文件名進行搜索,無論文件名是在引號還是尖括號中。
而且,如果命令行中出現了-I-,那么包括源文件本身的目錄不再自動作為搜索頭文件的目錄。
對於include目錄而言,通常的搜索順序是:
a) 包含指定源文件的目錄(對於在 #include 命令中以引號包括的文件名)。
b) 采用-iquote選項指定的目錄,依照出現在命令行中的順序進行搜索。只對 #include 命令中采用引號的頭文件名進行搜索。
c) 采用-I選型指定的目錄,依照出現在命令行中的順序進行搜索。
d) 采用環境變量 CPATH 指定的目錄。
e) 采用-isystem選項指定的目錄,依照出現在命令行中的順序進行搜索。
f) 采用環境變量 C_INCLUDE_PATH 指定的目錄。
g) 系統默認的 include 目錄。
鏈接器把多個二進制的目標文件(object file)鏈接成一個單獨的可執行文件。在鏈接過程中,它必須把符號(變量名、函數名等一些列標識符)用對應的數據的內存地址(變量地址、函數地址等)替代,以完成程序中多個模塊的外部引用。
GCC 的-l選項可以讓我們手動添加鏈接庫。
數學庫的文件名是 libm.a。前綴lib和后綴.a是標准的,m是基本名稱,GCC 會在-l選項后緊跟着的基本名稱的基礎上自動添加這些前綴、后綴,本例中,基本名稱為 m。
eg: gcc main.c -o main.out -lm
使用-L選項,為 GCC 增加另一個搜索鏈接庫的目錄:
eg: gcc main.c -o main.out -L/usr/lib -lm
Linux 下動態鏈接庫(shared object file,共享對象文件)的文件后綴為.so,它是一種特殊的目標文件(object file),可以在程序運行時被加載(鏈接)進來。
GCC 生成動態鏈接庫:
如果想創建一個動態鏈接庫,可以使用 GCC 的-shared選項。輸入文件可以是源文件、匯編文件或者目標文件。
另外還得結合-fPIC選項。
-fPIC 選項作用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code);這樣一來,產生的代碼中就沒有絕對地址了,全部使用相對地址,所以代碼可以被加載器加載到內存的任意位置,都可以正確的執行。
這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的。
eg: gcc -fPIC -shared func.c -o libfunc.so
C/C++程序在linux下被編譯和連接時,GCC/G++會查找系統默認的include和link的路徑,以及自己在編譯命令中指定的路徑。自己指定的路徑就不說了,這里說明一下系統自動搜索的路徑。
【1】include頭文件路徑
除了默認的/usr/include, /usr/local/include等include路徑外,還可以通過設置環境變量來添加系統include的路徑:
# C
export C_INCLUDE_PATH=XXXX:$C_INCLUDE_PATH
# CPP
export CPLUS_INCLUDE_PATH=XXX:$CPLUS_INCLUDE_PATH
以上修改可以直接命令行輸入(一次性),可以在/etc/profile中完成(對所有用戶生效),也可以在用戶home目錄下的.bashrc或.bash_profile中添加(針對某個用戶生效),修改完后重新登錄即生效。
【2】link鏈接庫文件路徑
鏈接庫文件在連接(靜態庫和共享庫)和運行(僅限於使用共享庫的程序)時被使用,其搜索路徑是在系統中進行設置的(也可以在編譯命令中通過 -l -L 來指定,這里講的是使用系統默認搜索路徑)。
一般 Linux 系統把 /lib /usr/lib /usr/local/lib 作為默認的庫搜索路徑,所以使用這幾個目錄中的鏈接庫文件可直接被搜索到(不需要專門指定鏈接庫路徑)。對於默認搜索路徑之外的庫,則需要將其所在路徑添加到gcc/g++的搜索路徑之中。
鏈接庫文件的搜索路徑指定有兩種方式:1)修改/etc/so.ld.conf 2)修改環境變量,在其中添加自己的路徑
1)在環境變量中添加
動態鏈接庫搜索路徑:
export LD_LIBRARY_PATH=XXX:$LD_LIBRARY_PATH
靜態鏈接庫搜索路徑:
export LIBRARY_PATH=XXX:$LIBRARY_PATH
以上修改可以直接命令行輸入(一次性),可以在/etc/profile中完成(對所有用戶生效),也可以在用戶home目錄下的.bashrc或.bash_profile中添加(針對某個用戶生效),修改完后重新登錄即生效。
2)在/etc/ld.so.conf 中添加指定的鏈接庫搜索路徑(需要root權限),然后運行 /sbin/ldconfig,以達到刷新 /etc/ld.so.cache的效果。
以上兩種方式均可以達到指定鏈接庫搜索路徑的效果。
查看添加結果:
對於C
echo | gcc -v -x c -E -
[root@lsgxeva ~]# echo | gcc -v -x c -E - 使用內建 specs。 COLLECT_GCC=gcc 目標:x86_64-redhat-linux 配置為:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux 線程模型:posix gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=generic' '-march=x86-64' /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -E -quiet -v - -mtune=generic -march=x86-64 忽略不存在的目錄“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include-fixed” 忽略不存在的目錄“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../x86_64-redhat-linux/include” #include "..." 搜索從這里開始: #include <...> 搜索從這里開始: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include /usr/local/include /usr/include 搜索列表結束。 # 1 "<stdin>" # 1 "<built-in>" # 1 "<命令行>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<命令行>" 2 # 1 "<stdin>" COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=generic' '-march=x86-64'
對於C++
echo | g++ -v -x c++ -E - 或者 echo | gcc -v -x c++ -E -
[root@lsgxeva ~]# echo | g++ -v -x c++ -E - 使用內建 specs。 COLLECT_GCC=g++ 目標:x86_64-redhat-linux 配置為:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux 線程模型:posix gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) COLLECT_GCC_OPTIONS='-v' '-E' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1plus -E -quiet -v -D_GNU_SOURCE - -mtune=generic -march=x86-64 忽略不存在的目錄“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include-fixed” 忽略不存在的目錄“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../x86_64-redhat-linux/include” #include "..." 搜索從這里開始: #include <...> 搜索從這里開始: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include /usr/local/include /usr/include 搜索列表結束。 # 1 "<stdin>" # 1 "<built-in>" # 1 "<命令行>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<命令行>" 2 # 1 "<stdin>" COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/4.8.5/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-E' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
注意:該方法只對當前ssh session有效,重新連接后,新加的include路徑,gcc/g++將不保存
understand 編輯器的配置
*.cpp; *.hpp; *.cxx; *.hxx; *.cc; *.c; *.inl; *.h; *.hh; *.hm; *.asm; *.asmx; *.rc; *.resx; *.idl; *.rc2; *Makefile; Makefile*; *makefile; makefile*; CMakeLists.*; *.cmake; *Config; *config; *.am; *.ac; *.in; *.mk; *config; *.inc; *.lds; *.s; *.S; *.def; *.odl; *.xsd; *.bin; *.rgs; *.html; *.htm; *.d; *.txt; *.text; *.lic; *.ini; *.conf; *.xml; *.json; *.ini; *.lang; *.properties; *.bat; *.ps; *.sh; *.bash; *.csh; *.pl; *.pm; *.plx; *.md; *.markdown; .gitconfig; .gitignore; .gitattributes; .gitmodules; .gitlab-ci.yml; _clang-format; BUILD; CHANGELOG; COPYRIGHT; LICENSE; VERSION; RELEASE; TODO
U:\root\develop\nslc\src U:\root\develop\nslc\incs\freebsd_x64\include U:\root\develop\nslc\vendor\install\freebsd_x64\glog U:\root\develop\nslc\vendor\install\freebsd_x64\gperftools U:\root\develop\nslc\vendor\install\freebsd_x64\gmock U:\root\develop\nslc\vendor\install\freebsd_x64\gtest U:\root\develop\nslc\vendor\install\freebsd_x64\gflags U:\root\develop\nslc\vendor\install\freebsd_x64\curl U:\root\develop\nslc\vendor\install\freebsd_x64\mbedtls U:\root\develop\nslc\vendor\install\freebsd_x64\libbson U:\root\develop\nslc\vendor\install\freebsd_x64\libcstl U:\root\develop\nslc\vendor\install\freebsd_x64\libev U:\root\develop\nslc\vendor\install\freebsd_x64\libtap U:\root\develop\nslc\vendor\install\freebsd_x64\zlog U:\root\develop\nslc\vendor\install\freebsd_x64\libtar U:\root\develop\nslc\vendor\install\freebsd_x64\zlib U:\root\develop\nslc\vendor\install\freebsd_x64\stlport U:\root\develop\nslc\vendor\install\freebsd_x64\boost U:\root\develop\nslc\vendor\install\freebsd_x64\libunwind U:\root\develop\nslc\vendor\install\freebsd_x64\execinfo U:\root\develop\nslc\vendor\install\freebsd_x64\pthread U:\usr\local\include U:\usr\include\c++\4.2\backward U:\usr\include\c++\4.2 U:\usr\include
__amd64= __amd64__= __cdecl=__attribute__((__cdecl__)) __ELF__= __FreeBSD__=8 __GNUC__=4 __LP64__= __STDC__= __unix= __unix__= __x86_64= __x86_64__= _DEBUG= _DEBUG_CDB= _FILE_OFFSET_BITS=64 _FORTIFY_SOURCE=1 _LP64= _UNICODE= amd64= CHECK_PTHREAD_RETURN_VALUE= DEBUG= UNICODE= unix= USE_GPERFTOOLS= VALGRIND= x86_64=
=============== End