Makefile编译大型工程
1.Makefile 简介
看到这篇文章相信你对Makefile已经有所了解,因此就跳过这部分。
2.工程组织
大型工程一般是模块化的,一般是不同的模块被放在不同的文件夹下,在编译时对不同的模块进行编译。本文就来聊聊怎么进行组织大型工程的编译。
先来看看例子吧。
3.例子
1.主目录的makefile
工程文件夹结构:
F:\LINUX\PRO1
│ 1.code-workspace
│ 1111makefile
│ makefile
│
├─.vscode
│ settings.json
│
├─obj
├─src
│ │ main.cpp
│ │ makefile
│ │
│ └─module1
│ 1.cpp
│ 1.h
│ makefile
│
└─target
makefile
说明,obj src target 是工程主目录下面的文件夹。module1是src下面的文件夹。
工程文件夹下的makefile
SRCDIRS :=src src/module1 target
curPath:=$(shell pwd)
export ROOT=$(abspath .)
export ROOT:=$(shell pwd)
INCDIR:=src src/module1
INCDIRS :=$(foreach dir, $(INCDIR), $(shell pwd)/$(dir) )
target:=target
obj_folder:=$(shell pwd)/obj
targetFolder:=target
objs=
OUTPUT_DIR_NAME := obj
cross_complier :=
complier :=$(cross_complier)gcc
cpp_complier:=$(cross_complier)g++
CFLAGS :=$(C_DEFINES) -Wall -std=c11 -O2
CPPFLAGS :=$(C_DEFINES) -Wall -std=c++11 -O2
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
VPATH := $(INCDIRS)
export cross_complier complier cpp_complier INCDIRS SRCDIRS CFLAGS CPPFLAGS obj_folder INCLUDE VPATH targetFolder target
.PHONY:clean rebuild debug
all: $(SRCDIRS)
#进入各个文件夹编译
$(SRCDIRS):createDir
make -C $@
createDir:
mkdir -p $(obj_folder) $(targetFolder)
rebuild:clean all
clean:
rm -rf $(targetFolder)/*.exe $(obj_folder)/*.o
从上面的文件可以看出,主makefile里面就是定义了一些变量,一些构建目标。然后再进入各个子文件夹进行构建。
Make -C
SRCDIRS 是源代码所在的路径,因此要把工程中所有的源代码文件件加入到此变量中。
INCDIR 是头文件所在路径,因此要把工程中所有的源代码文件件加入到此变量中。
2.源代码文件夹下的makefile
cur_folder=$(shell pwd)
#INCDIRS += \
$(cur_folder)
#INCLUDE += $(patsubst %, -I %, $(shell pwd))
CFILES := $(wildcard *.c)
CPLUSPLUSFILES := $(wildcard *.cpp)
COBJS :=$(patsubst %.c, $(obj_folder)/%.o,$(wildcard *.c))
CPLUSPLUSOBJS :=$(patsubst %.cpp, $(obj_folder)/%.o,$(wildcard *.cpp))
objs+= \
$(COBJS) $(CPLUSPLUSOBJS)
start:$(objs)
$(obj_folder)/%.o:%.c
$(complier) $(CFLAGS) $(INCLUDE) -c $< -o $@
$(obj_folder)/%.o:%.S
$(complier) $(CFLAGS) $(INCLUDE) -c $< -o $@
$(obj_folder)/%.o:%.cpp
$(cpp_complier) $(CPPFLAGS) $(INCLUDE) -c $< -o $@
这个makefile主要做了以下的事情:
- 寻找当前目录下的源文件,包括C文件,CPP文件
- 根据寻找到的源代码文件的名字,得到中间文件的名字。其实就是把原来的文件名后缀替换成.o
- 编译,最下面的三个目标是进行模式匹配,根据匹配的目标进行编译,
只要是有源代码的文件夹都用这个makefile
3.可执行文件夹下的makefile
$(target).exe:$(obj_folder)/*.o
$(cpp_complier) $^ -o $@
这个makefile很简单,就是把所有的目标文件进行链接成可执行文件。
总结
一共用到了三个makefile,完成编译的功能。上述说明清楚地说明了编译大型工程的makefile编写。