簡體   English   中英

Makefile將自己添加為目標

[英]Makefile adds itself as target

我有一個使用自動依賴項生成的C ++程序的Makefile。 %.d配方取自GNU Make手冊。

問題是以某種方式將“Makefile”添加為目標,然后隱式規則使其假定它是可執行文件並使用我的src /%。cpp規則來嘗試編譯src / Makefile.cpp。 查看調試信息時,這總是在執行include之后發生。

    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'.

我知道包含原因如果需要,可以重建給定的Makefile。 它是否也嘗試重建當前的Makefile? 如果是這樣,我如何阻止它,如果沒有,那么為什么“Makefile”被添加為目標呢?

此外,執行include,即使我在命令行上指定目標,例如make clean ,也會重新生成.d文件。 有沒有辦法阻止這種情況發生?



# $(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。

在您的情況下,以某種方式決定應該使用模式規則%.o: $(BUILD_DIR)/stamp來重新創建失敗的Makefile。

要防止make重新生成Makefile,您可以使用空配方編寫規則:

Makefile: ;

有關詳細說明,請參閱制作手冊中的Remaking Makefiles一章。

關於包含的Makefile:包含的Makefile將始終包含在內,無論目標如何。 如果包含的makefile缺失(或者早於其先決條件),則首先(重新)創建它們。 這意味着make clean將首先生成.d Makefile,只是再次刪除它們。

您可以通過將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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM