學習筆記:GNU Linux編程指南(第二版):一

來源:互聯網
上載者:User

目錄:

第一章 Linux及Linux編程綜述

第二章 設定開發系統

第三章 使用GNU CC

第四章 使用GNU make 管理項目

第五章 建立可移植的自配置軟體 GNU autoconf

第六章 比較和合并原始碼檔案

第七章 使用RCS和CVS控製版本

第八章 調試

第九章 出錯處理

註:原書639頁,內容繁多,不易快速定位要點。在第一次閱讀過程中,我摘抄要點、記錄心得,形成該筆記,供日後查閱和再學慣用。

說明:$ 表示 終端輸入命令

第一章 Linux及Linux編程綜述

1. Linux不是Unix,Unix是一個註冊商標,需要滿足一大串條款並且支付可觀的費用才能被許可使用
    Linux在運行特性上與Unix相似,所有核心代碼都是由Linus和幾位核心駭客手工編寫的。
   許多Linux上啟動並執行程式,也是手動編寫的,當然也有移植的

   Linux之所以和Unix相像,是因為它遵循POSIX標準 

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

第二章 設定開發系統第三章 使用GNU CC

1. GCC能編譯ANSI C和傳統C等C語言變體
   GCC能編譯C、C++、Objective C
   GNU Compiler Collection
2. 增加搜尋路徑 -I <針對標頭檔>

gcc hello.c -I /home/fred/include -o hello

3. 增加搜尋路徑 -L <針對庫檔案>

gcc hello.c -L/home/fred/lib -lnew -o hello

    gcc首先在/home/fred/lib 下尋找庫檔案,然後到預設路徑下搜尋
    -l 選項使得連結程式使用指定的函數庫中的目標代碼
4. 通常用法

gcc hello.c -L/home/fred/lib -I /home/fred/include -lnew -o hello

   告訴GCC連結libnew.so, 在/home/fred/lib 中尋找libnew.so, 以及在/home/fred/include中尋找任何非標準的標頭檔
5. 啟用任何一種調試的選項都會讓二進位檔案的大小急劇增長
6. gcc -c filename  得到目標檔案

第四章 使用GNU make 管理項目

1. make是一種控制編譯或者重複編譯軟體的工具
      make可以自動管理軟體編譯的內容、方式和時機,從而使程式員能夠把精力集中在編寫代碼上
2. 為何使用make
   (1). 包含多個源檔案的項目在編譯時間都有長而且複雜的命令列
   (2). 減少重複編譯所需要的時間。(編譯修改過的部分)
   (3). 構建依賴資訊資料庫,檢測是否能找到所需的檔案
   (4). 能夠建立一個穩定的編譯環境
   (5). 讓編譯過程自動執行
3. makefile
   (1). 文本形式的資料庫檔案,包含一些規則告訴make編譯哪些檔案、如何編譯以及在什麼條件下編譯
   (2). 規則--三個部分組成
          <1>. target     : 目標體,即make最終需要建立的東西。
          <2>. denpendency: 包含一或多個dependency列表,通常是編譯目標體需要的其它檔案。
          <3>. command    : 為了從指定依賴建立出目標體所需要執行的命令列表。
         target通常是程式,但可以是文字檔、手冊等任何東西。
         command可以是編譯器的命令或者shell命令,也可以是任何命令列能完成的命令
   (3). 通用形式

  target : dependency [denpendency [...]]               command               command                [...]

          注意:,每個command的第一個字元必須是 定位字元
4. 一個makefile檔案

  sayHelloApp: main.o simple_fun.o simple_fun.hgcc main.o simple_fun.o -o sayHelloApp  simple_fun.o: simple_fun.c simple_fun.hgcc -c simple_fun.c  main.o: main.cgcc -c main.c  .PHONY : clean  clean: rm main.o simple_fun.o

5. 偽目標
   上面的makefile檔案中的clean並不是對應實際的檔案,是偽目標
   偽目標規定了make應該執行的命令
   clean沒有依賴體,所以它的命令不會被自動執行,使用make clean
   如果不使用.PHONY,如果存在clean的檔案,make就會發現它,
   但是使用了.PHONY後,make不檢查是否存在有檔案名稱和依賴體中的一個名字相匹配的檔案,直接執行命令
6. 變數
   定義: VARNAME=some_text
   使用: $(VARNAME)
   除使用者自訂變數外,make運行使用環境變數、自動變數和預定義變數
      (1)環境變數:  如果makefile中有同名的,以makefile中的為準
      (2)自動變數:  make自動用特定的、熟知的值替換。$(@F) : 目標檔案的檔案名稱部分;。。。
      (3)預定義變數:用於定義程式名或者給這些程式傳遞標誌和參數。CC : C編譯器;RM :檔案刪除程式;。。。
7. 模式規則
   擴充make的隱式規則的一種方法。
   類似普通規則,但是它的目標必定有符號“%”,可以任何非Null 字元串匹配。
   依賴檔案也必須使用%
8. 注釋
   #
9. 命令列
   -f file   : 指定makefile的檔案名稱
   -n        : 列印將需要執行的命令,但實際上並不執行這些命令
   -s        : 在執行時不列印命令名
   -w        : 如果make在執行時改變目錄,列印目前的目錄名
   -d        : 列印調試資訊
第五章 建立可移植的自配置軟體 GNU autoconf

1. autoconf
   它產生一個能自動設定原始碼包的shell指令碼,以使程式能夠在許多不通品牌的UNIX和類UNIX系統上編譯和運行。
   這些指令碼通常名為configure,它們檢查在當前系統中是否提供者所需要的某些功能,在此基礎上產生makefile。
   ./configure
2. configure.in
   為了產生configure指令碼,需要在源檔案樹的根目錄下建立名為configure.in 的檔案。
   它調用一系列autoconf宏來測試程式需要的或用到的特性是否存在,以及這些特性的功能。
3. configure.in 檔案的常用格式

AC_INIT                #AC_INIT(unique_file_in_source_dir),用來測試目前的目錄是否正確  測試程式              #每個宏一行  測試函數庫            #如果超過一行,需要使用[]和\,[]擴住所有的參數  測試標頭檔            #  AC_CHECK_HEADERS([head1.h header2.h \  測試類型定義          #             header3.h])  測試結構  測試編譯器行為  測試庫函數  測試系統調用AC_OUTPUT               #AC_OUTPUT(file) file是空格分割的輸出檔案列表                        #用於建立名為makefile或者其它名字的輸出檔案

4. 運行autoscan
   autoscan 包含在autoconf軟體包中 (sudo apt-get install autoconf),
   是Perl指令碼
   從源檔案中抽取與函數調用和標頭檔有關的資訊,並將其輸出到configure.scan 檔案中。
5. config.h.in檔案
   包含程式需要的所有#define指令
   運行autoconf 內建的名為autoheader的shell指令碼
   autoheader通過讀入configure.in、作為autoconf軟體一部分的acconfig.h、
     位於原始碼根路徑下用於儲存預先處理符號的acconfig.h(即./acconfig.h) 產生 config.h.in檔案
6. ./acconfig.h 
   只需要包含可以被autoconf和autoheader讀取和使用的合法定義的C風格預先處理符號
   讓宏其作用,則設定其值為1
7. 流程

   (1). 編寫源檔案 和 Makefile.in檔案 和 acconfig.h檔案    (2). 運行autoscan   得到configure.scan   (3). 重新命名 由configure.scan得到configure.in   (4). 運行autoheader 由acconfig.h 和                          configure.in  得到 config.h.in   (5). 運行autoconf  由configure.in    得到 configure                  (6). ./configure   由config.h.in    得到 Config.h                       由Makefile.in     得到 Makefile   (7). 運行make      由makefile        得到 應用程式app
第六章 比較和合并原始碼檔案

1. diff 和 patch 區別
   如果認為 diff 是通過從一個檔案中減去另一個檔案來產生者兩個檔案的差別檔案
   那麼可以認為 patch 是使用這個差別檔案和其中的源檔案來產生另一個源檔案
2. diff 並排輸出兩個檔案 

 diff -y -W 80 a.vim b.vim

3. diff3 
   當兩個人同時修改一個共用檔案時,diff3 就會發揮作用。
   它比較兩個人做出的兩套修改內容,建立第3個檔案儲存合并後的輸出結果,並且指出雙方修改的衝突之處。
第七章 使用RCS和CVS控製版本第八章 調試

1. GDB GNU DeBugger
   自由軟體聯盟(Free Software Foundation,FSF)的主要軟體工具之一
2. make progname
   編寫源檔案main.c
   使用make main.c,則輸出cc main.c -o main,並得到main可執行檔
3. gdb 的使用步驟
   (1). 使用gcc -g test.c -o test
        使用-g 選項,編譯出的可執行代碼才包含調試資訊,否則gdb無法載入改執行檔案 
   (2). gdb test [core]
        core 為可選的檔案,記憶體轉存檔案,增強gdb調試能力
        至此進入gdb命令互動介面
4. gdb 常用調試命令
   (1). l  查看所載入的檔案
        註:gdb 中都可以使用縮減形式:

           如   l 代表 list;                b 代表 brekpoint;                p 代表 print                r 代表 run                n 代表 next                c 代表 continue

   (2). b  設定斷點

        b 6 在第6行設定斷點              tbreak 6    設定臨時斷點,運行到後就自動移除        ignore 6    忽略斷點6        enable 6    啟用斷點6        disable 6   使斷點6失效

   (3). info b 查看斷點
   (4). delete 移除斷點
          delete 1 移除斷點號為1的斷點
   (5). run 運行代碼
        預設從代碼首行運行
        run 6 從第六行運行
   (6). p 查看變數值
        p i : 查看變數i 的值
        結果顯示:$1 = 2
                '$1' 是變數i的標誌
   (7). n\s 單步運行
        當有函數調用時,s 會進入函數,n 不會進入函數
   (8). c 繼續
          c        : 運行,直到函數結束或者下一個斷點
          finish: 運行,直到函數結束
5. gdb 其它常用命令
   (1). help
         $ help
         $ help running
第九章 出錯處理

1. assert

 #include <assert.h> void assert(int expression);

   如果expression值為假(0),則向stderr列印一條出錯資訊,然後通過函數abort來終止程式運行
2. 如果在
   include <assert.h> 之前加上下面的語句
   #define NDEBUG
   則不會調用assert宏 
3. 使用系統日誌
   Linux 用兩個守護進程 klogd 和 syslogd 提供了集中的系統日誌功能
   syslogd 控制著來自使用者空間程式的訊息的產生。
   klogd 供核心和運行在核心空間的程式,特別是裝置驅動程式所使用。
   大多數Linux系統,系統日誌位於/var/log 目錄下,包括如:messages,debug,mail,news等等
   還可能有其它的日誌,取決於/etc/syslog.conf中定義的日誌功能配置(註:Ubuntu沒有檔案)

   標準的控制台日誌守護進程是syslogd,由它來維護這些記錄檔。
   寫入系統日誌的訊息由它的層級(level)和功能(facility)來控制,
   層級指出了訊息的嚴重性或重要性,而功能告訴維護系統日誌的syslogd守護進程是哪個程式發送的這條訊息
   一條日誌訊息的層級和功能合起來被稱為它的優先順序(priority)。
4. syslog的記錄層級

      層級                  嚴重性    LOG_EMERG             系統不可用    LOG_ALERT             要求立即處理    LOG_CRIT              重大錯誤,比如硬碟故障    LOG_ERR               錯誤條件    LOG_WARNING           警告條件     LOG_NOTICE            正常但重要的訊息    LOG_INFO              純粹的通報訊息     LOG_DEBUG             調試或跟蹤輸出

5. syslog的功能值

      功能                   訊息源    LOG_AUTHPRIV          私人的安全和授權訊息    LOG_CRON              時鐘守護進程(crond 和 atd)    LOG_DAEMON            其它系統守護進程    LOG_KERN              核心訊息    LOG_LOCAL[0-7]        為本地/網站使用而保留    LOG_LPR               列印子系統    LOG_MAIL              郵件子系統    LOG_NEWS              新聞子系統    LOG_SYSLOGsyslog      產生的內部訊息    LOG_USER             (預設值)一般使用者級訊息    LOG_UUCP              uucp子系統

    註:當出現錯誤時,對於使用者級程式來說LOG_WARN已經足夠了
       LOG_INFO 對於日常煩人的日誌訊息最合適
       LOG_ERR 出現了可能致命的系統錯誤
6. 系統日誌函數
   標頭檔 <syslog.h> 定義了syslogd的介面。
   建立一個日誌訊息,使用syslog函數,原型為: 

#include <syslog.h>void syslog(int priority, char* format,...);     

priority 是層級和功能的位邏輯“或”值
format指定寫入日誌的訊息和任何類似printf的格式說明字串    
         %m 由strerror為errno分配的錯誤訊息 替換    
7. 簡單的例子

    /***********************************************************                         程式碼    /***********************************************************/#include <stdio.h>#include <syslog.h>int main(int argc,int** argv){//LOG_WARNING 結果寫入 /var/log/syslog 檔案中syslog(LOG_WARNING | LOG_USER,\       "This is a warning from %s,%s %s,%m\n",\       __FILE__,__DATE__,__TIME__);   //ubuntu下,LOG_INFO 結果也是寫入 /var/log/syslog 檔案中//LOG_USER是預設的功能級syslog(LOG_INFO,"This is a normal message from %s\n",__FILE__);return 1;}      /***********************************************************                         運行結果    /***********************************************************//*   在/var/log/下的syslog檔案中,有如下兩條記錄條記錄:Sep  3 16:39:52 jarvischu-Studio-1435 using_syslog: This is a warning from using_syslog.c,Sep  3 2011 16:39:47,SuccessSep  3 16:39:52 jarvischu-Studio-1435 using_syslog: This is a normal message from using_syslog.c                        */

8. openlog 定製日誌操作,主要是加上首碼

#include <syslog.h>void openlog(const char *ident, int option, int facility);

   ident: 指定加到日誌訊息前的字串
   option: 多個選項的位邏輯“或”值        

       LOG_PID      在每條訊息中包含PID       LOG_CONS     如果訊息不能寫入記錄檔,則發送到控制台       LOG_NDELAY   立即開啟連結(預設是在syslog第一次被調用時才開啟連結)       LOG_PERROR   把訊息寫入記錄檔的同時也輸出到stderr

   facility:即 5. 中的某個值
   例:

openlog("JarvisChu",LOG_PID,LOG_USER);syslog(LOG_INFO|LOG_USER,"This is a message\n");

     則在/var/log/syslog 檔案中,有如下記錄:
                     JarvisChu[1231]:This is a message
9. 其它函數
      (1). closelog()   
              如同openlog,可選的,關閉openlog開啟的檔案描述符。
      (2). int setlogmask(int priority);
           設定所有日誌訊息的預設層級,(即哪些層級的訊息能寫入syslog,哪些不能寫入)
            函數返回原來的優先順序
            syslog拒絕任何沒有在掩碼中設定的優先順序訊息

             同 宏:

LOG_MASK(int priority) :建立僅由一個優先順序組成的掩碼LOG_UPTO(int priority) :建立一個由一系列降序優先順序組成的掩碼

              如LOG_UPTO(LOG_NOTICE)建立的掩碼包括了從LOG_EMERG到LOG_NOTICE之間的任何層級的訊息。

              而LOG_INFO和LOG_DEBUG層級的訊息則不能通過

待續...

作者:Jarvis Chu

首發:CSDN Blog

轉載請註明出處:http://blog.csdn.net/jarvischu/article/details/6747420

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.