鍍金池/ 教程/ Linux/ Linux 學(xué)習(xí)記錄--程序編譯與函數(shù)庫
Linux 學(xué)習(xí)記錄--開機(jī)掛載錯(cuò)誤
日志系統(tǒng)
數(shù)據(jù)流重定向
內(nèi)存交換空間的構(gòu)建
文件系統(tǒng)簡介
Linux 學(xué)習(xí)記錄--軟件安裝 RPM|SRPM|YUM
文件特殊權(quán)限
目錄配置 FHS
文件內(nèi)容查閱
Boot Loader
文件壓縮
Linux 學(xué)習(xí)記錄--文件權(quán)限
Linux 命令縮寫
命令與文件的查詢
文件|目錄的默認(rèn)權(quán)限與隱藏權(quán)限
shell script
服務(wù)
Linux 學(xué)習(xí)記錄--程序編譯與函數(shù)庫
正則表達(dá)式與其應(yīng)用
關(guān)機(jī)相關(guān)指令
shell
vim 與 vi 常用命令
系統(tǒng)調(diào)用:進(jìn)程控制
文件系統(tǒng)簡單操作
磁盤掛載與卸載
有名管道通訊
磁盤分區(qū),格式化與檢驗(yàn)
工作管理與進(jìn)程管理
匿名管道通訊
Linux 學(xué)習(xí)記錄--啟動流程
文件與目錄管理
管道命令
命名別名與歷史命令
文件備份|還原
shell變量
Linux 學(xué)習(xí)記錄--ACL 權(quán)限控制
內(nèi)核|內(nèi)核模塊編譯
文件管理相關(guān)系統(tǒng)編程

Linux 學(xué)習(xí)記錄--程序編譯與函數(shù)庫

http://wiki.jikexueyuan.com/project/learn-linux-step-by-step/images/16.bmp" alt="" />

程序編譯與函數(shù)庫

前面提到過對于機(jī)器來說只能識別0,1,我們?nèi)绻寵C(jī)器運(yùn)行必須輸入機(jī)器能夠識別的語言,可是機(jī)器語言不利于人們使用可理解,因此科學(xué)家就開發(fā)出人類能看的懂的程序語言,然后再創(chuàng)造出“編譯器”將程序語言轉(zhuǎn)換為機(jī)器語言。
C 語言就是我們能夠看懂的機(jī)器語言,gcc 就是 Linux 下編譯器。我們通常 C 語言寫的程序通過 gcc 編譯后,就能成為機(jī)器能夠識別的語言

gcc 程序編譯

如果 LINUX 系統(tǒng)中為安裝 GCC 編譯器,可以使用下面命令安裝
[root@bogon ~]# yum install gcc

gcc 常用語法

語法: gcc –c file.c
僅將源代碼編譯成目標(biāo)文件。并不會進(jìn)行鏈接以及生成可執(zhí)行文件

gcc –o 執(zhí)行文件名 源代碼文件
直接生成指定名稱的執(zhí)行文件。但不會生成目標(biāo)文件

gcc –o 執(zhí)行文件名 目標(biāo)文件
通過目標(biāo)文件生成可執(zhí)行文件

gcc [其他編譯操作] –L庫文件路徑
查找?guī)煳募穆窂侥J(rèn)是/usr/lib 與/ib

gcc [其他編譯操作] –I 包含文件路徑
查找包含文件的路徑默認(rèn)是/usr/include

gcc [其他編譯操作] –Wall
更加嚴(yán)謹(jǐn)?shù)木幾g方式,會輸出很多警告信息

gcc -O [其他編譯操作]
編譯時(shí)依據(jù)操作環(huán)境優(yōu)化執(zhí)行速度

gcc [其他編譯操作] –l庫文件名稱
編譯時(shí)引入其他的庫文件,其中庫文件 lib 與擴(kuò)展名不需要寫。如引入 libm.so 文件,可寫成-lm

單一程序編譯

  1. 編寫 C 語言程序 l
[root@bogon code]# vim hello.c
#include <stdio.h>
int main(void)
{
   printf("hello world!");
}
  1. 編譯
[root@bogon code]# gcc hello.c 
[root@bogon code]# ll hello.c a.out 
-rwxr-xr-x 1 root root 4947 04-05 16:07 a.out
-rw-r--r-- 1 root root   66 04-05 16:07 hello.c

說明:默認(rèn) gcc 編譯器編譯出來的執(zhí)行文件 a.out, 可以使用-o 來制定編譯后生產(chǎn)的執(zhí)行文件名稱

[root@bogon code]# gcc -o hello hello.c 
[root@bogon code]# ll hello
-rwxr-xr-x 1 root root 4947 04-05 16:11 hello
  1. 執(zhí)行
[root@bogon code]# ./a.out 
hello world!

[root@bogon code]# ./hello 
hello world!

多文件程序編譯

假設(shè)我們有 A.c ,B.c 兩個(gè)程序文件,并且他們之間存在函數(shù)調(diào)用,那么當(dāng)其中有一個(gè)文件更改了。是不是需要將這兩個(gè)文件都重新編譯?當(dāng)然不需要,這就需要引入目標(biāo)文件
目標(biāo)文件:編譯器編譯源代碼后生成的文件,目標(biāo)文件從結(jié)構(gòu)上講,它是已經(jīng)編譯后的可執(zhí)行文件格式,只是沒有經(jīng)過鏈接的過程。 接著上面的說,當(dāng) B.c 文件更改時(shí),我們執(zhí)行重新編譯 B 文件生產(chǎn)目標(biāo)文件。再講整體鏈接即可

  1. 編寫 C 語言程序
File:A.c
#include <stdio.h>
#include “B.c”
int main ()
{
printf("這是第一個(gè)文件\n");
method();
}

File:B.c
#include <stdio.h>
void method(void)
{
 printf("這是第二個(gè)文件!\n";)
}
  1. 編譯
root@bogon code]# gcc -c A.c B.c -I./
[root@bogon code]# ll 
-rw-r--r-- 1 root root   81 04-05 16:35 A.c
-rw-r--r-- 1 root root  912 04-05 16:35 A.o
-rw-r--r-- 1 root root   80 04-05 16:34 B.c
-rw-r--r-- 1 root root  860 04-05 16:35 B.o
  1. 鏈接
[root@bogon code]# gcc -o result A.o B.o
  1. 執(zhí)行
[root@bogon code]# ./result 
這是第一個(gè)文件
這是第二個(gè)文件!
  1. 更改 B.c 文件
#include <stdio.h>
void method(void)
{
 printf("這是更改后第二個(gè)文件!\n";)
}
  1. 重新編譯鏈接執(zhí)行
[root@bogon code]# gcc -c B.c =>只編譯了B這個(gè)文件
[root@bogon code]# gcc -o result A.o B.o
[root@bogon code]# ./result 
這是第一個(gè)文件
這是更改后第二個(gè)文件!

調(diào)用外部函數(shù)庫

  1. 編寫 C 語言程序
#include<stdio.h>
#include<math.h>

int main ()
{
  float val=sin(3.14);
  printf("val值是:%f\n",val);
}
  1. 編譯與執(zhí)行
[root@bogon code]# gcc -o sinmath sinmath.c -lm
[root@bogon code]# ./sinmath 
val值是:0.001593

函數(shù)庫介紹
函數(shù)庫依照是否編譯到程序內(nèi)部可分為
靜態(tài)函數(shù)庫:通常以.a 為擴(kuò)展名,編譯時(shí)會整合到程序文件中
動態(tài)函數(shù)庫:通常以.so 為擴(kuò)展名,編譯時(shí)會不會整合到程序文件中,只是在程序文件中存在一個(gè)指向的位置
因此程序執(zhí)行時(shí)是不需要靜態(tài)函數(shù)庫的,但是需要動態(tài)函數(shù)庫,使用動態(tài)函數(shù)庫的好處再在可以減少程序文件的大小

動態(tài)函數(shù)庫加載內(nèi)存
我們知道內(nèi)存的訪問速度是硬盤的好幾倍,如果先將動態(tài)函數(shù)庫加載到內(nèi)存中,那么在使用動態(tài)函數(shù)庫時(shí)就會,就會提高很多效率

語法:ldconfig[-f 需要緩存函數(shù)庫信息所在文件] [-C 已緩存函數(shù)庫信息所在文件]
ldconfig –p 列出已緩存函數(shù)庫信息

需要緩存函數(shù)庫信息所在文件:在這個(gè)文件中記錄所有需要緩存的的函數(shù)庫默認(rèn)值是
/etc/ ld.so.conf

舉例:查看下我的系統(tǒng)下緩存的函數(shù)庫

[root@bogon etc]# vim ld.so.conf
include ld.so.conf.d/*.conf

[root@bogon etc]# cd ld.so.conf.d/
[root@bogon ld.so.conf.d]# ll
-rw-r--r-- 1 root root  15 2013-01-23 mysql-i386.conf
-rw-r--r-- 1 root root  17 2013-01-09 openais-athlon.conf
-rw-r--r-- 1 root root  20 2012-08-20 qt-i386.conf
-rw-r--r-- 1 root root 276 02-22 19:23 vmware-tools-libraries.conf
-rw-r--r-- 1 root root  19 2013-08-07 xulrunner-32.conf
[root@bogon ld.so.conf.d]# vim mysql-i386.conf 
[root@bogon ld.so.conf.d]# ll /usr/lib/mysql
lrwxrwxrwx 1 root root      26 02-18 20:03 libmysqlclient_r.so.15 -> libmysqlclient_r.so.15.0.0
-rwxr-xr-x 1 root root 1460684 2013-01-23 libmysqlclient_r.so.15.0.0
lrwxrwxrwx 1 root root      24 02-18 20:03 libmysqlclient.so.15 -> libmysqlclient.so.15.0.0
-rwxr-xr-x 1 root root 1452764 2013-01-23 libmysqlclient.so.15.0.0
-rwxr-xr-x 1 root root   13220 2013-01-23 mysqlbug
-rwxr-xr-x 1 root root    6215 2013-01-23 mysql_config

已緩存函數(shù)庫信息所在文件:這個(gè)文件中記錄了已經(jīng)緩存的函數(shù)庫,默認(rèn)文件為
/etc/ld.so.cache ,通過-p 查詢到的信息就是從這個(gè)文件讀取而來

舉例:查看所有已緩存的函數(shù)庫

[root@bogon ld.so.conf.d]# ldconfig -p|more
947 libs found in cache `/etc/ld.so.cache'
        libz.so.1 (libc6) => /lib/libz.so.1
        libz.so.1 (libc6) => /usr/lib/libz.so.1
        libx11globalcomm.so.1 (libc6) => /usr/lib/libx11globalcomm.so.1
   ……..

查看程序所包含的動態(tài)函數(shù)庫
語法:ldd –v 文件名
-v:列出所有函數(shù)庫信息

舉例:

[root@bogon ld.so.conf.d]# ldd  /usr/bin/passwd
        linux-gate.so.1 =>  (0x00ddc000)
        libuser.so.1 => /usr/lib/libuser.so.1 (0x007c5000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x05c74000)
       ……

make 編譯

如果一個(gè)程序中有很多文件,那么還像上面那樣講每個(gè)文件列出來在進(jìn)行編譯就會很麻煩。因此這種時(shí)候就需要使用 make 工具了

Make 編譯好處
簡化編譯時(shí)所需的指令
若在編譯完成后,修改了某個(gè)源文件,只會針對修改的文件編譯

Make 使用方法
Make 是有個(gè)二進(jìn)制文件,其會查找當(dāng)前目錄下的 Makefile 文件,根據(jù)其里面定義的內(nèi)容執(zhí)行操作。 Makefile 里面包含了若干目標(biāo)與操作

其基本關(guān)于規(guī)則如下
目標(biāo):

操作 ``` REST2HTML=html.py --compact-lists --date --generator all: user_manual.html dev_manual.html user_manual.html: user_manual.rst $(REST2HTML) user_manual.rst user_manual.html dev_manual.html: dev_manual.rst $(REST2HTML) dev_manual.rst dev_manual.html clean: rm *.html ``` 以上內(nèi)容分為三個(gè)目標(biāo) all,user_manual.html,clean,其下面分別對應(yīng)的是其操作 我們可以通過 make 后面參數(shù)為目標(biāo)進(jìn)行執(zhí)行。如:make clean ## Tarball 的安裝 由于 Unix like 具有很多種。因此一個(gè)軟件安裝包不可能適用所有所本,因此有時(shí)我們需要根據(jù)軟件提供者提供的源碼自行編譯,以滿足在自己的操作系統(tǒng)上運(yùn)行 大部分軟件開發(fā)包編譯與安裝的流程大致是這樣的 1. 講壓縮文件解壓縮 2. 解壓縮后執(zhí)行里面的 configure 文件,其作用就是建立 makefile 文件 3. Make clean:清理一些上次操作的殘留 4. Make :默認(rèn)操作進(jìn)行編譯的行為 5. Make install:安裝 說明:安裝前如果有安裝文檔最好先查閱 3-4步驟 不一定都存在??刹榭?makefile 內(nèi)容判斷具體包括哪些目標(biāo) 舉例: ``` [root@bogon shared]# tar -zxvf ntp-4.2.4p7.tar.gz -C /tmp ….. [root@bogon ntp-4.2.4p7]# ./configure --prefix=/usr/loacl/ntp => --prefix=/usr/loacl/ntp 為指定安裝目錄 [root@bogon ntp-4.2.4p7]# ll Makefile -rw-r--r-- 1 root 6011 23950 04-05 21:40 Makefile =>生成了Makefile文件 root@bogon ntp-4.2.4p7]# ll Makefile root@bogon ntp-4.2.4p7]# make clean root@bogon ntp-4.2.4p7]# make root@bogon ntp-4.2.4p7]# make install ``` 本文出自 “StarFlex” 博客,請務(wù)必保留此出處[http://tiankefeng.blog.51cto.com/8687281/1372503](http://tiankefeng.blog.51cto.com/8687281/1372503)
上一篇:shell變量下一篇:磁盤掛載與卸載