不更改生成文件后,生成文件项目不会生成(几乎相同的生成,工作正常)

  • 本文关键字:文件 工作 项目 c++ c makefile
  • 更新时间 :
  • 英文 :


我昨天在linux下编译了一个makefile项目。现在该项目无法编译,我不记得对 makefile 本身进行了任何更改。它会在make处抛出make: *** No rule to make target 'obj/TranquilMain.o', needed by 'tranquil;. Stop.错误。我所做的唯一真正的更改是,当我从另一个项目复制代码和makefile时,我更改了某些文件(以及依赖项包括)的名称,然后更改了makefile中的_DEPS。所有文件都在必要的位置。

应该注意的是,如果我从_OBJ列表中删除除 TranquilMain.o 以外的所有其他文件,它可以很好地编译。enter code here我希望我能提供的不仅仅是代码和这些知识,但我不知道问题是什么。

适当的生成文件:"生成文件">

#!/usr/bin/make
CC      = gcc
CP      = g++
SRC_DIR     = #.
OBJ_DIR     = obj
INC_DIR     = ../include
LIB_DIR     = ../lib
LIBS        = -lm -lSDL -lSDLmain -lSDL_image -lSDL_mixer -lSDL_ttf -lSDL_net -lGL -lGLU -lGLEW
CFLAGS      = -I$(INC_DIR) -L$(LIB_DIR) -std=gnu++0x

_DEPS   = DefaultConfig.h BaseApplication.h BasePlugin.h SDLImage.h SDLFont.h SDLWindow.h SDLInput.h SDLRenderer.h SDLApplication.h Math2D.h SDLTimer.h
DEPS    = $(patsubst %,$(INC_DIR)/%,$(_DEPS))
_OBJ    = TranquilMain.o BaseApplication.o BasePlugin.o SDLImage.o SDLFont.o SDLWindow.o SDLInput.o SDLRenderer.o SDLApplication.o Math2D.o SDLTimer.o
OBJ = $(patsubst %,$(OBJ_DIR)/%,$(_OBJ))

$(OBJ_DIR)/%.o: %.cpp $(DEPS)
$(CP) -c -o $@ $< $(CFLAGS)
tranquil: $(OBJ)
$(CP) -o ../bin/$@ $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJ_DIR)/*.o *~ core $(INC_DIR)/*~

显然无用的TranquilMain.cpp(只是依赖项中的第一个文件)

#include <iostream>
#include <fstream>
#include <string>

int main( int argc, char* args[] )
{
bool running = true;
while( running == true )
{
}
return 0;
}

当我从上面的 Makefile 和项目结构开始时

├── include/
└── src/
├── Makefile
├── TranquilMain.cpp
└── obj/

然后我收到与您上面报告的相同的make: *** No rule to make target `obj/TranquilMain.o', needed by `tranquil'.错误。这是什么原因造成的?让我们在调试模式下运行 make 来找出答案。

首先添加

.SUFFIXES:
%:: SCCS/s.%
%:: RCS/%
%:: RCS/%,v
%:: %,v
%:: s.%

以取消一些只会使调试输出混乱的默认规则。

然后,运行make -d

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Updating makefiles....
Considering target file `Makefile'.
Looking for an implicit rule for `Makefile'.
No implicit rule found for `Makefile'.
Finished prerequisites of target file `Makefile'.
No need to remake target `Makefile'.
Updating goal targets....
Considering target file `tranquil'.
File `tranquil' does not exist.
Considering target file `obj/TranquilMain.o'.
File `obj/TranquilMain.o' does not exist.
Looking for an implicit rule for `obj/TranquilMain.o'.
Trying pattern rule with stem `TranquilMain'.
Trying implicit prerequisite `TranquilMain.cpp'.
Trying rule prerequisite `../include/DefaultConfig.h'.
Trying pattern rule with stem `TranquilMain'.
Trying implicit prerequisite `TranquilMain.cpp'.
Trying rule prerequisite `../include/DefaultConfig.h'.
Looking for a rule with intermediate file `../include/DefaultConfig.h'.
Avoiding implicit rule recursion.
No implicit rule found for `obj/TranquilMain.o'.
Finished prerequisites of target file `obj/TranquilMain.o'.
Must remake target `obj/TranquilMain.o'.
make: *** No rule to make target `obj/TranquilMain.o', needed by `tranquil'.  Stop.

make首先确保Makefile是最新的。然后,它尝试通过执行深度优先搜索来使tranquil成为目标,构建所有必需的依赖项。tranquil取决于${OBJ},其第一个元素是obj/TranquilMain.o。根据${OBJDIR}/%.o规则,这取决于TranquilMain.cpp和所有${DEPS}${DEPS}的第一个元素是../include/DefaultConfig.h,所以make试图构建它。但它不存在,也没有规则来构建它。make得出结论,它不能使用此规则构建obj/TranquilMain.o,因为缺少依赖项。它尝试找到另一个规则来使用确实存在的其他依赖项来构建它,但没有这样的规则。所以make停了下来,说:"没有[有效的]规则[存在或可以构建依赖关系]来使目标obj/TranquilMain.o

解决方案是什么?确保所有依赖项都存在。使用此生成文件,要编译任何内容,您的项目必须至少包含:

.
├── include/
│   ├── BaseApplication.h
│   ├── BasePlugin.h
│   ├── DefaultConfig.h
│   ├── Math2D.h
│   ├── SDLApplication.h
│   ├── SDLFont.h
│   ├── SDLImage.h
│   ├── SDLInput.h
│   ├── SDLRenderer.h
│   ├── SDLTimer.h
│   └── SDLWindow.h
├── lib/
└── src/
├── BaseApplication.cpp
├── BasePlugin.cpp
├── Makefile
├── Math2D.cpp
├── SDLApplication.cpp
├── SDLFont.cpp
├── SDLImage.cpp
├── SDLInput.cpp
├── SDLRenderer.cpp
├── SDLTimer.cpp
├── SDLWindow.cpp
├── TranquilMain.cpp
└── obj/

您可能还需要将库文件添加到lib/才能获得最终的可执行文件。

此外,请确保您没有无意中将制表符变成空格。

规则必须以"选项卡"开头:

#BAD!
tranquil: $(OBJ)
<space><space>$(CP) -o ../bin/$@ $^ $(CFLAGS) $(LIBS)
#GOOD!
tranquil: $(OBJ)
<tab>$(CP) -o ../bin/$@ $^ $(CFLAGS) $(LIBS)

最新更新