Why I get an error when including sdl image?

I set SDL2 and SDL_image 2 in Code::Blocks on windows and now I get an error: “fatal error: SDL.h: No such file or directory” Can someone help, everything seems okay. My includes look like this:

#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

The error is in SDL_Image.h line 27: #include “SDL.h” . It works fine only with SDL, the problem is in SDL_image. What do you suggest?

Fixed: I included SDL2 in the compiler path. I was wondering which IDE should I use for sdl and I came to conclusion, that Code:Blocks is a good one.

The official stance of SDL folks is that there’s no canonical place where the SDL2 headers are supposed to go, and so developers should put the headers wherever they like and just add that location to the compiler’s project header search path so that SDL.h can be accessed via #include "SDL.h".

They even conveniently ship a handy sdl2-config executable to help you do that (if your build system supports it), or a sdl2-config.cmake cmake package script if you’re a cmake user.

But with that said, yes, everything puts the header files inside an SDL2 folder and Linux/Mac distributions tend to put that inside a default system include path, and so it’s kind of natural to want to want to include them using <SDL2/SDL.h>. But you’re supposed to use sdl-config or sdl2-config.cmake to map that SDL2 directory as a project include path and then do #include "SDL.h" in your code to include the headers via that project include path, instead of via the absolute system path.

(but I’ll confess that I’ve never actually done that and I’ve more than once been guilty of editing SDL_image.h’s #include line to just Make It Work. I am very sorry, Sam! :cry:)

To make it more exciting, Apple now requires framework headers to have the prefix of the name of the framework, so there’s a script that turns all the SDL header includes into <SDL2/blah.h>

sigh

We’ll probably switch header includes styles at some point as well.

Yeah, I was banging into that earlier today. After writing the post above I finally said "You know, I should try setting it all up the canonically correct way and see what it’s like, using sdl2-config.cmake (as I’m one of those cmake users I mentioned)

…and it’s actually pretty great, apart from that framework issue you mention! (which I guess I could avoid by using SDL2 as a bare dylib or even just statically linking it)

I kind of wish I’d looked into how to use the cmake configuration scripts before; it likely would have saved me a bunch of time setting up my project!

@slouken I wasn’t aware they’re now requiring it, but Xcode has been giving warnings about it for a while now. To be fair, that’s how everyone was already doing it on macOS and iOS, except for SDL and a couple of others.

Honestly, I always thought it was kind of… unfortunate that SDL docs recommend projects use quoted includes instead of just #include <SDL2/SDL.h>, since on macOS it means editing the project settings to have an include path that points inside SDL2.framework, which is kind of gross.

use quoted includes instead of just #include <SDL2/SDL.h>

I don’t think this has anything to do with quoted, you could as well do #include <SDL.h> in the usual setup.

it means editing the project settings to have an include path that points inside SDL2.framework, which is kind of gross

Apple dictating a style of includes for crossplatform-libs (so it affects everyone) is also kinda gross :person_shrugging:

Quotes versus angle brackets in a #include statement have very different meanings, as defined by the C/C++ language standards. Although lots of compiilers let you get away with being lax about them these days.

→ Note: I’m certain you already know everything in this post, @Daniel_Gibson; I’m just posting this for newer coders reading the topic so they don’t take the wrong idea away from the conversation. This whole post is kind of one long “and technically correct is the best kind of correct” comment, and I apologise for that in advance!

Canonically, #include <header.h> is supposed to search for a file “header.h” which is included with the compiler toolchain, such as <stdlib.h> and <math.h> (and on Unix systems this has kind of expanded to include everything in /usr/include, /usr/local/include, and a couple other locations. Effectively, headers which have been ‘installed’ into system-recognised paths). These headers are supposed to be considered “owned” by the compiler toolchain.

Conversely, #include “header.h” is supposed to search for a file “header.h” which is not in one of those paths, and will generally first search in the same directory as the file being (pre)processed.

But with all of that said, lots of modern compilers now search everywhere for everything, and it’s only if a file with a given name exists both within the project and in somewhere in the system header search paths that it really matters. Like, if your project has a file named “stdio.h” in it, then #include “stdio.h” will include your project’s local file, and #include <stdio.h> will include the system one. But this permissive behaviour isn’t standard or guaranteed, it’s just what a lot of implementations happen to do at the moment.

1 Like

I think the meaning is a bit different, though if I understand Source file inclusion - cppreference.com correctly, most of it is implementation-defined anyway.

Usually #include <header.h> searches the compiler/toolchain standard paths (as you said) and the directories passed to the compiler with -I (see gcc docs) - or, in case of Visual C++, /I (see MSVC docs).
Or, as cppreference.com (for C) puts it (emphasis mine):

(1) Searches for the file in implementation-defined manner. The intent of this syntax is to search for the files under control of the implementation. Typical implementations search only standard include directories. The standard C++ library and the standard C library are implicitly included in these standard include directories. The standard include directories usually can be controlled by the user through compiler options.

#include "header.h" first tries searching paths relative to the current source file (meaning, in the same directory, or if you use #include "../bla/header.h" it looks in the bla/ subdirectory of the parent-directory of the current source file).
If it can’t find the header there, it will search the same paths as #include <header.h>, i.e. the ones specified with -I or /I and system/compiler default directories.
Or, in the words of cppreference:

(2) Searches for the file in implementation-defined manner. The intent of this syntax is to search for the files that are not controlled by the implementation. Typical implementations first search the directory where the current file resides and, only if the file is not found, search the standard include directories as with (1).

So including SDL.h with <> should be totally fine, unless for some reason it’s in a directory that’s relative to the current source file (and not in the compiler search directories, including the ones specified with -I)