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

Makefile GNU make-将每个先决条件转换为目标(隐式),makefile,gnu-make,Makefile,Gnu Make,我有另一个类似于make的工具,它在解析我的makefile之后生成一个XML作为工件,然后我将用Python进一步处理它 它会简化我的事情-很多-如果我可以有使< /C> >考虑每个前提都是一个实际的目标,因为这是另一个工具。 将每个文件分类为“作业” 这是我的makefile的一个片段: .obj/eventlookupmodel.o: C:/Users/User1/Desktop/A/PROJ/src/AL2HMIBridge/LookupModels/eventlookupmodel.c

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

<>它会简化我的事情-很多-如果我可以有<代码>使< /C> >考虑每个前提都是一个实际的目标,因为这是另一个工具。 将每个文件分类为“作业”

这是我的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变量

makeall makefile=Dummy.mk

使用包含此规则的
Dummy.mk
,这样我就不会修改生成文件

到目前为止,我已经尝试了以下方法

Dummy.mk:

%.h: 
    @echo header xyz = $@

%: 
    @echo other xyz= $@
这部分起作用

我运行
makeall--trace--print database MAKEFILES=Dummy.mk
,我可以看到
make
%规则“绑定”到头文件。在
--print database部分
中,我看到已将该规则分配给头文件

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
文件执行,也不会在
--打印数据库
部分“绑定”到它们。 但是,它是为没有后缀的现有目标绑定和执行的,即

all: library binary

binary: | library
ifs:    | library
对于
%:
规则,此行为的原因是

如果我将其设置为非终结符(无双冒号),则该规则不适用于内置类型,如
.cpp
,除非我取消定义否定预期
%:
规则的内置规则

如果我让它成为终端。但是
.h
.cpp
在技术上没有先决条件;我可以创建一个虚拟文件并将其作为先决条件吗

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

尝试为头文件生成静态模式规则。请参阅以下问题的答案之一

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

$(OBJECTS): %.o: %.c
    *recipe here*
其中变量
OBJECTS
在makefile的前面定义为目标文件列表(用空格分隔),例如:

OBJECTS := src/fileA.c src/fileB.c src/fileC.c
请注意,您可以使用各种
make
实用程序函数来构建目标文件列表。例如,
$(通配符模式)
$(addsuffix)
,等等

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

我发现使用静态模式规则而不是模式规则可以解决make无法构建不存在的先决条件或删除所需文件的问题


下面是一个使用
通配符
将文件从一个目录复制到另一个目录的示例

# 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 $< $@
#将图像复制到构建/图像
img_文件:=$(通配符src/images/*.png src/images/*.gif src/images/*.jpg\
src/images/*.mp3)
生成图像:=$(subst src/,$(build\u DIR)/,$(img\u文件))
$(构建图像):$(构建图像)/images/%:src/images/%
mkdir-p$(dir$@)
cp-v-a$<$@
还有其他
make
函数,如
addprefix
,可用于生成更复杂的文件规范。

尝试为头文件生成静态模式规则。请参阅以下问题的答案之一

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

$(OBJECTS): %.o: %.c
    *recipe here*
其中变量
OBJECTS
在makefile的前面定义为目标文件列表(用空格分隔),例如:

OBJECTS := src/fileA.c src/fileB.c src/fileC.c
请注意,您可以使用各种
make
实用程序函数来构建目标文件列表。例如,
$(通配符模式)
$(addsuffix)
,等等

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

我发现使用静态模式规则而不是模式规则可以解决make无法构建不存在的先决条件或删除所需文件的问题


下面是一个使用
通配符
将文件从一个目录复制到另一个目录的示例

# 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 $< $@
#将图像复制到构建/图像
img_文件:=$(通配符src/images/*.png src/images/*.gif src/images/*.jpg\
src/images/*.mp3)
生成图像:=$(subst src/,$(build\u DIR)/,$(img\u文件))
$(构建图像):$(构建图像)/images/%:src/images/%
mkdir-p$(dir$@)
cp-v-a$<$@

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

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

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

%: null
    @echo other xyz= $@

null:
    @:

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

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

%: null
    @echo other xyz= $@

null:
    @:

所以您实际上是在问如何使工作目录中的每个头文件成为。。。一些目标。是吗?@Beta no不是预请求。我想让
make
知道的每个文件都有一个空规则,即
AnyFile:
,这样我在
ImplTarget.mk
@Beta中定义的规则,如果某个文件,比如
.cpp
已经有了一个规则,那么附加的“空规则”将不会有任何效果。@Beta我正在尝试完成
gcc-E-m-Mp
所完成的工作,特别是
-Mp
标志所完成的工作:除了发出一条规则,说明
.cpp
所依赖的头以外,此外,它还以空目标的形式一次发送一行相同的头文件,即头文件后跟冒号。例如
标题1: