【问题标题】:GNU Make Exits Due to Syntax Error in If Statement由于 If 语句中的语法错误,GNU Make 退出
【发布时间】:2018-04-30 11:55:57
【问题描述】:

我正在使用 GNU Make(版本 3.80)构建一个 C++ 项目。 makefile 是从我正在使用的工具(IBM Rational Rhapsody)自动生成的。此 makefile 的示例在本文末尾。

这个makefile 有一个机制,允许我为目标文件(OBJ_DIR 变量)指定一个目录。如果设置了此项,则使用命令if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) 设置变量CREATE_OBJ_DIR。然后为项目中的每个目标文件调用它。

运行这个makefile没有设置一个目标文件目录按预期工作;代码编译没有问题。但是在 OBJ_DIR 设置为 'build' 的情况下运行它会导致以下错误:

C:\Users\XXX\AppData\Local\Temp\make52963.sh: C:\Users\XXX\AppData\Local\Temp\make52963.sh: line 2: syntax error: unexpected end of file
C:\Tools\XXX\x86-win32\bin\make.exe: *** [build/Example.o] Error 2

当调用$(CREATE_OBJ_DIR) 时,我确定问题在“/build/Example.o”的规则范围内。如果我手动编辑规则并将$(CREATE_OBJ_DIR) 替换为mkdir $(OBJ_DIR),则该命令将正确执行。如果我然后直接将其替换为if not exist build mkdir build,以消除由于变量扩展引起的任何问题,则会出现相同的错误。

我尝试过的其他事情:

  1. 运行cmd shell,并设置与调用makefile 时相同的环境变量,并尝试运行if not exist build mkdir build 命令。这没有问题。
  2. 确保在 makefile 中运行的命令中没有尾随字符。似乎没有。

在这一点上我唯一的结论是关于 if 语句的某些内容会导致 makefile 失败,但我不确定是什么。还有什么我应该尝试追查这个问题的根源吗?我是否遗漏了一些明显的东西。

如果需要更多详细信息,请告诉我。

注意:我已经对这个 makefile 进行了大量编辑,所以它只是为了说明我正在使用什么,并且可能不会执行。下面的一些环境变量是在调用make 之前在批处理文件中设置的,但我相信它们不是我所看到的问题的一部分,因为除了上述情况之外,makefile 可以正常工作。

CPU = XXX
TOOL = gnu

INCLUDE_QUALIFIER=-I
LIB_CMD=$(AR)
LINK_CMD=$(LD)

CPP_EXT=.cpp
H_EXT=.h
OBJ_EXT=.o
EXE_EXT=.out
LIB_EXT=.a

TARGET_NAME=Example

all : $(TARGET_NAME)$(EXE_EXT) Example.mak

TARGET_MAIN=Example

LIBS=
INCLUDE_PATH=
ADDITIONAL_OBJS=

OBJS= \
  build/Example.o \

OBJ_DIR=build

ifeq ($(OBJ_DIR),)
CREATE_OBJ_DIR=
else
CREATE_OBJ_DIR= if not exist $(OBJ_DIR) mkdir $(OBJ_DIR)
endif

build/Example.o : src/Example.cpp 
    @echo Compiling src/Example.cpp
    $(CREATE_OBJ_DIR)
    @$(CXX) $(C++FLAGS) -o build/Example.o src/Example.cpp

【问题讨论】:

  • 只是一个简单的问题:您是否使用制表符缩进?
  • @MortenJensen 是的,构建规则使用制表符缩进。
  • 你的文字很长,但在任何地方都没有任何冒犯make52963.sh的痕迹。了解它是如何创建的以及它包含什么...
  • 我怀疑您的 GNU make 版本(3.8 不是有效的 GNU make 发行号;也许您使用的是 3.80?)正在调用 POSIX shell,而不是 command.com。如果这是真的,那么声明 if not exist $(OBJ_DIR) mkdir $(OBJ_DIR) 是无效的。
  • @FelixPalmen 这是一个公平的观点。这必须在我每次运行make 时生成,但每次都有不同的数字。我在我的 Temp 文件夹中看不到它(在构建过程中它甚至不会暂时出现)。不知道如何找到这个。

标签: c++ c makefile gnu


【解决方案1】:

你的想法很复杂。一个更简单的解决方案是使用:

mkdir -p $(OBJ_DIR)

如果OBJ_DIR=my/little/obj/dir/deep/down/the/rabit/hole,这也将使其工作。

【讨论】:

  • 这绝对是一个很好的解决方案,问题是这是一个自动生成的makefile。我不认为有一个参数可以让我改变它。我更感兴趣的是为什么当语法有效时原始命令不起作用。
【解决方案2】:

看下面的Makefile:

OBJ_DIR=foo

CREATE_OBJ_DIR= if not exist $(OBJ_DIR) mkdir $(OBJ_DIR)

$(info CREATE_OBJ_DIR=$(CREATE_OBJ_DIR))

all:
        $(CREATE_OBJ_DIR)

它的输出:

% make         
CREATE_OBJ_DIR=if not exist foo mkdir foo
if not exist foo mkdir foo
/bin/sh: 1: Syntax error: end of file unexpected (expecting "then")
Makefile:8: recipe for target 'all' failed
make: *** [all] Error 2

您的“if”语句根本就不是有效的 shell 语法。另一方面,如果 OBJ_DIR 为空,则 CREATE_OBJ_DIR 为空且有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2015-09-08
    • 2018-08-30
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多