環(huán)境變量
系統環(huán)境變量
我們知道,我們經(jīng)常要設置一些環(huán)境變量,系統環(huán)境變量我們非常容易理解。其實(shí)我們在windows中經(jīng)常容易接觸。其實(shí)環(huán)境變量是一個(gè)非常廣泛的一個(gè)概念,它與web應用程序中的web.config所處的角色很像。什么意思呢?就是說(shuō),程序(系統或應用)要運行的時(shí)候,它的基本業(yè)務(wù)邏輯可能是一定的,但是實(shí)現業(yè)務(wù)邏輯的時(shí)候有些設置性的東西卻可以改變程序很多。如web應用程序,編譯之后他的業(yè)務(wù)邏輯基本不會(huì )發(fā)生改變,但是如果你更改一些web.config中的參數,程序的運行就會(huì )發(fā)生相應的改變。這些設置。就像電視機上面調制一樣。改變了設置會(huì )得到某些不同。
那么環(huán)境變量可以理解成設置的一種,為什么有不直接稱(chēng)為設置呢?因為它處于一種被動(dòng)的境地。越多說(shuō)越糊涂。
最常見(jiàn)的環(huán)境變量莫過(guò)于PATH,和ClassPATH,這個(gè)在設置jdk的時(shí)候就需要設置,這里的PATH變量指的是,當系統的接口接收到一個(gè)程序啟動(dòng)命令的時(shí)候,除了默認在當前目錄下尋找那個(gè)可執行文件意外,還需要到那些地方尋找。有了這個(gè)設置,你就不需要一定要進(jìn)入那個(gè)目錄才能執行那個(gè)程序了。ClassPATH變量也差不多,它設置的是那些類(lèi)似于動(dòng)態(tài)庫的路徑,也就是說(shuō),程序在執行的時(shí)候,發(fā)現要引入動(dòng)態(tài)庫,那樣就要在這個(gè)變量指定的地方去找。
在linux中,系統也有一個(gè)PATH變量。其實(shí)系統有一個(gè)文件是專(zhuān)門(mén)記錄那些環(huán)境變量的。
1)/etc/profile,系統登錄會(huì )執行這個(gè)文件在當前環(huán)境中引入那些變量。
2)還有
3)還有一種設置方法,就是通過(guò)終端命令直接修改,我們知道前面兩個(gè)文件其作用的方式就是當程序進(jìn)入狀態(tài)的時(shí)候,他們會(huì )被執行引入到當前空間,那么在當前狀態(tài)下就會(huì )有這些變量,程序也就是可以使用它們。那么如果我們直接在內存中修改該他們,就可以起到暫時(shí)的作用。
程序環(huán)境變量
根據前面我們說(shuō)過(guò)環(huán)境變量的作用和意義,就很容易推出,普通的程序也可以有環(huán)境變量。按照前面系統的環(huán)境變量起作用的模式。應用程序,也可以有一些配置文件來(lái)持久保存這些環(huán)境變量,在程序執行的時(shí)候,這些變量會(huì )通過(guò)某種方式進(jìn)入程序執行的空間,這樣程序執行的時(shí)候就可以使用這些變量了。而同樣,我們可以改變這些變量來(lái)“適量”的改變我們的程序。
GCC就是這樣一個(gè)程序。很多時(shí)候,應用程序需不需要環(huán)境變量機制,關(guān)鍵看他是否有很多的選擇性,GCC就是一個(gè)這樣的程序。
最常用GCC環(huán)境變量的就是include搜索路徑,以及庫搜索路徑。他們分別在編譯和連接的時(shí)候使用。
他們的使用背景是:
include搜索路徑
通常,使用C/C++進(jìn)行開(kāi)發(fā)程序的時(shí)候,會(huì )使用頭文件,并且有頭文件的實(shí)現文件,這個(gè)時(shí)候有三類(lèi)文件,使用頭文件的源文件,頭文件,實(shí)現頭文件的源文件。編譯的時(shí)候,頭文件和源文件一起就可以了。通常他們是在同一目錄下的。所以不會(huì )有什么問(wèn)題。
但是,當你使用到了系統自身的一些頭文件的時(shí)候,你需要引入一些頭文件,而這些文件不在當前目錄下,使用絕對地址是一個(gè)辦法,但是是一個(gè)極差的辦法。所以GCC就有一個(gè)搜索機制。就是在規定的那些文件夾下,搜索你所引入的那個(gè)頭文件。這樣解決了問(wèn)題。這個(gè)環(huán)境變量叫著(zhù)CPLUS_INCLUDE_PATH。屬于GCC,與系統無(wú)關(guān)。我們看看GCC頭文件搜索路徑
頭文件:
1.
搜索順序為:
①先搜索當前目錄
②然后搜索-I指定的目錄
③再搜索gcc的環(huán)境變量CPLUS_INCLUDE_PATH(C程序使用的是C_INCLUDE_PATH)
④最后搜索gcc的內定目錄
/usr/include
/usr/local/include
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/include
各目錄存在相同文件時(shí),先找到哪個(gè)使用哪個(gè)。
2.
①先搜索-I指定的目錄
②然后搜索gcc的環(huán)境變量CPLUS_INCLUDE_PATH
③最后搜索gcc的內定目錄
/usr/include
/usr/local/include
/usr/lib/gcc/x86_64-redhat-linux/4.1.1/include
與上面的相同,各目錄存在相同文件時(shí),先找到哪個(gè)使用哪個(gè)。這里要注意,#include<>方式不會(huì )搜索當前目錄!
雖然搜索了GCC自定義的環(huán)境變量目錄之后,下一個(gè)的內定目錄,就應該是操作系統有關(guān)這種頭文件的定義。這種推導很正確。事實(shí)上就算不是這樣的。GCC頭文件搜索模式,也是按照先“專(zhuān)”后“寬”的模式,也就是說(shuō),大部分都是使用自己的一套,所以基本都能找到,可能真有一些是那些大家共有的頭文件。所以,這里的內定目錄其實(shí)與繼承操作系統的目錄的意思沒(méi)有多大區別。
這里要說(shuō)下include的內定目錄,它不是由$PATH環(huán)境變量指定的,而是由g++的配置prefix指定的(知道它在安裝g++時(shí)可以指定,不知安裝后如何修改的,可能是修改配置文件,需要時(shí)再研究下):
-bash-3.2$ g++ -v
Using built-inspecs.
Target:x86_64-redhat-linux
Configured with:../configure --prefix=/usr --mandir=/usr/share/man--infodir=/usr/share/info --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=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre--with-cpu=generic --host=x86_64-redhat-linux
Thread model:posix
gcc version 4.1.2 20080704(Red Hat 4.1.2-46)
在安裝g++時(shí),指定了prefix,那么內定搜索目錄就是:
Prefix/include
Prefix/local/include
Prefix/lib/gcc/--host/--version/include
編譯時(shí)可以通過(guò)-nostdinc++選項屏蔽對內定目錄搜索頭文件。
庫搜索路徑:
在編譯之后,程序要進(jìn)行鏈接操作,前面指出,鏈接不管是動(dòng)態(tài)和是靜態(tài),GCC這個(gè)程序,必須確認“真的有”那些頭文件的實(shí)現。于是就需要定位找到那些文件。與include的情景差不多。使用絕對目錄是可以的,但不適于管理。于是就出現了lib搜索路徑這個(gè)環(huán)境變量。LIBRARY_PATH。
他們的搜索路徑為:
庫文件:
編譯的時(shí)候:
①gcc會(huì )去找-L
②再找gcc的環(huán)境變量LIBRARY_PATH
③再找內定目錄/lib /usr/lib/usr/local/lib 這是當初compile gcc時(shí)寫(xiě)在程序內的(不可配置的?)
運行時(shí)動(dòng)態(tài)庫的搜索路徑
(不要把這個(gè)和庫的搜索路徑混淆了,這里程序執行的時(shí)候有linux系統/usr/bin/ld程序控制的過(guò)程,這里只是順帶介紹。以完整程序整個(gè)生命周期。編譯、鏈接、啟動(dòng),裝載(包括動(dòng)態(tài)裝載)、執行):
動(dòng)態(tài)庫的搜索路徑搜索的先后順序是:
①編譯目標代碼時(shí)指定的動(dòng)態(tài)庫搜索路徑(
聯(lián)系客服