
在windows安裝軟件是極其簡(jiǎn)單的事,無非就是下載,然后一路點(diǎn)擊“下一步”即可。而在linux裝軟件就沒那么簡(jiǎn)單了,尤其是對(duì)于新手而言,往往會(huì)手足無措,覺得linux很不好用??梢坏┝?xí)慣了,就會(huì)驚嘆于linux的強(qiáng)大,安裝軟件可以簡(jiǎn)單地用一句命令行解決從下載到安裝的整個(gè)流程,比windows下的一鍵安裝還要輕爽。也可以自己到官網(wǎng)下載源碼,自己編譯,甚至修改源碼,真正自定義安裝軟件。
本系列文章主要講解通過源碼安裝軟件的原理以及方法。
我們知道,不管是windows,還是linux,最終能執(zhí)行的都是二進(jìn)制文件,而我們的代碼是用編程語言寫的文本文件,要轉(zhuǎn)換成操作系統(tǒng)能識(shí)別的二進(jìn)制碼就需要編譯器。
以下用實(shí)例演示編譯源碼的操作流程
編譯單一文件
新建c語言文件:hello.c
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
}
[senlong@linux ~]$ gcc hello.c
[senlong@linux ~]$ ll hello.c a.out
-rwxrwxr-x 1 senlong senlong 8512 7月 27 08:44 a.out
-rw-rw-r-- 1 senlong senlong 67 7月 27 08:44 hello.c
[senlong@linux ~]$ ./a.out
Hello World
以上實(shí)例演示了hello.c源碼文件經(jīng)由gcc命令編譯生成a.out可執(zhí)行文件
相關(guān)術(shù)語解釋:
- 源碼文件:即程序員寫的源代碼文件(hello.c)
- 編譯器:將便于人編寫,閱讀,維護(hù)的高級(jí)計(jì)算機(jī)語言所寫作的源碼程序,翻譯為計(jì)算機(jī)能解讀、運(yùn)行的低階機(jī)器語言的程序(gcc)
- 可執(zhí)行文件:操作系統(tǒng)能直接識(shí)別,可直接執(zhí)行的二進(jìn)制文件(a.out)
可執(zhí)行文件與普通文本文件可通過file指令識(shí)別:
[senlong@linux ~]$ file hello.c
hello.c: C source, ASCII text # 普通文本文件
[senlong@linux ~]$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=29c4c64ff2985490bb17a37ef188574a0009b3da, not stripped # 可執(zhí)行的二進(jìn)制文件
編譯多個(gè)文件
默認(rèn)情況下,使用gcc編譯輸出的二進(jìn)制文件是a.out, 我們可以將gcc的編譯行為拆分成兩個(gè)步驟:
-
gcc -c filename.c生成目標(biāo)文件(object file) -
gcc -o filename.o生成可執(zhí)行文件
[senlong@linux ~]$ gcc -c hello.c
[senlong@linux ~]$ ll hello*
-rw-rw-r-- 1 senlong senlong 67 7月 27 08:44 hello.c
-rw-rw-r-- 1 senlong senlong 1496 7月 27 08:53 hello.o # object file
[senlong@linux ~]$ gcc -o hello hello.o
[senlong@linux ~]$ ll hello*
-rwxrwxr-x 1 senlong senlong 8512 7月 27 08:54 hello # 二進(jìn)制文件
-rw-rw-r-- 1 senlong senlong 67 7月 27 08:44 hello.c
-rw-rw-r-- 1 senlong senlong 1496 7月 27 08:53 hello.o
[senlong@linux ~]$ ./hello
Hello World
那么問題來了,既然可以一步到位用一個(gè)命令生成可執(zhí)行文件,為什么還要拆分成兩步呢?
繼續(xù)以下實(shí)例:
thanks.c
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
thanks_2();
}
thanks_2.c
#include <stdio.h>
void thanks_2(void)
{
printf("Thank you!\n");
}
[senlong@linux ~]$ gcc -c thanks.c thanks_2.c
[senlong@linux ~]$ ll thanks*
-rw-rw-r-- 1 senlong senlong 71 7月 27 08:57 thanks_2.c
-rw-rw-r-- 1 senlong senlong 1504 7月 27 09:04 thanks_2.o
-rw-rw-r-- 1 senlong senlong 83 7月 27 08:56 thanks.c
-rw-rw-r-- 1 senlong senlong 1560 7月 27 09:04 thanks.o
[senlong@linux ~]$ gcc -o thanks thanks.o thanks_2.o
[senlong@linux ~]$ ll thanks*
-rwxrwxr-x 1 senlong senlong 8584 7月 27 09:05 thanks
-rw-rw-r-- 1 senlong senlong 71 7月 27 08:57 thanks_2.c
-rw-rw-r-- 1 senlong senlong 1504 7月 27 09:04 thanks_2.o
-rw-rw-r-- 1 senlong senlong 83 7月 27 08:56 thanks.c
-rw-rw-r-- 1 senlong senlong 1560 7月 27 09:04 thanks.o
[senlong@linux ~]$ ./thanks
Hello World
Thank you!
此時(shí)我們?cè)賮砀?code>thanks_2.c文件:
#include <stdio.h>
void thanks_2(void)
{
printf("Thank you very much!\n");
}
現(xiàn)在我們只需要單獨(dú)編譯thanks_2.c文件,再將兩個(gè)目標(biāo)文件聯(lián)結(jié)重新生成可執(zhí)行文件。不需要再去編譯thanks.c
[senlong@linux ~]$ gcc -c thanks_2.c
[senlong@linux ~]$ gcc -o thanks thanks.o thanks_2.o
[senlong@linux ~]$ ./thanks
Hello World
Thank you very much!
之所以要生成目標(biāo)文件,是因?yàn)樵创a文件很多時(shí)候不是單一文件,如果其中有一個(gè)文件變化了,只需要重新編譯此文件,而不用全部文件再次編譯
引用外部函數(shù)庫
函數(shù)庫指封裝好的實(shí)現(xiàn)一定功能的程序??梢栽趧e的程序直接引用,如以下實(shí)例:計(jì)算sina值,調(diào)用了sin()函數(shù)
sina.c
#include <stdio.h>
#include <math.h>
int main(void)
{
float value;
value = sin ( 3.14 / 2 );
printf("%f\n",value);
}
[senlong@linux ~]$ gcc sina.c
[senlong@linux ~]$ ./a.out
1.000000
以上介紹了編譯源碼的基本流程,可以很明顯地看出,當(dāng)我們的文件量大時(shí),如有幾百個(gè)、幾千個(gè)文件時(shí),如果還是按照以上這種手工編譯的方式,那linux就不好玩了。下篇文章將介紹快速編譯的方式。
敬請(qǐng)關(guān)注我的賬號(hào)。
本文借鑒于鳥哥linux