程序構建工具makefile、cmake、qmake的總結
1.一個簡單的例子
現在有一個hello world程序:
#include <stdlib.h>
int main()
{
printf("%s\n","hello world!");
return 0;
}
假如該文件的文件名爲helloworld.c
,在linux系統下可以通過下面的命令將程序編譯成可執行程序:
gcc -o helloworld helloworld.c
再輸入下面的命令運行程序:
./helloworld
就可以看到程序的輸出了hello world!
了。
2.多個文件的例子
現在有main.c、file1.c、file1.h、file2.c、file2.h
這幾個文件,main.c
中使用了file1.c
和file2.c
中的函數,這時可以使用下面命令來編譯生成可執行文件:
gcc -o exe main.c file1.c file2.c
而且實際開發不可能將所有源文件都放同一個目錄,如果把file1.c、file1.h
放在folder1
文件夾中,file2.c、file2.h
放在folder2
文件夾中,結構如下
–main.c
–folder1
----file1.c
----file1.h
–folder2
----file2.c
----file2.h
這時候的編譯命令如下:
gcc -o main.c foler1/file1.c folder2/file2.c
這是隻有3個源文件的情況,假如一個工程中有成千上萬的文件,每次編譯程序都需要把這些文件輸入一遍,這是不現實的。這個時候就有人想:爲什麼不把這個編譯命令用文件儲存起來呢?
3.makefile
簡介
makefile
就是基於編譯器命令,對程序的編譯過程記錄起來,它具有以下的作用
:
1.保存每次編譯時需要輸入的編譯命令
。
2.加入語法結構,makefile的語法側重於控制中間文件(從源文件到可執行文件之間)的生成,使得程序的編譯命令更容易維護,更利於模塊化開發,也更有可讀性。
3.加入了變量的概念,使得使得編譯命令更加簡潔。同時也加入了一些常用的函數,方便文件的編寫。
4.加入了自動推導以及批處理的功能,更容易實現大規模工程的編譯
關於makefile
的語法規則
,參考:《跟我一起寫makefile》
如何使用makefile來構建工程
1.在工程目錄下新建makefile
(或者Makefile
)文件
2.根據工程編寫makefile
文件
3.輸入make
命令
關於makefile
的一個例子,假如現在一個工程的結構如下
–main.c
–main.h
–folder1
----file1.c
----file2.c
----file3.c
–folder2
----file4.c
----file5.c
----file6.c
其中folder1
和folder2
中的文件分別爲一個功能模塊,main.c
使用了main.h
,那麼makefile
可以這麼編寫:
SRC1 = $(wildcard ./folder1/*.c)
SRC2 = $(wildcard ./folder2/*.c)
MODULE1= $(patsubst %.c,%.o,$(SRC1))
MODULE2= $(patsubst %.c,%.o,$(SRC2))
exe : main.o $(module1) $(module2)
gcc -o $@ $^
main.o : main.h
$(MODULE1):%.o:%.c
gcc -c -o $@ $<
$(MODULE2):%.o:%.c
gcc -c -o $@ $<
./PHONY:clean
clean:
-rm exe main.o $(MODULE1) $(MODULE2)
然後輸入make
命令即可生成可執行文件。
由於現在工程規模還太小,使用makefile
在代碼量上還看不出什麼優勢,但是可能看出在結構上makefile
有了很大的提升,具有可讀性。隨着工程規模的增大,跟直接使用編譯命令相比,makefile
的優勢會越來越大。
雖然跟直接使用編譯命令比較,makefile
已經有了很大的優勢,但是如果一個工程目錄結構複雜,文件之間的依賴關係比較複雜的時候,即使編寫makefile
也會是已經比較複雜的工作,所以又出現了專門用來生成makefile
的工具。
4.cmake
簡介
由於makefile是基於平臺命令的,所以不同的操作系統下的makefile文件都不相同,那麼每次移植工程到其他平臺時,就得重新編寫makefile文件。另外編寫一個makefile文件對於構建複雜的工程來說還是比較麻煩的工作。使用cmake可以隱藏跟平臺相關的細節。跟makefile相比,cmake具有以下優點:
(1) cmake是一個跨平臺工具,可以對不同平臺下的工程進行構建。
(2) 加入了 配置文件的概念,可以通過預定義一些參數和變量,用於控制代碼的生成。 利用這個特性,可以很容易實現版本管理,使得工程開發和工程管理分離。
(3) 使用簡單,只需要掌握十來個函數和常用的環境變量。
cmake
常用的命令:
- cmake_minimum_requied(VERSION X.X) #設置cmake所需的最低版本號爲X.X。
- project(name) #將工程名設置爲name。
- set(var value) #將變量var的值設置爲value。
- aux_source_director(dir var) #將目錄dir下的所有源文件賦值給變量var,假如var不存在,則新建變量var。
- include_directories(dir) #添加頭文件的搜索路徑
- link_directories(dir) #添加庫文件搜索路徑
- add_subdirectory(dir) #添加子目錄,子目錄中的CMakelists.txt也會被執行
- add_executable(target source1 source2 …) #從參數中的源文件列表生成可執行文件
- target_link_libraries(target lib) #將可執行文件target 鏈接到庫lib
- install(TARGETS target DESTINATION subdir) #將target複製到subdir目錄下,subdir的父目錄爲CMAKE_INSTALL_PREFIX,默認值一般爲/usr/local。
- add_library(lib source1 source2 …) #將列表中的源文件生成靜態庫lib。
- add_library(lib SHARED source1 source2 …) #將列表中的源文件生成動態庫lib。
- message([SEND_ERROR | STATUS | FATAL_ERROR] “message to display”) #打印信息
- add_definitions(“options”) #添加編譯器的編譯參數
cmake
的入門教程:http://www.hahack.com/codes/cmake/
cmake
的使用:
(1). 在工程目錄下新建並且編輯所需的CMakeList.txt,如果工程複雜,可以在每個模塊目錄下再新建CMakeList.txt,用於管理該目錄下的文件編譯。
(2). 生成makefile文件,在工程主目錄下輸入命令:
cmake ./
(3). 生成可執行文件:
make
(4). 如果CMakeLists.txt中定義了安裝規則,可以使用下面的命令將目標文件安裝到設定的目錄中:
make install
qmake
簡介
qmake
和cmake
一樣,都是通過編寫一個構建文件(cmake爲CMakeLists.txt,qmake爲*.pro),然後從構建文件中生成makefile
文件。qmake
相對來說,語法更加直觀。比如要添加頭文件路徑
在CMakeLists.txt中會這麼寫:
include_directories(path1 path2 ...)
而在qmake的.pro文件中會這麼寫:
INCLUDEPATH = path1 paht2
qmake的使用也跟cmake類似:
編寫.pro文件
->qmake *.pro
->make