Make:提取跟随已知目标路径段的目标路径段

问题描述 投票:2回答:2

我正在尝试优化我们的构建目标。在我们当前的流程中,我们为32位和64位构建提供了单独的目标。由于目标不同,我们的构建流程中有数百个目标。我们试图使其全局化,即32位和64位构建的目标。我正在尝试使用下面的代码实现此目的。

32位构建的目标/输出目录应如下所示:

/test/scratch/<client_name>/Linux/... 

64位版本的目标/输出目录应该是:

/test/scratch/<client_name>/Linux-64bit/... 

所以基于以上目标目录路径,我使用Linux函数搜索字符串$(findstring)并继续运行32位命令。否则它将运行64位命令,如下所示。

RELEASE_FILES := $(TARGET_DIR)/build/test/csimtime.c
$(RELEASE_FILES): $(TGTDIRFILES)/%: %
ifneq (Linux,$(findstring $(OS),$@))
    $(test_lib_32)
else
    $(test_lib_64)
endif

$(TARGET_DIR)变量作为参数传递给make命令

make TARGET_DIR=$(TGT32) all32

对于64位,我们将通过TARGET_DIR=$(TGT64)

注意:上面的test_lib_32 / 64是我们在当前make文件中包含的其他make文件中的宏定义。

它按预期工作正常,但我不确定这是否是最好的方法?我注意到这里有一个问题,我们传递的TGT32 / TGT64变量通常具有以下值:

/test/scratch/<client_name>/Linux/ (for 32bit)

要么

/test/scratch/<client_name>/Linux-64bit/... (for 64bit)

如果有人使用client_name'Linux'字符串创建客户端,它将不起作用。它总是会进入if块并尝试运行32位命令,即使我们运行64位构建。我怎么处理这个?

我正在寻找在上面的​​路径中获取'client_name'之后的字符串..可以请帮助吗?

makefile gnu-make gnu
2个回答
0
投票

如果您的目标目录名称总是如下:

/test/scratch/<client_name>/Linux/...

并且在/中没有<client-name>字符且没有空格,您可以根据路径中Linux(或Linux-64bit)的确切位置进行测试:

TYPE := $(word 4,$(subst /, ,$(TARGET_DIR)))

ifeq ($(TYPE),Linux)
<something>
else ifeq ($(TYPE),Linux-64bit)
<something-else>
else
$(error Unknown type: $(TYPE))
endif

编辑如果位置不是常数,但你知道<client-name>是什么,并且/中没有<client-name>字符且没有空格,你可以在<client-name>中提取$(TARGET_DIR)后面的目录名称,如下所示:

TAIL := $(subst /, ,$(TARGET_DIR))
$(foreach w,$(TAIL),$(eval TAIL := $(wordlist 2,$(words $(TAIL)),$(TAIL)))$(if $(patsubst $(CLIENT_NAME),,$(w)),,$(eval TYPE := $(word 1,$(TAIL)))))

all:
    @printf 'TYPE = $(TYPE)\n'

演示:

$ make TARGET_DIR=/a/b/test-client/Linux/c/d CLIENT_NAME=test-client
TYPE = Linux
$ make TARGET_DIR=/a/b/c/d/test-client/Linux-64bit/e/f/g CLIENT_NAME=test-client
TYPE = Linux-64bit

说明:

  • TAIL := $(subst /, ,$(TARGET_DIR))/中的$(TARGET_DIR)字符替换为一个空格,使其成为单词列表(路径中每个目录一个),并将结果分配给变量TAIL
  • $(foreach w,$(TAIL),...)评估...,其中w变量连续设置为$(TAIL)的每个单词。
  • $(eval TAIL := $(wordlist 2,$(words $(TAIL)),$(TAIL)))通过删除前导词重新分配变量TAIL
  • 如果$(if $(patsubst $(CLIENT_NAME),,$(w)),,...)等于...$(w)评估$(CLIENT_NAME)
  • $(eval TYPE := $(word 1,$(TAIL)))$(TAIL)的第一个词分配给变量TYPE

可能有更简单的方法来做同样的事情......


0
投票

如果我正确理解了您的问题,那么您会遇到以下$(TARGET_DIR)值的问题:

 /.../Linux/.../Linux-64bit

问题是你正在测试$@的价值:

 /.../Linux/.../Linux-64bit/some/other/file

正如您所看到的那样,无法确定路径中的哪个Linux应该用于决策。

我建议尝试这样做:

# if $(TARGET_DIR) ends with /Linux -> 32-bit build
$(RELEASE_FILES): $(TGTDIRFILES)/%: %
ifneq ($(filter %/Linux,$(TARGET_DIR)),)
        $(test_lib_32)
else
        $(test_lib_64)
endif
© www.soinside.com 2019 - 2024. All rights reserved.