0

I'm working on a small project in CLion with SDL2 on Windows.

When I compile and run (Shift+F10) my program in CLion, it does not show any console output. However, when I run it using the debugger (Shift+F9), it does show console output..

I have no idea what is causing this.

To make sure my project or CLion isn't corrupting something, I've copied the sources over to a new project and set it up using the same CMakeList.txt file, and it still does not work.

My CMakeList.txt:

CMakeList.txt

cmake_minimum_required(VERSION 3.6)
project(SDL_Project)

set(CMAKE_CXX_STANDARD 14)

# FindSDL2.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
#find_package(SDL2_ttf REQUIRED)

include_directories(${SDL2_INCLUDE_DIR})
include_directories(${SDL2_IMAGE_INCLUDE_DIR})
#include_directories(${SDL2_TTF_INCLUDE_DIR})

add_executable(SDL_Project src/main.cpp src/Game.cpp src/Game.h)
set_target_properties(SDL_Project PROPERTIES WIN32_EXECUTABLE FALSE)

target_link_libraries(SDL_Project ${SDL2_LIBRARY})
target_link_libraries(SDL_Project ${SDL2_IMAGE_LIBRARIES})
#target_link_libraries(SDL_Project ${SDL2_TTF_LIBRARIES})

I also tried compiling the following code (without SDL2, but using the same CMakeList.txt):

#include <iostream>

int main(int argv, char* args[]) {
    std::cout << "Hello World!" << std::endl;
    return 0;
}

This has the same issue; no console output.

Compiling the above code without the find_package, include_directories and target_link_libraries in CMakeList.txt shows console output! So it is related to SDL2, I think..?

Does anyone know what is causing this, and how to fix it?


Though I believe the problem lies in CMakeList.txt, here is the remaining code:

main.cpp

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

#include "Game.h"

int main(int argv, char* args[]) {

    const int FPS = 60;
    const uint32_t frameDelay = 1000 / FPS;

    const WindowSettings settings = {SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720};
    Game game;

    Uint32 frameStart;
    Uint32 frameTime;

    game.init("Game", settings);

    while (game.isRunning()) {
        frameStart = SDL_GetTicks();

        game.handleEvents();
        game.tick();
        game.render();

        frameTime = SDL_GetTicks() - frameStart;

        std::cout << "Frame time: " << frameTime << " / " << frameDelay << std::endl;
        if (frameTime < frameDelay) {
            std::cout << "Frame delay: " << (frameDelay - frameTime) << std::endl;
            SDL_Delay(frameDelay - frameTime);
        }
    }

    game.cleanup();

    return 0;
}

Game.h

#ifndef SDL_PROJECT_GAME_H
#define SDL_PROJECT_GAME_H

#include <SDL.h>

struct WindowSettings {
    int x;
    int y;
    int width;
    int height;
};

class Game {
private:
    bool running;
    SDL_Window* window;
    SDL_Renderer* renderer;

public:
    Game();
    ~Game();

    void init(const char* title, const WindowSettings &settings);
    void tick();
    void render();
    void cleanup();
    void handleEvents();

    bool isRunning() { return running; }
};


#endif //SDL_PROJECT_GAME_H

Game.cpp

#include <iostream>
#include "Game.h"

Game::Game():
        running(false),
        window(nullptr),
        renderer(nullptr) {
}

Game::~Game() = default;

void Game::init(const char *title, const WindowSettings &settings) {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cout << "SDL initialization failed: " << SDL_GetError() << std::endl;
        return;
    };

    window = SDL_CreateWindow(title, settings.x, settings.y, settings.width, settings.height, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cout << "Unable to create window: " << SDL_GetError() << std::endl;
        return;
    }

    renderer = SDL_CreateRenderer(window, -1 , 0);
    if (renderer == nullptr) {
        std::cout << "Unable to create renderer: " << SDL_GetError() << std::endl;
        return;
    }

    running = true;
}

void Game::tick() {

}

void Game::render() {
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
}

void Game::cleanup() {
    if (renderer) {
        SDL_DestroyRenderer(renderer);
    }
    if (window) {
        SDL_DestroyWindow(window);
    }

    SDL_Quit();
    std::cout << "Game clean exit" << std::endl;
}

void Game::handleEvents() {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            running = false;
        }
    }
}
Jochem Kuijpers
  • 1,770
  • 3
  • 17
  • 34
  • `handleEvents` doesn't do event loop properly, it should call `SDL_PollEvent` in a `while` loop so all the accumulated events are processed. As for main issue, do you copy all the necessary libraries into executable folder or make them otherwise visible for executable? – user7860670 Feb 17 '18 at 20:06
  • @VTT Good catch, thanks. The appropriate DLLs are in the `cmake-build-debug` directory. SDL2 initializes just fine and shows a window on both run configurations. – Jochem Kuijpers Feb 17 '18 at 22:53

2 Answers2

1

I can think of 1 issue. Are you sure your run configuration is correct CLION? The debug build could be running a different executable than you think. CLION does a lot of stuff behind the scenes. Click the run arrow drop down and look at edit configurations or something to that effect.

HSchmale
  • 1,838
  • 2
  • 21
  • 48
  • There's actually just one run configuration: https://i.imgur.com/qEnvsj2.png -- These are the 'factory' defaults of CLion, the only change I made was the working directory, but resetting that has no effect and creating a new project with new defaults doesn't change anything either. – Jochem Kuijpers Feb 17 '18 at 22:56
0

Alright, I figured it out..

Apparently, compiling on Windows redirects stdout and stderr to null (?). I was unable to locate/remove the compiler flag that influences this, however, SDL provides SDL_Log, which does in fact output to the console (and presumably stdout?).

Since I'm using SDL2 anyway, I might as well use the logger. It supports printf-style formatting, which is a nice bonus. And it allows me to set up a custom logging function if I want to redirect log messages.

Jochem Kuijpers
  • 1,770
  • 3
  • 17
  • 34