Makefile--由入门到放弃
入门:
最简单的makefile
目录结构如下:
# tree ./
./
├── 1unicode_test.c
├── a.test
├── comm
│ ├── cJSON.c
│ ├── cJSON.h
│ ├── Makefile
│ ├── unicode.c
│ ├── unicode.h
│ ├── url_code.c
│ └── url_code.h
├── include
│ ├── Makefile
│ ├── send_http.h
│ ├── ufile.h
│ └── uuser.h
├── Makefile
├── Makefile.bak
├── param.h
├── src
│ ├── Makefile
│ ├── send_http.c
│ ├── ufile.c
│ └── uuser.c
├── test.c
├── ucp.c
├── ucp.h
├── unicode_test.c
└── \351\205\215\347\275\256\346\211\223\345\214\205\347\216\257\345\242\203.txt
3 directories, 25 files
- makefile简单编写如下:
# cat Makefile
#gcc test.c comm/cJSON.c src/uuser.c comm/cJSON.h include/uuser.h -lcurl -lm
TARGET = a.test
CC = gcc
CCFLAG = -g
LIBP = -lcurl -lm
all:
$(CC) -o $(TARGET) test.c \
comm/cJSON.c \
comm/cJSON.h \
comm/url_code.c \
comm/url_code.h \
comm/unicode.c \
comm/unicode.h \
src/uuser.c \
src/ufile.c \
src/send_http.c \
include/uuser.h \
include/ufile.h \
include/send_http.h \
param.h \
$(LIBP)
.PHONY:clean
clean:
rm -f $(TARGET)
find ./* -name "*.gch" |xargs rm -f
- 加入一些自动推导,简单的优化之后:
# cat Makefile
#gcc test.c comm/cJSON.c src/uuser.c comm/cJSON.h include/uuser.h -lcurl -lm
TARGET = a.out
CC = gcc
CCFLAG = -g
LIBP = -lcurl -lm
COMM_DIR=./comm
SRC_DIR=./src
INCL_DIR=./include
OBJ_DIR=./obj
objects = test.o $(COMM_DIR)/cJSON.o $(COMM_DIR)/url_code.o $(COMM_DIR)/unicode.o \
$(SRC_DIR)/uuser.o $(SRC_DIR)/ufile.o $(SRC_DIR)/send_http.o
$(TARGET):$(objects)
mkdir -p obj
$(CC) -o $(TARGET) $(objects) $(LIBP)
test.o:param.h
cJSON.o:$(COMM_DIR)/cJSON.h
url_code.o:$(COMM_DIR)/url_code.h
unicode.o:$(COMM_DIR)/unicode.h
uuser.o:$(INCL_DIR)/uuser.h
ufile.o:$(INCL_DIR)/ufile.h
send_http.o:$(INCL_DIR)/send_http.h
#all:
# $(CC) -o $(TARGET) test.c \
# comm/cJSON.c \
# comm/cJSON.h \
# comm/url_code.c \
# comm/url_code.h \
# comm/unicode.c \
# comm/unicode.h \
# src/uuser.c \
# src/ufile.c \
# src/send_http.c \
# include/uuser.h \
# include/ufile.h \
# include/send_http.h \
# param.h \
# $(LIBP)
.PHONY:clean
clean:
rm -f $(TARGET)
find ./* -name "*.gch" |xargs rm -f
find ./* -name "*.o" |xargs rm -f
- 还是有很多的问题,如果文件数量很多的话,这样还是需要手动编写,会有很多大量的工作,所有再次进行优化
#gcc test.c comm/cJSON.c src/uuser.c comm/cJSON.h include/uuser.h -lcurl -lm
TARGET = a.out
CC = gcc
CCFLAG = -g
LIBP = -lcurl -lm
CUR_DIR=$(shell pwd)
COMM_DIR=./comm
SRC_DIR=./src
INCL_DIR=./include
OBJ_DIR=./obj
vpath %.c $(CUR_DIR):$(COMM_DIR):$(SRC_DIR)
objects = test.o cJSON.o url_code.o unicode.o \
uuser.o ufile.o send_http.o
objectds = $(wildcard $(OBJ_DIR)/*.o)
$(TARGET):$(objects)
$(CC) -o $@ $(objectds) $(LIBP)
@echo "..."
$(objects):%.o:%.c
$(CC) -c $< -o $(OBJ_DIR)/$@
#mkdir -p obj
.PHONY:clean
clean:
rm -f $(TARGET)
find ./* -name "*.gch" |xargs rm -f
find ./* -name "*.o" |xargs rm -f
- 这一次的自动推导更加多了,但是上面的objects的.o还是手写的,要是改成自动的,则变为一个通用的makefile了,所以在此优化
#目录结构如下所i示
# tree \
. \
├── comm \
│ ├── cJSON.c \
│ ├── cJSON.h \
│ ├── Makefile \
│ ├── unicode.c \
│ ├── unicode.h \
│ ├── url_code.c \
│ └── url_code.h \
├── include \
│ ├── Makefile \
│ ├── send_http.h \
│ ├── ufile.h \
│ └── uuser.h \
├── Makefile \
├── Makefile.bak \
├── Makefile.bak1 \
├── Makefile.bak2 \
├── param.h \
├── src \
│ ├── Makefile \
│ ├── send_http.c \
│ ├── ufile.c\
│ └── uuser.c\
├── test\
│ ├── 1unicode_test.c\
│ ├── ucp.c\
│ ├── ucp.h\
│ └── unicode_test.c\
├── test.c\
└── \351\205\215\347\275\256\346\211\223\345\214\205\347\216\257\345\242\203.txt\
4 directories, 26 files\
TARGET = a.out
CC = gcc
CCFLAG = -g
LIBP = -lcurl -lm
CUR_DIR=$(shell pwd)
COMM_DIR=$(CUR_DIR)/comm
SRC_DIR=$(CUR_DIR)/src
INCL_DIR=$(CUR_DIR)/include
OBJ_DIR=$(CUR_DIR)/obj
TEST_DIR=$(CUR_DIR)/test
#设置环境变量,寻找编译的c文件在设置的环境变量中进行寻找
VPATH_SRC_DIR := $(CUR_DIR):$(COMM_DIR):$(SRC_DIR)
vpath %.c $(VPATH_SRC_DIR)
#这一条语句的作用是遍历CUR_DIR目录下,深度为3的文件夹,输出文件夹名字列表
#DIRS = $(shell find $(CUR_DIR) -maxdepth 3 -type d)
#这一条是直接指定使用的文件夹列表,不会多余的遍历,主要是除去test文件夹下的测试文件干扰项目
DIRS = $(CUR_DIR) $(COMM_DIR) $(SRC_DIR)
SOURCES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
#将所有遍历出来的.c文件,替换生成.o文件,供下面%.o:%.c使用
objects = $(patsubst %.c,%.o,$(notdir $(SOURCES)))
#all:
# @echo 1 $(DIRS)
# @echo 2 $(SOURCES)
# @echo 3 $(objects)
#获取OBJ_DIR目录下的带路经的.o文件列表,供链接的时候使用
objectds = $(wildcard $(OBJ_DIR)/*.o)
$(TARGET):$(objects)
$(CC) -o $@ $(objectds) $(LIBP)
@echo "..."
#将所有.c文件编译生成.o文件,放在OBJ_DIR目录下
$(objects):%.o:%.c
# 如果OBJ_DIR目录不存在,则先创建该目录
@if [ ! -d $(OBJ_DIR) ];then mkdir -p $(OBJ_DIR);fi;
$(CC) -c $< -o $(OBJ_DIR)/$@
.PHONY:clean
clean:
rm -f $(TARGET)
rm -fr $(OBJ_DIR)
find ./* -name "*.gch" |xargs rm -f