代码改变世界

几个递进的make file

2020-02-08 13:31  chen.simon  阅读(408)  评论(0编辑  收藏  举报

春节在家写的几个递进的make file,部分有点问题。接下来 有空我要把GNU make的手册看完。不然这方面太菜了。

GNU make手册
都需要make先设置环境变量BUILD_MODE为run或者debug

1 源文件名 目标都hard code,且一次编译多个目标

PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

OBJS = lsdemo.o test.o

ifeq ($(BUILD_MODE),debug)
	CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
	CFLAGS += -O2
else
	$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif

all:	lsdemo test

lsdemo:	lsdemo.o
	$(CXX) -o $@ $^

lsdemo.o:	$(PROJECT_ROOT)/ch01/lsdemo.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
	
test:	test.o
	$(CXX) -o $@ $^

test.o:	$(PROJECT_ROOT)/ch01/test.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
	
clean:
	rm -fr lsdemo test  $(OBJS)

2 通过OBJS变量定义多个目标文件 通过遍历ch01/目录下所有c文件作为源文件

PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

OBJS = lsdemo.o test.o

ifeq ($(BUILD_MODE),debug)
	CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
	CFLAGS += -O2
else
	$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif

all:	lsdemo 

lsdemo:	$(OBJS)
	$(CXX) -o $@ $^

%.o:	$(PROJECT_ROOT)/ch01/%.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
	
#test:	test.o
#	$(CXX) -o $@ $^
#
#test.o:	$(PROJECT_ROOT)/ch01/test.c
#	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
#	
clean:
	rm -fr lsdemo test  $(OBJS)

3 ch01 ch02 多个子目录下多目标编译

PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

CH01OBJS = lsdemo.o test.o
CH02OBJS = test21.o test22.o

ifeq ($(BUILD_MODE),debug)
	CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
	CFLAGS += -O2
else
	$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif

all:	lsdemo ch02

lsdemo:	$(CH01OBJS)
	$(CXX) -o $@ $^

%.o:	$(PROJECT_ROOT)/ch01/%.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
	
ch02:	$(CH02OBJS)
	$(CXX) -o $@ $^

%.o:	$(PROJECT_ROOT)/ch02/%.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
	
#test:	test.o
#	$(CXX) -o $@ $^
#
#test.o:	$(PROJECT_ROOT)/ch01/test.c
#	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
#	
clean:
	rm -fr lsdemo test  $(OBJS)

4 通过修改CH_NO和APP_NAME切换到底编译哪个子目录下的应用,编译到指定路径下,适用于APUE学习时例程序编写

CH_NO = ch01
APP_NAME = lsdemo

# 获取makefile路径
PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
$(info MAKEFILE_LIST is: $(MAKEFILE_LIST))
$(info PROJECT_ROOT is: $(PROJECT_ROOT))

# 拼接路径
SOURCE_FRAGMENT :=$(CH_NO)/$(APP_NAME)
SOURCE_ROOT := $(PROJECT_ROOT)$(SOURCE_FRAGMENT)
$(info SOURCE_ROOT is: $(SOURCE_ROOT))
BUILD_ROOT := $(PROJECT_ROOT)build/make.debug.linux.x86_64/$(SOURCE_FRAGMENT)/
$(info BUILD_ROOT is: $(BUILD_ROOT))

ifeq ($(BUILD_MODE),debug)
	CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
	CFLAGS += -O2
else
	$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif

$(shell if [ ! -d $(BUILD_ROOT) ]; then mkdir -p $(BUILD_ROOT); fi;)

SOURCE := $(shell find $(SOURCE_ROOT) -name '*.c' |xargs -n1 basename)
OBJS := $(SOURCE:.c=.o)
$(info SOURCE is: $(SOURCE))
$(info OBJS is: $(OBJS))

all: $(APP_NAME)
	
#
$(APP_NAME):	$(OBJS)
	$(CXX) -o $(BUILD_ROOT)/$@ $(addprefix $(BUILD_ROOT), $^)

%.o:	$(SOURCE_ROOT)/%.c
	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $(BUILD_ROOT)/$@ $<

clean:
	rm -fr $(BUILD_ROOT)

附上第四种情况的目录结构:

appweb@simon-ububtu18-desk-2:~/600.self/03.code/01.cpp/03.APUE$ tree 
.
├── build
│   └── make.debug.linux.x86_64
│       └── ch01
│           └── lsdemo
│               ├── lsdemo
│               ├── lsdemo.o
│               └── test.o
├── ch01
│   └── lsdemo
│       ├── lsdemo.c
│       └── test.c
└── Makefile