環境變量,include搜索路徑,lib庫搜索路徑


環境變量

 

系統環境變量

 

我們知道,我們經常要設置一些環境變量,系統環境變量我們非常容易理解。其實我們在windows中經常容易接觸。其實環境變量是一個非常廣泛的一個概念,它與web應用程序中的web.config所處的角色很像。什么意思呢?就是說,程序(系統或應用)要運行的時候,它的基本業務邏輯可能是一定的,但是實現業務邏輯的時候有些設置性的東西卻可以改變程序很多。如web應用程序,編譯之后他的業務邏輯基本不會發生改變,但是如果你更改一些web.config中的參數,程序的運行就會發生相應的改變。這些設置。就像電視機上面調制一樣。改變了設置會得到某些不同。

那么環境變量可以理解成設置的一種,為什么有不直接稱為設置呢?因為它處於一種被動的境地。越多說越糊塗。

最常見的環境變量莫過於PATH,和ClassPATH,這個在設置jdk的時候就需要設置,這里的PATH變量指的是,當系統的接口接收到一個程序啟動命令的時候,除了默認在當前目錄下尋找那個可執行文件意外,還需要到那些地方尋找。有了這個設置,你就不需要一定要進入那個目錄才能執行那個程序了。ClassPATH變量也差不多,它設置的是那些類似於動態庫的路徑,也就是說,程序在執行的時候,發現要引入動態庫,那樣就要在這個變量指定的地方去找。

在linux中,系統也有一個PATH變量。其實系統有一個文件是專門記錄那些環境變量的。

1)etcprofile,系統登錄會執行這個文件在當前環境中引入那些變量。

2)還有  homeali.bashrc 這個文件,簡單的來說,etcprofile是對全局有效的,而.bashrc是對當前用戶有效.

3)還有一種設置方法,就是通過終端命令直接修改,我們知道前面兩個文件其作用的方式就是當程序進入狀態的時候,他們會被執行引入到當前空間,那么在當前狀態下就會有這些變量,程序也就是可以使用它們。那么如果我們直接在內存中修改該他們,就可以起到暫時的作用。

 

程序環境變量

 

根據前面我們說過環境變量的作用和意義,就很容易推出,普通的程序也可以有環境變量。按照前面系統的環境變量起作用的模式。應用程序,也可以有一些配置文件來持久保存這些環境變量,在程序執行的時候,這些變量會通過某種方式進入程序執行的空間,這樣程序執行的時候就可以使用這些變量了。而同樣,我們可以改變這些變量來“適量”的改變我們的程序。

GCC就是這樣一個程序。很多時候,應用程序需不需要環境變量機制,關鍵看他是否有很多的選擇性,GCC就是一個這樣的程序。

最常用GCC環境變量的就是include搜索路徑,以及庫搜索路徑。他們分別在編譯和連接的時候使用。

他們的使用背景是:

 

include搜索路徑

 

通常,使用CC++進行開發程序的時候,會使用頭文件,並且有頭文件的實現文件,這個時候有三類文件,使用頭文件的源文件,頭文件,實現頭文件的源文件。編譯的時候,頭文件和源文件一起就可以了。通常他們是在同一目錄下的。所以不會有什么問題。

但是,當你使用到了系統自身的一些頭文件的時候,你需要引入一些頭文件,而這些文件不在當前目錄下,使用絕對地址是一個辦法,但是是一個極差的辦法。所以GCC就有一個搜索機制。就是在規定的那些文件夾下,搜索你所引入的那個頭文件。這樣解決了問題。這個環境變量叫着CPLUS_INCLUDE_PATH。屬於GCC,與系統無關。我們看看GCC頭文件搜索路徑

 

頭文件:

1.       #include “headfile.h”

搜索順序為:

①先搜索當前目錄

②然后搜索-I指定的目錄

③再搜索gcc的環境變量CPLUS_INCLUDE_PATH(C程序使用的是C_INCLUDE_PATH)

④最后搜索gcc的內定目錄

usrinclude

usrlocalinclude

usrlibgccx86_64-redhat-linux4.1.1include

 

各目錄存在相同文件時,先找到哪個使用哪個。

2.       #include headfile.h

①先搜索-I指定的目錄

②然后搜索gcc的環境變量CPLUS_INCLUDE_PATH

③最后搜索gcc的內定目錄

usrinclude

usrlocalinclude

usrlibgccx86_64-redhat-linux4.1.1include

 

與上面的相同,各目錄存在相同文件時,先找到哪個使用哪個。這里要注意,#include方式不會搜索當前目錄!

 

雖然搜索了GCC自定義的環境變量目錄之后,下一個的內定目錄,就應該是操作系統有關這種頭文件的定義。這種推導很正確。事實上就算不是這樣的。GCC頭文件搜索模式,也是按照先“專”后“寬”的模式,也就是說,大部分都是使用自己的一套,所以基本都能找到,可能真有一些是那些大家共有的頭文件。所以,這里的內定目錄其實與繼承操作系統的目錄的意思沒有多大區別。

 

這里要說下include的內定目錄,它不是由$PATH環境變量指定的,而是由g++的配置prefix指定的(知道它在安裝g++時可以指定,不知安裝后如何修改的,可能是修改配置文件,需要時再研究下):

-bash-3.2$ g++ -v

Using built-in specs.

Target x86_64-redhat-linux

Configured with ..configure --prefix=usr --mandir=usrshareman --infodir=usrshareinfo --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=usrlibjvmjava-1.4.2-gcj-1.4.2.0jre --with-cpu=generic --host=x86_64-redhat-linux

Thread model posix

gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)

 

在安裝g++時,指定了prefix,那么內定搜索目錄就是:

Prefixinclude

Prefixlocalinclude

Prefixlibgcc--host--versioninclude

編譯時可以通過-nostdinc++選項屏蔽對內定目錄搜索頭文件。

 

 

庫搜索路徑:

 

在編譯之后,程序要進行鏈接操作,前面指出,鏈接不管是動態和是靜態,GCC這個程序,必須確認“真的有”那些頭文件的實現。於是就需要定位找到那些文件。與include的情景差不多。使用絕對目錄是可以的,但不適於管理。於是就出現了lib搜索路徑這個環境變量。LIBRARY_PATH。

他們的搜索路徑為:

庫文件:

編譯的時候:

①gcc會去找-L

②再找gcc的環境變量LIBRARY_PATH

③再找內定目錄 lib usrlib usrlocallib 這是當初compile gcc時寫在程序內的(不可配置的?)

 

運行時動態庫的搜索路徑

(不要把這個和庫的搜索路徑混淆了,這里程序執行的時候有linux系統usrbinld程序控制的過程,這里只是順帶介紹。以完整程序整個生命周期。編譯、鏈接、啟動,裝載(包括動態裝載)、執行):

動態庫的搜索路徑搜索的先后順序是:

①編譯目標代碼時指定的動態庫搜索路徑(這是通過gcc 的參數-Wl,-rpath,指定。當指定多個動態庫搜索路徑時,路徑之間用冒號:分隔)

②環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑(當通過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號:分隔)

③配置文件etcld.so.conf中指定的動態庫搜索路徑;

④默認的動態庫搜索路徑lib;

⑤默認的動態庫搜索路徑usrlib。

 

 

我們在來對GCC這個命令的這一方面進行總結一下。

編譯的時候使用-I命令可以裝入include搜索路徑。

連接的時候使用-l  -L命令可以裝入連接搜索路徑或文件

執行的時候。在當初編譯連接時候使用-Wl 這個可以裝入動態庫的搜索路徑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM