GNU make - 将每个先决条件转换为目标(隐式)

时间:2016-07-01 21:14:43

标签: makefile gnu-make

我有另一个make - 类工具,在解析我的makefile后会生成一个XML作为工件,然后我将用Python进一步处理它。

它为我简化了很多事情 - 如果我可以让make认为每一个先决条件都是一个真正的目标,那么这个其他工具 将每个文件归类为“工作”。

这是我的makefile的一个片段:

.obj/eventlookupmodel.o: C:/Users/User1/Desktop/A/PROJ/src/AL2HMIBridge/LookupModels/eventlookupmodel.cpp C:\Users\User1\Desktop\A\PROJ\src\AL2HMIBridge\LookupModels\eventlookupmodel.h \
        C:/Users/User1/Desktop/A/PROJ/qt5binaries/include/QtCore/qabstractitemmodel.h \
        C:/Users/User1/Desktop/A/PROJ/qt5binaries/include/QtCore/qvariant.h \
        ...

我希望make认为我对每个先决条件都有一个虚拟规则,如下所示:

C:/Users/User1/Desktop/A/PROJ/qt5binaries/include/QtCore/qvariant.h: 
     @echo target pre= $@

 C:/Users/User1/Desktop/A/PROJ/qt5binaries/include/QtCore/qabstractitemmodel.h: 
    @echo target pre=$@

C:/Users/User1/Desktop/A/PROJ/src/AL2HMIBridge/LookupModels/eventlookupmodel.cpp :
    @echo target pre=$@

C:\Users\User1\Desktop\A\PROJ\src\AL2HMIBridge\LookupModels\eventlookupmodel.h:
    @echo target pre=$@

我并不关心规则的确切形式,只是每个文件都被视为实际目标。

我传递此规则的方法是设置MAKEFILES变量,如此

make all MAKEFILES=Dummy.mk

Dummy.mk包含此规则,以便我不修改makefile。

到目前为止,我已尝试过以下内容。

Dummy.mk:

%.h: 
    @echo header xyz = $@

%: 
    @echo other xyz= $@

这部分有效。

我跑make all --trace --print-data-base MAKEFILES=Dummy.mk,我可以看到 make会将%.h:规则“绑定”到头文件中。在--print-data-base section中,我看到该规则被分配给头文件。

C:/Users/User1/Desktop/A/QNX_SDK/target/qnx6/usr/include/stddef.h:
#  Implicit rule search has been done.
#  Implicit/static pattern stem: 'C:/Users/User1/Desktop/A/QNX_SDK/target/qnx6/usr/include/stddef'
#  Last modified 2016-05-27 12:39:16
#  File has been updated.
#  Successfully updated.
#  recipe to execute (from '@$(QMAKE) top_builddir=C:/Users/User1/Desktop/A/HMI_FORGF/src/../lib/armle-v7/release/ top_srcdir=C:/Users/User1/Desktop/A/HMI_FORGF/ -Wall CONFIG+=release CONFIG+=qnx_build_release_with_symbols CONFIG+=rtc_build -o Makefile C:/Users/User1/Desktop/A/HMI_FORGF/src/HmiLogging/HmiLogging.pro
', line 2):
@echo header xyz = $@

但是,我没有看到“echo header xyz $ @” - 正在执行的规则。

关于%:规则,它既不会对.cpp文件执行,也不会在--print-data-base部分中“绑定”它们。 但是,对于没有后缀的现有目标,它是绑定和执行的,即

all: library binary

binary: | library
ifs:    | library

对于%:规则,此行为的原因是10.5.5 Match-Anything Pattern Rules: If you do not mark the match-anything rule as terminal, then it is non-terminal. A non-terminal match-anything rule cannot apply to a file name that indicates a specific type of data. A file name indicates a specific type of data if some non-match-anything implicit rule target matches it.

如果我将它设置为非终端 - 没有双冒号 - 那么该规则不适用于内置类型,如.cpp,除非我取消定义否定我的预期{{1}的内置规则规则。

如果我将它作为终端,"it does not apply unless its prerequisites actually exist"。但是%:.h在技术上并不具备先决条件;我可以创建一个虚拟文件并将其作为先决条件吗?

注意:这与.cpp代无关。是的gcc -M选项在标题和源文件的特定情况下会有所帮助,但是这个问题适用于启动-M时makefile中已存在的更通用的目标和先决条件。

2 个答案:

答案 0 :(得分:0)

尝试为头文件生成静态模式规则。请参阅Make ignoring Prerequisite that doesn't exist的答案之一。

静态模式规则仅适用于目标文件的显式列表,如下所示:

$(OBJECTS): %.o: %.c
    *recipe here*

其中变量OBJECTS在makefile中先前定义为目标文件列表(以空格分隔),例如:

OBJECTS := src/fileA.c src/fileB.c src/fileC.c

请注意,您可以使用各种make实用程序函数来构建目标文件列表。例如,$(wildcard pattern)$(addsuffix)

您还应该确保配方“触摸”头文件以更改时间戳。

我发现使用静态模式规则而不是模式规则修复了make不构建不存在的先决条件或删除所需文件的问题。

以下是使用wildcard将文件从一个目录复制到另一个目录的示例。

# Copy images to build/images
img_files := $(wildcard src/images/*.png src/images/*.gif src/images/*.jpg \
src/images/*.mp3)

build_images := $(subst src/,$(BUILD_DIR)/,$(img_files))
$(build_images): $(BUILD_DIR)/images/% : src/images/%
    mkdir -p $(dir $@)
    cp -v -a $< $@

还有其他make函数,例如addprefix,可用于生成更复杂的文件规范。

答案 1 :(得分:0)

这可能需要几次迭代。尝试:

%.h: null
    @echo header xyz = $@

%: null
    @echo other xyz= $@

null:
    @: