使用包含空格的文件名的 GNUMake 最可靠的方法是什么?

发布于 2024-07-16 03:23:47 字数 426 浏览 8 评论 0原文

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

根目录、部分子目录和部分文件包含空格。

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

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

有解决这个问题的灵丹妙药吗?

顺便说一句,我被 GNUMake 困住了,我无法使用不同的 make 工具。

I want to use GNUMake to run a rule-based makefile which builds a set of C files in a directory structure (on a Windows file system).

The root directory, some sub-directories and some files contain spaces.

Example file: "C:\Documents and Settings\<username>\My Documents\Test Dir\Build Me.c"

GNUMake doesn't really work when the file paths contain spaces. I've read about the possible ways of working around this issue (removing the spaces from my filenames, using the 8.3 format, substituting spaces with ? or \\ etc.) but none of them are perfect (or are they?)

Is there a silver bullet that will solve this problem?

BTW I am stuck with GNUMake, I can't use a different make tool.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

水波映月 2024-07-23 03:23:47

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

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

所以:
FN="\"C:\My Documents\myfiles.c\""
FN2="C:\My Documents\myfile2.c"

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

这里的技巧是用 echo 回显你的命令行

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

,或者使用 make -d 来获取 make 正在尝试执行的所有详细信息。

您可能需要对此进行一些修改,特别是您可能需要加倍转义

The easiest thing is indeed to fix the file names.

Failing that, though, write your commands to put double quotes around the file names. The easiest and safest thing is to put all the file names into macros; the trick there is that you have to escape the double quotes, which Make is otherwise going to want to eat up itself.

So:
FN="\"C:\My Documents\myfiles.c\""
FN2="C:\My Documents\myfile2.c"

or use
$(CC) $(CFLAGS) "$(FN2)"

The trick here is to echo your command line with echo

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

or use make -d to get all the details of what make is trying to do.

You may need to hack about with this a bit, in particular, you may need to double up the escapes

ㄟ。诗瑗 2024-07-23 03:23:47

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

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

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

You may be able to escape the spaces in your makefile, i.e.:

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

I've added the single quotes just in case, but I don't know if this works if you're using the windows terminal (rather than cygwin etc).

最佳男配角 2024-07-23 03:23:47

我在 http://www.mail-archive 找到了很大的灵感.com/[email protected]/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)

I found a great inspiration at http://www.mail-archive.com/[email protected]/msg05201.html which got me going. My own test application consists of a directory of WW2-era Jazz FLV files downloaded from YouTube and an audio subdirectory into which I'd like to store the OGA audio versions of each one. And, of course, the file names contain spaces. I would then like to run ffmpeg2theora to

Here is the GNUMake Makefile that I've hacked together to work. Thanks to all of the hints on this site and also the referenced site above!

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)
堇色安年 2024-07-23 03:23:47

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

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

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

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

I've typically used what is sort of a combination of Dana the Sane's answer and Brian Yoder's answer.

You just use the $(subst) function to replace all occurances of spaces with escaped spaces. EG:

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

(Note that with some older versions of make on Windows you would also need to use another $(subst) to change path backslashes to slashes)

还如梦归 2024-07-23 03:23:47

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

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

If the spaces are only in the "root" part of the pathname, you can mount that directory on a path without blanks. There are multiple ways of doing this: from the command line ("net use" or "subst") or from Explorer (Tools > Map Network Drive). So C:\Documents and Settings\\My Documents\Test Dir" might become X:\BuildMe.c

However, if there are blanks in the file names, or in directories below the "root" build directory, then there probably aren't any perfect solutions. I've used the other suggestions you mentioned (8.3 names, replacing blanks with a different character) and these work but they have their own problems.

醉城メ夜风 2024-07-23 03:23:47

我只需在有问题的字符串周围添加“单引号”:- '$(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 )' 现在使用 make -d 可以正确扩展为 'c:/Program Files/erl7.0/erts-7.0/include/'

也有助于揭示无效路径

I simply add 'single quotes' around the offending string:- '$(TARGET_DIR)'

Example: (this helped me get erlang.mk to work correctly on 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)' now correctly expands to 'c:/Program Files/erl7.0/erts-7.0/include/'

using make -d also helps reveal invalid paths

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文