MakeFiles基本使用指南

下面的內容是直接從個人ipython notebook中摘錄出來的因此可能不是很清楚,若是想查看完整版本以及例子,能夠訪問:html

git地址: git@github.com:liangz0707/WTF-makefile.gitpython

下載地址:https://github.com/liangz0707/WTF-makefile/archive/master.zipios

若是不能查看ipython notebook 能夠直接打開其中的lession.html 結果是同樣的 git

首先講解編譯器等內容

What is Compiler?程序員

Compiler=編譯器,就是將某種代碼編譯成機器語言,或者說編譯成可以由處理器直接執行的「代碼」。一個程序員會以一種語言在編輯器當中編寫語句。例如:c、Lisp。編寫完成後生成的文件就是源代碼。而後程序員運行具體的編譯器,把上述文件名做爲參數進行編譯。github

執行過程當中,編譯器會依照語法順序,逐一對語句進行解析。最終生成輸出代碼。通常的編譯器的輸出結果叫作object code或者object module(這裏的object和麪向對象中的object不一樣)。這裏的object code是機器語言。安全

在傳統的操做系統當中,在編譯以後每每還須要額外的步驟,由於當有多於一個Object Code時 他們的指令、和數據之間存在關係,因此須要進行連接,獲得的結果是。 load module。less


下面使用具體的編譯器GCC來說解

GCC是c語言的編譯器之一:編輯器

gcc is the "GNU" C Compiler, and g++ is the "GNU C++ compiler工具

咱們編寫一個hello.c文件(見目錄):

/#include "iostream.h"

int main()

{

cout << "Hello\n";

}

執行以下命令,輸出的結果就是可執行的機器碼(.exe可執行程序),默認文件名是a.exe

主要g++編譯的源文件中頭文件的引用通常爲#include< iostream>,而不是#include< iostream.h>,而且要注意使用命名空間。

!g++ hello.c -o hello


Makefiles的使用

在實際的編譯過程當中,逐個的編譯源代碼過於冗雜,尤爲是當你須要包含不少源文件時,你不得不每一次都要打字輸入。

而是用Makefile就是爲了簡化不少源文件的編譯過程。 例如咱們有不少c問見須要編譯:

  • main.cpp

  • hello.cpp

  • factorial.cpp

  • functions.h 以上的文件都是經過頭文件串聯起來的

#若是須要手動的編譯,以下很是麻煩
!g++ main.cpp hello.cpp factorial.cpp -o hello

#執行上面獲得的文件
!hello


編譯的過程包含了:

  • 把source code轉換成object files

  • 將不一樣的object files鏈接成可執行的機器碼(.exe) 下面使用最簡單的Makefile 來進行編譯,代替手工過程

基本的Makefile組成以下:

target: dependencies

[tab]system command

‘target’能夠理解爲要編譯的目標或任務(分號後的內容),dependencies表示要完成這個目標所須要的前提。編寫成咱們須要的格式以下:

all:     

    g++ main.cpp hello.cpp factorial.cpp -o hello

從makefile文件中能夠看出咱們的目的是‘all’,這是makefiles默認的目標。make工具在沒有特殊聲明的時候會有限執行‘all’,咱們看到all是沒有依賴的,因此能夠安全的執行。

那麼如何使用依賴關係呢?

有時候咱們會使用不一樣的‘target’。由於當咱們修改了一個文件的時候,不但願把全部的文件都進行從新編譯。

例如如下的例子:

all: hello

hello: main.o factorial.o hello.o     

    g++ main.o factorial.o hello.o -o hello main.o: main.cpp     

    g++ -c main.cpp factorial.o: factorial.cpp     

    g++ -c factorial.cpp hello.o: hello.cpp     

    g++ -c hello.cpp

clean:     

    del *o hello.exe

至關於把編譯的過程(上述的兩部,編譯、鏈接)拆分開。

咱們看到all只有一個依賴,而沒有命令,這是爲了讓make可以正確的執行。all必須執行才能完成。

對於每個可用的目標全部的依賴都會被搜索,若是找到則執行。

咱們還看到了一個clean的目標,他能夠快速的清楚全部的object和可執行程序,至於如何使用稍後解釋。

在makefiles中使用變量和註釋

例子以下:

# I am a comment, and I want to say that the variable CC will be

# the compiler to use. CC=g++

# Hey!, I am comment number 2. I want to say that CFLAGS will be the

# options I'll pass to the compiler.

CFLAGS=-c -Wall

all: hello

hello: main.o factorial.o hello.o    

    $(CC) main.o factorial.o hello.o -o hello

main.o: main.cpp     

    $(CC) $(CFLAGS) main.cpp

factorial.o: factorial.cpp     

    $(CC) $(CFLAGS) factorial.cpp

hello.o: hello.cpp     

    $(CC) $(CFLAGS) hello.cpp

clean:     

    del *o hello.exe

如上所示,使用$(VAR)就能夠輕鬆的訪問變量。

相關文章
相關標籤/搜索