1. 程式人生 > >Linux中的configure,make,make install到底在做些什麽

Linux中的configure,make,make install到底在做些什麽

根據 suffix 模塊 產生 image san option tdi cache

在Linux下經常要安裝部署一些軟件包或者工具,拿到安裝包之後一看,簡單,configure,make, make install即可搞定。

有時候我就在想,這個configure,make ,make install是什麽意思呢,configure是測試存在的特性,然後make開始編譯,make install生成相應的可執行文件。但是一個工具只是記住了其中的拼寫部分或是基本的概念,但是對於原理知之甚少,也是需要補補了。

幾個構建編譯隱藏的命令

要先說這個編譯安裝過程,使用命令aclocal會生成m4文件,aclocal本質上是一個perl腳本。先提提m4, m4是一種宏處理器,它是 POSIX 標準的一部分。為什麽叫m4呢,全稱是macro,m後面有4個字母,據說是這樣的,哈哈。摘錄一段對於m4的描述:從圖靈的角度來看 m4,輸入流與輸出流可以銜接起來構成一條無限延伸的紙帶,m4 是這條紙帶的讀寫頭,所以 m4 是一種圖靈機。m4 的計算能力與任何一種編程語言等同,區別只體現在編程效率以及所編寫的程序的運行效率方面。

然後是autoconf,是生成configure文件的,configure是一個腳本,它能設置源程序來適應各種不同的操作系統平臺,並且根據不同的系統來產生合適的Makefile,從而可以使你的源代碼能在不同的操作系統平臺上被編譯出來。

最後是automake用來生成Makefile.in文件

簡單總結一下,這個編譯過程涉及幾個命令工具,大體的功能點如下。

aclocal # 產生 aclocal.m4

autoconf # 根據 configure.in 生成configure

automake --add-missing # 根據 Makefile.am生成Makefile.in

網上找到一張總結的很牛的圖,很全面。

技術分享圖片

構建過程環境準備

我們寫個簡單的Hello world來了解下整個過程吧。

我寫了一段非常簡單的c程序,就湊合著編譯著用吧。文件為main.c

#include <stdio.h>

int main(int argc, const char *argv[])

{

printf("Hello world ,a new testn");

return 0;

}

可以看出,程序運行後的輸出就是Hello world,a new test

我們看看構建GNU程序中如何按照規範來模擬這個過程

我們創建一個文件configure.ac,裏面是一些宏,是接下倆的autoconf來處理的需要的,然後交給automake來處理,最終完成這個檢查。

AC_INIT([helloworld],[0.1],[[email protected]])

AM_INIT_AUTOMAKE

AC_PROG_CC

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

比如AC_INIT([helloworld],[0.1],[[email protected]])的含義是autoconf生成包的名字,版本(這個可以自己定義),反饋郵箱,

AM_INIT_AUTOMAKE是檢查automake嘗試Makefile時的工具,AC_PROG_CC是編譯器檢測,AC_CONFIG_FILES是automake構建出類似.in的文件。

然後就是Makefile的文件,我們設定名字為Makefile.am,這部分的內容和上面的配置是密切相關的。

[root@oel64 tmp]# cat Makefile.am

AUTOMAKE_OPTIONS=foreign

bin_PROGRAMS = helloworld

helloworld_SOURCES = main.c

automake提供了3種軟件等級:foreign、gnu和gnits。默認等級是gnu。此處AUTOMAKE_OPTIONS使用的是foreign,表示只檢測必要的文件。

bin_PROGRAMS定義了要產生的執行文件名,這裏我們定義為helloworld

file_SOURCES定義file這個執行程序的依賴文件,其中“file_SOURCES”中的前部分“file”要改寫成可執行文件名,即與bin_PROGRAMS定義的名稱一致,此處就是helloworld了。如果有多個可執行文件,那就要定義相應的file_SOURCES。

構建過程實踐

到目前為止,我們創建了3個文件 main.c,configure.ac,Makefile.am

[root@oel64 c]# ll

-rwxr-xr-x. 1 root root 108 Sep 13 12:13 configure.ac

-rw-r--r--. 1 root root 105 Sep 13 12:13 main.c

-rw-r--r--. 1 root root 79 Sep 13 12:13 Makefile.am

首先使用aclocal來得到m4文件。這裏生成了2個文件,一個是aclocal.m4,另外一個是cache文件autom4te.cache

[root@oel64 c]# aclocal

[root@oel64 c]# ll

total 56

-rw-r--r--. 1 root root 34611 Sep 13 12:14 aclocal.m4

drwxr-xr-x. 2 root root 4096 Sep 13 12:14 autom4te.cache

-rwxr-xr-x. 1 root root 108 Sep 13 12:13 configure.ac

-rw-r--r--. 1 root root 105 Sep 13 12:13 main.c

-rw-r--r--. 1 root root 79 Sep 13 12:13 Makefile.am

然後使用autoconf得到configure文件

[root@oel64 c]# autoconf

[root@oel64 c]# ll

-rw-r--r--. 1 root root 34611 Sep 13 12:14 aclocal.m4

drwxr-xr-x. 2 root root 4096 Sep 13 12:14 autom4te.cache

-rwxr-xr-x. 1 root root 135288 Sep 13 12:14 configure

-rwxr-xr-x. 1 root root 108 Sep 13 12:13 configure.ac

-rw-r--r--. 1 root root 105 Sep 13 12:13 main.c

-rw-r--r--. 1 root root 79 Sep 13 12:13 Makefile.am

然後使用automake來構建模塊

[root@oel64 c]# automake --add-missing

configure.ac:2: installing `./install-sh‘

configure.ac:2: installing `./missing‘

Makefile.am: installing `./depcomp‘

整個過程完成之後,就是我們平常執行的操作了。

執行configure的結果如下:

[root@oel64 c]# ./configure

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking for a thread-safe mkdir -p... /bin/mkdir -p

checking for gawk... gawk

checking whether make sets $(MAKE)... yes

checking for gcc... gcc

checking for C compiler default output file name... a.out

checking whether the C compiler works... yes

checking whether we are cross compiling... no

checking for suffix of executables...

checking for suffix of object files... o

checking whether we are using the GNU C compiler... yes

checking whether gcc accepts -g... yes

checking for gcc option to accept ISO C89... none needed

checking for style of include used by make... GNU

checking dependency style of gcc... gcc3

configure: creating ./config.status

config.status: creating Makefile

config.status: executing depfiles commands

[root@oel64 c]#

然後是make,這個過程你可以清晰的看到gcc開始編譯。

[root@oel64 c]# make

gcc -DPACKAGE_NAME="helloworld" -DPACKAGE_TARNAME="helloworld" -DPACKAGE_VERSION="0.1" -DPACKAGE_STRING="helloworld 0.1" -DPACKAGE_BUGREPORT="[email protected]" -DPACKAGE="helloworld" -DVERSION="0.1" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c

mv -f .deps/main.Tpo .deps/main.Po

gcc -g -O2 -o helloworld main.o

最後是make install,有了可執行的程序文件。

[root@oel64 c]# make install

make[1]: Entering directory `/root/c‘

test -z "/usr/local/bin" || /bin/mkdir -p "/usr/local/bin"

/usr/bin/install -c helloworld ‘/usr/local/bin‘

make[1]: Nothing to be done for `install-data-am‘.

make[1]: Leaving directory `/root/c‘

比如編譯後的main.o,如果使用strings來查看內容就是執行後的結果。

[root@oel64 c]# strings main.o

Hello world ,a new test

如果查看可執行程序helloworld的內容,裏面是有相應的堆棧的。

[root@oel64 c]# strings helloworld

/lib64/ld-linux-x86-64.so.2

__gmon_start__

libc.so.6

puts

__libc_start_main

GLIBC_2.2.5

fff.

手工執行一下 。

[root@oel64 c]# ./helloworld

Hello world ,a new test

Linux中的configure,make,make install到底在做些什麽