多目录多文件 简单Makefile
一.目录一览:
[user:test] tree
.
├── app_dev
│ ├── main.cpp
│ └── Makefile
├── lib_pub
│ ├── add.cpp
│ ├── add.h
│ ├── Makefile
│ ├── print.cpp
│ └── print.h
└── Makefile
2 directories, 8 files
二.Makefile文件详情:
1.顶层Makefile:
[user:test] cat Makefile
.PHONY:all clean
all:
@make all -C ./lib_pub
@make all -C ./app_dev
@
clean:
@make clean -C ./lib_pub
@make clean -C ./app_dev
2.app_dev目录的Makefile:
[user:test] cat app_dev/Makefile
SRCS:=$(wildcard *.cpp)
OBJS:=$(SRCS:.cpp=.o)
DEPS:=$(SRCS:.cpp=.d)
.PHONY: all clean
all : main
%.d : %.cpp
rm -f $@; \
g++ -MM $< > $@.$$$$; \ #把每个源文件的依赖关系重定向到一个以随机数结尾的文件,好处在于把头文件都依赖进来.
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ #如:main.d: main.cpp ../lib_pub/add.h ../lib_pub/print.h 改成 main.o main.d : main.cpp ../lib_pub/add.h ../lib_pub/print.h 解析:1.逗号[,]为分割符;2.小括号[()]里的内容给1.o的[1]作替换;3.把改后的内容重定向到[.d]文件
rm -f $@.$$$$ #把以随机数结尾的文件删除,只保留[.d]后缀的文件.
main:$(OBJS)
# ar rcs libappdev.a $^
g++ -o main ./main.o -L../lib_pub -L. -lpub -I../lib_pub
ifneq ($(MAKECMDGOALS), clean) #这个条件的作用在于:make clean 时不会运行$(DEPS)目标
sinclude $(DEPS) #把$(DEPS)加进来,当成目标,首先运行.然后才会运行all目标.
endif
clean:
-rm -f *.d *.d.* *.o *.a main
3.lib_pub目录的Makefile:
[user:test] cat lib_pub/Makefile
SRCS:=$(wildcard *.cpp)
OBJS:=$(SRCS:.cpp=.o)
DEPS:=$(SRCS:.cpp=.d)
.PHONY: all clean
all : main
%.d : %.cpp
rm -f $@; \
g++ -MM $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
main:$(OBJS)
ar rcs libpub.a $^
ifneq ($(MAKECMDGOALS), clean)
sinclude $(DEPS)
endif
clean:
-rm -f *.d *.d.* *.o *.a main
三.目录文件详情:
1.主函数main
[user:test] cat app_dev/main.cpp
/// @file main.cpp
/// @brief
/// @author EastonWoo
/// 0.01
/// @date 2013-03-19
#include "stdio.h"
#include "../lib_pub/add.h"
#include "../lib_pub/print.h"
int main(int argc, const char *argv[])
{
printf("%d\n",add(1,3));
print();
return 0;
}
2.库函数add
[user:test] cat lib_pub/add.cpp
/// @file add.cpp
/// @brief
/// @author EastonWoo
/// 0.01
/// @date 2013-03-20
#include "add.h"
#include "print.h"
int add(int a,int b)
{
print();
return (a+b);
}
[user:test] cat lib_pub/add.h
/// @file add.h
/// @brief
/// @author EastonWoo
/// 0.01
/// @date 2013-03-20
int add(int a,int b);
3.库函数print
[user:test] cat lib_pub/print.cpp
/// @file print.cpp
/// @brief
/// @author EastonWoo
/// 0.01
/// @date 2013-03-20
#include <stdio.h>
#include "print.h"
void print()
{
printf("hello world!\n");
}
[user:test] cat lib_pub/print.h
/// @file print.h
/// @brief
/// @author EastonWoo
/// 0.01
/// @date 2013-03-20
void print();
四.编译运行:
1.编译
[user:test] make
make[1]: Entering directory `/work/test/test/lib_pub'
rm -f print.d; \
g++ -MM print.cpp > print.d.$$; \
sed 's,\(print\)\.o[ :]*,\1.o print.d : ,g' < print.d.$$ > print.d; \
rm -f print.d.$$
rm -f add.d; \
g++ -MM add.cpp > add.d.$$; \
sed 's,\(add\)\.o[ :]*,\1.o add.d : ,g' < add.d.$$ > add.d; \
rm -f add.d.$$
make[1]: Leaving directory `/work/test/test/lib_pub'
make[1]: Entering directory `/work/test/test/lib_pub'
g++ -c -o add.o add.cpp
g++ -c -o print.o print.cpp
ar rcs libpub.a add.o print.o
make[1]: Leaving directory `/work/test/test/lib_pub'
make[1]: Entering directory `/work/test/test/app_dev'
rm -f main.d; \
g++ -MM main.cpp > main.d.$$; \
sed 's,\(main\)\.o[ :]*,\1.o main.d : ,g' < main.d.$$ > main.d; \
rm -f main.d.$$
make[1]: Leaving directory `/work/test/test/app_dev'
make[1]: Entering directory `/work/test/test/app_dev'
g++ -c -o main.o main.cpp
# ar rcs libappdev.a main.o
g++ -o main ./main.o -L../lib_pub -L. -lpub -I../lib_pub
make[1]: Leaving directory `/work/test/test/app_dev'
[user:test] tree
.
├── app_dev
│ ├── main
│ ├── main.cpp
│ ├── main.d
│ ├── main.o
│ └── Makefile
├── lib_pub
│ ├── add.cpp
│ ├── add.d
│ ├── add.h
│ ├── add.o
│ ├── libpub.a
│ ├── Makefile
│ ├── print.cpp
│ ├── print.d
│ ├── print.h
│ └── print.o
└── Makefile
2 directories, 16 files
2.运行
[user:test] ./app_dev/main
hello world!
4
hello world!
3.清除
[user:test] make clean
make[1]: Entering directory `/work/test/test/lib_pub'
rm -f *.d *.d.* *.o *.a main
make[1]: Leaving directory `/work/test/test/lib_pub'
make[1]: Entering directory `/work/test/test/app_dev'
rm -f *.d *.d.* *.o *.a main
make[1]: Leaving directory `/work/test/test/app_dev'
[user:test] tree
.
├── app_dev
│ ├── main.cpp
│ └── Makefile
├── lib_pub
│ ├── add.cpp
│ ├── add.h
│ ├── Makefile
│ ├── print.cpp
│ └── print.h
└── Makefile
2 directories, 8 files
[user:test] make clean
make[1]: Entering directory `/work/test/test/lib_pub'
rm -f *.d *.d.* *.o *.a main
make[1]: Leaving directory `/work/test/test/lib_pub'
make[1]: Entering directory `/work/test/test/app_dev'
rm -f *.d *.d.* *.o *.a main
make[1]: Leaving directory `/work/test/test/app_dev'
[user:test] tree
.
├── app_dev
│ ├── main.cpp
│ └── Makefile
├── lib_pub
│ ├── add.cpp
│ ├── add.h
│ ├── Makefile
│ ├── print.cpp
│ └── print.h
└── Makefile
2 directories, 8 files