各參數的意思,
本書的範例可以在<http://examples.oreilly.com/ 0636920025108/> 下載。
第一個範例是
/* Compile with:
make erf LDLIBS="-lm" CFLAGS="-g -Wall -std=gnu11 -O3"
*/
#include <math.h> //erf, sqrt
#include <stdio.h> //printf
int main(){
printf("The integral of a Normal(0, 1) distribution "
"between -1.96 and 1.96 is: %g\n", erf(1.96*sqrt(1/2.)));
}
這個例子的註解上寫著,可
make erf LDLIBS="-lm" CFLAGS="-g -Wall -std=gnu11 -O3"
在指令列裏這樣打,真的可以編譯,讓筆者蠻驚訝的。
以為這些字
LDLIBS,CFLAGS是打在Makefile 裏,原來可打在參數裏。make真利害。
當然erf.c不用打**.c**,直接會去找**.c**,自動編譯成同名的執行檔。
執行可得
tim$ ./erf
The integral of a Normal(0, 1) distribution between -1.96 and 1.96 is: 0.950004
書上寫的編譯方式,
gcc erf.c -o erf -lm -g -Wall -O3 -std=gnu11
這是一般書上的示範。
不用寫上LDLIBS,CFLAGS。
-g -Wall -O3 可當一組來解釋,g 是指加入除錯資訊,給gdb用,Wall 是秀所有警告訊息,O3 第三級的優化。
-std=gnu11,用C11的標準。指定編譯的方式。
-lm , 是引用MATH 函數庫。
也可以這樣編譯
c99 erf.c -o erf -lm -g -Wall -O3
查一下 c99
c99 --help
Usage: gcc [options] file...
看起來也是指向gcc.
因為C99目前還是使用的主流。所以需要符合C99,可以這樣寫
tim$ make erf LDLIBS="-lm" CFLAGS="-g -Wall -std=gnu99 -O3"
路徑篇:
有時候會引用不是套件的函數,或是這套件不是安裝在標準位置(如 /usr/local/lib, /usr/lib...), 另有其他路徑。
這時候作者建議用 find
如
find / -type f | wc -l
筆者的電腦 用sudo, 因為會全電腦全路徑的統計檔案個數,在一些目錄,會有權限不足的情況。
當你引用自己的檔案,#include <useful.h> ,這時該如何編譯呢?
gcc -I/usr/local/include use_useful.c -o use_useful -L/usr/local/lib -luseful
-I ,-L 是 搜尋路徑(目錄),前者是宣告檔(.h)的路徑,後者是.c檔的路徑。這裏是大寫的I,L。
注意排列的順序。
接下來是令人激賞的地方,
pkg-config的使用。
尤其是參照多個函數庫,如gsl, libxml-2.0,這時候pkg-config派上用途了!!
可這樣下:
tim$ pkg-config --libs gsl libxml-2.0
輸出
-lgsl -lgslcblas -lm -lxml2
可這樣下:
tim$ pkg-config --cflags gsl libxml-2.0
輸出
-I/usr/include/libxml2
這個工具pkg-config,可以找出.h檔的所在目錄,也可做所有相互引用的函數庫,如 -lgslcblas -lm,這是相依性引用到的,及函數庫的正確名稱。
更令人感動的部分,是pkg-config的輸出結果,可以當gcc 的輸入參數,
gcc pkg-config --cflags --libs gsl libxml-2.0
-o specific specific.c
這裏可以看出這本書美中不足的地方,
作者的練習範例很少,害讀者驚訝有餘,沒法多練習。
書中還有提到一些編譯用到的環境變數,
CPATH orLIBRARY_PATH or C_INCLUDE_PATH .同樣的作者只提到,沒有練習範例。