140
技術社區[雲棲]
unix環境高級編程 環境搭建踩過的那些坑~
在UBUNTU下進行APUE的代碼編譯的話,需要改動的地方很多,尤其是ubuntu12.04下,內核升級到3.0後。
一 首先進行一些改動,將工作區間改變,修改MAKE文件以為編譯打基礎
https://blog.csdn.net/dycwahaha/article/details/2300938
(一)作者提供的編譯方法的實現
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命令。如果還有其他問題,可以去網上搜索相關的解決方法。因為我在編譯的過程中沒有遇到這樣的問題,不再一一贅述。
(二)編譯生成可執行文件的位置
在路徑/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等等,基本上每一章的代碼都可以在這些文件夾中找到。
(三)如何編譯單獨的源文件
通過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第二版作者提供的源碼編譯方法和單獨源碼的編譯都已經實現。
二 提示status的問題,
https://topic.csdn.net/u/20111018/03/89b21b01-d8cb-4667-8cc6-c23f1e4f8f02.html
https://blog.csdn.net/ce_endless/article/details/6885708
gcc -DLINUX -ansi -I/home/alex/apue/apue.2e/include -Wall -D_GNU_SOURCE -DDEBUG -c -o printd.o printd.c
In file included from /usr/include/bits/time.h:86:0,
from /usr/include/time.h:42,
from /usr/include/pthread.h:26,
from printd.c:11:
/usr/include/bits/timex.h:31:7: 錯誤:expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘.’ token
make[2]: *** [printd.o] 錯誤 1
make[2]: 離開目錄“/home/alex/apue/apue.2e/ipp”
make[1]: *** [linux] 錯誤 1
make[1]: 離開目錄“/home/alex/apue/apue.2e”
make: *** [all] 錯誤 2
解決辦法:
謝謝,我已經解決這個問題了。是apue官方的源碼有問題。標準庫文件沒有問題。我把解決方法貼出來吧。
出現這個問題的原因是在timex.h的第31行出現了status的定義:
int status; /* clock command/status */
而文件apue.2e/ipp/ipp.h中有宏定義:
#define status u.st
這樣編譯的時候就出問題了,如編譯提示:
expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘.’ token
解決方法是把ipp.h文件裏的status改成其他名稱,比如Status,再次編譯,錯誤提示status神馬的信息,找到status出錯的位置,把它改為Status就行了。
此處我的status出錯位置在printd.c的第977行中:
i = ntohs(hp->status);
再次make就好了。
三 提示ARG_MAX參數未定義,由於我隻是想運行一些樣例,所以可以肆意的進行修改,因為目前而言,並不用到這個參數,所以先改正,編譯成功再說。參照網頁,https://ssepqhyneg.blog.163.com/blog/static/4105553920106804956179/
作者給出了解決辦法,
ARG_MAX undeclared.
Error description.
$ make
...
make[2]: Entering directory `/home/shunwang/shawn_file/myfiles/my_study/kernel/APUE_source_code/apue/apue.2e/threadctl'
gcc -DLINUX -ansi -I/home/shunwang/shawn_file/myfiles/my_study/kernel/APUE_source_code/apue/apue.2e/include -Wall -D_GNU_SOURCE -c -o getenv1.o getenv1.c
getenv1.c:4: error: ‘ARG_MAX’ undeclared here (not in a function)
make[2]: *** [getenv1.o] Error 1
make[2]: Leaving directory `/home/shunwang/shawn_file/myfiles/my_study/kernel/APUE_source_code/apue/apue.2e/threadctl'
make[1]: *** [linux] Error 1
make[1]: Leaving directory `/home/shunwang/shawn_file/myfiles/my_study/kernel/APUE_source_code/apue/apue.2e'
make: *** [all] Error 2
Solution:解決辦法
在apue.2e/include/apue.h中添加一行:
#define ARG_MAX 4096
打開apue.2e/threadctl/getenv3.c,添加一行:
#include "apue.h"
再運行make, 編譯通過。
我們可以看到作者在APUE的頭文件中加入了 ARG_MAX的定義,並在出錯的文件中添加引用該頭文件。由於我沒有將apue.h這個文件添加進係統頭文件夾中,所以我要將添加的#include "apue.h"這行,改為 #include "../include/apue.h"。
四 使用APUE源碼
- 使用第一章的例子fig1.3
- # ll fig1.3命令為ll fig1.3
- lrwxrwxrwx 1 shunwang shunwang 10 2010-07-08 10:30 fig1.3 -> file/ls1.c
- #ls file
- access cdpwd.c devrdev fileflags.c freebsd.mk hello hole.c longpath.c macos.mk seek testerror uidgid.c unlink zap.c
- access.c changemod devrdev.c filetype ftw4 hello.c linux.mk ls1 mycd seek.c testerror.c umask unlink.c
- cdpwd changemod.c fileflags filetype.c ftw4.c hole longpath ls1.c mycd.c solaris.mk uidgid umask.c zap
- # ./file/ls1 /home/進入目標所在目錄,執行
- shunwang
- ..
- lost+found
五,使用APUE
使用APUE進行單個文件的編譯時,可以將apue.h複製到/usr/include下,將編譯生成的在apue.2e/lib/libapue.a複製到/usr/lib下,這樣引用apue.h頭文件時就可以#include "apue.h",寫MAKEFILE時,將libapue.a複製到和makefile文件同文件夾下,定義變量LIBS=./libapue.a,就可以方便使用。libapue.a和apue.h放在c文件目錄下會比較好
我把我的文件放到附件裏。
Makefile 文件:
- CC = gcc -O2
- LIBS = ./libapue.a
- .PHONY: all clean
- all: pl1-1 pl1-2
- pl1-1:pl1-1.o
- $(CC) -o $@ pl1-1.o $(LIBS)
- pl1-2:pl1-2.o
- $(CC) -o $@ pl1-2.o $(LIBS)
- clean:
- rm -f *.o
最後更新:2017-04-03 05:39:34
上一篇:
OpenAPI用戶實名認證通知
下一篇:
牛腩新聞發布係統總結(四)--知識點滴
ASP.NET中的HTTP模塊和處理程序
Word2010中搜狗拚音輸入法(各種輸入法)消失了的解決辦法
java多線程知識要點
graph driver-device mapper-01driver初始化
Java 文件上傳下載管理器(控製台)
Android攝像頭開發完美demo---(循環聚焦,縮放大小,旋轉picture,查詢支持的picturesize, ImageButton按鍵效果)
Deepgreen & Greenplum DBA小白普及課之四(性能問題解答)
2017數據科學與機器學習行業現狀調查 Python是最受歡迎的語言
局部連接來減參,權值共享肩並肩(深度學習入門係列之十一)
從2017杭州·雲棲大會 看零售未來