Makefile学习笔记1

本文部分转载自:https://blog.csdn.net/u010312436/article/details/52461906

 


在写涉及到子目录的makefile文件时,从上面的博客学习到很多!自己写的也是仿照着写的,主要以此博客的makefile对知识点做一个 更详细的说明 和 对makefile做一个总结!

说明:如有错误,敬请见谅!我编译的是.so库,很多命令用不到,只是网上搜索学习了一下!

一,原博客

(1)目录结构:

(2)主文件加下的makefile

XX = g++
AR = ar
ARFLAG = -rcs
CFLAGS = -g 
 
CLIBS = -L./lib/ -lSender -lReceiver -lResponser  -lpthread
 
SUBDIRS = ./receiver ./responser ./sender
 
INCLUDES = $(wildcard ./include/*.h ./sender/*.h ./receiver/*.h ./responser/*.h) # INCLUDE = a.h b.h ... can't be defined like "INCLUDE = ./*.h"
#SOURCES = $(wildcard ./*.cpp ./sender/*.cpp ./receiver/*.cpp ./responser/*.cpp)
INCLUDE_DIRS = -I./include -I./sender/ -I./receiver/ -I./responser/ #指定头文件目录,代码中就不需要把头文件的完整路径写出来了
 
TARGET = mainApp
#OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))
OBJECTS = main.o
 
export XX CFLAGS AR ARFLAG
 
$(TARGET) : $(OBJECTS) $(SUBDIRS)
    $(XX) $< -o $@ $(CLIBS)     # $< 表示依赖列表的第一个 也就是 $(OBJECTS)
    
$(OBJECTS) : %.o : %.cpp 
    $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)
    
$(SUBDIRS):ECHO
    +$(MAKE) -C $@
ECHO:
    @echo $(SUBDIRS)
    @echo begin compile
.PHONY : clean
clean:
    for dir in $(SUBDIRS);\
    do $(MAKE) -C $$dir clean||exit 1;\
    done
    rm -rf $(TARGET) $(OBJECTS)  ./lib/*.a

(3)receiver目录下的makefile代码如下:



LIB_DIR = ./../lib/
TOP_DIR = ./..

SOURCES = $(wildcard ./*.cpp)
INCLUDE_DIRS = -I$(TOP_DIR)/include  -I$(TOP_DIR)/responser/ -I./ 

TARGET = libReceiver.a
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))

$(TARGET) : $(OBJECTS)
    $(AR) $(ARFLAG) $@ $^
    cp $@ $(LIB_DIR)
    
$(OBJECTS) : %.o : %.cpp 
    $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

.PHONY : clean
clean:
    rm -rf $(TARGET) $(OBJECTS)

二、对上述的makefile做说明以及总结

XX = g++

 定义变量XX,此后当需要用到g++的时候,可以用$(XX)替代

CLIBS = -L./lib/ -lSender -lReceiver -lResponser  -lpthread

同样是定义变量,但对几点做一下说明

-L./lib/  指明库的路径

-lpthread  在默认和指明的库路径中寻找libpthread.so(以lib开头)

INCLUDES = $(wildcard ./include/*.h ./sender/*.h ./receiver/*.h ./responser/*.h)

wildcard  函数获取工作目录下的.h文件列表

*.h  *为通配符,  在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效(这还是定义变量)

wildcard  将通配符展开,INCLUDES获取的就是这些目录下的所有.h文件

INCLUDE_DIRS = -I./include -I./sender/ -I./receiver/ -I./responser/

-I.include    头文件路径,在C++代码中可以不指定头文件的完整路径,将在这些目录下寻找

export XX CFLAGS AR ARFLAG

export 后跟随 变量 将其导出,这些变量在子目录中的makefile依旧可以使用

#OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))

完整命令应该是    $(patsubst %.cpp,%.o,$(wildcard *.cpp))

使用widcard获取到所有cpp文件,在将其文件后缀替换为.o  (我个人编译的是.so库不需要这些,但我认为应该并不是实际修改文件,而只是获得一个文件列表,即之后使用g++编译时的目标)

$(OBJECTS) : %.o : %.cpp 
    $(XX) -c $(CFLAGS) $< -o $@ $(INCLUDE_DIRS)

%.o : %.cpp    将所有.cpp文件编译为相应的.o文件  https://blog.csdn.net/voip3261/article/details/10335969

          实际应该是     main.o : main.cpp  这种形式(这也就是patsubst的用处了,获取所有的cpp对应.o文件列表)

$@        目标,即$(OBJECTS)的值

$<         编译时  :  符号后的第一个依赖文件

$(SUBDIRS):ECHO
    +$(MAKE) -C $@

ECHO      没有特殊用途,只是执行一下命令

+$(MAKE) -C $@  执行子目录下的makefile

.PHONY : clean
clean:
    for dir in $(SUBDIRS);\
    do $(MAKE) -C $$dir clean||exit 1;\
    done
    rm -rf $(TARGET) $(OBJECTS)  ./lib/*.a

.PHNOY      clean是没有依赖项的,也不会生成clean文件,如果该文件夹下存在clean文件,就无法执行clean:下的操作了,就是为了解决这个的

do $(MAKE) - C $$dir clean || exit 1;    执行子文件夹下的clean命令  (这里我不是特别懂语法,但是大概也是明白的)

执行到了子文件夹下的makefile,下一步操作类似了,就不在说明了!

猜你喜欢

转载自www.cnblogs.com/external/p/10581868.html