zoukankan      html  css  js  c++  java
  • Makefile 10——打造更专业的编译环境-huge项目

    先手工创建几个文件目录:

    接下来先创建code/foo/src目录下的Makefile:

     1 .PHONY: all clean
     2 
     3 MKDIR = mkdir
     4 RM = rm
     5 RMFLAGS = -rf
     6 
     7 CC =gcc
     8 AR =ar
     9 ARFLAGS =crs
    10 
    11 DIR_OBJS=objs
    12 DIR_EXES=../../../build/exes
    13 DIR_DEPS=deps
    14 DIR_LIBS=../../../build/libs
    15 DIRS =$(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS) $(DIR_LIBS)
    16 RMS=$(DIR_OBJS) $(DIR_DEPS)
    17 
    18 EXE=
    19 ifneq ("$(EXE)","")
    20 EXE :=$(addprefix $(DIR_EXES)/,$(EXE))
    21 RMS +=$(EXE)
    22 endif
    23 
    24 LIB=libfoo.a
    25 ifneq ("$(LIB)","")
    26 LIB :=$(addprefix $(DIR_LIBS)/,$(LIB))
    27 RM +=$(LIB)
    28 endif
    29 
    30 SRCS=$(wildcard *.c)
    31 OBJS=$(SRCS:.c=.o)
    32 OBJS:=$(addprefix $(DIR_OBJS)/,$(OBJS))
    33 DEPS=$(SRCS:.c=.dep)
    34 DEPS:=$(addprefix $(DIR_DEPS)/,$(DEPS))
    35 
    36 ifeq ("$(wildcard $(DIR_OBJS))","")
    37 DEP_DIR_OBJS :=$(DIR_OBJS)
    38 endif#dir_objs
    39 ifeq ("$(wildcard $(DIR_EXES))","")
    40 DEP_DIR_EXES :=$(DIR_EXES)
    41 endif#dir_exes
    42 ifeq ("$(wildcard $(DIR_DEPS))","")
    43 DEP_DIR_DEPS :=$(DIR_DEPS)
    44 endif#dir_deps
    45 ifeq ("$(wildcard $(DIR_LIBS))","")
    46 DEP_DIR_LIBS :=$(DIR_LIBS)
    47 endif#dir_libs
    48 
    49 all: $(EXE) $(LIB)
    50 ifneq ($(MAKECMDGOALS),clean)
    51 include $(DEPS)
    52 endif#clean
    53 
    54 $(DIRS):
    55     $(MKDIR) $@
    56 $(EXE):$(DEP_DIR_EXES) $(OBJS)
    57     $(CC) -o $@ $(filter %.o,$^)
    58 $(LIB):$(DEP_DIR_LIBS) $(OBJS)
    59     $(AR) $(ARFLAGS) $@ $(filter %.o,$^)
    60 $(DIR_OBJS)/%.o:$(DEP_DIR_OBJS) %.c 
    61     $(CC) -o $@ -c $(filter %.c,$^)
    62 $(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
    63     @echo "Creating $@ ..."
    64     @set -e;
    65     $(RM) $(RMFLAGS) $@.tmp;
    66     $(CC) -E -MM $(filter %.c,$^) > $@.tmp;
    67     sed 's,(.*).o[:]*,objs/1.o $@:,g' <$@.tmp >$@;
    68     $(RM) $(RMFLAGS) $@.tmp
    69 
    70 clean:
    71     $(RM) $(RMFLAGS) $(RMS)

    具体和complicated项目的差别可以看书或者上篇随笔。

     

    第一个提示没有那个目录,可以在include的时候加上'-'就可以忽略这个,因为这里对我们的项目没有实质影响,但是新手对于报错或者警告总是不放心,故再次提示一下。

    从运行结果来看,的确在build/libs目录下生成了一个libfoo.a库文件。运行make clean之后,也没有删除build/libs这个目录,而只是删除库文件libfoo.a 

    下面要做的就是将这个Makefile运用到code/huge/src目录。

    增进复用性:

    可以将公用部分放入一个独立的文件中——这就是bulid目录下make.rule文件的作用。这需要我们却别哪些是公用哪些是不能公用的变量。

    在考虑复用的情况下,foo模块的Makefile有两部分组成,分别是bulid目录中的make.rule和code/foo/src目录中的Makefile。

    foo模块中的Makefile比较简单,因为大部分代码移植道理make.rule中:

    EXE=
    LIB =libfoo.a
    include $(ROOT)/build/make.rule

    make.rule如下:

     1 .PHONY: all clean
     2 
     3 MKDIR = mkdir
     4 RM = rm
     5 RMFLAGS = -rf
     6 
     7 CC =gcc
     8 AR =ar
     9 ARFLAGS =crs
    10 
    11 DIR_OBJS=objs
    12 DIR_EXES=$(ROOT)/build/exes
    13 DIR_DEPS=deps
    14 DIR_LIBS=$(ROOT)/build/libs
    15 DIRS =$(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS) $(DIR_LIBS)
    16 RMS=$(DIR_OBJS) $(DIR_DEPS)
    17 
    18 
    19 ifneq ("$(EXE)","")
    20 EXE :=$(addprefix $(DIR_EXES)/,$(EXE))
    21 RMS +=$(EXE)
    22 endif
    23 
    24 
    25 ifneq ("$(LIB)","")
    26 LIB :=$(addprefix $(DIR_LIBS)/,$(LIB))
    27 RM +=$(LIB)
    28 endif
    29 
    30 SRCS=$(wildcard *.c)
    31 OBJS=$(SRCS:.c=.o)
    32 OBJS:=$(addprefix $(DIR_OBJS)/,$(OBJS))
    33 DEPS=$(SRCS:.c=.dep)
    34 DEPS:=$(addprefix $(DIR_DEPS)/,$(DEPS))
    35 
    36 ifeq ("$(wildcard $(DIR_OBJS))","")
    37 DEP_DIR_OBJS :=$(DIR_OBJS)
    38 endif#dir_objs
    39 ifeq ("$(wildcard $(DIR_EXES))","")
    40 DEP_DIR_EXES :=$(DIR_EXES)
    41 endif#dir_exes
    42 ifeq ("$(wildcard $(DIR_DEPS))","")
    43 DEP_DIR_DEPS :=$(DIR_DEPS)
    44 endif#dir_deps
    45 ifeq ("$(wildcard $(DIR_LIBS))","")
    46 DEP_DIR_LIBS :=$(DIR_LIBS)
    47 endif#dir_libs
    48 
    49 all: $(EXE) $(LIB)
    50 ifneq ($(MAKECMDGOALS),clean)
    51 include $(DEPS)
    52 endif#clean
    53 
    54 $(DIRS):
    55     $(MKDIR) $@
    56 $(EXE):$(DEP_DIR_EXES) $(OBJS)
    57     $(CC) -o $@ $(filter %.o,$^)
    58 $(LIB):$(DEP_DIR_LIBS) $(OBJS)
    59     $(AR) $(ARFLAGS) $@ $(filter %.o,$^)
    60 $(DIR_OBJS)/%.o:$(DEP_DIR_OBJS) %.c 
    61     $(CC) -o $@ -c $(filter %.c,$^)
    62 $(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c
    63     @echo "Creating $@ ..."
    64     @set -e;
    65     $(RM) $(RMFLAGS) $@.tmp;
    66     $(CC) -E -MM $(filter %.c,$^) > $@.tmp;
    67     sed 's,(.*).o[:]*,objs/1.o $@:,g' <$@.tmp >$@;
    68     $(RM) $(RMFLAGS) $@.tmp
    69 
    70 clean:
    71     $(RM) $(RMFLAGS) $(RMS)

    如果想运行foo模块中的Makefile,先要在shell上导出所需的ROOT变量:

     

    期间出现了一个问题,我检查了很久Makefile并没有发现问题,但是就是显示没有规则创建目标,最后,用vim重新输入了一下include后面的路径,就解决了,用vscode输入莫名奇妙不行,又没有出现TAB建这样字符,可能是文本编辑器本身的差异吧,但是vim是肯定不会出现格式不兼容问题的。所以以后还是用vim写Makefile把。

    完成上面的之后,我们需要考虑把code/huge/src目录中的Makefile了,我们希望这个目录中存放的程序能生成一个可执行文件。在测试Makefile之前,我们现在该目录中放一个main.c文件,内容如下:

    1 int main(void)
    2 {
    3     return 0;
    4 }

    Makefile如下所示:

    1 EXE =huge_app
    2 
    3 LIB =
    4 
    5 include $(ROOT)/build/make.rule

    从结果看huge_app已经成功生成了。

  • 相关阅读:
    Android:日常学习笔记(7)———探究UI开发(1)
    Android:日常学习笔记(6)——探究活动(4)
    JavaScript:基础扩展(1)——JSON
    JavaScript:学习笔记(3)——正则表达式的应用
    正则表达式:快速入门
    LeetCode_Easy_471:Number Complement
    Java实现——字符串分割以及复制目录下的所有文件
    DOM、SAX、JDOM、DOM4J以及PULL在XML文件解析中的工作原理以及优缺点对比
    一个简单电商网站开发过程中的业务资料整理
    大道至简,不简则死
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6850351.html
Copyright © 2011-2022 走看看