Linux學習記錄--程序編譯與函數庫

wKiom1NYYV-gaAqKAARqGLVZk-Q465.bmp

程序編譯與函數庫

前面提到過對於機器來講只能識別0,1,咱們若是讓機器運行必須輸入機器可以識別的語言,但是機器語言不利於人們使用可理解,所以科學家就開發出人類能看的懂的程序語言,而後再創造出「編譯器」將程序語言轉換爲機器語言。html

C語言就是咱們可以看懂的機器語言,gcc就是Linux下編譯器。咱們一般C語言寫的程序經過gcc編譯後,就能成爲機器可以識別的語言mysql


gcc程序編譯

若是LINUX 系統中爲安裝GCC編譯器,可使用下面命令安裝linux

[root@bogon ~]# yum install gccsql


gcc經常使用語法

語法:vim

gcc  –c  file.c緩存

僅將源代碼編譯成目標文件。並不會進行連接以及生成可執行文件ide


gcc –o 執行文件名 源代碼文件函數

直接生成指定名稱的執行文件。但不會生成目標文件工具


gcc –o 執行文件名 目標文件優化

經過目標文件生成可執行文件


gcc [其餘編譯操做]  –L庫文件路徑

查找庫文件的路徑默認是/usr/lib 與/ib


gcc  [其餘編譯操做] –I包含文件路徑

查找包含文件的路徑默認是/usr/include


gcc  [其餘編譯操做] –Wall

更加嚴謹的編譯方式,會輸出不少警告信息


gcc  -O  [其餘編譯操做]

編譯時依據操做環境優化執行速度


gcc  [其餘編譯操做] –l庫文件名稱

編譯時引入其餘的庫文件,其中庫文件lib與擴展名不須要寫。如引入libm.so文件,可寫成-lm


單一程序編譯


1.       編寫C語言程序l

[root@bogon code]# vim hello.c
#include <stdio.h>
int main(void)
{
   printf("hello world!");
}


2.       編譯

[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


說明:默認gcc編譯器編譯出來的執行文件a.out, 可使用-o來制定編譯後生產的執行文件名稱

[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


3.      執行

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

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


多文件程序編譯

假設咱們有A.c ,B.c兩個程序文件,而且他們之間存在函數調用,那麼當其中有一個文件更改了。是否是須要將這兩個文件都從新編譯?固然不須要,這就須要引入目標文件

目標文件:編譯器編譯源代碼後生成的文件,目標文件從結構上講,它是已經編譯後的可執行文件格式,只是沒有通過連接的過程。

接着上面的說,當B.c文件更改時,咱們執行從新編譯B文件生產目標文件。再講總體連接便可


1.       編寫C語言程序

File:A.c
#include <stdio.h>
#include 「B.c」
int main ()
{
printf("這是第一個文件\n");
method();
}

File:B.c
#include <stdio.h>
void method(void)
{
 printf("這是第二個文件!\n";)
}

2.       編譯

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

3.    連接

[root@bogon code]# gcc -o result A.o B.o

4.       執行

[root@bogon code]# ./result 
這是第一個文件
這是第二個文件!

5.  更改B.c文件

#include <stdio.h>
void method(void)
{
 printf("這是更改後第二個文件!\n";)
}

6.       從新編譯連接執行

[root@bogon code]# gcc -c B.c =>只編譯了B這個文件
[root@bogon code]# gcc -o result A.o B.o
[root@bogon code]# ./result 
這是第一個文件
這是更改後第二個文件!


調用外部函數庫

1.       編寫C語言程序

#include<stdio.h>
#include<math.h>
 
int main ()
{
  float val=sin(3.14);
  printf("val值是:%f\n",val);
}

2.       編譯與執行

[root@bogon code]# gcc -o sinmath sinmath.c -lm
[root@bogon code]# ./sinmath 
val值是:0.001593


函數庫介紹

函數庫依照是否編譯到程序內部可分爲

靜態函數庫:一般以.a爲擴展名,編譯時會整合到程序文件中

動態函數庫:一般以.so爲擴展名,編譯時會不會整合到程序文件中,只是在程序文件中存在一個指向的位置

所以程序執行時是不須要靜態函數庫的,可是須要動態函數庫,使用動態函數庫的好處再在能夠減小程序文件的大小


動態函數庫加載內存

咱們知道內存的訪問速度是硬盤的好幾倍,若是先將動態函數庫加載到內存中,那麼在使用動態函數庫時就會,就會提升不少效率


語法:ldconfig[-f 須要緩存函數庫信息所在文件] [-C 已緩存函數庫信息所在文件]

            ldconfig –p 列出已緩存函數庫信息


須要緩存函數庫信息所在文件:在這個文件中記錄全部須要緩存的的函數庫默認值是

/etc/ ld.so.conf


舉例:查看下個人系統下緩存的函數庫

[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


已緩存函數庫信息所在文件:這個文件中記錄了已經緩存的函數庫,默認文件爲

/etc/ld.so.cache ,經過-p查詢到的信息就是從這個文件讀取而來


舉例:查看全部已緩存的函數庫

[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
   ……..
查看程序所包含的動態函數庫

語法:ldd –v文件名

-v:列出全部函數庫信息


舉例:

[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編譯

若是一個程序中有不少文件,那麼還像上面那樣講每一個文件列出來在進行編譯就會很麻煩。所以這種時候就須要使用make工具了


Make編譯好處

簡化編譯時所需的指令

若在編譯完成後,修改了某個源文件,只會針對修改的文件編譯


Make使用方法

Make是有個二進制文件,其會查找當前目錄下的Makefile文件,根據其裏面定義的內容執行操做。 Makefile裏面包含了若干目標與操做


其基本關於規則以下

目標:

<tab>操做

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


以上內容分爲三個目標all,user_manual.html,clean,其下面分別對應的是其操做

咱們能夠經過make 後面參數爲目標進行執行。如:make clean


Tarball的安裝

因爲Unix like具備不少種。所以一個軟件安裝包不可能適用全部所本,所以有時咱們須要根據軟件提供者提供的源碼自行編譯,以知足在本身的操做系統上運行


大部分軟件開發包編譯與安裝的流程大體是這樣的

1.      講壓縮文件解壓縮

2.      解壓縮後執行裏面的configure文件,其做用就是創建makefile文件

3.      Make clean:清理一些上次操做的殘留

4.      Make :默認操做進行編譯的行爲

5.      Make install:安裝


說明:安裝前若是有安裝文檔最好先查閱

3-4步驟 不必定都存在。可查看makefile內容判斷具體包括哪些目標


舉例:

[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
相關文章
相關標籤/搜索