Search code examples
c++sdl-2undefined-reference

SDL.h No such file or directory in VSCode


I'm trying to add the relevant "-I"path_to_your_SDL_include_directory"" as outlined in several similar posts such as this one. I have tried three approaches;, adding it to tasks.json, Makefile and c_cpp_properties.json.

My file structure is as follows. My main.cpp is in MyProject/src. I have copied all the contents of SDL's include folder to MyProject/lib/SDL2_lib/include and copied the lib folder to MyProject/lib/SDL2_lib/lib. SDL2.dll lives in MyProject/lib/SDL2_lib.

The following is a visual summary as well as my code.

File Structure

main.cpp

#include <iostream>
#include <SDL.h>


const int WIDTH = 800, HEIGHT = 600;

int main( int argc, char *argv[] )
{
    SDL_Init( SDL_INIT_EVERYTHING );

    SDL_Window *window = SDL_CreateWindow( "Hello SDL WORLD", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI );

    if ( NULL == window )
    {
        std::cout << "Could not create window: " << SDL_GetError( ) << std::endl;
        return 1;
    }

    SDL_Event windowEvent;

    while ( true )
    {
        if ( SDL_PollEvent( &windowEvent ) )
        {
            if ( SDL_QUIT == windowEvent.type )
            { break; }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit( );

    return EXIT_SUCCESS;
}

Makefile

all:
    g++ -I lib/SDL2_lib/include -Llib/SDL2_lib/lib -o Main src/main.cpp

tasks.json

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe build active file",
            "command": "C:\\MinGW\\bin\\g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-I lib/SDL2_lib/include",
                "-L lib/SDL2_lib/lib",
                "-lmingw32",
                "-lSDL2main",
                "-lSDL2",
                "-o",
                "${workspaceFolder}/bin\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "${workspaceFolder}/lib/SDL2_lib/include"
                        ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:\\MinGW\\bin\\g++.exe",
            "cStandard": "gnu11",
            "cppStandard": "c++14",
            "intelliSenseMode": "windows-gcc-x86",
            "configurationProvider": "ms-vscode.makefile-tools",
            "compilerArgs": [
                "-I lib/SDL2_lib/include",
                "-L lib/SDL2_lib/lib",
                "-lmingw32",
                "-lSDL2main",
                "-lSDL2"
            ]
        }
    ],
    "version": 4
}

Despite all this, I am getting the error:

enter image description here

Edit: I should also add that adding a random file name instead of SDL.h underlines the entire include statement instead of just the end. So clearly, VSCode does know it exists, its just not adding it to the program which is what I'm guessing

Edit2: Running make from powershell gives the following error:

enter image description here


Solution

  • It is clear that you have two problems.

    1. The VSCode's C++ extension complains about the file SDL2.h
    2. There's a linking problem when you compile from your Makefile

    Let's address the Makefile thing first:

    There's a typo in your Makefile, it says SDL2_lib/libr instead of SDL2_lib/lib.

    After fixing that, you must add the libraries to link with. Technically, you only need libSDL2.la (assuming dynamic linking) since you already wrote your own main() function (therefore you don't need SDL2main.

    So, the command line in your Makefile should look like this (note how I put the project's files before the libs to guarantee symbols are loaded correctly, this becomes more important when using intermediate files):

    g++ -Ilib/SDL2_lib/include -Llib/SDL2_lib/lib src/main.cpp \
        -lmingw32 -lSDL2main -lSDL2 -mwindows \
        -o Main
    

    If that doesn't work, please provide the compiler output (as text, not image) but not before trying this:

    Option one: Specify the whole library's filename:

    g++ -Ilib/SDL2_lib/include -Llib/SDL2_lib/lib src/main.cpp \
        -lmingw32 -lSDL2main.la -llibSDL2.la -mwindows \
        -o Main
    

    Option two: Link statically (you won't need the DLL)

    g++ -Ilib/SDL2_lib/include -Llib/SDL2_lib/lib src/main.cpp \
        -lmingw32 lib/SDL2_lib/lib/libSDL2main.a lib/SDL2_lib/lib/libSDL2.a -mwindows \
        -o Main
    

    About VSCode:

    I don't think there's anything wrong with your configuration. You may want to try switching to backslashes (which should't make a difference anyway) or (yes, for real) reloading VSCode.