制作:提取遵循已知路径的目标路径段

时间:2019-03-13 02:38:58

标签: makefile gnu-make gnu

我正在尝试优化构建目标。在我们当前的过程中,我们为32位和64位构建有单独的目标。由于目标不同,我们的构建流程中有数百个目标。我们试图使其成为全球性的地方,即32位和64位构建的一个目标。我正在尝试通过下面的代码来实现这一目标。

用于32位构建的目标/输出目录应类似于:

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

用于64位构建的目标/输出目录应类似于:

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

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

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 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'字符串创建客户端,则它将无法正常工作。即使我们运行64位构建,它也将始终转到if块并尝试运行32位命令。我该如何处理?

我正在寻找上述路径中'client_name'之后的字符串。请帮忙吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)个字符,以使其成为单词列表(路径中每个目录一个),并将结果分配给变量{ {1}}。
  • 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)

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