GNU делает выход из-за синтаксической ошибки в операторе If - PullRequest
0 голосов
/ 30 апреля 2018

Я строю проект C ++, используя GNU Make (версия 3.80 ). Makefile автоматически генерируется из инструмента, который я использую ( IBM Rational Rhapsody ). Пример этого make-файла находится в конце этого поста.

Этот make-файл имеет механизм, который позволяет мне указывать каталог для объектных файлов (переменная OBJ_DIR). Если это установлено, переменная CREATE_OBJ_DIR устанавливается с помощью команды if not exist $(OBJ_DIR) mkdir $(OBJ_DIR). Затем он вызывается для каждого объектного файла в проекте.

Запуск этого make-файла без , установка директории объектного файла работает как положено; код скомпилирован без проблем. Но запуск его с 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

Я уверен, что проблема в правиле для /build/Example.o, когда вызывается $(CREATE_OBJ_DIR). Если я вручную отредактирую правило и заменим $(CREATE_OBJ_DIR) на mkdir $(OBJ_DIR), команда будет выполнена правильно. Если я затем заменю его на if not exist build mkdir build напрямую, чтобы устранить любые проблемы из-за расширения переменной, появится та же ошибка.

Другие вещи, которые я пробовал:

  1. Запустите оболочку cmd с теми же переменными окружения, которые установлены при вызове make-файла, и попытались запустить команду if not exist build mkdir build. С этим проблем нет.
  2. Убедитесь, что в команде, выполняемой в make-файле, нет завершающих символов. Похоже, никого нет.

Мой единственный вывод на данный момент заключается в том, что что-то в , если операторов приводит к сбою make-файла, но я не уверен, что. Есть ли что-то еще, что я должен попытаться отследить источник этой проблемы? Я что-то упускаю очевидное.

Дайте мне знать, если потребуется более подробная информация.

Примечание: я довольно сильно отредактировал этот make-файл, поэтому он просто дает представление о том, что я использую, и, вероятно, не будет выполняться. Некоторые из перечисленных ниже переменных среды настраиваются в пакетном файле до вызова make, но я уверен, что они не являются частью проблемы, которую я вижу, поскольку make-файл работает правильно, за исключением ситуации, описанной выше.

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

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Посмотрите на следующий 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 пуст, и это действительно.

0 голосов
/ 30 апреля 2018

Вы думаете о сложном. Гораздо более простым решением здесь является использование:

mkdir -p $(OBJ_DIR)

Это также заставит его работать, если OBJ_DIR=my/little/obj/dir/deep/down/the/rabit/hole.

...