Search code examples
c++visual-studiosdllinker-errorsvcpkg

Getting a linker issue with SDL2 and vcpkg about "invoke_main(void)"


I am aware there are questions with similar posed questions, and I have checked both here and here, but neither question has posed solutions that seem to solve my problem. My subsystem is set to Windows (as suggested in the other posts). I am using Visual Studio 2022 and installed vcpkg and its libraries today. Some of the solutions suggested making changes to CMake, but I am using vcpkg and am totally unsure how to implement these solutions. I apologize if this is something simple; I am new to SDL, and am following a YouTube series to learn. This is the exact same code as the series I'm following along with, but the code compiles correctly in the video.

I'll include what I believe to be the relevant code. Feel free to ask for more if needed.

main.cpp

#include "Game.h"
int main()
{
    Game* game = new Game();
    game->init("Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, false);

    while (game->running())
    {
        game->handle_events();
        game->update();
        game->render();
    }

    game->clean();
    delete game;
    return 0;
}

Game.h

#pragma once

#include <SDL2/SDL.h>

class Game {
public:
    Game();
    ~Game();

    void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
    
    void handle_events();
    void update();
    void render();
    void clean();

    [[nodiscard]] bool running() const;

private:
    bool is_running_;
    SDL_Window* window_;
    SDL_Renderer* renderer_;
};

Game.cpp

void Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen) 
{
    if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
    {
        std::cout << "Subsystems Initialized!" << std::endl;

        window_ = SDL_CreateWindow(title, xpos, ypos, width, height, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
        if (window_)
            std::cout << "Window created!" << std::endl;

        renderer_ = SDL_CreateRenderer(window_, -1, 0);
        if (renderer_)
        {
            SDL_SetRenderDrawColor(renderer_, 255, 255, 255, 255);

            std::cout << "Renderer created" << std::endl;
        }

        is_running_ = true;
    }
    else
    {
        is_running_ = false;
    }       
}

When trying to compile, this is my build log for the debug configuration:

Build started at 12:30 AM...
1>------ Build started: Project: SDLGame, Configuration: Debug x64 ------
1>main.cpp
1>MSVCRTD.lib(exe_winmain.obj) : error LNK2019: unresolved external symbol WinMain referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
1>G:\My Drive\Dev\C++\Examples\SDLGame\SDLGame\bin\Debug-x64\SDLGame.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "SDLGame.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 12:30 AM and took 01.942 seconds ==========

This is the build log for the release configuration:

Build started at 12:55 AM...
1>------ Build started: Project: SDLGame, Configuration: Release x64 ------
1>Game.cpp
1>main.cpp
1>MSVCRT.lib(exe_winmain.obj) : error LNK2001: unresolved external symbol WinMain
1>G:\My Drive\Dev\C++\Examples\SDLGame\SDLGame\bin\Release-x64\SDLGame.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "SDLGame.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 12:55 AM and took 03.084 seconds ==========

Solution

    1. Use int main(int argc, char* argv[]) instead of int main()
    2. add lib dependency

    debug: #pragma comment(lib, "sdl2maind")

    release #pragma comment(lib, "sdl2main")

    Find the lib folder and add additional library directory, such as release: vcpkg-master\installed\x64-windows\lib\manual-link