首页 文章

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

提问于
浏览
1

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

它为我简化了很多事情 - 如果我可以让 make 认为每个先决条件都是实际目标,那么这个其他工具会将每个文件归类为"job" .

这是我的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 = $@

However, I do NOT see the "echo header xyz $@"-rule being executed.

关于 %: 规则,它既没有为 .cpp 文件执行,也没有在 --print-data-base 部分执行"bound" . 但是,对于没有后缀的现有目标,它是绑定和执行的,即

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 ,除非我取消定义否定我的预期 %: 规则的内置规则 .

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

NOTE: This has NOTHING to do with gcc -M generation. Yes the -M option would help in the specific case of header and source files but this question is for more generic targets and prerequisites that already exist in the makefile when make is launched.

2 回答

  • 0

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

    %.h: null
        @echo header xyz = $@
    
    %: null
        @echo other xyz= $@
    
    null:
        @:
    
  • 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 ,可用于生成更复杂的文件规范 .

相关问题