Linux下C编程里的makefile

假设我们有下面这样的程序:
/*main.c*/
#include "mytool1.h"
#include "mytool2.h"
#include <stdio.h>

int main(int argc,char *argv[])
{
        mytool1_print("hello");
        mytool2_print("hello");
}
/*mytoo1.h*/
#ifndef _MYTOOL1_H
#define _MYTOOL1_H
void mytool1_print(char *print_str);
#endif
/*mytool1.c*/
#include "mytool1.h"

void mytool1_print(char *print_str)
{
        printf("This is mytool1 print %s\n",print_str);
}
/*mytool2.h*/
#ifndef _MYTOOL2_H
#define _MYTOOL2_H
void mytool2_print(char *print_str);
#endif
/*mytool2.c*/
#include "mytool2.h"

void mytool2_print(char *print_str)
{
        printf("This is mytool2 print %s\n",print_str);
}

我们可以这么编译链接这个程序:

gcc -c main.c

gcc -c mytool1.c

gcc -c mytool2.c

gcc -o myprint main.o mytool1.o mytool2.o

这样之后只需执行命令"./myprint",便可以简单的运行这个程序。

但是当我们修改了其中的一个文件之后是不是还要不厌其烦的输入上面的编译命令?

为了解决这一问题,我们有个好方法去解决,那就是编写一个makefile文件,用make命令去编译上面的程序。


执行命令"vim Makefile”

编写如下代码:

main: main.o mytool1.o mytool2.o
[Tab]gcc -o myprint main.o mytool1.o mytool2.o
main.o: main.c mytool1.h mytool2.h
[Tab]gcc -c main.c
mytool1.o: mytool1.c mytool1.h
[Tab]gcc -c mytool1.c
mytool2.o: mytool2.c mytool2.h
[Tab]gcc -c mytool2.c

保存后执行命令“make -f Makefile”

这样也可以生成一个可执行程序。

有了这个Makefile文件之后,无论我们修改什么地方,只要make一些这个文件,就可以轻松的生成可执行文件。


在Makefile中#开始的行为注释行,此文件的一般格式为:

(target目标):(components依赖对象)

【Tab制表符按键】(rule规则)


第一行为依赖关系,比如上面那个Makefile文件的第一行,我们的目标main的依赖对象为main.o、mytool1.o和mytool2.o

第二行为执行规则,当依赖的对象在目标修改后修改的话,就要执行规则这一行所指定的命令,注意,这一行开头必须是Tab键。


上面的make里的-f参数表示寻找到名为Makefile的文件进行make,因为make只能自动识别名为makefile或者Makefiile两个文件,如果你编译的

makefile文件名为my_makefile的话,就需要加上-f参数,否则make无法找到你指定的my_makefile文件。


此外,makefile里面还有三个非常有用的变量:$@(目标文件)、$^(所有的依赖文件)和$<(第一个依赖文件)

如果使用这三个变量,我们的Makefile文件可以简化为:

main: main.o mytool1.o mytool2.o
[Tab]gcc -o $@ $^
main.o: main.c mytool1.h mytool2.h
[Tab]gcc -c $<
mytool1.o: mytool1.c mytool1.h
[Tab]gcc -c $<
mytool2.o: mytool2.c mytool2.h
[Tab]gcc -c $<

最后,相信大家都已经看出来了吧,其实makefile的文件就是一个递归的过程。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
############################################################################# # Makefile for building: sample 2011-09-26 # # Project: # Template: # Command: # ------基本上简单用法的makefile------- #1. 第一个目标为最终目标 #2. 命令以 Tab开头,可以有多个命令 #3. 分行号\ 后面不可以跟空格 #4、加@可以去掉命令显示 #5. 变量为 abc = efd 访问为 $(abc) echo $abc # # # #缺点,单文件夹 #每次都会重新生成 # #foo.o : foo.c defs.h # foo模块 #cc -c -g foo.c # #多目录 一种方法,在主目录面include "",然后其面OBJS += .o,这样其实就是 或用foreach ############################################################################# #target EXECUTABLE := test CC := gcc CXX := g++ STRIP := strip AR := ar cqs LINK := g++ RM := rm -f CFLAGS := -g -Wall CXXFLAGS := $(CFLAGS) CXXFLAGS += -MD LIBS := -lm LIBPATH := -L/usr/local/lib INCPATH := ####### Output directory OBJSPATH := ../Obj/ EXECUTABLEPATH := ../Execute/ #######source Files SOURCE := $(wildcard *.c) $(wildcard *.cpp) OBJS := $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(SOURCE))) DEPS := $(patsubst %.o,%.d,$(OBJS)) #######rule .SUFFIXES: .cpp .c .o .so .a .d $(OBJSPATH)%.o:%.c $(CC) $(CFLAGS) -c $< -o $@ $(OBJSPATH)%.o:%.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ $(OBJSPATH)%.d:%.cpp $(CXX) -MM $ $@ ######main .PHONY : all deps objs clean rebuild all: $(EXECUTABLE) $(CXX) $(CXXFLAGS) $(INCLUDEPATH) $(LIBS) $(LIBPATH) $(addprefix $(OBJSPATH),$(OBJS)) \ -o $(EXECUTABLEPATH)$(EXECUTABLE) deps: $(addprefix $(OBJSPATH),$(DEPS)) objs: $(addprefix $(OBJSPATH),$(OBJS)) clean: @$(RM) $(OBJSPATH)*.o @$(RM) $(OBJSPATH)*.d @$(RM) $(EXECUTABLEPATH)$(EXECUTABLE) rebuild: clean all -include $(addprefix $(OBJSPATH),$(DEPS)) ##.d面是详细的.o rule 自己会括展开的,然后没有文件就自己去重建 $(EXECUTABLE) : objs

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值