1.自動化構建-make/makefile
1.1 背景
- 一個工程文件中的文件不計其數,其按類型、功能、模塊放在若干目錄中,makefile定義了一系列規則來指定哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于過呢更復雜的功能操作。
- makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make指令,整個工程完全自動編譯
- make是一個指令,makefile是一個文件,兩個搭配使用完成項目自動化構建
1.2基本使用
#include <stdio.h>
int main()
{printf("hello world\n");return 0;
}
Makefile文件
test:test.cgcc test.c -o test.PHONY:clean
clean:rm -f test
- 依賴關系:上面的文件test,依賴test.c
- 依賴方法:
gcc test.c -o test
就是對應的依賴方法 - 項目清理
1.工程時需要清理的
2.向clean這種沒有被第一個目標文件直接或間接關聯,那么他后面所對應的命令將不再被自動執行,不過我們可以顯示要make執行即命令“make clean”來清理目標文件
3.但是一般我們這種clean的目標文件,我們將他設置為偽目標用.PHONY
修飾,偽目標的特性是:總是被執行的
1.3 make是如何工作的
test:test.ogcc test.o -o test
test.o:test.cgcc -c test.c -o test.o.PHONY:clean
clean:rm -f *.i *.s *.o test
- make會在當前目錄下尋找名字為"Makefile"或“makefile”的文件。
- 如果找就會找文件中的第一個目標文件。
- 如果test文件不存在或是test所依賴的后面的test.o文件的修改時間要比這個test新,那么就會執行后面所定義的命令來生成test這個文件。
- 如果test依賴的test.o文件不存在,那么make會在當前文件尋找test.o的依賴性,如果找到則根據規則生成一個test.o文件。
- 當然.c文件.h存在于是make會生成test.o文件然后在用.o文件生成目標文件。
- 這就是make的依賴性,make會一層一層的去找文件的依賴關系。
- 在尋找過程中,如果出現錯入那么make會直接退出,并且報錯。而對于所定義的命令的錯誤或是編譯不成功,make根本不理
- make只管文件的依賴性,即在找到依賴關系后,冒號后面的文件還是不在,那么make就不工作了
1.4 適度擴展語法
compling ... test.c to test.o
linking ... test.o to test.exe
[jfs@superg-alicloud test07]$ cat Makefile
BIN=test.exe # 定義變量
CC=gcc
#SRC=$(shell ls *.c) # 采用shell命令行式,獲取當前所有.c文件名
SRC=$(wildcard *.c) # 或者使用wildcard函數,獲取當前所有.c文件名
OBJ=$(SRC:.c=.o) # 將SRC的所有同名.c替換成為.o目標文件列表
LFLAGS=-o # 鏈接選項
FLAGS=-c # 編譯選項
RM=rm -f # 引入命令$(BIN):$(OBJ)@$(CC) $(LFLAGS) $@ $^ # $@:代表目標文件名。 $^: 代表依賴文件列表@echo "linking ... $^ to $@"%.o:%.c # %.c 展開當前錄下所有的.c。 %.o: 同時展開同名.o@$(CC) $(FLAGS) $< # %<: 對展開的依賴.c文件,一個一個的交給gcc。@echo "compling ... $< to $@" # @:不回顯命令.PHONY:clean
clean:@$(RM) $(OBJ) $(BIN) # $(RM): 替換,用變量內容替換它.PHONY:test
test:@echo $(SRC)@echo $(OBJ)
2.Linux簡單的系統程序-進度條
通過主函數傳遞參數模擬下載過程
myproc.h
#pragma once#include <stdio.h>void download(double total, double current, double speed);
myproc.c
#include "myproc.h"
#include <string.h>
#include <unistd.h>#define NUM 101
#define STYLE '-'
void FlushProcess(double total, double current)
{char buffer[NUM];memset(buffer,0,sizeof(buffer));const char* lable="|/-\\";int len = strlen(lable);static int cnt=0;int num = (int)(current*100/total);int i = 0;for(; i < num; i++){buffer[i]=STYLE;}double rate = current*100/total;printf("[%-100s][%.1f][%c]\r",buffer,rate,lable[cnt%len]);cnt++;fflush(stdout);}
void process_v2(double total, double current, double speed)
{while(current <= total){FlushProcess(total, current);usleep(5000);current += speed;}
}void process_v1()
{char buffer[NUM];memset(buffer,0,sizeof(buffer));const char *lable="|/-\\";int len = strlen(lable);int cnt = 0;while(cnt <= 100){printf("[%-100s][%d%%][%c]\r",buffer,cnt,lable[cnt%len]);fflush(stdout);buffer[cnt]=STYLE;cnt++;usleep(50000);}printf("\n");
}void download(double total, double current, double speed)
{//process_v1();process_v2(total, current, speed);printf("\n download %.2fMB\n",current);
}
main.c
#include "myproc.h"double total = 1024.0;
double current = 0.0;
double speed = 1.0;
int main()
{download(total, current, speed);return 0;
}