我正在尝试优化我们的构建目标。在我们当前的流程中,我们为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'之后的字符串..可以请帮助吗?
如果您的目标目录名称总是如下:
/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
。可能有更简单的方法来做同样的事情......
如果我正确理解了您的问题,那么您会遇到以下$(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