This commit is contained in:
Anonymous Maarten 2026-06-05 10:43:21 +08:00 committed by GitHub
commit 787ca8341f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 243 additions and 16 deletions

View file

@ -63,4 +63,5 @@ runs:
id: final
shell: pwsh
run: |
echo "${{ runner.temp }}/djgpp/i586-pc-msdosdjgpp/bin" >> $env:GITHUB_PATH
echo "${{ runner.temp }}/djgpp/bin" >> $env:GITHUB_PATH

View file

@ -167,6 +167,7 @@ class SharedLibType(Enum):
SO_0 = "libSDL3.so.0"
SO = "libSDL3.so"
DYLIB = "libSDL3.0.dylib"
DXE = "SDL3.dxe"
FRAMEWORK = "SDL3.framework/Versions/A/SDL3"
@ -860,11 +861,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args
job.apt_packages = ["ccache", "libfl-dev"] # djgpp needs libfl.so.2
job.cmake_build_type = "Release"
job.setup_ninja = True
job.shared_lib = SharedLibType.DXE
job.static_lib = StaticLibType.A
job.shared_lib = None
job.clang_tidy = False
job.werror = False # FIXME: enable SDL_WERROR
job.shared = False
job.run_tests = False
job.test_pkg_config = False
job.cmake_toolchain_file = "$GITHUB_WORKSPACE/build-scripts/i586-pc-msdosdjgpp.cmake"

View file

@ -210,7 +210,19 @@ if(EMSCRIPTEN)
set(SDL_SHARED_AVAILABLE OFF)
endif()
if(VITA OR PSP OR PS2 OR N3DS OR RISCOS OR NGAGE OR DOS)
if(DOS)
if(NOT DJGPP)
message(FATAL_ERROR "SDL3 DOS support requires a DJGPP toolchain")
endif()
find_program(DJGPP_DXE3GEN_BIN NAMES dxe3gen)
if(NOT EXISTS "${DJGPP_DXE3GEN_BIN}")
message(STATUS "Disabling shared library support: dxe3gen not found")
set(SDL_SHARED_AVAILABLE OFF)
endif()
endif()
if(VITA OR PSP OR PS2 OR N3DS OR RISCOS OR NGAGE)
set(SDL_SHARED_AVAILABLE OFF)
endif()
@ -533,6 +545,9 @@ if(SDL_TEST_LIBRARY)
add_library(SDL3::SDL3_test ALIAS SDL3_test)
SDL_AddCommonCompilerFlags(SDL3_test)
target_compile_definitions(SDL3_test PRIVATE "$<$<CONFIG:Debug>:DEBUG>")
if("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES)
target_compile_features(SDL3_test PRIVATE c_std_99)
endif()
endif()
# Make sure SDL3::SDL3 always exists
@ -555,7 +570,7 @@ if (LIBC_IS_GLIBC AND CMAKE_SIZEOF_VOID_P EQUAL 4)
endif()
check_linker_supports_version_file(HAVE_WL_VERSION_SCRIPT)
if(HAVE_WL_VERSION_SCRIPT)
if(HAVE_WL_VERSION_SCRIPT AND (NOT DOS))
sdl_shared_link_options("-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym")
else()
# When building with tcc on Linux+glibc or Android, avoid emitting an error
@ -686,7 +701,7 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
endif()
endif()
if(NOT OPENBSD)
if(NOT (DOS OR OPENBSD))
cmake_push_check_state()
check_linker_flag(C "-Wl,--no-undefined" LINKER_SUPPORTS_WL_NO_UNDEFINED)
#FIXME: originally this if had an additional "AND NOT (USE_CLANG AND WINDOWS)"
@ -4104,6 +4119,16 @@ if(SDL_SHARED)
)
endif()
endif()
if(DJGPP)
# <LANG>_LINKER_LAUNCHER was introduced in CMake 3.21. genex support was added in 3.27.
cmake_minimum_required(VERSION 3.27)
set_property(TARGET SDL3-shared SDL_uclibc PROPERTY POSITION_INDEPENDENT_CODE FALSE)
set_property(TARGET SDL3-shared PROPERTY IMPORT_SUFFIX ".dxe.a")
set_property(TARGET SDL3-shared PROPERTY SUFFIX ".dxe")
set_property(TARGET SDL3-shared PROPERTY C_LINKER_LAUNCHER "${CMAKE_CURRENT_SOURCE_DIR}/build-scripts/djgpp-dxe-linker-wrapper.py;--dxe3gen=${DJGPP_DXE3GEN_BIN};--import-library;$<TARGET_IMPORT_FILE:SDL3-shared>;--library-paths;${DJGPP_LIBRARY_PATHS};--")
set_property(TARGET SDL3-shared APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/build-scripts/djgpp-dxe-linker-wrapper.py")
endif()
target_link_libraries(SDL3-shared PRIVATE ${SDL_CMAKE_DEPENDS})
target_include_directories(SDL3-shared

View file

@ -0,0 +1,75 @@
#!/usr/bin/env python3
import argparse
import os
import sys
import subprocess
def parse_wrapper_args(args):
parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument("--library-paths", nargs="*", help="Additional DJGPP Library paths")
parser.add_argument("--dxe3gen", default="dxe3gen", help="Path of dxe3gen")
parser.add_argument("--import-library", help="Import library name")
args = parser.parse_args(args)
return args
def parse_linker_args(args):
unknown_args = []
output = None
i = 1
while i < len(args):
arg = args[i]
if arg in ("-fPIC", "-shared"):
consumed = 1
elif arg.startswith("-Wl,"):
unknown_args.extend(arg[4:].split(","))
elif arg.startswith("-I"):
if arg == "-I":
consumed = 2
else:
consumed = 1
elif arg == "-o":
output = args[i + 1]
consumed = 2
elif arg.startswith("-D"):
consumed = 1
elif arg.startswith("-O"):
consumed = 1
else:
unknown_args.append(arg)
consumed = 1
i += consumed
if not output:
print("Missing \"-o\" argument", file=sys.stderr)
return output, unknown_args
try:
pos_double_dash = sys.argv.index("--")
wrapper_args = sys.argv[1:pos_double_dash]
original_args = sys.argv[pos_double_dash+1:]
except IndexError:
wrapper_args = []
original_args = sys.argv[1:]
wrapper_args = parse_wrapper_args(wrapper_args)
output_path, original_linker_args = parse_linker_args(original_args)
dxe3gen_command = [
wrapper_args.dxe3gen,
"-o", output_path,
"-U",
]
if wrapper_args.import_library:
dxe3gen_command.extend(["-Y", wrapper_args.import_library])
for libpath in wrapper_args.library_paths:
dxe3gen_command.append("-L" + libpath)
dxe3gen_command.extend(original_linker_args)
if not "-nostlib" in original_linker_args:
dxe3gen_command.append("-lgcc")
os.environ["DXE_LD_LIBRARY_PATH"] = "dontcare"
os.environ["DJDIR"] = "dontcare"
process_result = subprocess.run(dxe3gen_command)
raise SystemExit(process_result.returncode)

View file

@ -11,6 +11,11 @@
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dxe")
set(CMAKE_IMPORT_LIBRARY_PREFIX "lib")
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".dxe.a")
set(CMAKE_LINK_LIBRARY_SUFFIX "")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib")

View file

@ -15,9 +15,9 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE "${DJGPP_PLATFORM_OVERRIDES}")
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dxe")
set(CMAKE_IMPORT_LIBRARY_PREFIX "lib")
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".a")
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".dxe.a")
set(CMAKE_EXECUTABLE_SUFFIX ".exe")
set(CMAKE_LINK_LIBRARY_SUFFIX "")
set(CMAKE_DL_LIBS "")
@ -67,6 +67,11 @@ endforeach()
list(APPEND CMAKE_FIND_ROOT_PATH ${CC_ROOTS})
set(DJGPP_LIBRARY_PATHS )
foreach(__cc_root ${CC_ROOTS})
list(APPEND DJGPP_LIBRARY_PATHS "${__cc_root}" "${__cc_root}/lib")
endforeach()
# search for programs in the host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View file

@ -65,11 +65,13 @@ if(TEST_SHARED)
)
endif()
add_library(sharedlib-shared SHARED main_lib.c)
target_link_libraries(sharedlib-shared PRIVATE SDL3::SDL3-shared)
generate_export_header(sharedlib-shared EXPORT_MACRO_NAME MYLIBRARY_EXPORT)
target_compile_definitions(sharedlib-shared PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared_export.h\"")
set_target_properties(sharedlib-shared PROPERTIES C_VISIBILITY_PRESET "hidden")
if(NOT DOS)
add_library(sharedlib-shared SHARED main_lib.c)
target_link_libraries(sharedlib-shared PRIVATE SDL3::SDL3-shared)
generate_export_header(sharedlib-shared EXPORT_MACRO_NAME MYLIBRARY_EXPORT)
target_compile_definitions(sharedlib-shared PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared_export.h\"")
set_target_properties(sharedlib-shared PROPERTIES C_VISIBILITY_PRESET "hidden")
endif()
add_executable(cli-shared main_cli.c)
target_link_libraries(cli-shared PRIVATE SDL3::SDL3-shared)
@ -96,7 +98,7 @@ if(TEST_STATIC)
add_executable(gui-static WIN32 main_gui.c)
target_link_libraries(gui-static PRIVATE SDL3::SDL3-static)
if(TEST_SHARED)
if(TEST_SHARED AND NOT DOS)
# Assume SDL library has been built with `set(CMAKE_POSITION_INDEPENDENT_CODE ON)`
add_library(sharedlib-static SHARED main_lib.c)
target_link_libraries(sharedlib-static PRIVATE SDL3::SDL3-static)

View file

@ -286,7 +286,7 @@ SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
/* Byte swap 32-bit integer. */
#ifndef SDL_WIKI_DOCUMENTATION_SECTION
#if HAS_BUILTIN_BSWAP32
#define SDL_Swap32(x) __builtin_bswap32(x)
#define SDL_Swap32(x) (Uint32)__builtin_bswap32(x)
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
#pragma intrinsic(_byteswap_ulong)
#define SDL_Swap32(x) _byteswap_ulong(x)

View file

@ -220,6 +220,7 @@
void reset_IOP() {}
#elif defined(SDL_PLATFORM_DOS)
/*
On DOS, SDL provides a main function that sets up memory
page locking (code, data, stack are locked, future

View file

@ -148,4 +148,116 @@
#endif /* SDL_MAIN_HANDLED */
#ifdef SDL_PLATFORM_DOS
/* On DOS, the executable must export symbols for the SDL3 module.
*/
#define FOR_EACH_DXE_EXPORT(X) \
X(__Exit) \
X(___dj_huge_val) \
X(___dj_stderr) \
X(___dj_stdin) \
X(___djgpp_base_address) \
X(___djgpp_nearptr_enable) \
X(___dpmi_free_physical_address_mapping) \
X(___dpmi_int) \
X(___dpmi_physical_address_mapping) \
X(___dpmi_simulate_real_mode_procedure_retf) \
X(___fpclassifyd) \
X(___fpclassifyf) \
X(__go32_dpmi_allocate_dos_memory) \
X(__go32_dpmi_chain_protected_mode_interrupt_vector) \
X(__go32_dpmi_free_dos_memory) \
X(__go32_dpmi_get_protected_mode_interrupt_vector) \
X(__go32_dpmi_lock_code) \
X(__go32_dpmi_lock_data) \
X(__go32_dpmi_set_protected_mode_interrupt_vector) \
X(__go32_info_block) \
X(_abort) \
X(_atof) \
X(_atoi) \
X(_calloc) \
X(_clearerr) \
X(_close) \
X(_closedir) \
X(_delay) \
X(_dlregsym) \
X(_dosmemput) \
X(_environ) \
X(_errno) \
X(_fclose) \
X(_ferror) \
X(_fflush) \
X(_fgets) \
X(_fileno) \
X(_fopen) \
X(_fprintf) \
X(_fputs) \
X(_fread) \
X(_free) \
X(_fseeko) \
X(_fstat) \
X(_ftello) \
X(_fwrite) \
X(_getcwd) \
X(_getenv) \
X(_gethostname) \
X(_getpagesize) \
X(_gettimeofday) \
X(_gmtime_r) \
X(_itoa) \
X(_localtime_r) \
X(_longjmp) \
X(_lseek) \
X(_malloc) \
X(_memcmp) \
X(_memcpy) \
X(_memmove) \
X(_mkdir) \
X(_opendir) \
X(_read) \
X(_readdir) \
X(_realloc) \
X(_remove) \
X(_rename) \
X(_searchpath) \
X(_setenv) \
X(_setjmp) \
X(_sigaction) \
X(_stat) \
X(_strchr) \
X(_strcmp) \
X(_strerror) \
X(_strlcat) \
X(_strlcpy) \
X(_strlen) \
X(_strncmp) \
X(_strnlen) \
X(_strpbrk) \
X(_strrchr) \
X(_strstr) \
X(_strtod) \
X(_strtok_r) \
X(_strtol) \
X(_strtoll) \
X(_strtoul) \
X(_strtoull) \
X(_uclock) \
X(_unsetenv) \
X(_vsnprintf) \
X(_vsscanf) \
X(_write)
#define EXTERN_ASM_SEMICOLON(V) extern_asm(V);
#include <sys/dxe.h>
FOR_EACH_DXE_EXPORT(EXTERN_ASM_SEMICOLON)
DXE_EXPORT_TABLE(sdl3_export_syms)
FOR_EACH_DXE_EXPORT(DXE_EXPORT_ASM)
DXE_EXPORT_END
static __attribute__((constructor)) void sdl3_export_syms_auto_register (void)
{
dlregsym (sdl3_export_syms);
}
#endif
#endif /* SDL_main_impl_h_ */

View file

@ -256,6 +256,7 @@ function(add_sdl_test_executable TARGET)
if(AST_NAME83)
set_property(TARGET ${TARGET} PROPERTY OUTPUT_NAME "${AST_NAME83}")
endif()
target_compile_definitions(${TARGET} PRIVATE SDL_INCLUDE_INTTYPES_H)
endif()
if(OPENGL_FOUND)