【问题标题】:GNU Makefile - modifying Makefile after changing project directory structure, and outputing to different foldersGNU Makefile - 更改项目目录结构后修改 Makefile,并输出到不同的文件夹
【发布时间】:2021-12-02 17:49:39
【问题描述】:

我正在为一个项目处理旧的 Makefile。当前项目包含转储到名为 src 的单个项目中的所有文件。

我想将项目重组为以下结构:

-src           (C files)
  |- include   (header files)
- build        (intermediary build files - *.d, *.o)
- bin          (built binary [executable])
- lib          (built library)

这里是 Makefile 的摘要,以及我迄今为止所做的更改(创建了新的文件夹结构等)。

SOURCE_DIR = src
HEADER_DIR = $(SOURCE_DIR)/include
BUILD_DIR = build
LIB_DIR = lib
BIN_DIR = bin


OBJS = foo.o foobar.o foofoobar.o barbar.o barfoo.o barbarfoo.o 

all: dir release

dir:
    test -d $(HEADER_DIR) || mkdir -p $(HEADER_DIR)
    test -d $(BUILD_DIR) || mkdir $(BUILD_DIR)
    test -d $(LIB_DIR) || mkdir $(LIB_DIR)
    test -d $(BIN_DIR) || mkdir $(BIN_DIR)


debug : CC = gcc
debug : CFLAGS = -std=c99 -O0 -g
debug : LDLIBS = -lm
debug : project

release : CC = gcc
release : CFLAGS = -std=c99 -O3 -fno-strict-aliasing
release : LDLIBS = -lm
release : project

debug_cpp : CC = g++
debug_cpp : CFLAGS = -x c++ -std=c++11 -O0 -g
ifeq ($(PLATFORM),Darwin) # macOS
debug_cpp : WARNINGS += -Wcast-qual
endif
debug_cpp : LDLIBS = -lstdc++
debug_cpp : project

release_cpp : CC = g++
release_cpp : CFLAGS = -x c++ -std=c++11 -O3 -fno-strict-aliasing
ifeq ($(PLATFORM),Darwin) # macOS
release_cpp : WARNINGS += -Wcast-qual
endif
release_cpp : LDLIBS = -lstdc++
release_cpp : project

.c.o :
    $(CC) -c  $(CFLAGS) $(WARNINGS) $<

project : main.o libproject.a
    $(CC) -o $(BIN_DIR)/project main.o -L. -lproject $(LDLIBS)
    
libproject.a : $(OBJS)
    rm -f $@   
    ar cq $@ $(OBJS)   

clean : 
    -rm -f main.o $(OBJS)
    -rm -f $(BIN_DIR)/project $(BIN_DIR)/libproject.a
    
.PHONY : all project clean debug release debug_cpp release_cpp

# Dependencies generated using "gcc -MM *.c"

foo.o: file1.c afile.h bfile.h cfile.h dfile.h hfile.h \
  gfile.h file2.c file3.c fil4.c file5.c 

如何将 Makefile 修改为:

  1. 构建二进制可执行文件并放在bin 文件夹中(同时将中间文件转储到 $(BUILD) 文件夹中
  2. 构建二进制库并放在lib 文件夹中(同时将中间文件转储到 $(BUILD) 文件夹中

【问题讨论】:

  • 这不是一个很好的结构。如果某些东西依赖于dir,但用户调用了make target,您的食谱将不起作用。相反,您希望每个目标都依赖于它所需的 特定 导向器。因为在写入目录时会更新目录日期戳,所以可能在每个目录中使用单独的点文件作为实际依赖项(dike lib/library.a: lib/.created $(otherdeps)
  • @tripleee 是的,我自己也发现了这一点。我将在本地修改 Makefile - 请记住这一点。

标签: makefile build gnu-make


【解决方案1】:

我只修复了release 目标,所以你可以完成剩下的工作。

.PRECIOUS 和 %/.` 规则是自动创建目录的好方法。

.SECONDEXPANSION| $$(@D)/. 位是依赖创建目录的好方法。

您生成了依赖项并手动包含它们(我的答案中没有包含它们)。好的。您必须记住根据需要更新它们。 Make 手册包含有关如何完全自动处理此类依赖项的建议。在我看来,这种自动方法并不总是能正常工作,所以必须手动完成。

给你

SOURCE_DIR = src
BUILD_DIR = build/
LIB_DIR = lib
BIN_DIR = bin
PROJECT := $(BIN_DIR)/project
LIB := $(LIB_DIR)/libproject.a

OBJS:= $(addprefix $(BUILD_DIR),foo.o foobar.o foofoobar.o barbar.o barfoo.o barbarfoo.o)

all: release

release : CC = gcc
release : CFLAGS = -std=c99 -O3 -fno-strict-aliasing
release : LDLIBS = -lm
release : $(PROJECT)

.PRECIOUS: %/.
%/.:
    mkdir -p $(@:/.=)

.SECONDEXPANSION:

$(BUILD_DIR)%.o : $(SOURCE_DIR)/%.c Makefile | $$(@D)/.
    $(CC) -c  $(CFLAGS) $(WARNINGS) $< -o $@

$(PROJECT) : $(BUILD_DIR)main.o $(LIB) Makefile | $$(@D)/.
    $(CC) -o $@ $< -L$(LIB_DIR) -lproject $(LDLIBS)
    
$(LIB) : $(OBJS) Makefile | $$(@D)/.
    rm -f $@   
    ar cq $@ $(OBJS)   
    
.PHONY : all clean release

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    相关资源
    最近更新 更多