当前目录状态如下:
├── client_d
│ ├── client.c
│ └── Makefile
├── server_d
│ ├── Makefile
│ └── server.c
└── src
├── wrap.c
└── wrap.h
解决问题:
1. 多目录编译makefile,但这里有点缺陷是:它并不能很好地适应所有;当然,这是个小test
完整makefile如下:
#Makefile for client
#多目录 单Makefile
#编译选项
CC=gcc
CFLAGS= -g
#使用相对路径寻址
TARGET=client
SRCS = client.c ../src/wrap.c
#路径包含
INC = -I../src
#利用SRCS文件名字替换,使得c和o文件名字一一对应
#这样就有了所有的o文件,下面的clean使用到
OBJS = $(SRCS:.c=.o)
#终极目标
$(TARGET):$(OBJS)
$(CC) -o $@ $^
#伪目标
.PHONY:clean
clean:
-$(RM) -rf $(TARGET) $(OBJS)
#由上面的终极目标自动推导关系,
#下面使用模式规则(也可使用自定义变量来生成)
%.o:%.c
$(CC) $(CFLAGS) $(INC) -o $@ -c $<
#待改进地方:
#该Makefile会留下.o文件,实际上并不需要
Makefile知识点:
1. 基本语法:目标+依赖+命令;贯穿整个Makefile编写与执行
2. 伪目标:使用场景如下
1. 避开与目标同名的文件(不使用伪目标时同名,则make不断失败)
2. 指定clean、all等常用make XXX
3. 自定义变量:可以理解为一个宏(也就是替换作用),为了增加通用性(移植性也可)
4. Makefile变量:
1. 环境变量:注意使用的如下:
1. 自定义变量会覆盖同名环境变量
2. pwd:得到的是make开始运行时的路径
2. 自动变量:无需定义,根据上下文变化;使用场景如下:
1. 常用于节省编写工作
2. 可用于自动推导(如.o文件)
3. 预定义变量:定于程序名称和传递给这些程序的参数和标志位;常用如下:
1. AR
2. CC:编译程序,如gcc、arm-none-linux-gnueabi-gcc
3. CFLAGS:传给CC的标志,如-g(添加调试信息,等等)
4. LDFLAGS:传给链接程序的标志,如添加库(-L . -lFOO或者-lpthread,等等)
5. 隐式规则和显式规则:
1. make自己定义了一些既定的生成规则,比方遇见一个.o文件,隐式规则马上找寻找相应的.c文件,从而自己推导生成。