一. Make
在 認(rèn)識(shí)編譯器和C/C++編譯 一文中介紹過(guò),一個(gè) .c/.cpp 文件從源文件到目標(biāo)文件的過(guò)程叫做編譯桂塞,但是一個(gè)項(xiàng)目中不可能只存在一個(gè)文件凹蜂,這就涉及到多個(gè)文件的編譯問(wèn)題,在編譯的過(guò)程中必然涉及某個(gè)文件的先編譯阁危,某個(gè)文件的后編譯玛痊。構(gòu)建過(guò)程就是安排文件的編譯先后關(guān)系。
Make 就是一種構(gòu)建工具狂打,屬于 GNU 項(xiàng)目擂煞。在 Mac 上輸入 make -version 可查看 make 工具的版本。
>> 執(zhí)行
make -version
>> 輸出
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
二. Makefile
make 命令執(zhí)行時(shí)趴乡,需要一個(gè) makefile 文件对省,以告訴 make 命令如何去編譯和鏈接程序。makefile 規(guī)則的編寫(xiě)可參考 跟我一起寫(xiě)Makefile
舉個(gè)例子晾捏,現(xiàn)在有四個(gè)文件
>> add.cpp
int add (int num1,int num2) {
return num1 + num2 + 200;
}
>> div.cpp
int div(int num1,int num2) {
return num1 / num2;
}
>> sub.cpp
int sub(int num1,int num2) {
return num1 - num2;
}
>> hello.cpp
#include <stdio.h>
int add(int num1,int num2);
int sub(int num1,int num2);
int div(int num1,int num2);
int main(int argc,char* argcv[]) {
int a = 20;
int b = 10;
printf("%d+%d=%d",a,b,add(a,b));
printf("%d-%d=%d",a,b,sub(a,b));
printf("%d/%d=%d",a,b,div(a,b));
}
由于 hello.cpp 依賴 add.cpp 蒿涎、div.cpp 、sub.cpp , 所以按照正常的邊緣步驟是:
gcc hello.cpp div.cpp sub.cpp add.cpp -o hello
>> 拆分來(lái)就是
先生成所有的 .o 文件
gcc -c add.cpp -o add.o
gcc -c div.cpp -o div.o
gcc -c sub.cpp -o sub.o
gcc -c hello.cpp -o hello.o
gcc hello.o div.o sub.o add.o -o hello (沒(méi)有 -c)
使用 Make 就需要編寫(xiě) Makefile 文件惦辛,在源文件目錄下添加 Makefile 文件
hello.out:hello.o sub.o div.o add.o
gcc hello.o sub.o div.o add.o -o hello.out
div.o:div.cpp
gcc -c div.cpp -o div.o
sub.o:sub.cpp
gcc -c sub.cpp -o sub.o
add.o:add.cpp
gcc -c add.cpp -o add.o
hello.o:hello.cpp
gcc -c hello.cpp -o hello.o
執(zhí)行 make 命令同仆,make 會(huì)自動(dòng)查找 Makefile 文件并執(zhí)行。這樣就免去了一步步手動(dòng)編譯文件裙品。
三. CMake和CMakeLists.txt
雖然 Make 和 Makefile 簡(jiǎn)化了手動(dòng)構(gòu)建的過(guò)程,但是編寫(xiě) Makefile 文件仍然是一個(gè)麻煩的工作俗或,因此就有了 CMake 工具市怎。CMake 工具用于生成 Makefile 文件,而如何生成 Makefile 文件辛慰,則由 CMakeLists.txt 文件指定区匠。
舉例:通過(guò) CMakeLists.txt 編譯 hello.cpp
>> hello.cpp
#include <stdio.h>
int main(int argc,char* argcv[]) {
int a = 20;
int b = 10;
printf("%d+%d",a,b);
return 0;
}
>> 在同目錄下編寫(xiě) CMakeLists.txt
PROJECT (HELLO)
SET(SRC_LIST hello.cpp)
MESSAGE(STATUS "this is BINARY dir" ${HELLO_BINDARY_DIR})
MESSAGE(STATUS "this is SOURCE dir" ${HELLO_SOURCE_DIR})
MESSAGE(STATUS "this is PRPOJECT_SOURCE" ${PRPOJECT_SOURCE_DIR})
ADD_EXECUTABLE(hello.out ${SRC_LIST})
>> 執(zhí)行 cmake CMakeLists.txt 生成 Makefile 文件
>> 執(zhí)行 make 命令編譯 hello.cpp 生成 hello.o
最后生成產(chǎn)物如下:
總的來(lái)說(shuō),Make、Makefile驰弄、CMake 和 CMakeLists.txt 的關(guān)系可總結(jié)為下圖: