[Linux][c/c++]Multi Makefile

1.目的

主要是介绍一种多Makefile编译,即多个目录中含有Makefile,其好处是各自Makefile管理其对应目录的文件

2.组件

2.1 原始结构

├── include
│   ├── test1.h
│   └── test2.h
├── lib
├── main
│   ├── main.cpp
│   └── Makefile
├── Makefile
├── obj
│   └── Makefile
└── src
    ├── Makefile
    ├── test1.cpp
    └── test2.cpp

2.2 Makefile

2.2.1顶层Makefile


  1 ##top makefile
  2 
  3 ##directory
  4 PWD_DIR=$(shell pwd)
  5 SRC_DIR=$(PWD_DIR)/src
  6 OBJ_DIR=$(PWD_DIR)/obj
  7 MAIN_DIR=$(PWD_DIR)/main
  8 LIB_DIR=$(PWD_DIR)/lib
  9 INC_DIR=$(PWD_DIR)/include
 10 BIN_DIR=$(PWD_DIR)/bin
 11 
 12 ##compiler
 13 CXX=g++  ##CC=gcc
 14 CFLAG=-Wall -g -I$(INC_DIR)
 15 
 16 ##target
 17 TARGET=app0_makefile
 18 
 19 ##gloable variable
 20 export PWD_DIR SRC_DIR OBJ_DIR MAIN_DIR LIB_DIR INC_DIR BIN_DIR TARGET CXX CFLAG
 21 
 22 ##cmd
 23 MKDIR=-mkdir -p
 24 RM=-rm -rf
 25 
 26 ##make rule
 27 all:create_dir do_make cp_target
 28 
 29 create_dir:
 30         $(MKDIR) $(BIN_DIR)
 31 
 32 do_make:
 33         make -C $(SRC_DIR)
 34         make -C $(MAIN_DIR)
 35         make -C $(OBJ_DIR)
 36         
 37 cp_target:
 38         cp $(BIN_DIR)/$(TARGET) ~/workspace_sycong/
 39 
 40 ##clean
 41 clean:
 42         $(RM) $(OBJ_DIR)/*.o
 43         $(RM) $(BIN_DIR)
line4~10:指定一些目录
 
line13:指定编译器 g++ for .cpp, gcc for .c
 
line14:-I包含头文件,-g 包含debug信息,可gdb调试
 
line17:指定可执行程序名
 
line20:导出变量,使得在其他Makefile文件中可使用该变量
 
line27:all命令,执行其后面的命令
 
line29~30:创建目录
 
line32~35:使用src,main,obj目录的Makefile进程编译和链接
 
line37:可执行程序从./bin/目录拷贝至~/workspace_sycong/     (bin在非Linux分区,则chmod修改不成功)
 
line41~43:删除.o文件和bin目录

2.2.2 src层Makefile

  1 #ALL_FILES=$(wildcard *.cpp)
  2 #ALL_OBJS=$(patsubst %.cpp, %.o, $(ALL_FILES))
  3 
  4 ##cpp file in src dir
  5 FILE_1=test1.cpp
  6 FILE_2=test2.cpp
  7 #FILE_3=...
  8 
  9 ##relpace .cpp to $(OBJ_DIR)/.o
 10 OBJ_1=$(patsubst %.cpp, $(OBJ_DIR)/%.o, $(FILE_1))
 11 OBJ_2=$(patsubst %.cpp, $(OBJ_DIR)/%.o, $(FILE_2))
 12 #OBJ_3=$(patsubst %.cpp, $(OBJ_DIR)/%.o, $(FILE_3))
 13 
 14 ##make rule
 15 all:ECHO $(OBJ_DIR)/$(OBJ_1) $(OBJ_DIR)/$(OBJ_2)
 16 
 17 ECHO:
 18         @echo $(FILE_1) $(OBJ_1)
 19         @echo $(FILE_2) $(OBJ_2)
 20         @echo "echo end"
 21 
 22 $(OBJ_DIR)/$(OBJ_1):$(FILE_1)
 23         $(CXX) -c $^ -o $@ $(CFLAG)
 24 
 25 $(OBJ_DIR)/$(OBJ_2):$(FILE_2)
 26         $(CXX) -c $^ -o $@ $(CFLAG) 
 27  
line4~7:指定src下的.cpp文件
 
line9~12:制定obj下的.o文件
 
line14~15:all命令
 
line17~20:echo输出信息
 
line22~26:编译出.o文件

2.2.3 main层Makefile

 1 $(OBJ_DIR)/main.o:main.cpp
 2         $(CXX) -c $^ -o $@ $(CFLAG)

2.2.4 obj层Makefile

  1 ALL_OBJS=$(wildcard *.o)
  2 
  3 $(BIN_DIR)/$(TARGET):$(ALL_OBJS)
  4         $(CXX) -o $@ $^ $(CFLAG)
line3~4:链接生成可执行程序

3.make

make之后结构如下:


.
├── bin
│   └── app0_makefile
├── include
│   ├── test1.h
│   └── test2.h
├── lib
├── main
│   ├── main.cpp
│   └── Makefile
├── Makefile
├── obj
│   ├── main.o
│   ├── Makefile
│   ├── test1.o
│   └── test2.o
└── src
    ├── Makefile
    ├── test1.cpp
    └── test2.cpp
在obj目录中生成了2个.o目标文件,且在bin中生成了可执行程序

4.other

wildcard 这是扩展通配符函数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔;比如:罗列出src下的所有.c文件:$(wildcard ${SRC}/*.c)
      
patsubst 这是匹配替换函数, patsubst(需要匹配的文件样式,匹配替换成什么文件,需要匹配的源文件)函数。比如:用src下的*.c替换成对应的 *.o文件存放到obj中:$(patsubst  %.c, ${OBJ}/%.o, $(notdir $(SOURCE)))
       
notdir 这是去除路径函数,在上面patsubst函数中已经使用过,去除SOURCE中文件的所有目录,只留下文件名;
 
$@:表示目标文件
$^:表示所有依赖文件

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值