注:gilbc 源碼下載地址:http://www.oschina.net/code/explore/glibc-2.9linux
/*******************************************************************************
*第0種-最簡單實用(果真是最簡單的,後面的方法在feodra上總是報錯,不過ubuntu上能夠第二在方法仍是可行的)
*
*******************************************************************************/.
1.直接進入源碼目錄的lib目錄
cd lib
2.執行make命令
make -f linux.mk
3.把生成的libapue.a與apue.h拷貝到你的源代碼目錄。如你的file目錄下
4.使用gcc -o ls1 ls1.c libapue.a來編譯你的源代碼
5.成功
/*******************************************************************************
*第一種
*
*******************************************************************************/.
《UNIX環境高級編程》(這裏使用的是第二版本的源碼)每一個歷程中,都會有這樣一行源碼:
#include "apue.h"
這個頭文件是做者把把每一個例程中經常使用的標準頭文件,一些經常使用的出錯處理函數(err_**()之類的函
數)和一些經常使用的宏定義給整理在一個頭文件中。這個能夠省去在每一個例程中錄入較多的重複代碼,這樣可
以減小每一個例程的長度。給讀者帶來了很多麻煩。下面給出一種源代碼的編譯方法。
一、解壓文件到apue.2e目錄
二、修改相應平臺的文件,我使用的是linux,因此修改Make.defines.linux
你修改的只須要這一行WKDIR=/home/your_dir/apue2e_src/apue.2e,改爲本身的目錄路徑
三、cd到apue.2e目錄執行make -f linux.mk,以後你會在lib目錄下面找到libapue.a這個文件.
如今,你能夠把它拷貝到你能尋找的地方,在編寫例子的時候,你就能夠
四、拷貝apue2e_src/apue.2e/include/apue.h和apue2e_src/apue.2e/lib/libapue.a
到你的源代碼目錄。
五、使用gcc -o hello hello.c libapue.a來編譯你的源代碼
/*******************************************************************************
*第二種
*
*******************************************************************************/
最近在看apue的第二版,剛纔在Linux下把隨書的源代碼編譯了一遍,仍是稍微花了點時間,做爲備忘把編譯過
程記錄下來
隨書的源代碼可從www.apuebook.com上得到,下載後的解壓獲得名爲apue.2e的目錄,在個人系統中該目錄的
完整路徑爲/home/se/apue.2e
接着首先是要閱讀/home/se/apue.2e/README,這是由apue第二版的做者Steve Rago寫的如何編譯隨書代碼的
基本指導以及部分自本書初版以來的更改,主要內容以下:
Some source changes needed to be made after the book went out for the first
printing. I forgot to make corresponding changes in the source tree on the
system used to develop the book. The changes are summarized below.
1. lib/recvfd.c and sockets/recvfd.c - needed sys/uio.h on Mac OS X
2. lib/sendfd.c and sockets/sendfd.c - needed sys/uio.h on Mac OS X
3. stdio/buf.c - added code for Mac OS X
4. threadctl/suspend.c - changed wait to waitloc to avoid symbol definition
clash on Solaris
5. include/apue.h - FreeBSD compiles work better if we rely on the default
system settings. Solaris needed a different XOPEN_SOURCE definition
and also a CMSG_LEN definition.
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 automatically. If you are running on a system other than
FreeBSD, Linux, Mac OS X, or Solaris, you'll need to modify the makefiles
to include the settings for your system. Also, you'll probably need to
modify the source code to get it to build on a different operating system.
The example source was compiled and tested using FreeBSD 5.2.1, Linux 2.4.22,
Mac OS X 10.3, and Solaris 9.
For FAQs, updated source code, and the lost chapter, see http://www.apuebook.com.
Please direct questions, suggestions, and bug reports to sar@apuebook.com.
基本內容就是你用的系統若是是FreeBSD,Linux,Mac OS X或是Solaris,那麼你只要修改相應的
Make.defines.*文件(即若是你使用的是Linux,那麼你須要修改 Make.defines.linux文件的內容),將其中的
設置改成你本身系統的設置而後在apue.2e目錄下運行make就ok了.全部的代碼都在 FreeBSD 5.2.1,Linux
2.4.22,Mac OS X 10.3,Solaris 9上編譯經過.
總的來講要編譯成功是很簡單的,但總會由於平臺的不一樣會出現一些錯誤,這時你就要根據本身系統的配置情
況來進行修改了
1.首先粗略的看了一下makefile的內容,make首先會執行腳本文件systype.sh,判斷所用系統的類型,而後根
據該類型選擇對應的Make.defines文件.這裏所要作的就是給systype.sh添加執行權限,chmod u+x
systype.sh
2.由於我用的是Linux,因此先看Make.defines.linux,須要修改的地方是WKDIR=/home/sar/apue.2e,把WKDIR
改成你本身的工做目錄,在我這就是改成WKDIR=/home/se/apue.2e,這個路徑在編譯時尋找"apue.h"頭文件時
使用.
3.而後我嘗試性的運行了一次make,果真有問題,在進入std目錄後報錯了,說找不到nawk命令,nawk是new
awk,而個人系統上只有awk,這時你有兩種選擇,能夠在運行make以前執行alias nawk='awk',這樣本質上是給
awk取了個叫nawk的別名,實際上運行的仍是awk,另外一種方法就是修改WKDIR/std /linux.mk,把第10行和15行
中的nawk都改成awk,至於什麼是awk和nawk,以及它們的使用方法能夠參考我以前收藏的一篇文章
http://www.360doc.com/showWeb/0/0/308938.aspx
在這裏,awk用來分別從makeconf.awk和makeopt.awk生成conf.c和options.c源文件,注意,在修改了linux.mk
或是添加了alias以後要先把以前make失敗時生成的conf.c和options.c刪除,不然會報錯
4.進行了上述的修改後,回到WKDIR,運行make,ok,沒有報錯,編譯成功了
以後,若是你要利用apue的lib,編譯運行本身的代碼,必須在編譯時加上-I/home/se/apue.2e/include選項,
在鏈接時加上-L/home/se/apue.2e/lib source.c /home/se/apue.2e/lib/libapue.a選項,這樣你就能夠利
用apue提供的想err_sys等函數了^_^
/*******************************************************************************
*第三種
*
*******************************************************************************/
unix環境高級編程編譯方法
這裏要談到的一個問題就是該書中的源代碼編譯的問題。此書中差很少每一個歷程中,都會有這樣一行源
碼:
#include "ourhdr.h"
在第二版中改成:
#include "apue.h"
這個頭文件是做者把把每一個例程中經常使用的標準頭文件,一些經常使用的出錯處理函數(err_**()之類
的函數)和一些經常使用的宏定義給整理在一個頭文件中。這個能夠省去在每一個例程中錄入較多的重複代碼,這
樣能夠減小每一個例程的長度。可是,這樣就給讀者帶來了很多麻煩。由於咱們還要去搞明白如何把這個頭文
件編譯,而後作成庫文件,添加到咱們的系統中。特別讀於初學者,原本滿懷信心的,結果在編譯第一個程
序的時候就出現了問題。我也沒有搞明白如何把 "ourhdr.h"靜態的編譯到系統中。
不過,不明白如何使用"ourhdr.h"這個頭文件,並不會影響咱們學習APUE,也不會影響咱們編譯和
運行每個例程。其實,簡單的想一下,若是一個 C程序要能順利的編譯和運行,除了咱們要語法正確等方
面外,最根本的是要保證咱們程序中所調用的函數以及宏等等都要有完整的來源,也就是必須包含全部調用
函數和宏所在的頭文件。對於一個具體的源程序,若是咱們正確的包含了頭文件,那麼剩下的就是程序本生
語法方面應該注意的事項。
如何肯定系統調用函數包含在那個頭文件中呢?這在Unix/Linux系統下並不是一件難事。Unix/Linux
下命令man能夠幫助咱們找到。man命令不只能夠幫助咱們查找通常命令的用法,同時提供不一樣層次的幫助諸
如系統調用或者管理員級別的命令等等(譬如FreeBSD6.1中,man 1是用戶專用手冊,man 2是系統調用,
man 3是庫函數查詢等等)。
下面咱們就以APUE書中程序1-1 (實現ls命令部分功能)爲例,來講明如何將書中的程序改編成全
部使用標準頭文件的程序。其中,操做系統用的是FreeBSD6.1,通過相應的修改能夠在書中所說的幾個Unix
系統及Linux系統中運行,我也曾在Debian Linux下成功編譯和運行該程序。書中1-1.c的原始代碼以下:
#include <sys/types.h>
#include <dirent.h>
#include "ourhdr.h"
int
main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;
if (argc != 2)
err_quit("usage: ls directory_name");
if ((dp = opendir(argv[1])) == NULL)
err_sys("can't open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL)
printf("%s"n", dirp->d_name);
closedir(dp);
exit(0);
}
從書後面的附錄中能夠看到"ourhdr.h"的內容比較多,包含了比較多的經常使用頭文件,一些宏定義和
一些經常使用函數和出錯函數的定義。其實,對於每個具體的程序,咱們只須要找到該程序中用到的頭文件即
可。
該1-1.c中所用到的系統函數調用有:opnedir(),readdir(),printf(),closedir()和exit()。
其中,對於經常使用的函數prinft()和exit(),它們所在的頭文件通常都知道,分別是<stdio.h>和<
stdlib.h>。而對於opnedir (),readdir()和closedir(),咱們能夠經過man opendir,man readdir,man
closedir獲得這三個關於目錄操做的函數所在的頭文件都是:<sys/types.h>和<dirent.h>。這兩個頭文件
在源程序中也已經列出。
其次,1-1.c中還用到了做者自定義的兩個函數:err_quit()和err_sys()。這兩個函數主要使用來
進行出錯處理的。固然,使用這兩個函數對錯誤信息的處理是比較完善的。可是,做爲咱們學習來說,瞭解
程序的核心功能是首要的,咱們能夠將出錯處理簡化一點,即當遇到錯誤的時候,咱們只簡單的使用
printf()函數來提示一下有錯誤發生。固然,用printf()來進行出錯處理並非一種很合理的方法,並且往
往咱們看不到更關鍵的錯誤信息,但對於咱們僅僅做爲學習來用仍是能夠接受的。畢竟咱們要理解的核心部
分是程序的功能實現,出錯處理在於其次。
經過以上的說明,咱們能夠將1-1.c修改成以下內容:
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
DIR *dp;
struct dirent *dirp;
if(argc != 2)
{
printf("You need input the directory name."n");
exit(1);
}
if((dp = opendir(argv[1])) == NULL)
{
printf("cannot open %s"n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL)
printf("%s"n", dirp->d_name);
closedir(dp);
exit(0);
}
這樣修改後的程序已經與做者的頭文件"ourhdr.h"沒有關係,能夠單獨的進行編譯。我使用的是
root用戶,執行命令:
# gcc 1-1.c //生成目標文件a.out
或者
# gcc -o 1-1 1-1.c //生成目標文件1-1
沒有任何錯誤和警告,說明編譯成功。這時咱們執行生成的目標文件:
# ./a.out /home
或者
# ./1-1 /home
則會列出/home路徑下的全部文件,包括目錄(.)和(..)。
經過這樣的方法,基本上咱們能夠將該書中全部的例程修改爲不包含"ourhdr.h"的程序。這樣,我
們就能夠單獨的編譯每個例程,而不用顧及做者所給的雜湊的頭文件。同時這種比較笨的方法,反而有利
於幫助咱們瞭解不一樣系統調用所對應的頭文件,對於學習來講,這應該是一件好事。編程