APUE源代碼編譯

轉自: http://linux.chinaunix.net/doc/2004-10-05/22.shtml

 

 



最近學習Linux編程,收穫真的很多。以前都是別人或man告訴你某個命令怎麼使用,但現在我才領悟到,是程序的源代碼決定了全部。
linux編程,首先需要安裝gcc與其它編程工具與庫文件。最簡單的方法是進入圖形界面的添加刪除程序,選上開發工具就可以了。 

1.APUE2源代碼下載:http://www.apuebook.com/src.tar.gz
2.我保存到了/root下.解壓縮:tar -xzvf src.tar.gz
3.cd apue.2e進入apue.2e目錄,查看README,告訴我們linux系統只要修改Make.defines.linux再make
4.vi Make.defines.linux 修改WKDIR=/root/apue.2e 就是說工作目錄爲WKDIR=/root/apue.2e
5.修改/root/apue.2e/std/linux.mk把全部的nawk改爲awk.因些linux默認沒有nawk
6.make

一個需要注意的地方:
apue編程的例子都有關include "apue.h"的代碼,其實apue.h並不是系統自帶的,它是作者編寫的頭文件,源代碼在附錄B中.因此一個方法是.把剛纔生成的 /root/apue.2e/include/apue.h直接複製到/usr/include下.
還有像err_sys 的函數也在附錄B中.同樣的方法是在/usr/include新建一個 my_err.h的文件,把Figure B.3. Error functions that output to standard error內容複製進去.這樣按例子編程就只需要在行首添加:#include "my_err.h"就可以了..

(轉載自:http://blog.chinaunix.net/u1/52350/showart_426726.html)




APUE2作者提供的源碼編譯方法及單個源碼編譯的實現

前面一篇文章講解了《UNIX環境高級編程》源碼編譯方法。文中所講到的編譯方法是非作者提供的編譯方法,即不使用作者提供的頭文件,程序中所有使用的頭文件都一一列出。而程序中的出錯處理函數則簡單的用printf函數替代。隨後,也有網友提出如何採用作者的方法來對所有的程序進行編譯。出於解決問題,同時也想實現這個方法,畢竟實現之後每個程序都可以直接運行,還是比較方便的。因此,就按照源代碼文件夾中的README的步驟,對整個源代碼進行了編譯。

(1)作者提供的編譯方法的實現
README文件中給出的編譯方法如下:
To build the source, edit the Make.defines.* file for your system and set WKDIR to the pathname of the tree containing the source code.  Then just run "make".  It should figure out the system type and build the source for that platform utomatically.
參照該方法,我將源碼的編譯分爲三步。整個步驟都是在root超級用戶下進行的,如果其他用戶沒有權限進行編譯,可以通過su命令切換到超級用戶。
第一步,編輯Make.defines.*文件。由於我所使用的操作系統是FreeBSD6.1,所以應該編輯文件Make.defines.freebsd。其實,編輯該文件的內容主要是修改其中的WKDIR,即我們源碼所在文件夾的絕對路徑名。原文件中WKDIR=/home/sar/apue.2e,我們可以根據我們實際文件夾所在的位置進行相應的修改。我的apue.2e文件夾直接放在/home下了,所以我將WKDIR修改爲WKDIR=/home/apue.2e。其餘內容不用修改,保存修改後的文件。
第二步,修改腳本文件systype.sh的權限。由於原始的systype.sh文件不具有可執行的權限。通過執行命令:#chmod +x systype.sh  
給當前用戶及其所在組和其他組添加可執行權限;或者#chmod u+x systype.sh 僅給當前用戶添加可執行權限。
該腳本文件的功能主要是檢測操作系統的類型。它可以檢測到系統的類型有:FreeBSD,Linux,MacOS和Solaris等。如果單獨執行這個shell腳本:
#./systype.sh 則輸出結果爲:freebsd。即檢測本機的操作系統爲FreeBSD。
第三步,進行源碼的編譯。在命令行下執行make命令。通過查看Makefile文件可知,make之後,首先執行systype.sh腳本,即首先確定操作系統的類型,然後在進行源碼的編譯。在編譯的過程中,會有一些Warning。這些都是正常的,導致警告的原因可能是採用編譯起的版本不同或者是同一類型操作系統的版本不同。但是,只要make的過程不出現error,就會順利的生成可執行文件。我的在編譯過程中沒有出現error,因此意味着編譯成功。

注意:編譯的過程中可能會出現的一個問題,也是一個網友曾經問到的問題,就是在編譯中出現這個的錯誤,提示nawk command cannot be found。這個問題可能的原因是,有些操作系統的內核版本較低,可能還不支持nawk(new awk)這個命令。但應該支持awk命令。因此,問題的解決方法就是將相關文件中的nawk命令替換爲awk,或者爲系統添加一個別名alias,alias nawk awk。這樣在編一的過程中,遇到nawk命令時,實際會去執行awk命令。如果還有其他問題,可以去網上搜索相關的解決方法。因爲我在編譯的過程中沒有遇到這樣的問題,不再一一贅述。

(2)編譯生成可執行文件的位置
在路徑/home/apue.2e/下雖然有所有的源文件,都是以figx.x的形式命名。但是實際編譯的過程並不是編譯的這些文件。而是編譯在該路徑下各個文件夾中的後綴名爲*.c的程序。作者把同一章節或者相近幾個章節的源代碼放在某一個文件夾下面(include和lib文件夾除外)。而文件夾的命名一般是和該章對應的標題是一致的,採用的是英文標題的全稱或簡寫。譬如,advio文件夾對應Chapter 14. Advanced I/O,該章的代碼就放在該文件夾下面。還有文件夾proc對應Chapter 8. Process Control,文件夾termios對應Chapter 18. Terminal I/O等等,基本上每一章的代碼都可以在這些文件夾中找到。

(3)如何編譯單獨的源文件
通過make命令是直接將所有的源程序編譯成可執行文件的。對於喜歡修改和調試程序的朋友來說,make生成的可執行文件顯然不具有這樣的功能,而且,也不可能修改了一個源文件,然後還要make。如何需要編譯和調試單個程序的話,方法如下:
1.首先還是要用make對所有文件進行編譯。成功編譯後,會在WKDIR/lib/下生成庫文件libapue.a,主要是將apue.h(位於WKDIR/include/)中定義的所有內容生成一個靜態的庫,這樣可以方便調用。
2.我們以WKDIR/下的fig1.3(實現ls部分功能)文件爲例說明需要修改的地方。將fig1.3文件重命名爲fig1.3.c,然後編輯該文件,將包含頭文件的一行代碼:
#i nclude "apue.h"  //默認所引用頭文件的位置爲當前的路徑WKDIR=/home/apue.2e
修改爲
#i nclude "include/apue.h"
即頭文件apue.h的位置爲當前路徑下inlucde文件夾中,這個就正確的指定了apue.h的位置。
這樣就可以進行編譯了,但在編譯的時候還要加上庫文件libapue.a,因爲該文件實現了apue.h中的所有功能,主要有常用頭文件,宏定義以及自定義函數的實現。
輸入命令
#gcc fig1.3.c lib/libapue.a  
則會生成可執行文件a.out。執行命令
#./a.out /home
則列出我的/home路徑下的所有文件和文件夾:
.
..
david
simsun .ttc
simkai.ttf
simsun.ttf
MYKERNEL
unix_advance_program
freebsd
APUE Source Code
LumaQQ
apue.2e
bash-script
lumaqq_2005_patch_2006.01.22.15.00.zip
lumaqq_2005-linux_gtk2_x86_with_jre.tar
apue_src_complied.tar

當然,如果需要編譯的是各個文件夾中的一個源程序時,則只需對所包含的頭文件apue.h的路徑作相對修改,改爲
#i nclude "../include/apue.h"
以及編譯是庫文件的位置也相應修改,改爲:
#gcc sourcefile.c ../lib/libapue.a
至此,APUE第二版作者提供的源碼編譯方法和單獨源碼的編譯都已經實現。
(轉載自:http://www.blog.edu.cn/user2/shawnchen/archives/2007/1955932.shtml)

------------------------------------------------------------------------------------------

我自己首次編譯時遇到一個問題,現將現象及解決方法記錄在此,供遇到同樣問題的童鞋參考。

我的環境是RHEL5.3 按照《一》的方法修改完後,
在編譯std目錄時仍然報錯:undefined reference to `main'
我進入std目錄查看時發現生成一個conf.c的空文件,同時目錄下還存在一個conf.c.modified文件
我嘗試把conf.c.modified修改爲conf.c,編譯成功,再次刪除conf.c之後,編譯仍然成功。爲什麼之前沒conf.c編譯就報錯。複製一個後編譯成功,刪掉conf.c再編譯就能成功,至今還沒想明白到底是爲什麼。

 

----------------------------------------

以上部分爲轉載:

PS: 我在Ubuntu下編譯會遇到 limits.h  這個文件不包含比如 ARG_MAX之類的變量,是由於不同的標準導致的。解決方法有兩個:

一個是用sysconf獲取。第二個是包含linux/limits.h這個文件

發佈了10 篇原創文章 · 獲贊 1 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章