7

因此,一些匿名开发人员决定使用一种荒谬的约定,即在包含其源文件的文件夹名称中使用空格。我会更改这些文件夹以不使用空格,但遗憾的是我没有在这里制定规则,所以这不是一个选项(尽管我希望它是)。

LUAC            = luac

SRC_DIR         = .
SOURCE          =                                                      \
stupid/naming\ convention/a.lua                                        \
stupid/naming\ convention/very\ annoying/b.lua                         \

vpath .lua $(SRC_DIR)

OUT_DIR         = ../out/
OUTPUT          = $(patsubst %.lua, $(OUT_DIR)/%.luac, $(SOURCE))


all: $(OUTPUT)

$(OUT_DIR)/%.luac: %.lua
    $(LUAC) "$<"
    mv luac.out "$@"

.PHONY: all

简单的 Makefile。它要做的就是编译我拥有的所有 Lua 文件并将它们放入输出目录。

不管我怎么做,它总是想SOURCE在文件夹中的空格上拆分字符串,所以我以这样一个漂亮的错误结束:

make: *** No rule to make target `stupid/naming ', needed by `all'.  Stop.

有没有办法在不重命名文件夹的情况下解决这个问题?

提前致谢。

4

4 回答 4

5

非常简短但 IMO 最终正确的答案是 make(不仅仅是 GNU make,而是所有 POSIX 样式的 make 实现)不支持包含空格的路径名。如果您想使用 make,您的“匿名开发人员”根本无法使用它们。如果他们坚持这是绝对要求,您应该完全切换到不同的构建工具,它确实支持文件名中的空格。

是的,几乎不可能创建一个可以使用包含空格的文件名的 makefile,但是您基本上必须从头开始重写所有 makefile,并且您将无法使用 GNU make 的许多功能,因此您的 makefile 将是长,难以阅读,难以维护。

只是告诉他们克服自己。或者,如果他们真的不能,请尝试让他们在路径名中创建他们的工作区,名称中没有任何空格,然后创建一个包含指向真实工作区的空格的符号链接(相反的方法并非在所有情况下都有效)。

于 2013-07-31T11:50:37.747 回答
1

不幸的是,处理空格分隔列表的 GNU Make 函数不尊重空格的转义。唯一的例外是wildcard

编辑:

这是我的解决方法:

LUAC            = luac

SRC_DIR         = .
SOURCE          =                                                      \
stupid/naming\ convention/a.lua                                        \
stupid/naming\ convention/very\ annoying/b.lua                         \

vpath .lua $(SRC_DIR)


OUT_DIR         = ../out/
OUTPUT          = $(patsubst %.lua,%.luac,$(SOURCE))


all: $(OUTPUT)

%.luac: %.lua
    $(LUAC) "$<"
    mv luac.out "$@""

.PHONY: all

我试着先这样输出它:

%.luac: %.lua
    @echo "$<"
    @echo "$@""

输出如下所示:

stupid/naming convention/a.lua
../out/stupid/naming convention/a.luac
stupid/naming convention/very annoying/b.lua
../out/stupid/naming convention/very annoying/b.luac
于 2013-07-31T10:17:30.890 回答
0

如果您查看这篇出色的文章:http ://www.cmcrossroads.com/article/gnu-make-meets-file-names-spaces-them ,作者认为这主要是一项艰巨的任务。但是如果你真的无法避免空格,他的替换功能可以让你继续前进。

把它放到你的 makefile 中看起来像这样(对不起,如果我改变了你的一些路径,但这适用于我的 Cygwin 安装):

LUAC            = luac

s+ = $(subst \\ ,+,$1)
+s = $(subst +,\ ,$1) 

SRC_DIR  = .
SOURCE  := stupid/naming\\ convention/a.lua 
SOURCE := $(call s+,$(SOURCE)) 

vpath .lua $(SRC_DIR)

OUT_DIR         = out/
OUTPUT          = $(patsubst %.lua, $(OUT_DIR)/%.luac, $(SOURCE))

all: $(call +s,$(OUTPUT))

$(OUT_DIR)/%.luac: %.lua
    $(LUAC) "$<"
    mv luac.out "$@"

.PHONY: all

我知道这不是一个完整的答案,但也许是一种鼓励,它实际上是可能的。但我同意其他海报的观点,如果你真的可以完全避免空间,你的生活会更轻松!

于 2013-07-31T22:32:49.063 回答
0

当您自动生成 Makefile 时,另一种有效的策略是这个,也用于Perl 的 ExtUtils::MakeMaker:将格式化为可用于配方的名称与可用作依赖项的名称分开。这里的例子有 aTHISFILE和 a THISFILEDEP

AWKWARD_DIR = sub dir
AWKWARD_DIRDEP = sub\ dir
THISFILE = $(AWKWARD_DIR)/d1
THISFILEDEP = $(AWKWARD_DIRDEP)/d1
AWKWARD_DIR_EXISTS = $(AWKWARD_DIR)/.exists
AWKWARD_DIR_EXISTSDEP = $(AWKWARD_DIRDEP)/.exists
TARGET = $(AWKWARD_DIR)/t1
TARGETDEP = $(AWKWARD_DIRDEP)/t1
MAKEFILE = spacemake.mk

$(TARGETDEP): $(THISFILEDEP) $(AWKWARD_DIR_EXISTSDEP)
        cat "$(THISFILE)" >"$(TARGET)"

$(THISFILEDEP): $(AWKWARD_DIR_EXISTSDEP)
        echo "yo" >"$(THISFILE)"

$(AWKWARD_DIR_EXISTSDEP): $(MAKEFILE)
        @echo MAKEFILE = $(MAKEFILE)
        -mkdir "$(AWKWARD_DIR)"
        touch "$(AWKWARD_DIR_EXISTS)"

您可以通过将其放在名为 eg 的文件中进行尝试spacemake.mk,然后使用gmake -f spacemake.mk.

于 2020-08-08T02:37:00.587 回答