动机
用makefile文件和make命令自动编译。以工程的角度管理文件。
示例1
要被编译链接的源程序示例。
main.c
/*main.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include "menu.h"
int main() {
init_menu();
start_menu();
return 0;
}
menu.h
/*menu.h*/
#define MENU_COUNT 5
#define MENU_PROMPT 9
extern char* menu[MENU_PROMPT];
extern char* separator;
extern char* prompt;
int init_menu();
int start_menu();
menu.c
/*menu.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include "menu.h"
char* menu[MENU_PROMPT];
char* separator;
char* prompt;
int init_menu() {
menu[0] = "************************************\n";
menu[1] = "* This is my shel demol. Please try it. *\n";
menu[2] = "* 1 : File *\n";
menu[3] = "* 2 : Edit *\n";
menu[4] = "* 3 : View *\n";
menu[5] = "* 4 : Tool *\n";
menu[6] = "* 0 : Quit *\n";
menu[7] = "************************************\n";
menu[8] = "* You can use \"0: Quit\" to exit.\n";
separator = "************************************\n";
prompt = "my shell >>> ";
return 0;
}
int start_menu() {
int user_choice = 0;
int quit = 0;
while(1) {
user_choice = display_menu();
quit = dispatch_task(user_choice);
if (quit)
break;
}
return 0;
}
int display_menu() {
int i;
for ( i=0; i<MENU_PROMPT; i++ ) {
printf(menu[i]);
}
printf(prompt);
int choice = 0;
scanf("%d", &choice);
return choice;
}
util.h
/*util.h*/
int dispatch_task(int choice);
util.c
/*util.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include "util.h"
int dispatch_task(int choice) {
int result_quit = 0;
switch (choice) {
case 1:
func1();
break;
case 2:
func2();
break;
case 3:
func3();
break;
case 4:
func4();
break;
case 0:
quit();
result_quit = 1;
break;
}
return result_quit;
}
int func1() {
printf("********** Task is processing. **********\n");
printf("This is function1 File. \n");
printf("This is function1 File. \n");
printf("This is function1 File. \n");
printf("*********** Task is completed. **********\n");
}
int func2() {
printf("********** Task is processing. **********\n");
printf("This is function2 Edit. \n");
printf("This is function2 Edit. \n");
printf("This is function2 Edit. \n");
printf("*********** Task is completed. **********\n");
}
int func3() {
printf("********** Task is processing. **********\n");
printf("This is function3 View. \n");
printf("This is function3 View. \n");
printf("This is function3 View. \n");
printf("*********** Task is completed. **********\n");
}
int func4() {
printf("********** Task is processing. **********\n");
printf("This is function4 Tool. \n");
printf("This is function4 Tool. \n");
printf("This is function4 Tool. \n");
printf("*********** Task is completed. **********\n");
}
int quit() {
printf("************************************\n");
printf("The Program demo is over. \n");
printf("************************************\n");
}
示例2
makefile文件以及执行的结果。
makefile示例:示例1(错误)
makefile文件
./bin/testmake: ./obj/main.o ./obj/menu.o ./obj/util.o
gcc ./obj/main.o ./obj/menu.o ./obj/util.o -o ./bin/testmake
./obj/main.o: main.c
gcc main.c -o ./obj/main.o
./obj/menu.o: menu.c
gcc menu.c -o ./obj/menu.o
./obj/util.o: util.c
gcc util.c -o ./obj/util.o
make执行结果
[tj@tj 002_makefile]$ make
gcc main.c -o ./obj/main.o
/tmp/ccVOxWW1.o:在函数‘main’中:
main.c:(.text+0xa):对‘init_menu’未定义的引用
main.c:(.text+0x14):对‘start_menu’未定义的引用
collect2: 错误:ld 返回 1
make: *** [obj/main.o] 错误 1
makefile示例:示例2
makefile文件
./bin/testmake: ./obj/main.o ./obj/menu.o ./obj/util.o
gcc ./obj/main.o ./obj/menu.o ./obj/util.o -o ./bin/testmake
./obj/main.o: main.c
gcc -c main.c -o ./obj/main.o
./obj/menu.o: menu.c
gcc -c menu.c -o ./obj/menu.o
./obj/util.o: util.c
gcc -c util.c -o ./obj/util.o
.PHONY: clean
clean:
rm ./obj/*.o
rm ./bin/*
第一次make执行结果
4个gcc命令都被执行。
生成./obj
下面的3个.o
文件,
生成./bin
下面的1个testmake
文件。
[tj@tj 002_makefile]$ make
gcc -c main.c -o ./obj/main.o
gcc -c menu.c -o ./obj/menu.o
gcc -c util.c -o ./obj/util.o
gcc ./obj/main.o ./obj/menu.o ./obj/util.o -o ./bin/testmake
第二次make执行结果
没有新的修改,4个gcc命令不需要执行。
[tj@tj 002_makefile]$ make
make: “bin/testmake”是最新的。
第三次make执行结果
修改了menu.c文件。
只对修改后受影响的文件(menu.o
,testmake
)重新编译链接。
[tj@tj 002_makefile]$ make
gcc -c menu.c -o ./obj/menu.o
gcc ./obj/main.o ./obj/menu.o ./obj/util.o -o ./bin/testmake
第四次make执行结果
执行伪目标 make clean
删除所有生成文件。
[tj@tj 002_makefile]$ make clean
rm ./obj/*.o
rm ./bin/*
第五次make执行结果
没有了目标文件,再一次全部重新生成。
[tj@tj 002_makefile]$ make
gcc -c main.c -o ./obj/main.o
gcc -c menu.c -o ./obj/menu.o
gcc -c util.c -o ./obj/util.o
gcc ./obj/main.o ./obj/menu.o ./obj/util.o -o ./bin/testmake
示例3
改进的makefile文件。
等待更新中。。。。。。
参考
(Linux)make编译用法简述
linux系统命令make、clean、distclean的用法讲解
使用make命令编译项目文件入门
make编译
linux Makefile PHONY作用
makefile输出到指定目录
如何用一个makefile编译多个目标