機器語言,匯編語言與高級語言
機器語言是機器指令的集合。機器指令展開來講就是一台機器可以正確執行的命令。電子計算機的機器指令是一列二進制數字。計算機將之轉變為一列高低電平,以使計算機的電子器件受到驅動,進行運算。
早期的程序設計均使用機器語言。程序員們將用0, 1數字編成的程序代碼打在紙帶或卡片上,1打孔,0不打孔,再將程序通過紙帶機或卡片機輸入計算機,進行運算。這樣的機器語言由純粹的0和1構成,十分復雜,不方便閱讀和修改,也容易產生錯誤。
編語言的主體是匯編指令。匯編指令和機器指令的差別在於指令的表示方法上。匯編指令是機器指令便於記憶的書寫格式。
1000100111011000 機器指令
mov ax,bx 匯編指令
將匯編指令轉換成機器指令的翻譯程序,這樣的程序我們稱其為編譯器。程序員用匯編語言寫出源程序,再用匯編編譯器將其編譯為機器碼,由計算機最終執行。
由於匯編語言依賴於硬件體系,且助記符量大難記,於是人們又發明了更加易用的所謂高級語言。在這種語言下,其語法和結構更類似普通英文,且由於遠離對硬件的直接操作,使得一般人經過學習之后都可以編程。
高級語言: 面向過程-C, 面向對象C++,Java.
所以, 高級語言要執行,最終是要經過編譯轉化為匯編語言才能被機器執行。
C語言的編譯和鏈接
編譯是把源碼編譯成中間代碼文件,
在Windows下是.obj文件, 在Linix下是.o 的文件,即Object File, 目標文件
鏈接處理的是目標文件之間的調用關系。方式就是把目標文件打個包, 在Windows 下這個包文件愛你叫Library-庫文件, 以.lib結尾。
在Linux下叫Archive文件, 以 .a結尾。
源文件首先會生成中間目標文件,再由中間目標文件生成執行文件。在編譯時,編譯器只檢測程序語法,和函數、變量是否被聲明。如果函數未被聲明,編譯器會給出一個警告,但可以生成Object File。而在鏈接程序時,鏈接器會在所有的Object File中找尋函數的實現。
沒有Makefile的編譯
gcc -o myapp main.c func1.c func2.c func3.c
以上編碼包括代碼:
主程序代碼 main.c
三個子函數 : funcx.c
寫在Makefile 文件中:
myapp: main.c func1.c func2.c func3.c
gcc -o calc main.c func1.c func2.c func3.c
這是一個基本的Makefile語句,它主要分成了三個部分,
第一部分:第一行冒號之前的myapp,我們稱之為目標(target),被認為是這條語句所要處理的對象,具體到這里就是我們所要編譯的這個程序myapp。
第二部分:冒號后面的部分(main.c func1.c func2.c func3.c),我們稱之為依賴關系表,也就是編譯所需要的文件
第三部分: 命令部分,就是一條編譯命令
什么是Makefile?
Makefile是一個文件。
makefile定義整個工程的編譯規則。一個工程中的源文件不計數,其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至於進行更復雜的功能操作,因為makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。
Makefile文件被 make命令使用。make是如何工作的呢?
在默認的方式下,
1. make會在當前目錄下找名字叫“Makefile”或“makefile”的文件。
2. 如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到“edit”這個文件,並把這個文件作為最終的目標文件。
3. 如果edit文件不存在,或是edit所依賴的后面的 .o 文件的文件修改時間要比edit這個文件新,那么,他就會執行后面所定義的命令來生成edit這個文件。
4. 如果edit所依賴的.o文件也存在,那么make會在當前文件中找目標為.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
5. make會生成 .o 文件,然后再用 .o 文件聲明make的終極任務,也就是執行文件edit了。
這就是整個make的依賴性,make會一層又一層地去找文件的依賴關系,直到最終編譯出第一個目標文件。在找尋的過程中,如果出現錯誤,比如最后被依賴的文件找不到,那么make就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make根本不理。make只管文件的依賴性,即,如果在我找了依賴關系之后,冒號后面的文件還是不在,那么對不起,我就不工作啦
autoconf&automake
Makefile中紀錄有文件的信息,在make時會決定在鏈接的時候需要重新編譯哪些文件。
Makefile的宗旨就是:讓編譯器知道要編譯一個文件需要依賴其他的哪些文件。當那些依賴文件有了改變,編譯器會自動的發現最終的生成文件已經過時,而重新編譯相應的模塊。
當系統環境變量或路徑發生了變化后,Makefile可能還要跟着修改。這樣就造成了手工書寫Makefile的諸多問題,automake恰好能很好地幫助我們解決這些問題。
使用automake,程序開發人員只需要寫一些簡單的含有預定義宏的文件,由autoconf根據一個宏文件生成configure,由automake根據另一個宏文件生成Makefile.in,再使用configure依據Makefile.in來生成一個符合慣例的Makefile
autoconf用來生成configure configure生成makefile make就去調gcc編譯源文件
使用autoconf和automake兩個工具來幫助我們自動地生成符合自由軟件慣例的Makefile.
實例
- 在工作目錄下新建testmake目錄
mkdir testmake
cd testmake
- 1
- 2
- 3
- 編寫源代碼 helloworld.c
vi helloworld.c
int main(int argc,char** argv) { printf("Hello,My First Linux Make"); return 0; }
- 1
- 2
- 3
- 4
- 5
- 生成configure.
使用autoscan命令,生成configure.scan的文件
autoscan
重命名為configure.in, 並修改文件內容
mv configure.scan configure.in
-*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_INIT(helloworld.c) AM_INIT_AUTOMAKE(helloworld,1.0) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT(Makefile)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 執行 aclocal 和autoconf, 產生aclocal.m4及configure
aclocal根據configure.in文件的內容,自動生成aclocal.m4文件。aclocal是一個perl腳本程序,它的定義是:“aclocal - create aclocal.m4 by scanning configure.ac”。
autoconf 是用來生成自動配置軟件源代碼腳本(configure)的工具。configure腳本能獨立於autoconf運行,且在運行的過程中,不需要用戶的干預。
autoconf需要GNU m4宏處理器來處理aclocal.m4,生成configure腳本。
m4是一個宏處理器。將輸入拷貝到輸出,同時將宏展開。宏可以是內嵌的,也可以是用戶定義的。除了可以展開宏,m4還有一些內建的函數,用來引用文件,執行命令,整數運算,文本操作,循環等。m4既可以作為編譯器的前端,也可以單獨作為一個宏處理器.
5.創建Makefile.am
新建Makefile.am文件,命令:$ vi Makefile.am
automake會根據你寫的Makefile.am來自動生成Makefile.in。Makefile.am中定義的宏和目標,會指導automake生成指定的代碼。例如,宏bin_PROGRAMS將導致編譯和連接的目標被生成。
AUTOMAKE_OPTIONS=foreign bin_PROGRAMS=helloworld helloworld_SOURCES=helloworld.c
- 1
- 2
- 3
- 4
- 5
6.運行automake –add-missing
automake會根據Makefile.am文件產生一些文件,包含最重要的Makefile.in。
- 執行configure生成Makefile
./configure
- 1
8.使用Makefile編譯代碼
make
- 1
9.運行
./helloworld
