Linux入职基础-7.5_Makefile应用综合实例

时间:2021-01-30 14:54:07

Makefile应用综合实例

大项项目软件都具有专门的代码存放结构,包括源码文件、头文件信息、库文件信息、目标文件、调试目录、宏定义和编译选项等多项内容,为了管理,有经验的开发者往往使用变量来替换这些复杂的信息。

现在举个综合例子:项目软件:crm ;文件主目录:/root/crmpro 。

主目录包含的各子目录定义,如下:

./src : 存放项目源代码文件(*.c )

./include :存放项目的头文件信息

./lib :存放项目生成的或者第三方的库文件

./libsrc :存放项目生成库文件的源码文件

./obj :存放项目生成的目标文件信息

./ release :存放生成后的执行文件crm

./ debug :存放调试信息

文件目录结构如下:

|-- Makefile

|-- release

|-- obj

|--debug

|-- include

|    |-- def1.h

|    |-- def2.h

|    |--defuser.h

|-- lib

|    |--liblog.a

|--libsrc

|    |--user.c

|    |--admin.c

|    |--Makefile1     //use “make” to build a lib file:../lib/liblog.a

|-- src

    |-- main.c

    |-- f1.c

    |-- f2.c

代码文件中函数调用与包含关系:

f1.c-->def1.h

f2.c-->def2.h

user.c-->defuser.h

admin.c -->defuser.h

liblog.a-->user.c  admin.c

mian.c-->f1.c f2.c liblog.a

test-->

项目文件目录含义:

bin:存放生成执行程序test

obj:存放所有*.c源码编译后的文件

lib:存放静态库libadmin.a(admin.c) libuser.a (user.c)

源文件清单如下:

/*def1.h*/

void func_one();

/*def2.h*/

void func_two();

/*defuser.h*/

void list_user();

void list_admin();

/*f1.c*/

#include "stdio.h"

#include "../include/def1.h"

void func_one()

{

        printf("This isfunc_one() ,it is in f1.c!\n");

}

/*f2.c*/

#include "stdio.h"

#include "../include/def2.h"

void func_two()

{

        printf("This isfunc_two(),it is in f2.c!\n");

}

/*user.c*/

#include "stdio.h"

#include "../include/defuser.h"

Void list_user()

{

       printf("This is list_user(),itis in user.c!,and user.c is libuser.a\n");

}

 

/*admin.c*/

#include "stdio.h"

#include "../include/defuser.h"

Void list_user()

{

       printf("This islist_admin(),it is in user.c!,and admin.c is libadmin.a\n");

}

 

/*main.c*/

#include "stdio.h"

#include "../include/def1.h"

#include "../include/def2.h"

#Incluce “../include/defuser.h

int main()

{

        printf("main() isruning!\n");

        func_one();

        func_two();

                  list_user();

                  list_admin();

        return 1;

}

#编辑Makefile文件,如下:

/*Makefile*/

# Readme:

# use: make

# use: make test

# use: make clean

# use: make rebuild

 

#use "make config" or "make dir" to

# build a source files struct.and then,

# put your source files into the DIR src

# link libs to the DIR lib

CC=gcc

MAKE_DIR=$(PWD)

 

INCLUDE_DIR=$(MAKE_DIR)/include/

SRC_DIR=$(MAKE_DIR)/src/

SRC_LIB_DIR=$(MAKE_DIR)/libsrc/

 

LIB_DIR=$(MAKE_DIR)/lib/

OBJ_DIR=$(MAKE_DIR)/obj/

RELEASE_DIR=$(MAKE_DIR)/release/

DEBUG_DIR=$(MAKE_DIR)/debug/

OUTPUT_DIR=

 

INCLUDE=-I$(INCLUDE_DIR) -I$(SRC_DIR)

LIB=-L$(LIB_DIR) -L$(OBJ_DIR)

 

vpath %.c $(SRC_DIR)

vpath %.h $(INCLUDE_DIR)

vpath %.o $(OBJ_DIR)

vpath %.a $(LIB_DIR)

 

SRC_FILES:=$(wildcard $(SRC_DIR)*.c)

OBJ_FILES:=$(patsubst %.c,%.o,$(SRC_FILES))

LIB_FILES_NAME:=$(notdir $(wildcard $(LIB_DIR)*.a))

LIB_NAME=$(subst lib,-l,$(basename $(LIB_FILES_NAME)))

OUTPUT_FILE=crm

 

FLAG_DEBUG=-c -g -Wall -ansi

FLAG_COMPLE=-c -O -Wall –ansi

FLAG_LINK=

 

DEBUG=1

ifeq ($(DEBUG),1)

OUTPUT_DIR:=$(DEBUG_DIR)

FLAG_COMPLE:=$(FLAG_DEBUG)

FLAG_LINK:=

else

OUTPUT_DIR:=$(RELEASE_DIR)

FLAG_COMPLE:=$(FLAG_COMPLE)

FLAG_LINK:=

endif

 

OUT=$(OUTPUT_DIR)$(OUTPUT_FILE)

$(OUT): $(OBJ_FILES)

        @echo -e"building: $(notdir $@) \n\t please wait ...\n"

        @$(CC) $(FLAG_LINK)$(addprefix $(OBJ_DIR),$(notdir $^)) $(LIB) $(LIB_NAME)  -o $@

%.o:%.c

        @echo -e"building: $(notdir $@) \n\t please wait ...\n"

        @$(CC) $(FLAG_COMPLE) $< $(INCLUDE) -o$(OBJ_DIR)$(notdir $@)

.PHONY: all rebuild clean cleanall test

 

clean:

        @rm -rf $(OBJ_DIR)*.o

        @rm -rf $(OUT)

        @clear

 

rebuild: cleanall

cleanall:

        @rm -rf $(OBJ_DIR)*

        @rm -rf $(RELEASE_DIR)*

        @rm -rf $(DEBUG_DIR)*

test:

        $(OUT)

 

/*bin/Makefile1*/

#reademe

#use: make -f Makefile1

#Makefile1 is in the dir(/root/crmpro/libsrc)

#make  to build a libfile:../lib/liblog.a

INCLUDE_DIR=../include/

LIB_DIR=../lib/

SRC_FILES:=$(wildcard *.c)

OBJ_FILES:=$(patsubst %.c,%.o,$(SRC_FILES))

%.o:%.c

        gcc -c $< -o $@-I$(INCLUDE_DIR)

liblog.a:$(OBJ_FILES)

        ar -rcs $@ $^

        mv $@ $(LIB_DIR)

        rm $(OBJ_FILES)

注意:上述案例已经成功测试通过,助于加深对Makefile文件的理解!当你复制这些源代码文件时,注意去除文件中的空格,否则make命令时会出错!