完整 makefile 举例

2021-10-02  本文已影响0人  404Not_Found

代码准备

//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

  1. 依赖关系 是依靠inlucde 导入的,include 的文件如果不在,会尝试去生成。
  2. include 需要放到 all 的后面,否则会优先构造include 导入的 目标文件,比如 obj/func.o deps/func.dep: xxxx 但是此时又没有obj目录。makefile 会报错
  3. 注意 后面注销的test , .DEFAULT_GOAL,test 会被当作默认的目标文件。那么make 的时候 就只会输出 this is test target.

最终结果:

结果.png tree.png
上一篇下一篇

猜你喜欢

热点阅读