https://blog.csdn.net/haoel/article/details/2886
https://blog.csdn.net/haoel/article/details/2891
跟我一起写 Makefile ------------------------------陈皓
我很喜欢陈皓在第一篇博文里的范例,这种写法很容易看清各种依赖关系。
参考了一个网友的嵌套范例的写法,有了下面这个mac和ubuntu下makefile,main函数所在的文件我还是喜欢单独拿出来,最起码这一层依赖一目了然。
mac makefile
-------------------------------------------------------------------------------------------------------------
#VPATH = BaseRender:shaderUtil:testApp:glad:.
PROJECT_PATH = $(shell pwd)
export OBJSDIR = $(PROJECT_PATH)/objs
CFLAGS = -g -Wall -O0 -lstdc++
CPPFLAGS = -g -Wall
DIRS = BaseRender shaderUtil testApp glad.
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS = $(patsubst %.cpp, %.o, $(FILES))
LIBS += -lGLEW -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
TARGET = tutorialEdit
all:$(TARGET)
$(TARGET):$(OBJSDIR) winMain.o
$(MAKE) -C BaseRender
$(MAKE) -C shaderUtil
$(MAKE) -C utils
$(MAKE) -C glad
$(MAKE) -C testApp
$(CC) $(CFLAGS) $(LIBS) $(OBJSDIR)/*.o -o $@
$(OBJSDIR):
mkdir -p $@
winMain.o:%.o:%.cpp
$(CC) -c $< -o $(OBJSDIR)/$@ $(CPPFLAGS) $(CFLAGS) -IBaseRender -IshaderUtil -Iutils -ItestApp -Iglad
.PHONY:clean
clean :
-$(RM) $(TARGET) $(OBJSDIR)/*.o
-------------------------------------------------------------------------------------------------------------
OBJSDIR是在顶层makefile里定义的,用export申明,传导到BaseRender shaderUtil utils glad testApp这几个子文件夹的makefile文件里面,winmain和他们的o文件都放在$(PROJECT_PATH)/objs目录下。
“%.o”表明要所有以“.o”结尾的目标,也就是“winMain.o”,而依赖模式“%.cpp”则取模式“%.o”的“%”,也就是“winMain”,并为其加下“.cpp”的后缀,于是依赖目标就是“winMain.cpp”。命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“winMain.cpp”),“$@”表示目标集(也就是“winMain.o”)。于是,上面的规则展开后等价于
winMain.o : winMain.pp
$(CC) -c $(CFLAGS) -IBaseRender -IshaderUtil -Iutils -ItestApp -Iglad winMain.cpp -o winMain.o
BaseRender shaderUtil utils glad testApp这几个子文件夹里面的makefile就很好写了,跟winMain的做法一样。
-----------------------------------------------------------------------------------------------------------------------
OBJS = CGfxOpenGLRender.o
all:$(OBJS)
$(OBJS):%.o:%.cpp
$(CC) $(CFLAGS) -c $< -o $(OBJSDIR)/$@
clean:
$(RM) $(OBJS)
make的时候,嵌套执行的makefile里面出现警告'linker' input unused,我就在生成TARGET需要最终链接.o文件时加上LIBS,但是我写嵌套makefile一开始的目的是想把各种不同的依赖在各个子文件夹里面处理的,现在只能拿出来,刚开始玩gcc的时候,就是一堆文件然后LIBS加在一起。
另外在target这里$(CC) $(CFLAGS) $(LIBS) $(OBJSDIR)/*.o -o $@,如果写成 $(CC) $(CFLAGS) $(LIBS) $(OBJSDIR)/*.o $< -o $@ 就会报错ld: can't map file, errno=22 file '/Users/.../objs' for architecture x86_64 这里我的理解是应该是依赖目标是以$(OBJSDIR) 定义的,那么"$<"将是符合模式的一系列的文件,也就把objs路径也加进来,并不是一个o文件。
现在的makefile是把o文件集中放一起,如果改成放在各自所在的路径下,那就在顶层makefile加上
DIRS = BaseRender shaderUtil testApp glad.
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS = $(patsubst %.cpp, %.o, $(FILES))
然后各个生成o文件的地方去掉路径,-o $(OBJSDIR)/$@改成-o $@,target这里改成
$(CC) $(CFLAGS) $(LIBS) $(OBJS) winMain.o -o $@
再make,o文件都放在各自默认的地方了,这样看起来更适合嵌套make。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ubuntu makefile
PROJECT_PATH = $(shell pwd)
export OBJSDIR = $(PROJECT_PATH)/objs
CFLAGS = -O2 -lstdc++
DIRS = BaseRender shaderUtil testApp glad.
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp) $(wildcard *.c))
OBJS = $(patsubst %.cpp, %.o, $(FILES))
LIBS += -lGLEW -lglfw3 -lGL -lassimp -lX11 -pthread -lXrandr -lXi -lXxf86vm -lXinerama -lXcursor -lrt -lm -lfreetype -ltiff -lpng -ljpeg -lassimp -lz -ldl
TARGET = tutorialEdit
all:$(TARGET)
$(TARGET):$(OBJSDIR) winMain.o
$(MAKE) -C testApp
$(MAKE) -C BaseRender
$(MAKE) -C shaderUtil
$(MAKE) -C utils
$(MAKE) -C glad
$(CC) -o $@ winMain.o $(CPPFLAGS) $(CFLAGS) $(OBJSDIR)/*.o $(LIBS)
$(OBJSDIR):
mkdir -p $@
winMain.o:%.o:%.cpp
$(CC) $(CFLAGS) -c $< -o $@ -ItestApp -IBaseRender -IshaderUtil -Iutils -Iglad
.PHONY:clean
clean :
-$(RM) $(TARGET) $(OBJSDIR)/*.o
今天在使用gdb过程中出现value optimized out
(gdb) print dx
$3 = <optimized out>
由于gcc在编译过程中默认使用-O2优化选项,我希望进行单步跟踪调试,不进行编译优化,CFLAGS = -O2 -lstdc++ 这里改成-O0选项。发布项目的时候不使用 -O0参数项。
我希望make clean的时候只清除testApp和winMain,testApp的makefile改成
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $(OBJSDIR)/$@
其余的obj文件就生成在各自的目录下,
OBJS = CGfxOpenGLRender.o
CFLAGS = -O2 -lstdc++
CGfxOpenGLRender.o : CGfxOpenGLRender.cpp
$(CC) $(CFLAGS) -c $< -o CGfxOpenGLRender.o
clean:
$(RM) $(OBJS)
OBJS = shader.o
CFLAGS = -O2 -lstdc++
all:$(OBJS)
$(OBJS):%.o:%.cpp
$(CC) $(CFLAGS) -c $< -o $@
clean:
$(RM) $(OBJS)
这样make的时候,检测到各个目录下已经make过了,就不再重新make。
https://www.cnblogs.com/dayInAndOut/p/3727319.html ---------------使用-c是编译成.o的中间文件,只检查语法错误,不检查依赖关系,指明链接文件也不会用。
http://blog.chinaunix.net/uid-20681545-id-3786786.html -----------gcc命令中,-c和-lz不能一起使用,-c编译的时候,并有没有执行link这一动作。