最近开始慢慢接触Linux编程,系统能对Linux的网络编程能重点学习,Linux的熟练程序恐怕跟你使用shell的熟练程序成正比的,所以本人也是一步步的慢慢学习,刚刚学习了如何使用VIM,现在开始学习如何编写Makefile文件,不得不说Makefile还是很强大的,给了一些预定义的宏,而且还可以在里面使用函数,Makefile其实说白了就一句话,基于目标、依赖项和命令的一个组合。我感觉写Makefile跟写解释型代码似的还是相当有意思的。
目标:依赖项
(TAB) 命令
当然这里需要强调的是依赖项是有先后顺序的,例如你可能在编译的过程中,想先生成一个目录,然后将需要生成的*.o目标文件都放进去,那么你必须首先依赖这个目标,然后通过命令来生成。
如下是我写的一个测试的Makefile的Demo,文件结构如下
calc.c (根目录)
|(add)
add_int.c
add_int.h
add_float.c
add_float.h
|(sub)
sub_int.c
sub_int.h
sub_float.c
sub_float.h
以下是Makefile的全部代码
#设置环境变量,CC有默认值,不设置也是可以的
CC = gcc
CFLAGS = -Iadd -Isub -O2
TARGET = calc
DIRS = sub add .
#将DIS三个目录中的所有的*.c的文件都赋值给FILES变量
#这里用到了两个函数一个是foreach 一个是wildcard
#$(foreach VAR,LIST,function)
#$(wildcard ??(filter))
FILES = $(foreach dir,$(DIRS),$(wildcard $(dir)/*.c))
#将字符串的后缀进行替换,生成*.o的目标文件
#$(patsubst ??,??, stringlist)
#to replace some chars in this
OBJS = $(patsubst %.c,%.o,$(FILES))
#将所有的目标文件都生成到这个目录下
OBJDIR = ${shell pwd}/objs
OBJ_FILES = $(foreach i, $(OBJS),$(OBJDIR)/$(notdir $i))
#$(OBJDIR) 必须是第一个被依赖项,如果目录生成则编译失败
$(TARGET):$(OBJDIR) $(OBJS)
$(CC) -o $(TARGET) $(OBJ_FILES)
$(OBJS):%.o:%.c
$(CC) -c $< -o $(OBJDIR)/$(notdir $@) $(CFLAGS)
$(OBJDIR):
mkdir -p $@
clean:
-$(RM) $(TARGET)
-$(RM) $(OBJDIR)/*.o