- 作者: 雪山肥鱼
- 时间:20211003 12:14
- 目的: 完整的makefile 例子, 理解依赖关系
代码准备
//main.c
#include <stdio.h>
#include "func.h"
int main(int argc,char **argv)
{
foo();
return 0;
}
//func.h
#ifndef FUNC_H
#define FUNC_H
#define HELLO "hello world!!!!!!!"
void foo();
#endif
//func1.h
#ifndef FUNC1_H
#define FUNC1_H
#define ERICSSON "Ericsson"
#endif
//func.c
#include <stdio.h>
#include "func.h"
#include "func1.h"
void foo()
{
printf("void foo():%s\n", HELLO);
printf("void foo():%s\n", ERICSSON);
}
依赖关系
关于依赖关系:
辅助链接 关于依赖关系:
https://blog.csdn.net/huyansoft/article/details/8924624
https://www.cnblogs.com/hoiday/p/9265731.html
对于下述命令的解读:
$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ : ]*,objs/\1.o $@ : ,g' > $@
替换而已,话不多说直接上例子。
gcc -MM -E func.c
func.o: func.c func.h func1.h
#################经过sed处理 #####################
objs/func.o deps/func.dep : func.c func.h func1.h
语义替换,生成新的规则,为的就是生成依赖关系。
Makefile
.PHONY : all clean rebuild
MKDIR := mkdir
RM := rm -fr
CC := gcc
DIR_DEPS := deps
DIR_EXES := exes
DIR_OBJS := objs
# deps exes objs
DIRS := $(DIR_DEPS) $(DIR_EXES) $(DIR_OBJS)
EXE := app.out
# exe/app.out
EXE := $(addprefix $(DIR_EXES)/, $(EXE))
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
# objs/*.o
OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
DEPS := $(SRCS:.c=.dep)
# deps/*.dep
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
# all: deps exes exe/app.out
all : $(DIR_OBJS) $(DIR_EXES) $(EXE)
ifeq ("$(MAKECMDGOALS)", "all")
-include $(DEPS)
endif
ifeq ("$(MAKECMDGOALS)", "")
-include $(DEPS)
endif
$(EXE) : $(OBJS)
$(CC) -o $@ $^
@echo "Success! Target => $@"
$(DIR_OBJS)/%.o : %.c
$(CC) -o $@ -c $(filter %.c, $^)
$(DIRS) :
$(MKDIR) $@
ifeq ("$(wildcard $(DIR_DEPS))", "")
$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
else
$(DIR_DEPS)/%.dep : %.c
endif
@echo "Creating $@ ..."
@set -e; \
$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ : ]*,objs/\1.o $@ : ,g' > $@
clean :
$(RM) $(DIRS)
rebuild :
@$(MAKE) clean
@$(MAKE) all
#test:
# @echo "this is test target"
#
#.DEFAULT_GOAL := test
- 依赖关系 是依靠inlucde 导入的,include 的文件如果不在,会尝试去生成。
- include 需要放到 all 的后面,否则会优先构造include 导入的 目标文件,比如 obj/func.o deps/func.dep: xxxx 但是此时又没有obj目录。makefile 会报错
- 注意 后面注销的test , .DEFAULT_GOAL,test 会被当作默认的目标文件。那么make 的时候 就只会输出 this is test target.
网友评论