【问题标题】:What is the most reliable way of using GNUMake with filenames containing spaces?将 GNUMake 与包含空格的文件名一起使用的最可靠方法是什么?
【发布时间】:2010-10-14 16:14:10
【问题描述】:

我想使用 GNUMake 运行基于规则的 makefile,它在目录结构中(在 Windows 文件系统上)构建一组 C 文件。

根目录,一些子目录和一些文件包含空格。

示例文件:"C:\Documents and Settings\<username>\My Documents\Test Dir\Build Me.c"

当文件路径包含空格时,GNUMake 并不真正起作用。我已经阅读了解决此问题的可能方法(从我的文件名中删除空格,使用 8.3 格式,用 ?\\ 等替换空格)但它们都不是完美的(或者它们是完美的吗? )

有没有灵丹妙药可以解决这个问题?

顺便说一句,我被 GNUMake 卡住了,我不能使用其他 make 工具。

【问题讨论】:

    标签: windows filenames space gnu-make


    【解决方案1】:

    最简单的事情确实是修复文件名。

    如果做不到这一点,请编写命令以在文件名周围加上双引号。最简单最安全的就是把所有的文件名放到宏里面;诀窍是你必须转义双引号,否则 Make 会想吃掉它自己。

    所以: FN="\"C:\我的文档\myfiles.c\"" FN2="C:\我的文档\myfile2.c"

    或使用 $(CC) $(CFLAGS) "$(FN2)"

    这里的诀窍是用 echo 回显你的命令行

    echo $(CC) $(CFLAGS) "$(FN2)"
    

    或使用make -d 获取有关 make 尝试执行操作的所有详细信息。

    您可能需要稍微修改一下,特别是,您可能需要加倍转义

    【讨论】:

    • “修复文件名”?名字没有坏掉。无法处理空格的工具已损坏。示例路径甚至是 MS 标准(我怀疑这是一种促使开发人员修复无法处理空格的损坏工具的策略。)
    • 不,使用不符合 UNIX 标准的文件名的工具已损坏。还有操作系统。
    • 允许空格的操作系统和工具坏了?!
    • 是的。你们这些孩子从我的草坪上下来。
    【解决方案2】:

    您可以转义 makefile 中的空格,即:

    $(CC) $(CFLAGS) 'C:\Documents\ and\ Settings\<username>\My\ Documents\Test\ Dir\Build Me.c'
    

    我添加了单引号以防万一,但如果您使用的是 Windows 终端(而不是 cygwin 等),我不知道这是否有效。

    【讨论】:

    • 也许可以,因为我没有安装方便的 Windows 安装工具来确保测试。我想不出为什么这不起作用的原因。
    【解决方案3】:

    我在http://www.mail-archive.com/help-make@gnu.org/msg05201.html 找到了很大的灵感,这让我开始前进。我自己的测试应用程序包含一个从 YouTube 下载的 WW2 时代 Jazz FLV 文件的目录和一个音频子目录,我想在其中存储每个文件的 OGA 音频版本。当然,文件名包含空格。然后我想运行 ffmpeg2theora 到

    这是我一起破解的 GNUMake Makefile。感谢本网站以及上面引用的网站上的所有提示!

    sq = $(subst $(sp),?,$1)
    qs = $(subst ?,$(sp),$1)
    
    e :=
    sp := $(e) $(e)
    
    FLVS := $(foreach file,var,$(call sq,$(wildcard *.flv)))
    FLVS := $(subst .flv?,.flv ,$(FLVS))
    
    AUDIOS := $(patsubst %.flv,audio/%.oga,$(FLVS))
    
    .PHONY: audios show
    
    audios: $(AUDIOS)
    
    $(AUDIOS) : $(FLVS)
        ffmpeg2theora --novideo -o "$(call qs,$@)" "$(call qs,$(notdir $(patsubst %.oga,audio/%.flv,$@)))"
    
    show:
        echo $(FLVS)
        echo $(AUDIOS)
    

    【讨论】:

    • 或者您可以替换其他字符并在需要时将它们转换回空格。 s+ = $(subst \ ,+,$1)+s = $(subst +,\ ,$1)$(call s+,foo bar): $(call s+,bar baz)@echo Making $(call +s,$@) from $(call +s,$&lt;)
    【解决方案4】:

    我通常使用 Dana the Sane 的答案和 Brian Yoder 的答案的组合。

    您只需使用$(subst) 函数将所有出现的空格替换为转义空格。例如:

    empty := 
    space := $(empty) $(empty)
    program_files := $(subst $(space),\$(space),$(ProgramFiles))
    

    (请注意,在 Windows 上使用一些旧版本的 make 您还需要使用另一个 $(subst) 将路径反斜杠更改为斜杠)

    【讨论】:

      【解决方案5】:

      如果空格仅在路径名的“根”部分,您可以将该目录挂载在不带空格的路径上。有多种方法可以做到这一点:从命令行(“net use”或“subst”)或从资源管理器(工具 > 映射网络驱动器)。所以 C:\Documents and Settings\\My Documents\Test Dir" 可能会变成 X:\BuildMe.c

      但是,如果文件名或“根”构建目录下的目录中有空格,则可能没有任何完美的解决方案。我已经使用了您提到的其他建议(8.3 名称,用不同的字符替换空格)并且这些工作有效,但它们有自己的问题。

      【讨论】:

      • 它需要在所有情况下都能正常工作。即当根目录包含空格时,以及子目录本身以及文件名本身。
      【解决方案6】:

      我只是在有问题的字符串周围添加“单引号”:- '$(TARGET_DIR)'

      示例:(这帮助我让 erlang.mk 在 Windows 上正常工作!)

      app:: $(C_SRC_ENV)
          @mkdir -p priv/
          $(c_src_verbose) $(CC) $(CFLAGS) $(C_SRC_DIR)/*.c -fPIC -shared -o $(C_SRC_OUTPUT) \
              -I '$(ERTS_INCLUDE_DIR)' $(C_SRC_OPTS)
      

      '$(ERTS_INCLUDE_DIR)' 现在可以正确扩展为 'c:/Program Files/erl7.0/erts-7.0/include/'

      使用make -d 也有助于揭示无效路径

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-02
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多