使用多个通配符进行Makefile路径替换

使用多个通配符进行Makefile路径替换,makefile,Makefile,我有一个目标,它是需要生成的test.mk文件的路径(通过基于配置的脚本修改),我想提取路径的一部分,该部分是要测试的组件 路径采用以下格式,其中[component]和[test_name]未知 TEST=absolute_path/[component]/unit_tests/[test_name]/test.mk 我想将此路径重新格式化为相对路径/[component],我已经尝试了这一行,它没有替代任何内容 $(TEST): @echo $(patsubst absolute_

我有一个目标,它是需要生成的test.mk文件的路径(通过基于配置的脚本修改),我想提取路径的一部分,该部分是要测试的组件

路径采用以下格式,其中[component]和[test_name]未知

TEST=absolute_path/[component]/unit_tests/[test_name]/test.mk
我想将此路径重新格式化为相对路径/[component],我已经尝试了这一行,它没有替代任何内容

$(TEST):
    @echo $(patsubst absolute_path/%/unit_tests/%, relative_path/%, $@)

GNU make手册中有关于patsubst的说明,因此我认为它应该在单个patsubst调用中使用多个通配符:

在这里,模式可能包含一个“%”,它充当通配符,匹配单词中任意数量的字符。如果替换还包含“%”,则“%”将替换为模式中与“%”匹配的文本。只有模式和替换中的第一个“%”被这样处理;任何后续“%”都将保持不变


我想你知道相对路径。我还假设组件的名称和测试的名称是可变的(它们可以更改)。所以我把它们叫做“组件X”和“测试名称Y”。假设所有这一切,以下措施应该有效:

    # Definitions for the space-string and the newline-string
    # ---------------------------------------------------------
    nullstring :=
    space := $(nullstring) #End

    TEST=some/abs/path/component_X/unit_tests/test_name_Y/test.mk

    # Some manipulations of the path:
    # ---------------------------------
    TEMP1=$(subst /,$(space),$(TEST))
    TEMP2=$(filter-out $(lastword $(TEMP1)),$(TEMP1))
    TEMP3=$(filter-out $(lastword $(TEMP2)),$(TEMP2))
    TEMP4=$(filter-out $(lastword $(TEMP3)),$(TEMP3))
    ABS_PATH=$(subst $(space),/,$(filter-out $(lastword $(TEMP4)),$(TEMP4)))
    REL_PATH=some/rel/path
    REL_FILE_PATH=$(patsubst $(ABS_PATH)/%,$(REL_PATH)/%,$(TEST))
    COMP_NAME=$(firstword $(subst /,$(space),$(patsubst $(ABS_PATH)/%,$(nullstring)%,$(TEST))))
    TEST_NAME=$(firstword $(subst /,$(space),$(patsubst $(ABS_PATH)/$(COMP_NAME)/unit_tests/%,$(nullstring)%,$(TEST))))


    # The test target
    # ----------------
    $(TEST): FORCE
        @echo.
        @echo The calculated ABS_PATH:
        @echo $(ABS_PATH)
        @echo.
        @echo The chosen REL_PATH:
        @echo $(REL_PATH)
        @echo.
        @echo The relative file path:
        @echo $(REL_FILE_PATH)
        @echo.
        @echo The component name:
        @echo $(COMP_NAME)
        @echo.
        @echo The test name:
        @echo $(TEST_NAME)

    FORCE: 
别忘了复制粘贴可能会导致制作错误。在配方行中,应使用制表符替换所有4个空格

请让我知道这个解决方案是否对您有效。 我在Windows上测试了它。但它也应该在Linux上工作

编辑:


我在
ABS\u PATH=…
的定义中犯了一个小错误。现在它应该是正确的:-)

您的意思是
绝对路径是固定的,必须在makefile中硬编码吗?“我认为它应该在一个patsubst调用中使用多个通配符”。您似乎忽略了您引用的
patsubst
文档的最后一句话。你的问题也不清楚。您需要发布一个示例makefile,指明您不知道如何完成的间隔。绝对路径和相对路径是通过变量知道的。谢谢,这样做的诀窍是:
@echo-relative\u-path/$(firstword$(subst/,$(space),$(patsubst-absolute\u-path/%,%,$)
或者更好:
@echo-relative\u-path/$(firstword)$(subst/unit_tests/,$(patsubst absolute_path/%,%,$@))
因为即使组件位于我们通常拥有的子目录中,这也会起作用。
绝对_path/[component]/[subcomponent]/[unit_tests/[test_name]/test.mk
=>
相对_path/[component]/[subcomponent]