From d4bef0d5ba7d231bd757f4b59e966c4b5b086553 Mon Sep 17 00:00:00 2001 From: tsst-tsst <67490539+tsst-tsst@users.noreply.github.com> Date: Sat, 15 Nov 2025 20:24:15 +0100 Subject: [PATCH] Add support for tcc to cmake (#14464) This PR adds support to the cmake build scripts so to allow building SDL with the Tiny C Compiler (tcc). TinyCC supports the subset of C99 used by SDL and will complete the build once the --version-script linker flag is removed. 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. --- CMakeLists.txt | 18 +++++++++++++----- cmake/sdlcompilers.cmake | 9 ++++++++- include/SDL3/SDL_assert.h | 2 +- src/atomic/SDL_spinlock.c | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bfe65da1f..16111a817d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,12 +169,12 @@ else() endif() set(SDL_ASSEMBLY_DEFAULT OFF) -if(USE_CLANG OR USE_GCC OR USE_INTELCC OR MSVC_VERSION GREATER 1400) +if(USE_CLANG OR USE_GCC OR USE_INTELCC OR USE_TCC OR MSVC_VERSION GREATER 1400) set(SDL_ASSEMBLY_DEFAULT ON) endif() set(SDL_GCC_ATOMICS_DEFAULT OFF) -if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC) +if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC OR TCC) set(SDL_GCC_ATOMICS_DEFAULT ON) endif() @@ -463,7 +463,10 @@ if(SDL_SHARED) if ("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES) target_compile_features(SDL3-shared PRIVATE c_std_99) else() - message(WARNING "target_compile_features does not know c_std_99 for C compiler") + # tcc does support the subset of C99 used by SDL + if (NOT USE_TCC) + message(WARNING "target_compile_features does not know c_std_99 for C compiler") + endif() endif() endif() @@ -476,7 +479,9 @@ if(SDL_STATIC) if ("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES) target_compile_features(SDL3-static PRIVATE c_std_99) else() - message(WARNING "target_compile_features does not know c_std_99 for C compiler") + if (NOT USE_TCC) + message(WARNING "target_compile_features does not know c_std_99 for C compiler") + endif() endif() endif() @@ -510,7 +515,10 @@ check_linker_supports_version_file(HAVE_WL_VERSION_SCRIPT) if(HAVE_WL_VERSION_SCRIPT) sdl_shared_link_options("-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym") else() - if((LINUX AND LIBC_IS_GLIBC) OR ANDROID) + # When building with tcc on Linux+glibc or Android, avoid emitting an error + # for lack of support of the version-script linker flag: the option will be + # silently ignored by the compiler and the build will still succeed. + if(((LINUX AND LIBC_IS_GLIBC) OR ANDROID) AND (NOT USE_TCC)) message(FATAL_ERROR "Linker does not support '-Wl,--version-script=xxx.sym'. This is required on the current host platform (${SDL_CMAKE_PLATFORM}).") endif() endif() diff --git a/cmake/sdlcompilers.cmake b/cmake/sdlcompilers.cmake index af80a8eb24..ab62c5012e 100644 --- a/cmake/sdlcompilers.cmake +++ b/cmake/sdlcompilers.cmake @@ -3,6 +3,7 @@ macro(SDL_DetectCompiler) set(USE_GCC FALSE) set(USE_INTELCC FALSE) set(USE_QCC FALSE) + set(USE_TCC FALSE) if(CMAKE_C_COMPILER_ID MATCHES "Clang|IntelLLVM") set(USE_CLANG TRUE) # Visual Studio 2019 v16.2 added support for Clang/LLVM. @@ -16,6 +17,8 @@ macro(SDL_DetectCompiler) set(USE_INTELCC TRUE) elseif(CMAKE_C_COMPILER_ID MATCHES "QCC") set(USE_QCC TRUE) + elseif(CMAKE_C_COMPILER_ID MATCHES "TinyCC") + set(USE_TCC TRUE) endif() endmacro() @@ -39,7 +42,7 @@ function(SDL_AddCommonCompilerFlags TARGET) cmake_pop_check_state() endif() - if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC) + if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC OR USE_TCC) if(MINGW) # See if GCC's -gdwarf-4 is supported # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101377 for why this is needed on Windows @@ -159,6 +162,10 @@ function(SDL_AddCommonCompilerFlags TARGET) sdl_target_compile_option_all_languages(${TARGET} "-fdiagnostics-color=always") endif() endif() + + if(USE_TCC) + sdl_target_compile_option_all_languages(${TARGET} "-DSTBI_NO_SIMD") + endif() endfunction() function(check_x86_source_compiles BODY VAR) diff --git a/include/SDL3/SDL_assert.h b/include/SDL3/SDL_assert.h index ddb89b8848..f0c4637b93 100644 --- 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" ) diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index 75bacda7c9..2f609327e2 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -91,7 +91,7 @@ bool SDL_TryLockSpinlock(SDL_SpinLock *lock) : "cc", "memory"); return result == 0; -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#elif (defined(__GNUC__) || defined(__TINYC__)) && (defined(__i386__) || defined(__x86_64__)) int result; __asm__ __volatile__( "lock ; xchgl %0, (%1)\n"