包含 SDL2/SDL_Image 时 SDL 包含错误
SDL include error when including SDL2/SDL_Image
这是一个简单的 SDL2 程序,它使用 SDL_Image 并且运行良好:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
// Manage error messages
void check_error_sdl(bool check, const char* message);
void check_error_sdl_img(bool check, const char* message);
// Load an image from "fname" and return an SDL_Texture with the content of the image
SDL_Texture* load_texture(const char* fname, SDL_Renderer *renderer);
int main(int argc, char** argv) {
// Initialize SDL
check_error_sdl(SDL_Init(SDL_INIT_VIDEO) != 0, "Unable to initialize SDL");
// Create and initialize a 800x600 window
SDL_Window* window = SDL_CreateWindow("Test SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
check_error_sdl(window == nullptr, "Unable to create window");
// Create and initialize a hardware accelerated renderer that will be refreshed in sync with your monitor (at approx. 60 Hz)
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
check_error_sdl(renderer == nullptr, "Unable to create a renderer");
// Set the default renderer color to corn blue
SDL_SetRenderDrawColor(renderer, 100, 149, 237, 255);
// Initialize SDL_img
int flags=IMG_INIT_JPG | IMG_INIT_PNG;
int initted = IMG_Init(flags);
check_error_sdl_img((initted & flags) != flags, "Unable to initialize SDL_image");
// Load the image in a texture
SDL_Texture *texture = load_texture("img_test.png", renderer);
// We need to create a destination rectangle for the image (where we want this to be show) on the renderer area
SDL_Rect dest_rect;
dest_rect.x = 50; dest_rect.y = 50;
dest_rect.w = 337; dest_rect.h = 210;
// Clear the window content (using the default renderer color)
SDL_RenderClear(renderer);
// Copy the texture on the renderer
SDL_RenderCopy(renderer, texture, NULL, &dest_rect);
// Update the window surface (show the renderer)
SDL_RenderPresent(renderer);
// Wait for 10 seconds
SDL_Delay(5000);
// Clear the allocated resources
SDL_DestroyTexture(texture);
IMG_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
// In case of error, print the error code and close the application
void check_error_sdl(bool check, const char* message) {
if (check) {
std::cout << message << " " << SDL_GetError() << std::endl;
SDL_Quit();
std::exit(-1);
}
}
// In case of error, print the error code and close the application
void check_error_sdl_img(bool check, const char* message) {
if (check) {
std::cout << message << " " << IMG_GetError() << std::endl;
IMG_Quit();
SDL_Quit();
std::exit(-1);
}
}
// Load an image from "fname" and return an SDL_Texture with the content of the image
SDL_Texture* load_texture(const char* fname, SDL_Renderer *renderer) {
SDL_Surface *image = IMG_Load(fname);
check_error_sdl_img(image == nullptr, "Unable to load image");
SDL_Texture *img_texture = SDL_CreateTextureFromSurface(renderer, image);
check_error_sdl_img(img_texture == nullptr, "Unable to create a texture from the image");
SDL_FreeSurface(image);
return img_texture;
}
我编译它:
g++ -std=c++0x -Wall -pedantic sdl2_test.cpp -o sdl2_test `sdl2-config --cflags --libs` -lSDL2_image
它正确执行并显示图像。
但是在同一系统上我的游戏在编译时出现了这个错误:
g++ -c frogmain.cc
In file included from level.hh:2,
from game.hh:1,
from frogmain.cc:2:
/usr/local/include/SDL2/SDL_image.h:27:10: fatal error: SDL.h: No such file or directory
#include "SDL.h"
^~~~~~~
compilation terminated.
make: *** [makefile:5: frogmain.o] Error 1
这是我的 makefile:
FrogGame: frogmain.o game.o level.o sprite.o actor.o vector.o
g++ -std=c++0x -Wall -pedantic -o FrogGame frogmain.o game.o level.o sprite.o actor.o vector.o `sdl2-config --cflags --libs` -lSDL2_image
#g++ -o FrogGame frogmain.o game.o level.o sprite.o actor.o vector.o
frogmain.o: frogmain.cc game.hh level.hh sprite.hh vector.hh
g++ -c frogmain.cc
game.o: game.cc level.hh sprite.hh actor.hh vector.hh
g++ -c game.cc
level.o: level.cc sprite.hh actor.hh vector.hh
g++ -c level.cc
actor.o: actor.cc vector.hh
g++ -c actor.cc
sprite.o: sprite.cc vector.hh
g++ -c sprite.cc
vector.o: vector.cc
g++ -c vector.cc
唯一需要SDL的class是关卡class,这里是.cc文件:
#include <iostream>
#include <sys/time.h>
#include <chrono>
#include "level.hh"
#include "sprite.hh"
#include "actor.hh"
#include "vector.hh"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
using namespace std;
level::level()
{
this->levelPlaying = false;
this->levelPaused = false;
this->levelWon = false;
this->curTime = 0;
this->timeLimit = 0;
this->screen = 0;
this->renderer = 0;
this->imageArray = 0;
this->imLength = 0;
this->createScreen();
}
void level::setLevelPlaying(bool p)
{
this->levelPlaying = p;
}
bool level::getLevelPlaying()
{
return this->levelPlaying;
}
void level::setLevelPaused(bool p)
{
this->levelPlaying = p;
}
bool level::getLevelPaused()
{
return this->levelPlaying;
}
void level::setLevelWon(bool p)
{
this->levelWon = p;
}
bool level::getLevelWon()
{
return this->levelWon;
}
void level::setCurTime(int t)
{
this->curTime = t;
}
int level::getCurTime()
{
return this->curTime;
}
void level::setTimeLimit(int t)
{
this->timeLimit = t;
}
int level::getTimeLimit()
{
return this->timeLimit;
}
bool level::createScreen()
{
bool success = 0;
//get size of screen
SDL_DisplayMode dm;
SDL_GetDesktopDisplayMode(0, &dm);
if (dm.w < 1920 && dm.h < 1080)
{
screenW = dm.w;
screenH = dm.h;
}
else
{
screenW = 1920;
screenH = 1080;
}
success = this->checkSDLError(SDL_Init(SDL_INIT_EVERYTHING) == 0, "SDL Initialization failed");
this->screen = SDL_CreateWindow("Test SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screenW, screenH, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
success = this->checkSDLError(this->screen, "Window Initialization failed");
this->renderer = SDL_CreateRenderer(this->screen, -1, 0);
success = this->checkSDLError(this->renderer, "Renderer Initialization failed");
return success;
}
bool level::loadImageArrayToMemory(const char** imageNames, int length)
{
IMG_Init(IMG_INIT_PNG);
//allocate space for all textures
this->imageArray = new SDL_Texture*[length];
this->imLength = length;
//run through entire list
for (int i = 0; i < length; i++)
{
//load the image to a temp surface
SDL_Surface* tmp = IMG_Load(imageNames[i]);
this->checkSDLError(tmp, "Unable to load image");
//create a texture from the surface, for hardware rendering
this->imageArray[i] = SDL_CreateTextureFromSurface(this->renderer, tmp);
this->checkSDLError(imageArray[i], "Unable to create texture");
//destroy the surface
SDL_FreeSurface(tmp);
}
return 1;
}
bool level::destroyImageArrayFromMemory()
{
//loop through image array
for (int i = 0; i < this->imLength; i++)
{
//destroy the texture in each index of the array
SDL_DestroyTexture(imageArray[i]);
}
//delete the array
delete[] imageArray;
return 1;
}
bool level::loadSoundArrayToMemory()
{
//TODO
return 0;
}
bool level::destroySoundArrayFromMemory()
{
//TODO
return 0;
}
bool level::levelLoop()
{
const int TPF = 33;
auto curT = chrono::high_resolution_clock::now();
auto prevT = curT;
auto diff = 0;
vector p(4,5);
vector d(78,90);
actor a(p, d, 1, 100);
while (this->getLevelPlaying())
{
//create a destination rectangle for the images
SDL_Rect tmp;
tmp.x= 0;
tmp.y = 0;
tmp.w = 1920;
tmp.h = 1080;
//get current time
curT = chrono::high_resolution_clock::now();
//get the difference of the current time from the last time the screen was updated
diff = chrono::duration_cast<chrono::milliseconds>(curT - prevT).count();
if (diff > TPF)
{
//check for keyboard input
this->checkForInput();
//clear the screen
SDL_RenderClear(this->renderer);
//for every texture in the imageArray
for (int i = 0; i < imLength; i++)
{
tmp.x = tmp.x + 20;
tmp.y = tmp.y + 20;
// Copy the texture on the renderer
SDL_RenderCopy(this->renderer, this->imageArray[i], NULL, &tmp);
// Update the window surface (show the renderer)
SDL_RenderPresent(this->renderer);
}
prevT = curT;
//add to the current level time
this->curTime+=diff;
}
if (this->curTime > 4000)
{
this->setLevelPlaying(false);
}
}
//destroy images in memory to free up space and avoid leaks
this->destroyImageArrayFromMemory();
return this->getLevelWon();
}
void level::checkForInput()
{
cout << "inside checkforinput\n";
//create an empty event
//SDL_Event event;
//loop through all events in the queue
while (SDL_PollEvent(&event))
{
cout << "inside while loop\n";
switch(event.type)
{
//cout << "inside switch\n";
//a keyboard button is pressed down
case SDL_KEYDOWN:
cout << "inside case\n";
//if it is escape key
if (event.key.keysym.sym == SDLK_ESCAPE)
{
cout << "Escape key pressed" << endl;
this->setLevelPlaying(false);
}
else if (event.key.keysym.sym == SDLK_q)
{
cout << "Q key pressed" << endl;
}
continue;
default:
cout << "unhandled key pressed\n";
}
}
}
bool level::checkSDLError(bool c, const char* s)
{
if (c == 0)
{
std::cout << s << " " << SDL_GetError() << endl;
SDL_Quit();
return 0;
}
return 1;
}
我同时安装了 SDL2 和 SDL2Image。我的 makefile 是否有问题,这就是为什么我可以在这个简单的示例中使用 SDLImage 而不能在我的更复杂的程序中使用?我有另一个 raspberry pi,我的游戏的示例和 makefile 都可以正常工作。
当您 编译 .cc
[到 .o
].
您只传递用于 link .o
文件的 c++
行上的标志。
其中一个 .o
目标需要 sdl2-config
以及它的 c++
命令。
这是你的直接问题。然而...
当您执行以下操作时:sdl2-config --cflags
,它[部分] 生成(例如)-I/usr/local/include/SDL2
,因此如果源 .cc
文件执行了:#include <SDL.h>
,它就可以工作。
但是,您的 .cc
文件确实:#include <SDL2/SDL.h>
.
这可能行不通,因为它位于不同的目录级别 [除非您添加 -I/usr/local/include
,这是次优的,因为您硬连接了路径。
如果 可以正常工作,那是因为编译器假设 /usr/local/include
是 default 路径的一部分 .h
文件
更新:
You'll have to excuse me I'm not very good at compiling yet. I tried adding -I/usr/local/include/SDL2/SDL.h
in some different spots and it didn't change anything. Could you spell it out a bit more for me?
你不想要:-I/usr/local/include/SDL2/SDL.h
那指向一个文件。
你想要:-I/usr/local/include/SDL2
指向目录。
但是,您应该做 两件事:(1) 修复您的 makefile 和 (2) 更改 level.cc
中的 #include
指令以使其兼容
这是我对您的 makefile 所做的调整:
OBJS += frogmain.o
OBJS += game.o
OBJS += level.o
OBJS += sprite.o
OBJS += actor.o
OBJS += vector.o
SDLCFG := sdl2-config
CPLSDL = $(shell $(SDLCFG) --cflags)
LIBSDL = $(shell $(SDLCFG) --libs)
LIBSDL += -lSDL2_image
COPTS += -std=c++0x
COPTS += -Wall
COPTS += -Werror
COPTS += -pedantic
FrogGame: $(OBJS)
g++ -o FrogGame $(OBJS) $(LIBSDL)
frogmain.o: frogmain.cc game.hh level.hh sprite.hh vector.hh
g++ -c $(COPTS) frogmain.cc
game.o: game.cc level.hh sprite.hh actor.hh vector.hh
g++ -c $(COPTS) game.cc
level.o: level.cc sprite.hh actor.hh vector.hh
g++ -c $(COPTS) $(CPLSDL) level.cc
actor.o: actor.cc vector.hh
g++ -c $(COPTS) actor.cc
sprite.o: sprite.cc vector.hh
g++ -c $(COPTS) sprite.cc
vector.o: vector.cc
g++ -c $(COPTS) vector.cc
clean:
rm -f $(OBJS) FrogGame
如果你从那里复制粘贴,TAB
应该是四个空格 [因为这里的代码块是如何格式化的]。因此,您需要手动编辑以将其改回。 (即 make
对前导 TAB
很挑剔)。
在 level.cc
中,您有以下两个 #include
指令:
#include <SDL2/SDL.h>
#include <SDL2/SDL_Image.h>
你想要:
#include <SDL.h>
#include <SDL_Image.h>
这是一个简单的 SDL2 程序,它使用 SDL_Image 并且运行良好:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
// Manage error messages
void check_error_sdl(bool check, const char* message);
void check_error_sdl_img(bool check, const char* message);
// Load an image from "fname" and return an SDL_Texture with the content of the image
SDL_Texture* load_texture(const char* fname, SDL_Renderer *renderer);
int main(int argc, char** argv) {
// Initialize SDL
check_error_sdl(SDL_Init(SDL_INIT_VIDEO) != 0, "Unable to initialize SDL");
// Create and initialize a 800x600 window
SDL_Window* window = SDL_CreateWindow("Test SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
check_error_sdl(window == nullptr, "Unable to create window");
// Create and initialize a hardware accelerated renderer that will be refreshed in sync with your monitor (at approx. 60 Hz)
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
check_error_sdl(renderer == nullptr, "Unable to create a renderer");
// Set the default renderer color to corn blue
SDL_SetRenderDrawColor(renderer, 100, 149, 237, 255);
// Initialize SDL_img
int flags=IMG_INIT_JPG | IMG_INIT_PNG;
int initted = IMG_Init(flags);
check_error_sdl_img((initted & flags) != flags, "Unable to initialize SDL_image");
// Load the image in a texture
SDL_Texture *texture = load_texture("img_test.png", renderer);
// We need to create a destination rectangle for the image (where we want this to be show) on the renderer area
SDL_Rect dest_rect;
dest_rect.x = 50; dest_rect.y = 50;
dest_rect.w = 337; dest_rect.h = 210;
// Clear the window content (using the default renderer color)
SDL_RenderClear(renderer);
// Copy the texture on the renderer
SDL_RenderCopy(renderer, texture, NULL, &dest_rect);
// Update the window surface (show the renderer)
SDL_RenderPresent(renderer);
// Wait for 10 seconds
SDL_Delay(5000);
// Clear the allocated resources
SDL_DestroyTexture(texture);
IMG_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
// In case of error, print the error code and close the application
void check_error_sdl(bool check, const char* message) {
if (check) {
std::cout << message << " " << SDL_GetError() << std::endl;
SDL_Quit();
std::exit(-1);
}
}
// In case of error, print the error code and close the application
void check_error_sdl_img(bool check, const char* message) {
if (check) {
std::cout << message << " " << IMG_GetError() << std::endl;
IMG_Quit();
SDL_Quit();
std::exit(-1);
}
}
// Load an image from "fname" and return an SDL_Texture with the content of the image
SDL_Texture* load_texture(const char* fname, SDL_Renderer *renderer) {
SDL_Surface *image = IMG_Load(fname);
check_error_sdl_img(image == nullptr, "Unable to load image");
SDL_Texture *img_texture = SDL_CreateTextureFromSurface(renderer, image);
check_error_sdl_img(img_texture == nullptr, "Unable to create a texture from the image");
SDL_FreeSurface(image);
return img_texture;
}
我编译它:
g++ -std=c++0x -Wall -pedantic sdl2_test.cpp -o sdl2_test `sdl2-config --cflags --libs` -lSDL2_image
它正确执行并显示图像。
但是在同一系统上我的游戏在编译时出现了这个错误:
g++ -c frogmain.cc
In file included from level.hh:2,
from game.hh:1,
from frogmain.cc:2:
/usr/local/include/SDL2/SDL_image.h:27:10: fatal error: SDL.h: No such file or directory
#include "SDL.h"
^~~~~~~
compilation terminated.
make: *** [makefile:5: frogmain.o] Error 1
这是我的 makefile:
FrogGame: frogmain.o game.o level.o sprite.o actor.o vector.o
g++ -std=c++0x -Wall -pedantic -o FrogGame frogmain.o game.o level.o sprite.o actor.o vector.o `sdl2-config --cflags --libs` -lSDL2_image
#g++ -o FrogGame frogmain.o game.o level.o sprite.o actor.o vector.o
frogmain.o: frogmain.cc game.hh level.hh sprite.hh vector.hh
g++ -c frogmain.cc
game.o: game.cc level.hh sprite.hh actor.hh vector.hh
g++ -c game.cc
level.o: level.cc sprite.hh actor.hh vector.hh
g++ -c level.cc
actor.o: actor.cc vector.hh
g++ -c actor.cc
sprite.o: sprite.cc vector.hh
g++ -c sprite.cc
vector.o: vector.cc
g++ -c vector.cc
唯一需要SDL的class是关卡class,这里是.cc文件:
#include <iostream>
#include <sys/time.h>
#include <chrono>
#include "level.hh"
#include "sprite.hh"
#include "actor.hh"
#include "vector.hh"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
using namespace std;
level::level()
{
this->levelPlaying = false;
this->levelPaused = false;
this->levelWon = false;
this->curTime = 0;
this->timeLimit = 0;
this->screen = 0;
this->renderer = 0;
this->imageArray = 0;
this->imLength = 0;
this->createScreen();
}
void level::setLevelPlaying(bool p)
{
this->levelPlaying = p;
}
bool level::getLevelPlaying()
{
return this->levelPlaying;
}
void level::setLevelPaused(bool p)
{
this->levelPlaying = p;
}
bool level::getLevelPaused()
{
return this->levelPlaying;
}
void level::setLevelWon(bool p)
{
this->levelWon = p;
}
bool level::getLevelWon()
{
return this->levelWon;
}
void level::setCurTime(int t)
{
this->curTime = t;
}
int level::getCurTime()
{
return this->curTime;
}
void level::setTimeLimit(int t)
{
this->timeLimit = t;
}
int level::getTimeLimit()
{
return this->timeLimit;
}
bool level::createScreen()
{
bool success = 0;
//get size of screen
SDL_DisplayMode dm;
SDL_GetDesktopDisplayMode(0, &dm);
if (dm.w < 1920 && dm.h < 1080)
{
screenW = dm.w;
screenH = dm.h;
}
else
{
screenW = 1920;
screenH = 1080;
}
success = this->checkSDLError(SDL_Init(SDL_INIT_EVERYTHING) == 0, "SDL Initialization failed");
this->screen = SDL_CreateWindow("Test SDL 2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screenW, screenH, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
success = this->checkSDLError(this->screen, "Window Initialization failed");
this->renderer = SDL_CreateRenderer(this->screen, -1, 0);
success = this->checkSDLError(this->renderer, "Renderer Initialization failed");
return success;
}
bool level::loadImageArrayToMemory(const char** imageNames, int length)
{
IMG_Init(IMG_INIT_PNG);
//allocate space for all textures
this->imageArray = new SDL_Texture*[length];
this->imLength = length;
//run through entire list
for (int i = 0; i < length; i++)
{
//load the image to a temp surface
SDL_Surface* tmp = IMG_Load(imageNames[i]);
this->checkSDLError(tmp, "Unable to load image");
//create a texture from the surface, for hardware rendering
this->imageArray[i] = SDL_CreateTextureFromSurface(this->renderer, tmp);
this->checkSDLError(imageArray[i], "Unable to create texture");
//destroy the surface
SDL_FreeSurface(tmp);
}
return 1;
}
bool level::destroyImageArrayFromMemory()
{
//loop through image array
for (int i = 0; i < this->imLength; i++)
{
//destroy the texture in each index of the array
SDL_DestroyTexture(imageArray[i]);
}
//delete the array
delete[] imageArray;
return 1;
}
bool level::loadSoundArrayToMemory()
{
//TODO
return 0;
}
bool level::destroySoundArrayFromMemory()
{
//TODO
return 0;
}
bool level::levelLoop()
{
const int TPF = 33;
auto curT = chrono::high_resolution_clock::now();
auto prevT = curT;
auto diff = 0;
vector p(4,5);
vector d(78,90);
actor a(p, d, 1, 100);
while (this->getLevelPlaying())
{
//create a destination rectangle for the images
SDL_Rect tmp;
tmp.x= 0;
tmp.y = 0;
tmp.w = 1920;
tmp.h = 1080;
//get current time
curT = chrono::high_resolution_clock::now();
//get the difference of the current time from the last time the screen was updated
diff = chrono::duration_cast<chrono::milliseconds>(curT - prevT).count();
if (diff > TPF)
{
//check for keyboard input
this->checkForInput();
//clear the screen
SDL_RenderClear(this->renderer);
//for every texture in the imageArray
for (int i = 0; i < imLength; i++)
{
tmp.x = tmp.x + 20;
tmp.y = tmp.y + 20;
// Copy the texture on the renderer
SDL_RenderCopy(this->renderer, this->imageArray[i], NULL, &tmp);
// Update the window surface (show the renderer)
SDL_RenderPresent(this->renderer);
}
prevT = curT;
//add to the current level time
this->curTime+=diff;
}
if (this->curTime > 4000)
{
this->setLevelPlaying(false);
}
}
//destroy images in memory to free up space and avoid leaks
this->destroyImageArrayFromMemory();
return this->getLevelWon();
}
void level::checkForInput()
{
cout << "inside checkforinput\n";
//create an empty event
//SDL_Event event;
//loop through all events in the queue
while (SDL_PollEvent(&event))
{
cout << "inside while loop\n";
switch(event.type)
{
//cout << "inside switch\n";
//a keyboard button is pressed down
case SDL_KEYDOWN:
cout << "inside case\n";
//if it is escape key
if (event.key.keysym.sym == SDLK_ESCAPE)
{
cout << "Escape key pressed" << endl;
this->setLevelPlaying(false);
}
else if (event.key.keysym.sym == SDLK_q)
{
cout << "Q key pressed" << endl;
}
continue;
default:
cout << "unhandled key pressed\n";
}
}
}
bool level::checkSDLError(bool c, const char* s)
{
if (c == 0)
{
std::cout << s << " " << SDL_GetError() << endl;
SDL_Quit();
return 0;
}
return 1;
}
我同时安装了 SDL2 和 SDL2Image。我的 makefile 是否有问题,这就是为什么我可以在这个简单的示例中使用 SDLImage 而不能在我的更复杂的程序中使用?我有另一个 raspberry pi,我的游戏的示例和 makefile 都可以正常工作。
当您 编译 .cc
[到 .o
].
您只传递用于 link .o
文件的 c++
行上的标志。
其中一个 .o
目标需要 sdl2-config
以及它的 c++
命令。
这是你的直接问题。然而...
当您执行以下操作时:sdl2-config --cflags
,它[部分] 生成(例如)-I/usr/local/include/SDL2
,因此如果源 .cc
文件执行了:#include <SDL.h>
,它就可以工作。
但是,您的 .cc
文件确实:#include <SDL2/SDL.h>
.
这可能行不通,因为它位于不同的目录级别 [除非您添加 -I/usr/local/include
,这是次优的,因为您硬连接了路径。
如果 可以正常工作,那是因为编译器假设 /usr/local/include
是 default 路径的一部分 .h
文件
更新:
You'll have to excuse me I'm not very good at compiling yet. I tried adding
-I/usr/local/include/SDL2/SDL.h
in some different spots and it didn't change anything. Could you spell it out a bit more for me?
你不想要:-I/usr/local/include/SDL2/SDL.h
那指向一个文件。
你想要:-I/usr/local/include/SDL2
指向目录。
但是,您应该做 两件事:(1) 修复您的 makefile 和 (2) 更改 level.cc
中的 #include
指令以使其兼容
这是我对您的 makefile 所做的调整:
OBJS += frogmain.o
OBJS += game.o
OBJS += level.o
OBJS += sprite.o
OBJS += actor.o
OBJS += vector.o
SDLCFG := sdl2-config
CPLSDL = $(shell $(SDLCFG) --cflags)
LIBSDL = $(shell $(SDLCFG) --libs)
LIBSDL += -lSDL2_image
COPTS += -std=c++0x
COPTS += -Wall
COPTS += -Werror
COPTS += -pedantic
FrogGame: $(OBJS)
g++ -o FrogGame $(OBJS) $(LIBSDL)
frogmain.o: frogmain.cc game.hh level.hh sprite.hh vector.hh
g++ -c $(COPTS) frogmain.cc
game.o: game.cc level.hh sprite.hh actor.hh vector.hh
g++ -c $(COPTS) game.cc
level.o: level.cc sprite.hh actor.hh vector.hh
g++ -c $(COPTS) $(CPLSDL) level.cc
actor.o: actor.cc vector.hh
g++ -c $(COPTS) actor.cc
sprite.o: sprite.cc vector.hh
g++ -c $(COPTS) sprite.cc
vector.o: vector.cc
g++ -c $(COPTS) vector.cc
clean:
rm -f $(OBJS) FrogGame
如果你从那里复制粘贴,TAB
应该是四个空格 [因为这里的代码块是如何格式化的]。因此,您需要手动编辑以将其改回。 (即 make
对前导 TAB
很挑剔)。
在 level.cc
中,您有以下两个 #include
指令:
#include <SDL2/SDL.h>
#include <SDL2/SDL_Image.h>
你想要:
#include <SDL.h>
#include <SDL_Image.h>