我刚刚学习 SDL 并完成了twinklebear 教程。在我开始将代码拆分为多个文件后,我的 makefile 停止工作,我不得不手动编译它。它说:
make: *** No rule to make target `main.o', needed by `ooptest'. Stop.
当我使用类似的规则时.cxx.o:
,或者,如果我为我的所有规则制定单独的规则.cxx
:
g++ main.o -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib -o ooptest
main.o: In function `main':
main.cxx:(.text+0x247): undefined reference to `init(SDL_Window**, SDL_Renderer**)'
main.cxx:(.text+0x42e): undefined reference to `quit(SDL_Window**, SDL_Renderer**)'
collect2: error: ld returned 1 exit status
make: *** [ooptest] Error 1
我知道这是因为它只链接 main.o 而没有其他文件,但我不知道为什么。
以下是 7 个相关文件(除非它们有助于解决问题,否则请跳过这些文件,我不知道如何将它们放入扰流板或其他东西中):makefile:
CXX = g++
SRCS = main.cxx init.cxx quit.cxx
SDL_LIB = -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib
SDL_INCLUDE = -I/usr/local/include
CXXFLAGS = -Wall -c -std=c++11 $(SDL_INCLUDE)
LDFLAGS = $(SDL_LIB)
OBJS = $(SRCS:.cxx=.o)
EXE = ooptest
all: $(EXE) $(SRCS)
$(EXE): $(OBJS)
$(CXX) $< $(LDFLAGS) -o $@
main.o:
$(CXX) $(CXXFLAGS) main.cxx -o $@
init.o:
$(CXX) $(CXXFLAGS) init.cxx -o $@
quit.o:
$(CXX) $(CXXFLAGS) quit.cxx -o $@
#.cxx.o:
# $(CXX) $(CXXFLAGS) $< -o $@
clean:
rm *.o && rm $(EXE)
主.h:
#ifndef _MAIN_
#define _MAIN_
#include <string>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
const int WIDTH=640;
const int HEIGHT=480;
void lgErr(std::string);
SDL_Texture*loadTex(const std::string&,SDL_Renderer*);
void renderTex(SDL_Texture*,SDL_Renderer*,int,int);
int main(void);
#endif
主.cxx:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
#include "quit.h"
using namespace std;
void lgErr(string msg){
cout<<msg<<" error: "<<SDL_GetError()<<endl;
}
SDL_Texture* loadTex(const string &file,SDL_Renderer *ren){
SDL_Texture *tex=0;
SDL_Surface *img=SDL_LoadBMP(file.c_str());
if(img){
tex=SDL_CreateTextureFromSurface(ren,img);
SDL_FreeSurface(img);
if(tex==0)lgErr("CreateTextureFromSurface");
}else
lgErr("LoadBMP");
return tex;
}
void renderTex(SDL_Texture *tex,SDL_Renderer *ren,int x,int y){
SDL_Rect dst;
dst.x=x;dst.y=y;
SDL_QueryTexture(tex,NULL,NULL,&dst.w,&dst.h);
SDL_RenderCopy(ren,tex,NULL,&dst);
}
int main(){
SDL_Window *win;
SDL_Renderer *ren;
init(&win,&ren);
SDL_Texture *bg=loadTex("bg.bmp",ren);
SDL_Texture *fg=loadTex("fg.bmp",ren);
if(bg==0 || fg==0)return 4;
int bw,bh;
SDL_QueryTexture(bg,NULL,NULL,&bw,&bh);
SDL_RenderClear(ren);
for(int i=0;i<WIDTH;i+=bw)
for(int j=0;j<HEIGHT;j+=bh)
renderTex(bg,ren,i,j);
int fw,fh;
SDL_QueryTexture(fg,NULL,NULL,&fw,&fh);
int x=WIDTH/2-fw/2;
int y=HEIGHT/2-fh/2;
renderTex(fg,ren,x,y);
SDL_RenderPresent(ren);
SDL_Delay(2000);
SDL_DestroyTexture(bg);
SDL_DestroyTexture(fg);
quit(&win,&ren);
}
初始化.h:
#ifndef _INIT_
#define _INIT_
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
int init(SDL_Window**,SDL_Renderer**);
#endif
初始化.cxx:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "quit.h"
using namespace std;
int init(SDL_Window** win,SDL_Renderer** ren){
if(SDL_Init(SDL_INIT_EVERYTHING)!=0){
lgErr("SDL_Init");
return 1;
}
*win=SDL_CreateWindow("Lesson 2",100,100,WIDTH,HEIGHT,SDL_WINDOW_SHOWN);
if(*win==0){
lgErr("CreateWindow");
return 2;
}
*ren=SDL_CreateRenderer(*win,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(*ren==0){
lgErr("CreateRenderer");
return 3;
}
return 0;
}
退出.h:
#ifndef _QUIT_
#define _QUIT_
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void quit(SDL_Window**,SDL_Renderer**);
#endif
退出.cxx:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
void quit(SDL_Window** win,SDL_Renderer** ren){
SDL_DestroyRenderer(*ren);
SDL_DestroyWindow(*win);
SDL_Quit();
}
最后,我将GNU Make 3.81
、g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
和 SDL2 与图像库一起使用。
.cpp.o 的 makefile 规则和 $(EXE) 的规则有什么问题?另外,我是否正确使用#include?