【问题标题】:Makefile: Test directories for existence and take first one foundMakefile:测试目录是否存在并找到第一个
【发布时间】:2013-03-08 09:57:19
【问题描述】:

我正在使用 makefile 来编译 MATLAB/C 项目。 MATLAB 通常可以安装到多个标准位置,具体取决于其版本,例如/Applications/MATLAB_2012b.app、/Applications/MATLAB_2013a.app等

查看这些路径是否存在的最简单方法是什么,一个接一个,然后取第一个找到的路径?我至少要测试五个值。我找到了$(wildcard filename) 语法,但我想知道是否有什么比一一写出更短的方法。


根据要求进行澄清。我可以拼凑一些有用的东西,但我确信这远非最好/最简洁的方式。有没有更好的办法?

ifeq ($(MATLAB),)
ifneq ($(wildcard /Applications/MATLAB_2011b.app),)
    MATLAB = /Applications/MATLAB_2011b.app
endif
endif

ifeq ($(MATLAB),)
ifneq ($(wildcard /Applications/MATLAB_2012a.app),)
    MATLAB = /Applications/MATLAB_2012a.app
endif
endif

ifeq ($(MATLAB),)
ifneq ($(wildcard /Applications/MATLAB_2012b.app),)
    MATLAB = /Applications/MATLAB_2012b.app
endif
endif

ifeq ($(MATLAB),)
ifneq ($(wildcard /Applications/MATLAB_2013a.app),)
    MATLAB = /Applications/MATLAB_2013a.app
endif
endif

【问题讨论】:

  • 这还不清楚。 $(wildcard /Applications/MATLAB_*.app 怎么了?
  • @Beta 请查看编辑
  • 太糟糕了,这个问题限制了 MATLAB_* 模式的路径。
  • @techtonik 你的意思是什么?答案很笼统。
  • 接受的答案假定路径具有公共组件,这在一般情况下是不正确的。

标签: makefile


【解决方案1】:

如果存在,你可以得到第一个这样的目录

MATLAB_DIR := $(firstword $(wildcard /Applications/MATLAB_*.app))

如果不存在,则变量为空

ifeq (,$(MATLAB_DIR))
  $(error Matlab not found)
endif

如果你的路径有空格,你可以使用 shell。这样的事情可能会奏效:

MATLAB_DIR := $(shell ls -d /Applications/MATLAB_*.app | tail -n 1)

【讨论】:

  • 谢谢,这很有用!我想我会使用lastword。您在这里使用:= 而不是= 很重要吗? (我现在正在查找差异)
  • 在这种情况下:= 更好但不是必需的。 stackoverflow.com/questions/448910/makefile-variable-assignment
  • 如果 MATLAB 的路径中有空格,这将失败,因为 firstword 会将其分开。您对如何在保持通配符通用性的同时解决此问题有任何建议吗?也许我应该为此提出一个单独的问题。
  • 如果你的路径有空格,你可以改用shell。这样的事情可能会起作用:MATLAB_DIR := $(shell ls /Applications/MATLAB_*.app | tail -n 1)
  • 谢谢。如果您不介意,我将其添加到您的答案中。最后一个问题是逃离该空间,以便我可以正确使用路径。我这样做了:space := 然后space += 然后$(subst $(space),\ ,$(MATLAB_DIR))。这是最简单的方法吗?
【解决方案2】:

为了回答您有关文件/目录名称中空格的问题,大多数 Makefile 函数不处理文件名中的空格,并且大多数函数甚至不尊重 \ 转义空格的方式。

像$@、$<、$% 和函数wildcard 这样的变量似乎很少将\ 转义序列作为空格正确处理,但大多数其他makefile 变量和函数如firstword 等。无法处理空格。

假设如果您在通配符中找到有效目录,则无法区分列表中的 2 个有效目录与路径中包含空格的单个目录。

如果您使用的是 Makefile,我建议您尽可能避免在路径中使用空格。

但总有一些变通方法;)假设您在 *nix 环境中使用 find 和 sort 命令可用,这似乎可行。

BASE_DIR_NAME := .
MATLAB_DIR := $(subst $(NULL) ,\ ,$(shell find $(BASE_DIR_PATH) -mindepth 1 -maxdepth 1 -name 'MATLAB_*.app' -type d -print | sort | head -1))

default:
    @echo MATLAB_DIR="$(MATLAB_DIR)"
    ls -l $(MATLAB_DIR)

.PHONY: default

这是目录结构和 Makefile 的输出:

$ ls -l
total 16
-rw-r--r-- 1 ash users  236 Mar 20 01:15 Makefile
drwxr-xr-x 2 ash users 4096 Mar 20 01:13 MATLAB_ a.app
drwxr-xr-x 2 ash users 4096 Mar 20 01:13 MATLAB_ b.app
drwxr-xr-x 2 ash users 4096 Mar 20 01:13 MATLAB_ c.app

$ find . -type f
./Makefile
./MATLAB_ a.app/file1
./MATLAB_ b.app/file2

$ make
MATLAB_DIR=./MATLAB_\ a.app
ls -l ./MATLAB_\ a.app
total 0
-rw-r--r-- 1 ash users 0 Mar 20 01:13 file1

【讨论】:

    猜你喜欢
    • 2014-01-12
    • 1970-01-01
    • 2018-02-19
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多