# 初探Makefile
Copyright 2021, [月下麒麟](https://hackmd.io/@YMont/note-catalog)
---
## 起源
reference:[Why are Makefiles in Linux so useful](https://bit.ly/3ATh7cR)
>A makefile is useful because **(if properly defined) allows recompiling only what is needed when you make a change.** In a large project rebuilding the program can take some serious time because there will be many files to be compiled and linked and there will be documentation, tests, examples etc.
每次都敲打指令gcc -o...,修改程式過程中,不斷來回compile,
重工又繁瑣,若是要編譯、連結的檔案繁多,那工程又更浩大。
此時,撰寫makefile腳本會使編譯過程輕鬆。
(在windows上,建議可先安裝git,然後再開啟git bash做指令操作)
## 建立C語言檔案
```c=
//filename:hello.c
#include <stdio.h>
int main(){
printf("hello world.");
return 0;
}
```
## #1-1 實作練習
```cmake=
# filename:Makefile (makefile沒有副檔名喔!)
# Comment # this is a Makefile
# Notice that the space before cc must be a TAB, NOT four spaces!!
compile: hello.c
gcc -c hello.c
output: hello.o
gcc -o hello hello.o
execute: output
./hello.exe
clean:
rm -f *.o *.exe
```
該寫法比較陽春,如同終端機下的編譯命令。
有個不錯的makefile格式解釋範例,如下:
(reference:[簡單學 makefile:makefile 介紹與範例程式](https://mropengate.blogspot.com/2018/01/makefile.html))
## #1-2 實作練習
```cmake=
# filename:Makefile
# Comment # this is a Makefile
# Notice that the space before cc must be a TAB, NOT four spaces!!
CC = gcc
FILENAME = hello
compile: $(FILENAME).c
$(CC) -c $(FILENAME).c
output: $(FILENAME).o
$(CC) -o $(FILENAME) $(FILENAME).o
execute: output
./$(FILENAME)
clean:
rm -f *.o $(FILENAME)
```
利用符號 **$()** 作為變數名稱,增加許多使用上的彈性。
---
**make命令執行**
```bash=
$ make execute
```
```
# Output
gcc -c -o hello.o hello.c
gcc -o hello hello.o
./hello.exe
hello world.
```
同時也會**生成hello.o, hello.exe**的檔案
另外,也可僅執行某個target,如:make compile , make install...
```bash=
$ make clean
```
```
# Output
rm -f *.o *.exe
```
即**刪除.o與.exe副檔名結尾的檔案**
以上為簡易示範,這樣就可以減少大量的敲打指令時間,讓寫程式更有效率。
## 補充
```cmake=
test: test.c $(TOPDIR)/lib/test.h
$(CC) $(CFLAGS) $(LDFLAGS) test.c -o main $(LDLIBS) $(SYSLIBS)
```
發現open source有這類的應用,可參考如下連結。
Reference:[CFLAGS详解](https://blog.csdn.net/xinyuan510214/article/details/50457433)
>CFLAGS 表示用於C 編譯器的選項,這兩個變量實際上涵蓋了編譯和彙編兩個步驟。
>CFLAGS 同樣地,安裝一個包時會在安裝路徑下建立一個include目錄,當安裝過程中出現問題時,試著把以前安裝的包的include目錄加入到該變量中來。
>LDFLAGS 用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安裝一個包都幾乎一定的會在安裝目錄裡建立一個lib目錄。如果明明安裝了某個包,而安裝另一個包時,它愣是說找不到,可以抒那個包的lib路徑加入的LDFALGS中試一下。
>LIBS
簡單地說,不過使用時鏈接階段這兩個參數都會加上,所以你即使將這兩個的值互換,也沒有問題。
<font color="gray">版權聲明:本文為CSDN博主「xinyuan0214」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xinyuan510214/article/details/50457433</font>
Reference:[第 22 章 Makefile基礎-3.變數](http://shihyu.github.io/books/ch22s03.html)
該連結也有解釋到CFLAGS, LDFLAGS...等相關意涵。
###### tags: `Cmake`