libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.55k stars 1.77k forks source link

Window doesn't open when I run the project, even with event loop #8291

Closed gojzdar closed 10 months ago

gojzdar commented 1 year ago

I am writing a program with C++/SDL2, but I can't get a window to show up. Before switching to SDL2, I used SDL2pp (switched due to vcpkg issues, where I couldn't use vcpkg and imgui renderer + normal binding. Decided to put everything inside a docker container to ensure that if I get it to work once I can get it to work anytime). I had similar issues, but it magically fixed itself (not really sure why). I compiled it on my PC without a docker image. I tried compiling it again but it didn't work.

I know there is a somewhat related issue on MacOS where you have to pump events to get the window to show up and I did that, with no results. This project has over 4000 lines of code and I think I handled everything properly, including event handling, yet a window still doesn't show up.

OS: Kubuntu 23.04, x64 DE: KDE X11 / KDE Wayland / XFCE (tried on all of them) DM: SDDM

Compilation process:

CMakeListst.txt

cmake_minimum_required(VERSION 3.16.0)

set(CMAKE_CXX_STANDARD 20)

project(myProject)

SET(ADDITIONAL_COMPILER_FLAGS "-g")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ADDITIONAL_COMPILER_FLAGS}")

add_executable(${PROJECT_NAME} main.cpp )

find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)
find_package(SDL2_mixer REQUIRED)

target_include_directories(${PROJECT_NAME} 
PRIVATE 
    PRIVATE ../inc
    PRIVATE /app/vcpkg/installed/x64-linux/include/ 
)

target_link_libraries(${PROJECT_NAME} PRIVATE
    SDL2::SDL2main
    SDL2::SDL2-static
    SDL2_image::SDL2_image-static
    SDL2_ttf::SDL2_ttf-static
    SDL2_mixer::SDL2_mixer-static
)

CMake command `cmake -B build -S latest/src -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCPPFILENAME=$(f) -DCMAKE_TOOLCHAIN_FILE=/app/vcpkg/scripts/buildsystems/vcpkg.cmake

Docker images: vcpkg base image: (I haven't used them outside this project)

FROM ubuntu
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
    build-essential \
    cmake \
    git \
    curl \
    zip unzip tar \
    && rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/microsoft/vcpkg.git /app/vcpkg
WORKDIR /app/vcpkg
ENV VCPKG_DISABLE_METRICS=true
RUN ./bootstrap-vcpkg.sh
ENV PATH="/app/vcpkg:$PATH"

RUN apt-get update
WORKDIR /app/workspace
CMD ["bash"]

Project specific image:

FROM vcpkg-base:1.0
RUN apt-get update && apt-get install pkg-config libasound2-dev zlib1g-dev libpng-dev libfreetype6-dev -y
RUN vcpkg install freetype zlib libpng sdl2pp imgui[sdl2-binding] imgui[sdl2-renderer-binding] dbg-macro
WORKDIR /app/workdir
CMD ["bash"]

Vcpkg version: (inside docker) 2023-08-09-9990a4c9026811a312cb2af78bf77f3d9d288416

Library versions:

sdl2-image:x64-linux                              2.6.3               SDL_image is an image file loading library. It l...
sdl2-mixer:x64-linux                              2.6.3#1             Multi-channel audio mixer library for SDL.
sdl2-ttf:x64-linux                                2.20.2              A library for rendering TrueType fonts with SDL
sdl2:x64-linux                                    2.28.3              Simple DirectMedia Layer is a cross-platform dev...
sdl2[base]:x64-linux                                                  Base functionality for SDL
sdl2[ibus]:x64-linux                                                  Build with ibus IME support
sdl2[wayland]:x64-linux                                               Build with Wayland support
sdl2[x11]:x64-linux                                                   Build with X11 support

Program: (the last one I tried, among literally a dozen others, most from tutorials and solutions for other's issues

#include <SDL_events.h>
#include <stdio.h>
#include <SDL2/SDL.h>

int main(int argc, char** argv)
{

    puts("Started program!\n");
    if (SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
        return -1;
    }

    {
        SDL_Window* pWindow = NULL;
        auto fgs = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_ALWAYS_ON_TOP;
        pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
                                                                  SDL_WINDOWPOS_UNDEFINED,
                                                                  643,
                                                                  487,
                                                                  fgs);

        if( pWindow )
        {
            for(int i = 0; i < 100; i++) {

                SDL_Event event;
                while(SDL_PollEvent(&event)) {
                    // do nothing
                    switch(event.type) {
                        case SDL_QUIT:
                        i = 1000;
                        break;
                    }
                }
                SDL_Delay(100);

            }

            SDL_DestroyWindow(pWindow);
        }
        else
        {
            fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
        }
    }

    SDL_Quit();

    return 0;
}

Most of my setup was improvised and I haven't followed any tutorials.

Any help would be appreciated.

gojzdar commented 1 year ago

I have tried many hacks, like adding a delay between SDL_CreateWindow and every possible combination I could think of and set up environmental variables to toggle composition but still nothing.

madebr commented 1 year ago

SDL uses libdecor to draw the window decorations on Wayland. At SDL build time, you need the libdecor-dev package. At runtime, you need libdecor. (Verify SDL_WAYLAND_LIBDECOR is enabled at the end of CMake configuration)

Wayland needs you to draw something before it creates a window. Add the following code after the call to SDL_CreateWindow

SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);

and do the following just before the SDL_Delay.

SDL_RenderPresent(pRenderer);
madebr commented 1 year ago

@woxels About https://github.com/libsdl-org/SDL/issues/8185#issuecomment-1732209403. You might have the same problem.

gojzdar commented 1 year ago

Still nothing. And I doubt this has much to do with Wayland since the same issue occurs on KDE X11 and XFCE. Another thing. When l logged out I saw a message "amd topaz is not supported" or something similar. Still, I doubt this has anything to do with this, since I successfully compiled and ran SDL programs before on the exact same OS, exact same PC and zero updates in between except a few program installations (namely docker)

What I did: Added SET(SDL_WAYLAND_LIBDECOR 1) to the end of CMakeLists.txt Modified the code to be:

#include <SDL_events.h>
#include <stdio.h>
#include <SDL2/SDL.h>

int main(int argc, char** argv)
{

    puts("Started program!\n");
    if (SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
        return -1;
    }

    {
        SDL_Window* pWindow = NULL;
        auto fgs = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_ALWAYS_ON_TOP;
        pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
                                                                  SDL_WINDOWPOS_UNDEFINED,
                                                                  643,
                                                                  487,
                                                                  fgs);

        SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);

        if( pWindow )
        {
            for(int i = 0; i < 100; i++) {

                SDL_Event event;
                while(SDL_PollEvent(&event)) {
                    // do nothing
                    switch(event.type) {
                        case SDL_QUIT:
                        i = 1000;
                        break;
                    } 
                }
                SDL_RenderPresent(pRenderer);
                SDL_Delay(100);
            } 

            SDL_DestroyWindow(pWindow);
        }
        else
        {
            fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
        }
    }

    SDL_Quit();

    return 0;
}
madebr commented 1 year ago

SET(SDL_WAYLAND_LIBDECOR 1) won't do anything. SDL_WAYLAND_LIBDECOR is merely a hint for the cmake script to look for it. Please manually verify the output of the cmake configuration.

gojzdar commented 1 year ago

Since you didn't correct me, I guess it is a variable. The output of this block did not contain anything about wayland. Granted, I compiled it whilst on X11, but that shouldn't really make a difference since CMake instide the docker container can't see the difference. And again, not sure what Wayland has to do with the window not showing up since it doesn't work even outside of wayland.

get_cmake_property(_variableNames VARIABLES)
list (SORT _variableNames)
foreach (_variableName ${_variableNames})
    message(STATUS "${_variableName}=${${_variableName}}")
endforeach()

Thank you for taking the time

gojzdar commented 1 year ago

Any other ideas? Still not working...

madebr commented 1 year ago

@woxels please create a new issue from scratch. One SDL binary is able to support both x11 and wayland.

Kontrabant commented 1 year ago

Any other ideas? Still not working...

The above sample code works as expected when I build it on Fedora 38, although I had to drop the #include <SDL_events.h> line, so the only thing I can think of is that there is some misconfiguration on your specific system.

Does it build cleanly and work if you build it with no docker or CMake, just g++ main.cpp -lSDL2 -o sdl_test?

gojzdar commented 1 year ago

Any other ideas? Still not working...

The above sample code works as expected when I build it on Fedora 38, although I had to drop the #include <SDL_events.h> line, so the only thing I can think of is that there is some misconfiguration on your specific system.

Does it build cleanly and work if you build it with no docker or CMake, just g++ main.cpp -lSDL2 -o sdl_test?

#include <stdio.h>
#include <SDL2/SDL.h>

int main(int argc, char** argv)
{

        puts("Started program!\n");
    if (SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
        return -1;
    }

    {
        SDL_Window* pWindow = NULL;
                auto fgs = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_ALWAYS_ON_TOP;
        pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
                                                                  SDL_WINDOWPOS_UNDEFINED,
                                                                  643,
                                                                  900,
                                                                  fgs);

                SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);

        if( pWindow )
        {
                        for(int i = 0; i < 100; i++) {

                                SDL_Event event;
                                while(SDL_PollEvent(&event)) {
                                        // do nothing
                                        switch(event.type) {
                                                case SDL_QUIT:
                                                i = 1000;
                                                break;
                                        }
                                }
                                SDL_RenderPresent(pRenderer);
                                SDL_Delay(100);
                        }

            SDL_DestroyWindow(pWindow);
        }
        else
        {
            fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
        }
    }

    SDL_Quit();

    return 0;
}

Compiled with g++ main.cpp -lSDL2 -o sdl_test

Resulted in no window appearing.

I can try using some library other than SDL, but not really sure which one I should try. And in that case, I would also appreciate the actual code I should compile so I can avoid some pitfalls which might result in the program not working.

gojzdar commented 1 year ago

If I can't fix this issue, I'll be forced to switch to an alternative. Any suggestions? Requirements:

madebr commented 1 year ago

Using x11docker, I get the following error:

INFO: SDL_CreateWindowAndRenderer failed (failed to create an EGL window surface)

@Kontrabant Do you know what I'm doing wrong?

Steps to reproduce:

  1. Build the app: gcc -o app app.c -lSDL2 -I/usr/include/SDL2
  2. Build the docker image: docker build -t vm_wayland . (do this again whenever you rebuild the app)
  3. Start the container with x11docker: x11docker --wayland vm_wayland /app/app
Dockerfile ``` FROM ubuntu:latest WORKDIR /app # A real dockerfile should do this in one step, and clean itself up afterwards RUN apt-get update -y # Install x11, libdecor, libwayland-client and sdl2 RUN apt-get install -y libwayland-client0 libdecor-0-0 libsdl2-2.0-0 libx11-6 libegl1 COPY app . CMD ["/app/app"] ```
app.c ```c #include "SDL.h" int main(int argc, char *argv[]) { const char *hint_video = "wayland"; if (argc > 1) { hint_video = argv[1]; } const char *hint_renderer = "software"; if (argc > 2) { hint_renderer = argv[2]; } SDL_Log("SDL_SetHint(\"%s\", \"%s\")", SDL_HINT_VIDEODRIVER, hint_video); SDL_SetHint(SDL_HINT_VIDEODRIVER, hint_video); SDL_Log("SDL_SetHint(\"%s\", \"%s\")", SDL_HINT_RENDER_DRIVER, hint_renderer); SDL_SetHint(SDL_HINT_RENDER_DRIVER, hint_renderer); if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDL_Log("SDL_Init failed (%s)", SDL_GetError()); return 1; } SDL_Window *window; SDL_Renderer *renderer; if (SDL_CreateWindowAndRenderer(640, 480, 0, &window, &renderer) < 0) { SDL_Log("SDL_CreateWindowAndRenderer failed (%s)", SDL_GetError()); return 1; } SDL_Log("video driver: %s", SDL_GetCurrentVideoDriver()); for (;;) { SDL_Event event; int quit = 0; while (1) { SDL_Event event; if (!SDL_PollEvent(&event)) { break; } if (event.type == SDL_QUIT) { quit = 1; break; } } if (quit) { break; } SDL_RenderClear(renderer); SDL_RenderPresent(renderer); } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); } ```
Full debug log ``` $ x11docker --debug --wayland vm_wayland /app/app DEBUGNOTE[14:50:01,974]: Detected cgroup v2 DEBUGNOTE[14:50:02,148]: check_host(): ps can watch root processes: yes DEBUGNOTE[14:50:02,180]: host user: maarten 1000:1000 /home/maarten x11docker WARNING: User maarten is member of group docker. That allows unprivileged processes on host to gain root privileges. DEBUGNOTE[14:50:02,199]: check_host(): Guess if running on console: no DEBUGNOTE[14:50:02,422]: storeinfo(): cache=/home/maarten/.cache/x11docker/374014815815-vm_wayland DEBUGNOTE[14:50:02,431]: storeinfo(): stdout=/home/maarten/.cache/x11docker/374014815815-vm_wayland/share/stdout DEBUGNOTE[14:50:02,441]: storeinfo(): stderr=/home/maarten/.cache/x11docker/374014815815-vm_wayland/share/stderr DEBUGNOTE[14:50:02,471]: waitforlogentry(): tailstdout: Waiting for logentry "x11docker=ready" in store.info DEBUGNOTE[14:50:02,471]: waitforlogentry(): tailstderr: Waiting for logentry "x11docker=ready" in store.info DEBUGNOTE[14:50:02,483]: storeinfo(): containeruser=maarten DEBUGNOTE[14:50:02,492]: container user: maarten 1000:1000 /home/maarten DEBUGNOTE[14:50:02,571]: Default runtime: runc DEBUGNOTE[14:50:02,587]: Backend: docker, Backendbin: /usr/bin/docker, Rootless: no DEBUGNOTE[14:50:02,621]: storepid(): Stored pid '62615' of 'watchpidlist': 62615 pts/0 00:00:00 bash DEBUGNOTE[14:50:02,639]: storepid(): Stored pid '62625' of 'watchmessagefifo': 62625 pts/0 00:00:00 bash DEBUGNOTE[14:50:02,689]: check_xcontainer(): --xc disabled DEBUGNOTE[14:50:02,743]: Dependency check for --hostwayland: 0 DEBUGNOTE[14:50:02,748]: Dependencies of --hostwayland already checked: 0 DEBUGNOTE[14:50:02,754]: Dependencies of --hostwayland already checked: 0 DEBUGNOTE[14:50:02,759]: Dependencies of --hostwayland already checked: 0 DEBUGNOTE[14:50:02,764]: Dependencies of --hostwayland already checked: 0 x11docker note: Using X server option --hostwayland DEBUGNOTE[14:50:02,770]: storeinfo(): xserver=--hostwayland DEBUGNOTE[14:50:02,815]: storeinfo(): XAUTHORITY= DEBUGNOTE[14:50:02,824]: storeinfo(): WAYLAND_DISPLAY=wayland-0 DEBUGNOTE[14:50:02,834]: storeinfo(): XDG_RUNTIME_DIR=/run/user/1000 DEBUGNOTE[14:50:02,846]: storeinfo(): Xenv=XAUTHORITY= WAYLAND_DISPLAY=wayland-0 XDG_SESSION_TYPE=wayland GDK_BACKEND=wayland QT_QPA_PLATFORM=wayland CLUTTER_BACKEND=wayland SDL_VIDEODRIVER=wayland ELM_DISPLAY=wl ELM_ACCEL=opengl ECORE_EVAS_ENGINE=wayland_egl XDG_RUNTIME_DIR=/run/user/1000 x11docker note: You are running a pure Wayland environment. X applications without Wayland support will fail. x11docker note: Option --network=none is set to disable network access. If you need network and internet access, set option -I, --network [=NET]. DEBUGNOTE[14:50:02,945]: storeinfo(): x11dockerpid=61649 DEBUGNOTE[14:50:02,979]: x11docker version: 7.6.1-beta Backend version: Docker version 24.0.5, build %{shortcommit_cli} Running rootless: no OCI Runtime: runc Host system: "Fedora Linux 38 (Workstation Edition)" Host architecture: amd64 (x86_64) Command: '/tmp/x11docker/x11docker' '--debug' '--wayland' 'vm_wayland' '/app/app' Parsed options: () --debug --wayland -- 'vm_wayland' '/app/app' x11docker was started by: maarten As host user serves: maarten Container user will be: maarten Container user password: x11docker Running in a terminal: yes Running on console: no Running over SSH: no Running sourced: no bash $-: huBE DEBUGNOTE[14:50:02,990]: storeinfo(): tini=/usr/libexec/catatonit/catatonit DEBUGNOTE[14:50:03,052]: Image architecture: amd64 DEBUGNOTE[14:50:03,122]: Image CMD: /app/app DEBUGNOTE[14:50:03,160]: Image USER: DEBUGNOTE[14:50:03,166]: storeinfo(): containeruser=maarten DEBUGNOTE[14:50:03,214]: Image ENTRYPOINT: DEBUGNOTE[14:50:03,253]: Image WORKDIR: DEBUGNOTE[14:50:03,278]: storeinfo(): containername=x11docker_X120_vm_wayland-app-app_374014815815 DEBUGNOTE[14:50:03,413]: docker command (rootless no): /usr/bin/docker run \ --pull never \ --rm \ --detach \ --tty \ --name x11docker_X120_vm_wayland-app-app_374014815815 \ --user 1000:1000 \ --userns=host \ --group-add 1000 \ --runtime='runc' \ --network none \ --cap-drop ALL \ --security-opt no-new-privileges \ --security-opt label=type:container_runtime_t \ --mount type=bind,source='/usr/libexec/catatonit/catatonit',target='/usr/local/bin/init',readonly \ --tmpfs /run:exec \ --tmpfs /run/lock \ --tmpfs /tmp \ --mount type=bind,source='/home/maarten/.cache/x11docker/374014815815-vm_wayland/share',target='/x11docker' \ --mount type=bind,source='/run/user/1000/wayland-0',target='/wayland-0' \ --workdir '/tmp' \ --entrypoint env \ --env 'container=docker' \ --env 'ECORE_EVAS_ENGINE=wayland_egl' \ --env 'ELM_ACCEL=opengl' \ --env 'ELM_DISPLAY=wl' \ --env 'SDL_VIDEODRIVER=wayland' \ --env 'CLUTTER_BACKEND=wayland' \ --env 'QT_QPA_PLATFORM=wayland' \ --env 'GDK_BACKEND=wayland' \ --env 'XDG_SESSION_TYPE=wayland' \ --env 'WAYLAND_DISPLAY=wayland-0' \ --env 'USER=maarten' \ -- vm_wayland /usr/local/bin/init -g -- /bin/sh - /x11docker/containerrc DEBUGNOTE[14:50:03,689]: waitforlogentry(): start_container(): Waiting for logentry "xinitrc is ready" in xinit.log DEBUGNOTE[14:50:03,698]: storepid(): Stored pid '63479' of 'containershell': 63479 pts/0 00:00:00 bash DEBUGNOTE[14:50:03,729]: Running xinitrc DEBUGNOTE[14:50:04,205]: waitforlogentry(): start_container(): Found log entry "xinitrc is ready" in xinit.log. DEBUGNOTE[14:50:04,217]: start_container(): Running image DEBUGNOTE[14:50:04,222]: start_container(): Running repeated checks if container is ready. DEBUGNOTE[14:50:04,246]: start_container(): Container is up and running. DEBUGNOTE[14:50:04,251]: start_container(): 1. check for PID 1 DEBUGNOTE[14:50:04,449]: waitforlogentry(): containerrc: Waiting for logentry "containerrootrc=ready" in store.info DEBUGNOTE[14:50:04,482]: start_container(): PID1=63655 DEBUGNOTE[14:50:04,522]: storeinfo(): containerip= DEBUGNOTE[14:50:04,564]: storeinfo(): containerid=110b57c9cfaf4d706b9c5815e4e2ba1974a9e5269629641763ee27f36b17322e DEBUGNOTE[14:50:04,574]: storeinfo(): pid1pid=63655 DEBUGNOTE[14:50:04,586]: start_container(): Starting containerrootrc with docker exec DEBUGNOTE[14:50:04,684]: Running containerrootrc: Setup as root in container DEBUGNOTE[14:50:04,706]: containerrootrc: Container libc: glibc DEBUGNOTE[14:50:04,718]: containerrootrc: maarten:x:1000:1000:maarten,,,:/home/maarten:/bin/bash DEBUGNOTE[14:50:04,730]: containerrootrc: Container user: uid=1000(maarten) gid=1000(maarten) groups=1000(maarten) DEBUGNOTE[14:50:04,731]: watchpidlist(): Setting pid 63655 on watchlist: pid1pid DEBUGNOTE[14:50:04,742]: storeinfo(): containerrootrc=ready DEBUGNOTE[14:50:04,753]: watchpidlist(): Watching pids: 63655 pts/0 00:00:00 init DEBUGNOTE[14:50:04,753]: storepid(): Stored pid '63655' of 'pid1pid': 63655 pts/0 00:00:00 init DEBUGNOTE[14:50:04,831]: Process tree of container: (maybe not complete yet) init(63655)---sh(63674)---sleep(63682) DEBUGNOTE[14:50:04,906]: Process tree of x11docker: bash(61649)-+-bash(62468)---tail(62471) |-bash(62470)---sleep(63716) |-bash(62472)---sleep(63715) |-bash(62615) |-bash(62625) |-bash(63479)---bash(63998)---pstree(63999) `-sh(63511) DEBUGNOTE[14:50:04,913]: storeinfo(): Stored info: cache=/home/maarten/.cache/x11docker/374014815815-vm_wayland stdout=/home/maarten/.cache/x11docker/374014815815-vm_wayland/share/stdout stderr=/home/maarten/.cache/x11docker/374014815815-vm_wayland/share/stderr xserver=--hostwayland XAUTHORITY= WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 Xenv=XAUTHORITY= WAYLAND_DISPLAY=wayland-0 XDG_SESSION_TYPE=wayland GDK_BACKEND=wayland QT_QPA_PLATFORM=wayland CLUTTER_BACKEND=wayland SDL_VIDEODRIVER=wayland ELM_DISPLAY=wl ELM_ACCEL=opengl ECORE_EVAS_ENGINE=wayland_egl XDG_RUNTIME_DIR=/run/user/1000 x11dockerpid=61649 tini=/usr/libexec/catatonit/catatonit containeruser=maarten containername=x11docker_X120_vm_wayland-app-app_374014815815 containerip= containerid=110b57c9cfaf4d706b9c5815e4e2ba1974a9e5269629641763ee27f36b17322e pid1pid=63655 containerrootrc=ready DEBUGNOTE[14:50:04,920]: storepid(): Stored pids: 62615 watchpidlist 62625 watchmessagefifo 63479 containershell 63655 pid1pid DEBUGNOTE[14:50:04,925]: storeinfo(): x11docker=ready DEBUGNOTE[14:50:04,954]: waitforlogentry(): containerrc: Found log entry "containerrootrc=ready" in store.info. DEBUGNOTE[14:50:04,965]: Running containerrc: Unprivileged user commands in container DEBUGNOTE[14:50:05,005]: waitforlogentry(): tailstdout: Stopped waiting for x11docker=ready in store.info due to terminating signal. DEBUGNOTE[14:50:05,004]: waitforlogentry(): tailstderr: Stopped waiting for x11docker=ready in store.info due to terminating signal. INFO: SDL_SetHint("SDL_VIDEODRIVER", "wayland") INFO: SDL_SetHint("SDL_RENDER_DRIVER", "software") INFO: SDL_CreateWindowAndRenderer failed (failed to create an EGL window surface) DEBUGNOTE[14:50:05,010]: containerrc: HOME is empty. Copying from /etc/skel DEBUGNOTE[14:50:05,069]: cmdrc: Running container command: '/app/app' DEBUGNOTE[14:50:05,081]: storeinfo(): cmdexitcode=1 DEBUGNOTE[14:50:05,093]: time to say goodbye (cmdrc) DEBUGNOTE[14:50:05,761]: watchpidlist(): PID 63655 has terminated DEBUGNOTE[14:50:05,765]: time to say goodbye (watchpidlist 63655) DEBUGNOTE[14:50:05,771]: time to say goodbye (watchpidlist) DEBUGNOTE[14:50:05,771]: time to say goodbye (main) DEBUGNOTE[14:50:05,778]: Terminating x11docker. DEBUGNOTE[14:50:05,783]: time to say goodbye (finish) DEBUGNOTE[14:50:05,812]: finish(): Checking pid 63655 (pid1pid): (already gone) DEBUGNOTE[14:50:05,838]: finish(): Checking pid 63479 (containershell): (already gone) DEBUGNOTE[14:50:05,863]: finish(): Checking pid 62625 (watchmessagefifo): 62625 pts/0 00:00:00 bash DEBUGNOTE[14:50:05,889]: finish(): Checking pid 62615 (watchpidlist): (already gone) DEBUGNOTE[14:50:05,941]: termpid(): Terminating 62625 (watchmessagefifo): 62625 pts/0 00:00:00 bash DEBUGNOTE[14:50:06,060]: x11docker exit code: 0 DEBUGNOTE[14:50:06,070]: CMD exit code: 1 ```
Kontrabant commented 12 months ago

Wayland still uses a hardware texture to scan out, even with software rendering. I think Docker needs to be started with --gpu (Nvidia might require more configuration).

The only other suggestion I have for the original issue is to try and verify or reinstall all the relevant packages and maybe try building SDL from source to see if that helps. I can't replicate the issue, and if the sample code doesn't work for the OP even in the simplest case with no build systems or containers in the way, that would seem to suggest a bad package or misconfiguration on their specific system.

madebr commented 12 months ago

I got it working by also installing libgl1. (--gpu was not needed for my example) So these are the minimal packages required to run sdl2 in a docker container: libwayland-client0 libdecor-0-0 libsdl2-2.0-0 libegl1 libgl1 (add libgles2 for the opengles2 renderer)

gojzdar commented 12 months ago

try building SDL from source to see if that helps

I just built it from source and ran the tests. Both main and SDL2 branch are working, at least for testdrawchessboard and testdraw2 files. I don't have any time right now so I'll try more tomorrow.

The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.

gojzdar commented 12 months ago

Is it worth trying to build SDL from source inside a docker container? Would it should still work right? So the issue is that both the SDL apt package and SDL vcpkg package are not configured correctly for me? Is there a way to troubleshoot the issue now that I have a working copy, or is that too hard to do? I should probably try to build the same source code with my toolchain, SDL-dev packages and from source.

madebr commented 12 months ago

The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.

Some SDL3 tests have a --fullscreen argument. Does it also happen with these? Does the black screen delay happen when running the test outside the docker container?

Is it worth trying to build SDL from source inside a docker container? Would it should still work right?

If you install the same packages we install on ci, it should result in a working SDL3 FYI, you can download binaries from the actions page so you can compare with a "known good" (SDL2 does not provide binaries).

So the issue is that both the SDL apt package and SDL vcpkg package are not configured correctly for me? Is there a way to troubleshoot the issue now that I have a working copy, or is that too hard to do?

It would surprise me Ubuntu's package to be non-functional. In my use of docker above, I built the app with Fedora's SDL2 and ran it with Ubuntu's SDL2 inside a container. But you can always build the SDL2 tests and run them against various SDL2 libraries (using LD_LIBRARY_PATH). vcpkg should allow you to compare the cmake configure arguments easily.

gojzdar commented 12 months ago

Progress update: since I used cmake --install on both SDL2 and SDL3 build directories. Now compiling with -lSDL2 and -lSDL3 works. However SDL3 stopped working after installing SDL2. Not sure when exactly, if right after the installation or when I renamed the parent folder of the build dir from SDL to SDL3 to avoid confusion. However, the issue was fixed after I used sudo ldconfig. And is it safe to alter/remove the build directories after I used cmake install?

So right now, compiling with the recommended CMake file works (the one provided in README-cmake.md) and also using the system libraries.

Just to makes things clear, I use docker only as a compilation tool chain. I run the compiled programs outside of it.


The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.

The issue seems to have fixed itself.

Some SDL3 tests have a --fullscreen argument. Does it also happen with these?

When I try to use the --fullscreen flag on SDL3 tests, the screen flickers a few times before the display resolution matches the app's.

If you install the same packages we install on ci, it should result in a working SDL3 FYI, you can download binaries from the actions page so you can compare with a "known good" (SDL2 does not provide binaries).

So I should install these (two?) inside the docker container? If yes -> why, the compilation works perfectly fine and I would think that if anything went wrong I would be notified If no -> how could that help with the window showing up outside the container?

But you can always build the SDL2 tests and run them against various SDL2 libraries (using LD_LIBRARY_PATH).

I tried using export LD_LIBRARY_PATH=/usr/local/lib (the place where cmake --install places the files) and then running the result of my docker compilation toolchain (in the same shell session, outside of the docker container), but nothing changed.

I never specified that my project is to be statically linked, so I assume it isn't, however the file is still 6mb large (with debugging symbols) so I am not 100% sure. I also ran the command

file myProject                       
myProject: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=58a9930606a7b5cd258b55b6f9950d47008959ab, for GNU/Linux 3.2.0, with debug_info, not stripped

vcpkg should allow you to compare the cmake configure arguments easily.

How can I do that? And what exactly do you mean by that?

If I can't get vcpkg to play nicely, how can I port my compiled binaries inside of cmake Docker so it uses the working ones instead of the faulty ones it is using right now? Directly copying them into /usr/local/lib and modifying the CMake file?

Thank you for the response, thanks to you all I've come closer to SDL working and avoided a lot more potential hassle.

madebr commented 12 months ago

And is it safe to alter/remove the build directories after I used cmake install?

After doing cmake --install, the build directory can be removed. Since it contains absolute paths, you can't move it and re-use elsewhere. The installed package is free of paths, so you can do whatever you want with it.

Some SDL3 tests have a --fullscreen argument. Does it also happen with these?

When I try to use the --fullscreen flag on SDL3 tests, the screen flickers a few times before the display resolution matches the app's.

For me, with SDL_VIDEO_DRIVER=wayland testsprite goes fullscreen immediately. With x11, testsprite appears with the 2nd attempt.

So I should install these (two?) inside the docker container? If yes -> why, the compilation works perfectly fine and I would think that if anything went wrong I would be notified If no -> how could that help with the window showing up outside the container?

If you have a working build and install procedure, then all is good. We often see reports of people having not installed e.g. libx11-dev libraries. The archive does still require the installation of non-development libwayland, libdecor and/or libx11 libraries.

I never specified that my project is to be statically linked, so I assume it isn't, however the file is still 6mb large (with debugging symbols) so I am not 100% sure. I also ran the command

We discourage linking to a static SDL library. Your app is not stripped. With c++ code, I often see an explosion in debug information size. Try running strip on the app. Before stripping, using objdump/nm, you can see what symbols are available in the library and what ones are undefined. Undefined symbols are made available through dynamic libraries.

vcpkg should allow you to compare the cmake configure arguments easily.

How can I do that? And what exactly do you mean by that?

Again, I was thinking you had build problems. This comment says there are logs somewhere. I'm no vcpkg export so you'll have to look this one up elsewhere.

If I can't get vcpkg to play nicely, how can I port my compiled binaries inside of cmake so it uses the working ones instead of the faulty ones it is using right now? Directly copying them into /usr/local/lib and modifying the CMake file?

Make sure cmake finds the correct SDL2/3 package, and use rpaths. Running ldd on your app will show what libraries the dynamic loader will load. CMake's default behavior is to use rpaths in the build directories. This way, executables will use the correct dynamic library. At install time, CMake removes these. This is done such that no directories of the build machines end up in the final binaries. But as written above, there are ways to modify rpaths.

gojzdar commented 12 months ago

I mistyped. I meant how to do so within a Docker image/container instead of CMake. A possible option would be to build SDL from source inside a container, or maybe just copying the .so files. But I don't know much about these things so I am really not sure.

madebr commented 12 months ago

You can mount a volume using the -v option.

Since it looks like you're no longer have SDL-specific issues, is it ok to close this issue?

gojzdar commented 12 months ago

Not really sure how the whole system works here on github, but I would like to find the reason why both vcpkg and apt SDL packages don't work on my machine, which I think is an SDL problem. The docker workaround is just a quick and dirty solution, but I would prefer something permanent and less awkward. I do realize that this may be a fault with my machine or (less likely) with apt and docker packages, so you make the call on that.

Thank you everyone for help.

gojzdar commented 12 months ago

You can mount a volume using the -v option.

Since it looks like you're no longer have SDL-specific issues, is it ok to close this issue?

So I would just mount the /usr/local/lib during compilation and hope for the best?