我正在使用 GNU Make (版本 3.80 )构建一个C ++项目。 makefile是从我正在使用的工具( IBM Rational Rhapsody )自动生成的。这个makefile的一个例子是在这篇文章的末尾。
这个makefile有一个允许我为目标文件指定目录的机制(OBJ_DIR
变量)。如果设置了此项,则使用命令CREATE_OBJ_DIR
设置变量if not exist $(OBJ_DIR) mkdir $(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
替换它,以消除由于变量扩展引起的任何问题,则会出现相同的错误。
我尝试过的其他事情:
cmd
shell,并尝试运行if not exist build mkdir build
命令。没问题。此时我唯一的结论是关于 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
答案 0 :(得分:1)
你在考虑复杂。这里更简单的解决方案是使用:
mkdir -p $(OBJ_DIR)
如果OBJ_DIR=my/little/obj/dir/deep/down/the/rabit/hole
。
答案 1 :(得分:0)
查看以下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
你的"如果"语句无效 shell 语法。另一方面,如果OBJ_DIR为空,则CREATE_OBJ_DIR为空且有效。