zoukankan      html  css  js  c++  java
  • 简单工程Makefile的编写

     本例工程,实现几种排序算法的具体代码实现和性能比较。工程结构如下:
    sort
    |-- Makefile
    |-- Makefile.rule
    |-- main
    |   |-- Makefile
    |   |-- include
    |   |   |-- heap_sort.h
    |   |   |-- quick_sort.h
    |   |   `-- shell_sort.h
    |   |-- libs
    |   `-- src
    |       `-- sort.c
    |-- heap_sort
    |   |-- Makefile
    |   |-- include
    |   `-- src
    |       `-- heap_sort.c
    |-- quick_sort
    |   |-- Makefile
    |   |-- include
    |   `-- src
    |       `-- quick_sort.c
    `-- shell_sort
        |-- Makefile
        |-- include
        `-- src
            `-- shell_sort.c
        工程名:sort,根目录下的一级子目录包括main,heap_sort,quick_sort,shell_sort,每级目录中,有include和 src目录,include中,包含该模块用到的相关头文件,src中是源代码。在main目录中,另有libs文件夹,工程需要引入的库可以放在该文件夹中。

    Makefile.rule
        该文件为工程Makefile的通用规则定义,在各个模块的Makefile中被include。

        该文件具体内容如下:

    CC := gcc

    AR := ar
    ARFLAGS := -rcs
    SRC := src
    INCLUDES := include
    LIBS := libs
    CFLAGS := -g -Wall -O3  $(addprefix -I,$(INCLUDES))
        $(addprefix -L,$(LIBS))
    CXXFLAGS := $(CFLAGS)
    CPPFLAGS += -MD
    RM_F := rm -rf


    HIDE_PREFIX := .
    EXPORT_ODIR := $(HIDE_PREFIX)o
    IMPORT_IDIR := $(HIDE_PREFIX)i

    SOURCE := $(wildcard $(SRC)/*.c) $(wildcard $(SRC)/*.cc)
    OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
    DEPS := $(patsubst %.o,%.d,$(OBJS))
    MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
    MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS))
        $(patsubst %.d,%.cc,$(MISSING_DEPS)))


        该文件主要定义了工程的编译工具,编译链接的参数等。 EXPORT_ODIR和IMPORT_IDIR是编译之后模块的输入输出,编译生成.i和.o文件夹,.i中为模块需要引入的文件的软链接,.o中是该模块输出的文件的软链接。

    工程总Makefile

        根目录下的Makefile,内容如下:

    TOPDIR := .
    MODDIR := .
    TARGET := $(notdir $(shell cd $(MODDIR) && pwd))
    MODULES += quick_sort
               heap_sort
               shell_sort
               main

    -include $(TOPDIR)/Makefile.rule

    submodule_make = $(MAKE) -C $(TOPDIR)/$(1);
    submodule_clean = $(MAKE) clean -C $(TOPDIR)/$(1);

    .PHONY : all deps objs clean cleanall rebuild modules cleanmodules

    all : $(TARGET)

    deps : $(DEPS)

    objs : $(OBJS)

    modules :
        @ $(foreach n,$(MODULES),$(call submodule_make,$(n)))

    cleanmodules :
        @ $(foreach n,$(MODULES),$(call submodule_clean,$(n)))

    clean :
        @ $(RM_F) *.o
        @ $(RM_F) *.d
        @ $(RM_F) *.a
        @ $(RM_F) $(wildcard $(SRC)/*.o)
        @ $(RM_F) $(wildcard $(SRC)/*.d)
        @ $(RM_F) $(wildcard $(MODIR)/*.d)
        @ $(RM_F) $(EXPORT_ODIR)
        @ $(RM_F) $(IMPORT_IDIR)
        @ echo CLEAN DONE

    cleanall: cleanmodules clean
        @ $(RM_F) $(wildcard $(TOPDIR)/*.d)
        @ $(RM_F) $(TARGET)
        @ echo CLEANALL DONE

    rebuild: clean all

    ifneq ($(MISSING_DEPS),)
    $(MISSING_DEPS) :
        @ $(RM_F) $(patsubst %.d,%.o,$@)
    endif

    -include $(DEPS)

    $(TARGET) : $(OBJS) modules
        @ echo MAKE $(TARGET) START
        @ mkdir -p $(EXPORT_ODIR)
        @ mkdir -p $(IMPORT_IDIR)
        @ echo MAKE $(TARGET) DONE 

        在这个Makefile中,变量MODULES 定义了各个子模块,quick_sort,heap_sort,shell_sort,  main。

    main模块中Makefile

        main模块下的Makefile,内容如下:

    TOPDIR := ..
    MODDIR := .
    MODNAME := $(notdir $(shell cd $(MODDIR) && pwd))
    TARGET := $(notdir $(shell cd $(TOPDIR) && pwd))
    ALIBS = $(addprefix ../, $(wildcard $(TOPDIR)/$(IMPORT_IDIR)/*.a))
    LDFLAGS += $(addprefix -L,$(IMPORT_IDIR))
    LDFLAGS += $(foreach n,$(MODULES),$(addprefix -l,$(n)))

    MODULES += quick_sort
               heap_sort 
               shell_sort

    -include $(TOPDIR)/Makefile.rule

    submodule_make = $(MAKE) -C $(TOPDIR)/$(1);
    submodule_clean = $(MAKE) clean -C $(TOPDIR)/$(1);

    .PHONY : all deps objs clean cleanall rebuild modules cleanmodules

    all : $(TARGET)

    deps : $(DEPS)

    objs : $(OBJS)

    modules :
        @ $(foreach n,$(MODULES),$(call submodule_make,$(n)))

    cleanmodules :
        @ $(foreach n,$(MODULES),$(call submodule_clean,$(n)))

    clean :
        @ $(RM_F) *.o
        @ $(RM_F) *.d
        @ $(RM_F) $(wildcard $(SRC)/*.o)
        @ $(RM_F) $(wildcard $(SRC)/*.d)
        @ $(RM_F) $(EXPORT_ODIR)
        @ $(RM_F) $(IMPORT_IDIR)
        @ echo CLEAN DONE

    cleanall: cleanmodules clean
        @ $(RM_F) $(TARGET)
        @ echo CLEANALL DONE

    rebuild: clean all

    ifneq ($(MISSING_DEPS),)
    $(MISSING_DEPS) :
        @ $(RM_F) $(patsubst %.d,%.o,$@)
    endif

    -include $(DEPS)

    $(TARGET) : $(OBJS) modules
        @ echo MAKE $(TARGET) START
        @ mkdir -p $(EXPORT_ODIR)
        @ mkdir -p $(IMPORT_IDIR)
        @ ln -sft $(IMPORT_IDIR) $(ALIBS)
        $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
        @ cp -f $@ $(TOPDIR) 
        @ echo MAKE $(TARGET) DONE 

        在此模块中,变量MODULES定义了其依赖的子模块。首先编译子模块,然后编译本模块。

    其他模块中Makefile

        其他模块下的Makefile,内容如下:

    TOPDIR := ..
    MODDIR := .
    MODNAME := $(notdir $(shell cd $(MODDIR) && pwd))
    TARGET := $(addprefix lib,$(addsuffix .a,$(MODNAME)))
    EXPORT_HEADERS += $(INCLUDES)/*.h
    MODULES +=

    -include $(TOPDIR)/Makefile.rule

    submodule_make = $(MAKE) -C $(TOPDIR)/$(1);
    submodule_clean = $(MAKE) clean -C $(TOPDIR)/$(1);

    .PHONY : all deps objs clean cleanall rebuild

    all : $(TARGET)

    deps : $(DEPS)

    objs : $(OBJS)

    modules :
        @ $(foreach n,$(MODULES),$(call submodule_make,$(n)))

    cleanmodules :
        @ $(foreach n,$(MODULES),$(call submodule_clean,$(n)))

    clean :
        @ $(RM_F) *.o
        @ $(RM_F) *.d
        @ $(RM_F) $(wildcard $(SRC)/*.o)
        @ $(RM_F) $(wildcard $(SRC)/*.d)
        @ $(RM_F) $(EXPORT_ODIR)
        @ $(RM_F) $(IMPORT_IDIR)
        @ echo CLEAN DONE

    cleanall: cleanmodules clean
        @ $(RM_F) $(TARGET)
        @ echo CLEANALL DONE

    rebuild: clean all

    ifneq ($(MISSING_DEPS),)
    $(MISSING_DEPS) :
        @ $(RM_F) $(patsubst %.d,%.o,$@)
    endif

    -include $(DEPS)

    $(TARGET) : $(OBJS) modules
        @ echo MAKE $(TARGET) START
        @ mkdir -p $(EXPORT_ODIR)
        @ mkdir -p $(IMPORT_IDIR)
        @ mkdir -p $(TOPDIR)/$(IMPORT_IDIR)
        @ $(AR) $(ARFLAGS) -o $(TARGET) $(OBJS) 
        @ ln -sft $(TOPDIR)/$(IMPORT_IDIR) $(TOPDIR)/$(MODNAME)/$(TARGET) 
        @ echo MAKE $(TARGET) DONE 

        此Makefile不依赖于模块名及模块具体内容,具有较好的移植性。添加新的模块,只需直接将该Makefile复制到新模块目录下就可以了,然后在main模块Makefile和根Makefile中添加新的模块名。直接编译就可以了。

        准备好了Makefile,就可以进行编译了。

        在sort根目录下运行make:
    root@mygirl:/study/sort# make
    root@mygirl:/study/sort# ls
    heap_sort  sort  main  Makefile  Makefile.rule  quick_sort  shell_sort
        看到的新出现的文件sort,就是编译后的可之执行文件。

        在sort根目录下运行make cleanall:
    root@mygirl:/study/sort# make cleanall
    root@mygirl:/study/sort# ls
    heap_sort main  Makefile  Makefile.rule  quick_sort  shell_sort
        这样,就可以清除编译生成的各个文件了。


  • 相关阅读:
    android:id="@android:id/tabhost" 、android:id="@+id/llRoot" 、android:id="@id/llRoot" 之间的区别
    android:ellipsize的使用
    PopupWindow为什么要设置setBackgroundDrawable(new BitmapDrawable());
    android中LayoutInflater的3种使用以及getSystemService的API
    context 的理解
    Android 中this、getContext()、getApplicationContext()、getApplication()、getBaseContext() 之间的区别
    android Matrix 使用
    public private protected frientdly 作用域
    pyinstaller参数介绍以及总结
    MongoDB高级查询详细
  • 原文地址:https://www.cnblogs.com/huazhen/p/3443467.html
Copyright © 2011-2022 走看看