我必须为具有以下文件夹结构的项目构建一个makefile:
1)所有标题都在/ include
中2)在/ provided_objects
中提供了一些.o编译的实现(没有.c)3)我创建的源代码必须在/ src
中4)我的C代码生成的.o文件必须在/ built_objects
中5)可执行文件位于根目录
中我最初的目的是用我的实现替换/ provided_objects中的一些实现,记住我的实现可以使用我没有实现的头文件定义的函数。这已经是一个包含的默认makefile(在较小的细节中) ):
LD = gcc
LDFLAGS = -lm
OBJDIR = provided_objects
OBJECTS = $(OBJDIR)/obj1.o \ /$(OBJDIR)/obj2.o ...
MY_OBJECTS =
quiet-command = $(if $(VERB),$1,$(if $(2),@echo $2 && $1, @$1))
all : $(OBJDIR) $(PROG)
$(PROG) : $(OBJECTS) $(MY_OBJECTS)
$(call quiet-command, $(LD) $^ -o $@, " LD $@" $(LDFLAGS))
$(OBJDIR):
$(call quiet-command, mkdir -p $(OBJDIR),)
我应该删除我在OBJECTS中命名的实现条目,并在MY_OBJECTS中引用它们。我的问题是,我该怎么做?我对makefile没有很多经验,我发现研究的链接没有解决我的限制。
提前致谢!
答案 0 :(得分:0)
假设我理解你想要什么,下面的makefile中的OBJECTS := ...
行应该做你想要的。
OBJDIR = provided_objects
OBJECTS = $(OBJDIR)/obj1.o \
$(OBJDIR)/obj2.o \
$(OBJDIR)/obj3.o \
$(OBJDIR)/obj4.o \
$(OBJDIR)/obj5.o
MY_OBJDIR = built_objects
MY_OBJECTS = $(MY_OBJDIR)/obj2.o $(MY_OBJDIR)/obj4.o
$(info Before)
$(info OBJECTS: $(OBJECTS))
$(info MY_OBJECTS: $(MY_OBJECTS))
OBJECTS := $(filter-out $(addprefix $(OBJDIR)/,$(notdir $(MY_OBJECTS))),$(OBJECTS))
$(info After)
$(info OBJECTS: $(OBJECTS))
$(info MY_OBJECTS: $(MY_OBJECTS))
答案 1 :(得分:0)
让我们一步一步地做到这一点:
所有标题都在/include
CPPFLAGS := -I /include # preprocessor flags
在.o
.c
已编译的实施(没有/provided_objects
)
PROVIDED_OBJ_DIR := /provided_objects
PROVIDED_OBJ := $(wildard $(PROVIDED_OBJ_DIR)/*.o)
我创建的源代码必须位于/src
SRC_DIR := /src
SRC := $(wildcard $(SRC_DIR)/*.c)
我的C代码生成的.o
个文件必须位于/built_objects
MY_OBJ_DIR := /built_objects
MY_OBJ := $(SRC:$(SRC_DIR)/%.c=$(MY_OBJ_DIR)/%.o)
可执行文件位于根
中EXE := /executable
我应该删除我在OBJECTS
中命名的实施条目,并在MY_OBJECTS
中引用它们。
PROVIDED_OBJ := $(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
这条线有点长而复杂,所以让我们一起来看看:
主要目标是从提供的文件中过滤掉您重新实现的目标文件
因此,使用的函数是$(filter-out files_to_remove, files_to_remove_from)
。
$(filter-out $(MY_OBJ), $(PROVIDED_OBJ))
问题是MY_OBJ
中的文件以/built_objects/
为前缀,而PROVIDED_OBJ
中的文件以/provided_objects/
为前缀,因此按原样提供,不会过滤掉任何内容。我们需要从名称中删除任何路径组件,因此函数$(notdir files)
。
$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ)))
最后一步:我们需要重新添加正确的路径,否则make将无法找到文件。功能$(addprefix prefix, files)
救援!
$(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
最后,不要忘记编译所有这些的正确规则!完成Makefile :
EXE := /executable
SRC_DIR := /src
SRC := $(wildcard $(SRC_DIR)/*.c)
MY_OBJ_DIR := /built_objects
MY_OBJ := $(SRC:$(SRC_DIR)/%.c=$(MY_OBJ_DIR)/%.o)
PROVIDED_OBJ_DIR := /provided_objects
PROVIDED_OBJ := $(wildcard $(PROVIDED_OBJ_DIR)/*.o)
PROVIDED_OBJ := $(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
LDFLAGS := # -L flags
LDLIBS := -lm # -l flags
CFLAGS := -W -Wall
CPPFLAGS := -I /include
.PHONY: all
all: $(EXE)
$(EXE): $(MY_OBJ)
$(CC) $(LDFLAGS) $^ $(PROVIDED_OBJ) $(LDLIBS) -o $@
$(MY_OBJ_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<