【问题标题】:Allow space in target of GCC makefile在 GCC makefile 的目标中允许空间
【发布时间】:2013-02-06 21:30:26
【问题描述】:

在使用 make.exe 时,有没有办法让目标名称中的空格起作用?如果这个非常古老的错误报告是正确的,这似乎是不可能的: http://savannah.gnu.org/bugs/?712

作为参考,最大的问题是makefile命令如下:

"foo bar baz": $(OBJ)
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

... 似乎被视为三个单独的命令:一个用于构建“foo(注意包含的”),一个用于构建 bar,最后一个用于构建 baz”(再次,包括“)。这是因为 make.exe 似乎使用空格作为分隔符。

但是,假设一个人可能想要构建“Hello World.exe”是合理的。这似乎是不可能的。双引号不起作用,转义单独的单词也不起作用(我在某处读过,不记得链接了):

"foo\\ bar\\ baz": $(OBJ)
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

还有其他方法可以解决这个问题吗?官方手册只确认了tokenize-by-spaces的东西,但没有提供一种将空间用于任何其他目的的方法: http://www.gnu.org/software/make/manual/make.html#Rule-Syntax

编辑: 正如建议的那样,我也尝试过单斜杠,但这些与双斜杠的效果完全相同。抱怨它找不到第一个单词的规则:

mingw32-make.exe: *** No rule to make target `foo', needed by `all'.  Stop.

虽然可以正确生成可执行文件“foo bar baz.exe”,但每次每个单词都会进行链接。

【问题讨论】:

    标签: gcc makefile mingw target space


    【解决方案1】:

    不要使用双反斜杠,而是使用单反斜杠。以下 Makefile 有效(至少对于 gnu make):

    goal:   foo\ bar
    
    foo\ bar:
        gcc -o "foo bar" "foo bar.c"
    

    【讨论】:

    • @Orwell:那么,这似乎是操作系统的问题。如何在 shell 中指定名称中包含空格的文件?
    • 目标名称中的冒号也需要加引号:some\:target\ name: ... - 也可能是其他字符。
    【解决方案2】:

    正如马蒂亚斯所说,这是“\”的问题,但也是双引号的问题。这是我成功的方法:

    EXECUTABLE=foo\ bar\ baz
    all: $(SOURCES) $(EXECUTABLE)
    $(EXECUTABLE): $(OBJECTS)
                    $(CC) $(OBJECTS) -o "$@" $(LDFLAGS)
    

    注意 $@ 周围的双引号 在我看来,当 make 到达目标“$(EXECUTABLE)”时,它会扩展“\”,所以命令行变成了

    gcc file.o -o foo bar baz -LFlags
    

    这不是你想要的,你想在文件名两边加上双引号。

    现在你在 Windows 上,我不记得它如何处理名称中的空格,所以正如 Matthias 所说,首先检查“cmd.exe”如何处理空格(除了用双引号括起来的名称......)

    【讨论】:

      【解决方案3】:

      也许更容易考虑一个更简单的 Makefile,它忽略标准 targetRule: dependencies 调用中的依赖关系。 OP 适用于 Windows,以下是在 Linux 上的 bash shell 中完成的;但我猜它可能应该适用于通过cygwin 使用bash shell 的Windows。我的Makefile 中有以下内容(注意,在echo 命令之前应该有一个 TAB ,它会转换为空格):

      testA:
          echo "testA"
      
      unrelated:
          echo "unrelated"
      
      testA\ clean:
          echo "testA clean"
      
      clean:
          echo "clean"
      

      如果我在bash shell 终端中使用目标cleantestA 调用make,我会得到预期的结果:

      $ make testA 
      echo "testA"
      testA
      $ make clean
      echo "clean"
      clean
      

      现在,如果我按原样调用make testA cleanbash shell 将在空格处拆分参数,因此make 将接收两个参数,并将分别运行它们:

      $ make testA clean
      echo "testA"
      testA
      echo "clean"
      clean
      

      ... 但是如果我将提供给make 的目标用引号括起来 - 或者如果我转义空格 - shell 将理解它应该是一个内部带有空格的单个参数,并将其传播为比如make,它将继续执行写为testA\ clean目标规则的内容:

      $ make "testA clean"
      echo "testA clean"
      testA clean
      $ make testA\ clean
      echo "testA clean"
      testA clean
      

      这样做的一个后果是,很遗憾,您不能在命令行中使用“TAB”来自动完成testA\ clean;如果你在命令行输入make teTAB,只有testA会自动完成(testA\ clean不会显示为自动完成选项)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-20
        相关资源
        最近更新 更多