gpt4 book ai didi

include - Makefile 将自身添加为目标

转载 作者:行者123 更新时间:2023-12-04 13:44:20 25 4
gpt4 key购买 nike

我有一个使用自动依赖生成的 C++ 程序的 Makefile。 %.d 配方取自 GNU Make 手册。

问题是不知何故“Makefile”被添加为目标,然后一个隐式规则导致它假设它是一个可执行文件并使用我的 src/%.cpp 规则来尝试编译 src/Makefile.cpp。查看调试信息时,这总是在执行包含之后立即发生。

    No need to remake target `build/Sprite.d'.
Considering target file `Makefile'.
Looking for an implicit rule for `Makefile'.
...
Trying pattern rule with stem `Makefile'.
Trying implicit prerequisite `Makefile.o'.
Looking for a rule with intermediate file `Makefile.o'.

我知道 include 会导致在必要时重建给定的 Makefile。它是否也尝试重建当前的 Makefile?如果是这样,我该如何阻止它,如果不是,那么为什么将“Makefile”添加为目标?

另外,include 被执行,导致 .d 文件被重新制作,即使我在命令行上指定了一个目标,例如 make clean .有什么办法可以阻止这种情况发生吗?


# $(call setsuffix,newsuffix,files)
# Replaces all the suffixes of the given list of files.
setsuffix = $(foreach file,$2,$(subst $(suffix $(file)),$1,$(file)))

# $(call twinfile,newdir,newsuffix,oldfile)
# Turns a path to one file into a path to a corresponding file in a different
# directory with a different suffix.
twinfile = $(addprefix $1,$(call setsuffix,$2,$(notdir $3)))

MAIN = main

SOURCE_DIR = src/
INCLUDE_DIR = include/
BUILD_DIR = build/

SOURCES = $(wildcard $(SOURCE_DIR)*.cpp)
OBJECTS = $(call twinfile,$(BUILD_DIR),.o,$(SOURCES))
DEPENDENCIES = $(call twinfile,$(BUILD_DIR),.d,$(SOURCES))

CXX = g++
LIBS = -lpng
CXXFLAGS = -I $(INCLUDE_DIR)


.PHONY: all
all: $(MAIN)

$(MAIN): $(OBJECTS)
$(CXX) $(LIBS) $^ -o $(MAIN)

include $(DEPENDENCIES)

%.o: $(BUILD_DIR)stamp
$(CXX) $(CXXFLAGS) -c $(call twinfile,$(SOURCE_DIR),.cpp,$@) -o $@

$(BUILD_DIR)%.d: $(SOURCE_DIR)%.cpp $(BUILD_DIR)stamp
@ echo Generate dependencies for $ $@.$$$$; \
sed 's,\($*\)\.o[ :]*,$(BUILD_DIR)\1.o $@ : ,g' $@; \
rm -f $@.$$$$

$(BUILD_DIR)stamp:
mkdir -p $(BUILD_DIR)
touch $@

.PHONY: clean
clean:
rm -rf $(BUILD_DIR)

.PHONY: printvars
printvars:
@ echo $(SOURCES)
@ echo $(OBJECTS)
@ echo $(DEPENDENCIES)


最佳答案

Make 总是会在执行 Makefile 之前尝试重新制作 Makefile。为此,make 将查找可用于重新创建 Makefile 的规则。 Make 会寻找很多隐含的规则和其他晦涩的方法来(重新)创建 Makefile。

在你的情况下,make 以某种方式决定模式规则 %.o: $(BUILD_DIR)/stamp应该用于重新创建失败的 Makefile。

为了防止 make 重新制作 Makefile,您可以使用空配方编写规则:

Makefile: ;

阅读章节 Remaking Makefiles在 make 手册中以获得更多解释。

关于包含的 Makefile:包含的 Makefile 将始终被包含,无论目标如何。如果包含的 makefile 丢失(或早于它们的先决条件),那么它们将首先被(重新)创建。这意味着 make clean将首先生成 .d Makefiles,只能再次删除它们。

您可以通过包装 include 来防止包含特定目标。有条件的指令:
ifneq ($(MAKECMDGOALS),clean)
include $(DEPENDENCIES)
endif

这是您的整个 Makefile 并进行了一些修复。我标记了我更改某些内容的地方。
# Makefile

# $(call setsuffix,newsuffix,files)
# Replaces all the suffixes of the given list of files.
setsuffix = $(foreach file,$2,$(subst $(suffix $(file)),$1,$(file)))

# $(call twinfile,newdir,newsuffix,oldfile)
# Turns a path to one file into a path to a corresponding file in a different
# directory with a different suffix.
twinfile = $(addprefix $1/,$(call setsuffix,$2,$(notdir $3)))

MAIN = main

SOURCE_DIR = src
INCLUDE_DIR = include
BUILD_DIR = build

SOURCES = $(wildcard $(SOURCE_DIR)/*.cpp)
OBJECTS = $(call twinfile,$(BUILD_DIR),.o,$(SOURCES))
DEPENDENCIES = $(call twinfile,$(BUILD_DIR),.d,$(SOURCES))

CXX = g++
LIBS = -lpng
CXXFLAGS = -I $(INCLUDE_DIR)


.PHONY: all
all: $(MAIN)

$(MAIN): $(OBJECTS)
$(CXX) $(LIBS) $^ -o $(MAIN)

# -------> only include if goal is not clean <---------
ifneq ($(MAKECMDGOALS),clean)
include $(DEPENDENCIES)
endif

# ---------> fixed this target <--------------
$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.cpp $(BUILD_DIR)/stamp
$(CXX) $(CXXFLAGS) -c $(call twinfile,$(SOURCE_DIR),.cpp,$@) -o $@

# ---------> and this target <---------------
$(BUILD_DIR)/%.d: $(SOURCE_DIR)/%.cpp $(BUILD_DIR)/stamp
@ echo Generate dependencies for $@;
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,$(BUILD_DIR)\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

$(BUILD_DIR)/stamp:
mkdir -p $(BUILD_DIR)
touch $@

.PHONY: clean
clean:
rm -rf $(BUILD_DIR)

.PHONY: printvars
printvars:
@ echo $(SOURCES)
@ echo $(OBJECTS)
@ echo $(DEPENDENCIES)

关于include - Makefile 将自身添加为目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4266281/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com