Why is `libSDL2-dev` required when building SDL2 statically?

Hi

I have tried to build a project on Zorin OS, and tried to link it with a statically built SDL2 lib (v2.0.20). But when I try and compile my sources, I get the following error:

fatal error: SDL2/SDL.h: No such file or directory
   19 | #include <SDL2/SDL.h>

However, this error goes away when I installed libSDL2-dev. Why aren’t the static headers being recognized (and thus forcing me to install libSDL2-dev system headers to force compilation)?

Why *-dev packages on stackoverflow

statically built SDL2

I’m pretty sure you need *-dev packages for the static *.a files, does zorin do it differently?

Why aren’t the static headers being recognized

I haven’t really heard of the term “static headers”, what do you mean by that?

The header files (*.h) are required because C requires forward declaration

This is not a SDL specific problem but a C one because it will happen with any library if it’s header file is not found.

I haven’t really heard of the term “static headers”, what do you mean by that?

Yeah, I didn’t say that part very well. I was referring to the include headers in the SDL 2.0.20 release version which I’m statically linking to, and not the system installed headers (which are installed with the dynamically linked .so libs (libSDL2-dev)).

The header files (*.h) are required because C requires [forward declaration]

But what I’m having issues with is trying to “force” the compiler to use the headers that come with the release version, and not the ones that get installed on my system in usr/include/SDL. I have used include_directories(SDL/include) in my makelists file, but strangely enough it doesn’t find them

Try looking in the SDL/include directory, if SDL/include contains SDL.h and not SDL2/SDL.h you could just replace the include directive with #include <SDL.h>.

Otherwise, if there isn’t a directory called SDL2 in SDL/include which contains SDL.h then that’s not the directory you should be including.

I’m guessing you didn’t install the compiled version (will be installed to /usr/local by default) which is why you’re including it separately instead of using sdl2-config.

Ok thanks for the tips. I’ll try and search for the SDL/include folder when I’m back on my zorin boot

I’m guessing you didn’t install the compiled version

Yeah I didn’t run make install on the compiled one. I thought it is enough to just use target_include_directories(<target> PUBLIC path/to/SDL/include) (or include_directories), where path/to/SDL/include points to the headers in the compiled version

I recommend including SDL like this:
#include “SDL.h”

Alright, seems like SDL2 folder doesn’t exist on zorin, only SDL. So #include “SDL.h” as suggested in the replies above is probably the solution. Although I have tried to compile my project after upgrading some packages on zorin, and for some reason I get some new build errors which I didn’t get before. I might open a future issue detailing what the errors are, but for now I’ll probably leave zorin for doing dev projects

I’ve changed the SDL include to be #include "SDL.h", but it now throws an error on another distro I’m using (not zorin, but manjaro):

fatal error: SDL.h: No such file or directory
   19 | #include "SDL.h"

Also tried it with the angle brackets ( #include <SDL.h>) but I still get an error

How are you compiling the program that throws the error?

Knowing archlinux, sdl2 is required by a lot of other programs including ffmpeg, so I’m guessing it’s installed. if it’s not do sudo pacman -S sdl2. You can also do pacman -Fl sdl2 to list out all the files that are installed and pacman -Fl sdl2 | grep SDL.h will get the path where the header files are installed.

if your building from source, just do sudo make install. If you don’t want to install it, create a shell script or something with the name sdl2-config which outputs the appropriate flags that you need and place it on your PATH before the other sdl2-config.

Don’t really bother to statically link it (at least for linux) because sdl is available at pretty much every distro. Then use this command to compile source.c.

 cc source.c `sdl2-config --cflags`

The source code for source.c

#include "SDL.h"
int main(){}

You could also do cc source.c -I<SDL_INCLUDE_DIR> where <SDL_INCLUDE_DIR> is replaced with the appropriate directory that contains SDL.h. Though I do not recommend this because it might not be the same in different distros / environment. sdl2-config and pkg-config provide a convenient way to pass the required flags for a library to the compiler that can be changed by the distro maintainers when needed.

if this works it might be a problem with your build system.

Otherwise, look at what sdl2-config actually outputs by doing sdl2-config --cflags on it’s own without using it for command substitution. If it outputs the same error, compare what’s given by sdl2-config with the -I flag and compare it to the directory where the SDL2 include directory is located. See if the directory actually exists and that there’s a SDL.h file in there.

I’ll also encourage you to learn the c compilation process. Learn the c preprocessor, compiling (creating an object file) and linking. Learning assembly may help. In your case the problem was at the preprocessing stage and can be reproduced by doing cpp source.c or cc -E source.c. By the way, there’s no reason for you to try #include <file.h> after doing #include "file.h" since the former only searches in predefined directories while the latter searches in the directory the header was included from and in the predefined directories.

Also, next time when you ask try to give more information like the command used to compile and try to give the smallest possible test case where the problem can be replicated. Without knowing what you did, we can’t replicate it and can’t really help you. If you’re wondering why this reply is long, it’s because I can’t really assume anything since you didn’t give enough information.

Possibly helpful links:
http://catb.org/~esr/faqs/smart-questions.html

if it’s not do sudo pacman -S sdl2.

Yeah, that’s already installed on my manjaro system

Don’t really bother to statically link it (at least for linux) because sdl is available at pretty much every distro

Fair point, but Ideally i’d like to pack the lib inside the binary, and reduce the number of dynamically linked lib dependencies. So static liking is the route I am taking here.

Then use this command to compile source.c.

Ok I should clarify. I am using SDL in a cpp project, and writing makelists.txt files for the build. So running those compiler commands directly inside the terminal is not necessary, as it’s handled auto by the build system.

I’ll also encourage you to learn the c compilation process. Learn the c preprocessor, compiling (creating an object file) and linking.

Oh don’t worry about that, I have an adequate understanding of c and cpp build process :wink:

there’s no reason for you to try #include <file.h> after doing #include "file.h"

Yes I know that. But I intentionally included it in my previous post to reply to both you and slouken, which suggested I use #include “SDL.h”. That way I prove that I’ve read both your replies and am not being negligent :slight_smile:

Also, next time when you ask try to give more information like the command used to compile and try to give the smallest possible test case where the problem can be replicated

I think there is a decent amount of info from previous posts to clarify my issue. Although I should have added, that I am including SDL in a Cpp project, and the make is being used to compile. To re-iterate – I am trying to add SDL statically to my project (in order to reduce number of dyn linked libs to the binary). A simple test case would be this:
(1) create a blank main.cpp file, and add #include <SDL.h> at the top
(2) add download the zipped version of SDL 2.0.20, and in the makelists.txt, add_subdirectory(SDL) [also target_link_libraries( <target> SDL2-static) and target_link_directories(<target> SDL) ]
(3) generate make files and run make -j<number of proc>
(4) error reported above

Your distro’s SDL2 developer package (libSDL2-dev) is installing the headers in an SDL2 subdirectory of /usr/include or /usr/local/include, which the compiler already knows about. So it’s able to find an include file called SDL2/SDL.h since the path works out to something like /usr/include/SDL2/SDL.h

Trying to use the headers directly out of the zip file doesn’t work with this, since the path will be something like /home/foo/SDL-2.0.20/include/SDL.h and doesn’t contain an SDL2 subdirectory.

You could always make a directory in your project called SDL2, put the headers in there, and then point CMake at that directory with target_include_directories or whatever. Advantage there would be having the headers in your source control (you should also do this with the static libraries you’re using, if that’s the route you’re going down), so if you have to roll back to an earlier version of your project you’ll have the version of SDL it was built with too.

Thanks ver much for the explanation, that clears it up.

You could always make a directory in your project called SDL2, put the headers in there, and then point CMake at that directory with target_include_directories or whatever.

Cool, sounds like the best option for this case! Thanks