· 閆健勇·CPCW
當前,雖然Linux還不很普及,在Linux下編寫和編譯程序的人不多。但是我相信,隨著Linux性能的不斷提升和逐漸普及,會有許多自由軟件出現,也會有許多人成為Linux下的程序員。我結合自己的經驗,介紹一下Linux下編寫和編譯程序所要注意的幾個問題,奉獻給希望為Linux的發展作出貢獻的人們。
Linux下怎樣編譯程序?
大多數Linux程序都是由C語言編寫的并由GNU C編譯而成。現在GCC是各種發行套件的一部分。有關最新GCC編譯器的版本、文章和補丁請看ftp://ftp.gnu.org/pub/gnu/。
由C++編寫的程序必須由GNU C++編譯,GNU C++也是各種發行套件的一部分,在以上網址也有最新版本和補丁。
編譯2.0.x的內核需要2.7.2.x版本的GCC,如用象GCC 2.8.x, EGCS, or PGCC別的編譯器編譯內核可能產生不可預想的后果。
怎樣移植其它Unix程序到Linux上?
總得來說,Unix上的程序不需要做改動,只要簡單的按照提示就可以移植到Linux上,如果安裝過程中出現錯誤信息,而你又不知道怎么處理,你可以猜或略去,不過這樣產生的程序往往帶有bug。所以最好還是問一下有經驗的人。
如果要從BSD-ish移植程序,試一試在編譯時加上-I/usr/include/bsd 和 ?lbsd命令。
什么是ld.so,從哪可以找到它?
ld.so是動態函數庫裝載器。過去,使用共享函數庫的程序在原代碼開頭使用約3K的空間來尋找和加載共享函數庫,現在,這段代碼被加進了一個特殊共享函數庫/lib/ld.so,所有的程序都可以使用該共享庫,這樣就節省了磁盤空間,而且升級方便。
ld.so可以從以下網址得到tsx-11.mit.edu/pub/linux/packages/GCC/。
怎樣升級庫函數而不使系統崩潰?
注意:進行此操作應該養成做備份的習慣,因為這項操作很容易出錯。
如果你升級象libc4這樣的老函數庫,這個過程會變得非常困難。而且你應該在該系統上讓libc4和libc5共存,因為,有些老程序還需要它。升級libc5也一樣。
升級動態庫的問題常出現在當你移走老的函數庫時,用來升級的程序也運行不了了。有許多方法可以解決這個問題。一個方法就是暫時備份一下運行程序所需函數庫,它們一般在/lib/、/usr/lib/、 /usr/local/lib/、或其它的地方,在文件/etc/ld.so.conf中都有詳細記錄。
例如,當你升級libc5時,目錄/lib/中有如下文件
libc.so.5
libc.so.5.4.33
libm.so.5
libm.so.5.0.9
這些是C函數庫和數學庫,拷貝它們到文件/etc/ld.so.conf中含有的其它的目錄,如/usr/lib/中:
cp -df /lib/libc.so.5* /usr/lib/
cp -df /lib/libm.so.5* /usr/lib/
ldconfig
一定要記住運行ldconfig來升級函數庫的配置文件。
文件libc.so.5 和 libm.so.5是實際庫文件的鏈接文件,當你升級的時候,如果老的鏈接文件存在,新的鏈接不會產生,除非你使用CP命令的-f選項。CP的-d選項只復制鏈接文件,不復制原文件。
如果你需要直接覆蓋鏈接,使用ln命令的選項-f。
例如,拷貝新的庫函數覆蓋舊的。先對新的函數庫做一個鏈接,然后把函數庫和鏈接一起拷貝到/lib/中,命令如下:
ln -sf ./libm.so.5.0.48 libm.so.5
ln -sf ./libc.so.5.0.48 libc.so.5
cp -df libm.so.5* /lib
cp -df libc.so.5* /lib
重申一下,拷貝完別忘記運行ldconfig.
如果一切工作順利的話,你可以刪除老的函數庫的備份。
我能否把在486上編譯的代碼或編譯器拿到386上用?
當然,除非你編譯的是內核。
GCC用來在486上編譯的選項-m486 只是優化了所編譯程序,使其運行快一些。這些編譯的程序仍能很好的在386上運行,只是效果差一些。
然而,從內核1.3.35以后,采用486或Pentium選項編譯的內核不能用于386的機器。
GCC可以針對386和486進行配置。兩者區別在于,針對386配置的GCC把-m386作為缺省選項,而針對486配置的GCC把-m486作為缺省選項,僅此而已。
gcc -O6可以干什么?
目前,它和 -O2 (GCC 2.5) 或 -O3 (GCC 2.6, 2.7)功能一樣,所有版本大于它的功能也一樣。新版內核的Makefiles使用-O2,所以你也應該用-O2。
linux/*.h 和asm/*.h在什么地方?
目錄 /usr/include/linux/ 和 /usr/include/asm/低下的文件是內核頭文件的軟鏈接,內核頭文件其實在目錄/usr/src/kernel*/低下。
怎樣作一個共享函數庫?
對ELF, 命令如下:
gcc -fPIC -c *.c
gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
對a.out,從 http://tsx-11.mit.edu/pub/linux/packages/GCC/src/ 下載n.nn.tar.gz,其中包含詳細說明。建議你將共享庫由a.out升級為ELF。
為什么我編譯的可執行程序非常大?
用ELF編譯器,生成可執行程序太大最可能的原因是沒有合適的.so庫與你使用的庫函數鏈接。對每一個象libc.so.5.2.18的函數庫,應該有一個象libc.so的鏈接。
用a.out編譯器,生成可執行程序太大可能是使用了-g選項,這會生成靜態鏈接庫而不是動態鏈接庫。
從哪可以得到對于Linux的‘lint’?
大部分‘lint’的功能已經內置進了GCC,打開GCC的-Wall選項會打開許多有用的外部警告。
還有一個叫`lclint'的軟件功能和傳統的lint差不多,原代碼可以在http://larch.lcs.mit.edu /pub/Larch/lclint/中找到。
做人要厚道,請注明轉自酷網動力(www.ASPCOOL.COM)。