Skip to content

Conversation

@tsst-tsst
Copy link
Contributor

@tsst-tsst tsst-tsst commented Nov 14, 2025

This PR adds support to the cmake build scripts so to allow building SDL with the Tiny C Compiler (tcc).

Description

TinyCC supports the subset of C99 used by SDL and will complete the build once the --version-script linker flag is removed. One other small fix was needed in SDL_waylandevents.c to achieve a successful build. The changes have been tested with various build configurations, including X11 and Wayland, and using tcc version 0.9.28rc 2025-10-27 mob@f4e01bfc on x86_64 Linux.

Changes:

  • cmake/sdlcompilers.cmake:

    • Add a test case to the SDL_DetectCompiler macro in order to identify the tcc compiler.
    • Make tcc share compile options with gcc, clang, intelcc and qcc in function sdl_target_compile_option_all_languages
    • Disable the inclusion of the intrinsics header in function check_x86_source_compiles() when building with tcc (also in sdl_target_compile_option_all_languages).
    • Enable SDL_ASSEMBLY_DEFAULT for tcc.
    • Enable SDL_GCC_ATOMICS_DEFAULT for tcc.
  • CMakeLists.txt:

    • Skip test for C99 features when building with tcc.
    • Bypass the test for adding the '--version-script=xxx.sym' linker flag. tcc does not explicitly support it but it will silently ignore it and complete the build anyway.
  • src/video/wayland/SDL_waylandevents.c:

    • Change the definition of ROLLOVER_INTERVAL_HIGH so to not depend on the variable ROLLOVER_INTERVAL_LOW as it was causing an "initializer element is not constant" error.

Existing Issue(s)

Related to #14300

@slouken slouken modified the milestones: 3.6.0, 3.4.0 Nov 14, 2025
@slouken slouken requested a review from madebr November 14, 2025 15:12
@madebr
Copy link
Contributor

madebr commented Nov 14, 2025

I see 3 issues with TInyCC, of which only the first one should be handled by this pr imho. The slow testatomic is also worthwhile to look into.

  1. Building SDL with latest tinycc from https://repo.or.cz/tinycc.git,
    I get the following warning and link error when using SDL_TriggerBreakpoint (and link error)

    /home/maarten/projects/SDL/src/test/SDL_test_assert.c:70: warning: implicit declaration of function 'SDL_TriggerBreakpoint'
    tcc: error: undefined symbol 'SDL_TriggerBreakpoint'
    

    The following patch fixes this for me (on x86_64 Linux):

    --- a/include/SDL3/SDL_assert.h
    +++ b/include/SDL3/SDL_assert.h
    @@ -136,7 +136,7 @@ extern "C" {
         #define SDL_TriggerBreakpoint() __builtin_debugtrap()
     #elif SDL_HAS_BUILTIN(__builtin_trap)
         #define SDL_TriggerBreakpoint() __builtin_trap()
    -#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
    +#elif (defined(__GNUC__) || defined(__clang__) || defined(__TINYC__)) && (defined(__i386__) || defined(__x86_64__))
         #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
     #elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
         #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
  2. It looks like the render_testColorspaceLinear test fails with tinycc.
    epsilon is 3e-4 where the maximum allowed is 1e-4.

  3. testatomic is much slower when built with tinycc: 46 seconds vs 6 seconds using gcc. This causes timeouts when using CTest.

Using:

$ tcc --version
tcc version 0.9.28rc 2025-11-14 mob@d9ec17d (x86_64 Linux)

@tsst-tsst
Copy link
Contributor Author

tsst-tsst commented Nov 14, 2025

Thanks a lot for taking a look.

I have also noticed some warnings about macros being redefined that do not trigger when using gcc or clang:

In file included from /home/user/SDL/src/core/linux/SDL_evdev_kbd.c:33:
In file included from /usr/include/linux/keyboard.h:5:
/usr/include/linux/wait.h:5: warning: WNOHANG redefined
In file included from /home/user/SDL/src/core/linux/SDL_evdev_kbd.c:33:
In file included from /usr/include/linux/keyboard.h:5:
/usr/include/linux/wait.h:6: warning: WUNTRACED redefined
In file included from /home/user/SDL/src/core/linux/SDL_evdev_kbd.c:33:
In file included from /usr/include/linux/keyboard.h:5:
/usr/include/linux/wait.h:7: warning: WSTOPPED redefined
In file included from /home/user/SDL/src/core/linux/SDL_evdev_kbd.c:33:
In file included from /usr/include/linux/keyboard.h:5:
/usr/include/linux/wait.h:8: warning: WEXITED redefined
In file included from /home/user/SDL/src/core/linux/SDL_evdev_kbd.c:33:
In file included from /usr/include/linux/keyboard.h:5:
/usr/include/linux/wait.h:9: warning: WCONTINUED redefined
[ 79%] Building C object CMakeFiles/SDL3-shared.dir/src/io/io_uring/SDL_asyncio_liburing.c.o
In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:286: warning: RWF_HIPRI redefined
In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:289: warning: RWF_DSYNC redefined
In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:292: warning: RWF_SYNC redefined
In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:295: warning: RWF_NOWAIT redefined
In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:298: warning: RWF_APPEND redefined

Probably harmless but I thought I'd mention it anyway.

@slouken slouken modified the milestones: 3.4.0, 3.x Nov 14, 2025
@icculus
Copy link
Collaborator

icculus commented Nov 14, 2025

It's not urgent, but I do think it would be cool if we could squeeze this into 3.4.0.

@madebr
Copy link
Contributor

madebr commented Nov 14, 2025

Thanks a lot for taking a look.

I have also noticed some warnings about macros being redefined that do not trigger when using gcc or clang:

In file included from /home/user/SDL/src/io/io_uring/SDL_asyncio_liburing.c:32:
In file included from /usr/include/liburing.h:25:
In file included from /usr/include/liburing/io_uring.h:11:
/usr/include/linux/fs.h:298: warning: RWF_APPEND redefined

Probably harmless but I thought I'd mention it anyway.

I see those too.

$ grep RWF_NOWAIT -irn /usr/include
/usr/include/bits/uio-ext.h:48:#define RWF_NOWAIT	0x00000008 /* per-IO nonblocking mode.  */
/usr/include/linux/fs.h:327:#define RWF_NOWAIT	((__kernel_rwf_t)0x00000008)

gcc says:

However, if an identifier which is currently a macro is redefined, then the new definition must be effectively the same as the old one. Two macro definitions are effectively the same if:

Both are the same type of macro (object- or function-like).
All the tokens of the replacement list are the same.
If there are any parameters, they are the same.
Whitespace appears in the same places in both. It need not be exactly the same amount of whitespace, though. Remember that comments count as whitespace. 

tinycc is thus correct in emitting a warning. Not 100% sure why gcc isn't. Maybe because they are system headers or SDL adds those paths through -isystem.

@Kontrabant
Copy link
Contributor

Kontrabant commented Nov 15, 2025

Change the definition of ROLLOVER_INTERVAL_HIGH so to not depend on the variable ROLLOVER_INTERVAL_LOW as it was causing an "initializer element is not constant" error.

This commit was dropped, as I changed the values in question to defines. I never realized until now that declaring something as static const and having it be actually const in C was an extension (it's only part of the standard in C++).

@madebr
Copy link
Contributor

madebr commented Nov 15, 2025

Rebased on current main so it can be built with tinycc :)

With the SDL_TryLockSpinLock patch, I see only a 10% difference in duration of running testatomic.

@icculus
Copy link
Collaborator

icculus commented Nov 15, 2025

Yeah, and this is more for iteration and special-case projects..."serious" things will build with gcc, clang, msvc, whatever.

So 10% loss on that compiler is acceptable.

@slouken slouken merged commit d4bef0d into libsdl-org:main Nov 15, 2025
42 of 43 checks passed
@icculus icculus modified the milestones: 3.x, 3.4.0 Nov 15, 2025
@madebr
Copy link
Contributor

madebr commented Nov 15, 2025

2. It looks like the render_testColorspaceLinear test fails with tinycc.
epsilon is 3e-4 where the maximum allowed is 1e-4.

Tne render_testColorspaceLinear fails because tcc uses the vulkan driver by default (I have not investigated yet why the default renderer is different for tcc). But I can reproduce the epsilon error when using using the vulkan/gpu render driver using "normal gcc".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants