Skip to content

Commit 63eba62

Browse files
authored
Merge pull request #3141 from pygame-community/sdl3_compile
Add meson flag for compiling with SDL3
2 parents 3435256 + 464e206 commit 63eba62

14 files changed

+320
-60
lines changed

.github/workflows/build-sdl3.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# SDL3 porting is WIP
2+
name: SDL3 build
3+
4+
# Run CI only when a release is created, on changes to main branch, or any PR
5+
# to main. Do not run CI on any other branch. Also, skip any non-source changes
6+
# from running on CI
7+
on:
8+
push:
9+
branches: main
10+
paths-ignore:
11+
- 'docs/**'
12+
- 'examples/**'
13+
- '.gitignore'
14+
- '*.rst'
15+
- '*.md'
16+
- '.github/workflows/*.yml'
17+
# re-include current file to not be excluded
18+
- '!.github/workflows/build-sdl3.yml'
19+
20+
pull_request:
21+
branches: main
22+
paths-ignore:
23+
- 'docs/**'
24+
- 'examples/**'
25+
- '.gitignore'
26+
- '*.rst'
27+
- '*.md'
28+
- '.github/workflows/*.yml'
29+
# re-include current file to not be excluded
30+
- '!.github/workflows/build-sdl3.yml'
31+
32+
# the github release drafter can call this workflow
33+
workflow_call:
34+
35+
concurrency:
36+
group: ${{ github.workflow }}-${{ github.ref }}-ubuntu-sdist
37+
cancel-in-progress: true
38+
39+
jobs:
40+
build:
41+
runs-on: ${{ matrix.os }}
42+
strategy:
43+
fail-fast: false # if a particular matrix build fails, don't skip the rest
44+
matrix:
45+
os: [ubuntu-24.04, windows-latest, macos-14]
46+
47+
env:
48+
# Pip now forces us to either make a venv or set this flag, so we will do
49+
# this
50+
PIP_BREAK_SYSTEM_PACKAGES: 1
51+
# We are using dependencies installed from apt
52+
PG_DEPS_FROM_SYSTEM: 1
53+
54+
steps:
55+
- uses: actions/checkout@v4.2.0
56+
57+
- name: Install deps (linux)
58+
if: matrix.os == 'ubuntu-24.04'
59+
run: sudo apt-get install libfreetype6-dev libportmidi-dev python3-dev
60+
61+
- name: Install deps (mac)
62+
if: matrix.os == 'macos-14'
63+
run: brew install freetype portmidi
64+
65+
# taken from https://wiki.libsdl.org/SDL3/Installation
66+
- name: Install SDL3
67+
if: matrix.os != 'windows-latest'
68+
run: |
69+
git clone https://github.com/libsdl-org/SDL
70+
cd SDL
71+
mkdir build
72+
cd build
73+
cmake -DCMAKE_BUILD_TYPE=Release ..
74+
cmake --build . --config Release --parallel
75+
sudo cmake --install . --config Release
76+
77+
- name: Make sdist and install it
78+
run: >
79+
python3 -m pip install . -v -Csetup-args=-Dsdl_api=3
80+
-Csetup-args=-Dimage=disabled
81+
-Csetup-args=-Dmixer=disabled
82+
-Csetup-args=-Dfont=disabled
83+
84+
# - name: Run tests
85+
# env:
86+
# SDL_VIDEODRIVER: "dummy"
87+
# SDL_AUDIODRIVER: "disk"
88+
# run: python3 -m pygame.tests -v --exclude opengl,music,timing --time_out 300

buildconfig/download_win_prebuilt.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ def get_urls(x86=True, x64=True):
8282
'9121a66a4bc45d657d0c15300cee6c7f37ade51d',
8383
],
8484
[
85+
'https://github.com/libsdl-org/SDL/releases/download/preview-3.1.3/SDL3-devel-3.1.3-VC.zip',
86+
'8e4d7104193ba976406fe9968301de6f6b57f342'
87+
],
88+
[
8589
'https://github.com/pygame-community/SDL_image/releases/download/2.8.2-pgce/SDL2_image-devel-2.8.2-VCpgce.zip',
8690
'983484dd816abf25cdd5bce88ac69dbca1ea713a'
8791
],
@@ -242,6 +246,17 @@ def copy(src, dst):
242246
'SDL2-2.30.7'
243247
)
244248
)
249+
copy(
250+
os.path.join(
251+
temp_dir,
252+
'SDL3-devel-3.1.3-VC/SDL3-3.1.3'
253+
),
254+
os.path.join(
255+
move_to_dir,
256+
prebuilt_dir,
257+
'SDL3-3.1.3'
258+
)
259+
)
245260

246261
def update(x86=True, x64=True):
247262
move_to_dir = "."

meson.build

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ endif
7878

7979
pg_dir = py.get_install_dir() / pg
8080

81+
sdl_api = get_option('sdl_api')
82+
sdl = 'SDL@0@'.format(sdl_api)
83+
sdl_mixer = '@0@_mixer'.format(sdl)
84+
sdl_ttf = '@0@_ttf'.format(sdl)
85+
sdl_image = '@0@_image'.format(sdl)
86+
87+
if sdl_api == 3
88+
add_global_arguments('-DPG_SDL3=1', language: 'c')
89+
endif
90+
8191
pg_inc_dirs = []
8292
pg_lib_dirs = []
8393
if plat == 'win' and host_machine.cpu_family().startswith('x86')
@@ -99,60 +109,68 @@ if plat == 'win' and host_machine.cpu_family().startswith('x86')
99109
)
100110
endif
101111

102-
sdl_ver = '2.30.7'
112+
sdl_ver = (sdl_api == 3) ? '3.1.3' : '2.30.7'
103113
sdl_image_ver = '2.8.2'
104114
sdl_mixer_ver = '2.8.0'
105115
sdl_ttf_ver = '2.22.0'
106116

107117
dlls = []
108118

109-
# SDL2
110-
sdl_dir = prebuilt_dir / 'SDL2-@0@'.format(sdl_ver)
119+
# SDL
120+
sdl_dir = prebuilt_dir / '@0@-@1@'.format(sdl, sdl_ver)
111121
sdl_lib_dir = sdl_dir / 'lib' / arch_suffix
112122
pg_inc_dirs += fs.relative_to(sdl_dir / 'include', base_dir)
113123
pg_lib_dirs += sdl_lib_dir
114-
dlls += sdl_lib_dir / 'SDL2.dll'
115-
116-
# SDL2_image
117-
sdl_image_dir = prebuilt_dir / 'SDL2_image-@0@'.format(sdl_image_ver)
118-
sdl_image_lib_dir = sdl_image_dir / 'lib' / arch_suffix
119-
pg_inc_dirs += fs.relative_to(sdl_image_dir / 'include', base_dir)
120-
pg_lib_dirs += sdl_image_lib_dir
121-
dlls += [
122-
sdl_image_lib_dir / 'SDL2_image.dll',
123-
sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll',
124-
sdl_image_lib_dir / 'optional' / 'libpng16-16.dll',
125-
sdl_image_lib_dir / 'optional' / 'libtiff-5.dll',
126-
sdl_image_lib_dir / 'optional' / 'libwebp-7.dll',
127-
sdl_image_lib_dir / 'optional' / 'libwebpdemux-2.dll',
128-
]
129-
130-
# SDL2_mixer
131-
sdl_mixer_dir = prebuilt_dir / 'SDL2_mixer-@0@'.format(sdl_mixer_ver)
132-
sdl_mixer_lib_dir = sdl_mixer_dir / 'lib' / arch_suffix
133-
pg_inc_dirs += fs.relative_to(sdl_mixer_dir / 'include', base_dir)
134-
pg_lib_dirs += sdl_mixer_lib_dir
135-
dlls += [
136-
sdl_mixer_lib_dir / 'SDL2_mixer.dll',
137-
sdl_mixer_lib_dir / 'optional' / 'libogg-0.dll',
138-
sdl_mixer_lib_dir / 'optional' / 'libopus-0.dll',
139-
sdl_mixer_lib_dir / 'optional' / 'libopusfile-0.dll',
140-
sdl_mixer_lib_dir / 'optional' / 'libwavpack-1.dll',
141-
sdl_mixer_lib_dir / 'optional' / 'libxmp.dll',
142-
]
143-
144-
# SDL2_ttf
145-
sdl_ttf_dir = prebuilt_dir / 'SDL2_ttf-@0@'.format(sdl_ttf_ver)
146-
sdl_ttf_lib_dir = sdl_ttf_dir / 'lib' / arch_suffix
147-
pg_inc_dirs += fs.relative_to(sdl_ttf_dir / 'include', base_dir)
148-
pg_lib_dirs += sdl_ttf_lib_dir
149-
dlls += sdl_ttf_lib_dir / 'SDL2_ttf.dll'
124+
dlls += sdl_lib_dir / '@0@.dll'.format(sdl)
125+
126+
# SDL_image
127+
if get_option('image').enabled()
128+
sdl_image_dir = prebuilt_dir / '@0@-@1@'.format(sdl_image, sdl_image_ver)
129+
sdl_image_lib_dir = sdl_image_dir / 'lib' / arch_suffix
130+
pg_inc_dirs += fs.relative_to(sdl_image_dir / 'include', base_dir)
131+
pg_lib_dirs += sdl_image_lib_dir
132+
dlls += [
133+
sdl_image_lib_dir / '@0@.dll'.format(sdl_image),
134+
sdl_image_lib_dir / 'optional' / 'libjpeg-62.dll',
135+
sdl_image_lib_dir / 'optional' / 'libpng16-16.dll',
136+
sdl_image_lib_dir / 'optional' / 'libtiff-5.dll',
137+
sdl_image_lib_dir / 'optional' / 'libwebp-7.dll',
138+
sdl_image_lib_dir / 'optional' / 'libwebpdemux-2.dll',
139+
]
140+
endif
141+
142+
# SDL_mixer
143+
if get_option('mixer').enabled()
144+
sdl_mixer_dir = prebuilt_dir / '@0@-@1@'.format(sdl_mixer, sdl_mixer_ver)
145+
sdl_mixer_lib_dir = sdl_mixer_dir / 'lib' / arch_suffix
146+
pg_inc_dirs += fs.relative_to(sdl_mixer_dir / 'include', base_dir)
147+
pg_lib_dirs += sdl_mixer_lib_dir
148+
dlls += [
149+
sdl_mixer_lib_dir / '@0@.dll'.format(sdl_mixer),
150+
sdl_mixer_lib_dir / 'optional' / 'libogg-0.dll',
151+
sdl_mixer_lib_dir / 'optional' / 'libopus-0.dll',
152+
sdl_mixer_lib_dir / 'optional' / 'libopusfile-0.dll',
153+
sdl_mixer_lib_dir / 'optional' / 'libwavpack-1.dll',
154+
sdl_mixer_lib_dir / 'optional' / 'libxmp.dll',
155+
]
156+
endif
157+
158+
# SDL_ttf
159+
if get_option('font').enabled()
160+
sdl_ttf_dir = prebuilt_dir / '@0@-@1@'.format(sdl_ttf, sdl_ttf_ver)
161+
sdl_ttf_lib_dir = sdl_ttf_dir / 'lib' / arch_suffix
162+
pg_inc_dirs += fs.relative_to(sdl_ttf_dir / 'include', base_dir)
163+
pg_lib_dirs += sdl_ttf_lib_dir
164+
dlls += sdl_ttf_lib_dir / '@0@.dll'.format(sdl_ttf)
165+
endif
150166

151167
# freetype, portmidi and porttime
152-
common_lib_dir = prebuilt_dir / 'lib'
153-
pg_inc_dirs += fs.relative_to(prebuilt_dir / 'include', base_dir)
154-
pg_lib_dirs += common_lib_dir
155-
dlls += [common_lib_dir / 'freetype.dll', common_lib_dir / 'portmidi.dll']
168+
if get_option('freetype').enabled() and get_option('midi').enabled()
169+
common_lib_dir = prebuilt_dir / 'lib'
170+
pg_inc_dirs += fs.relative_to(prebuilt_dir / 'include', base_dir)
171+
pg_lib_dirs += common_lib_dir
172+
dlls += [common_lib_dir / 'freetype.dll', common_lib_dir / 'portmidi.dll']
173+
endif
156174

157175
# clean unneeded file that causes build issues
158176
unneeded_file = common_lib_dir / 'libportmidi.dll.a'
@@ -183,7 +201,7 @@ else
183201
foreach inc_dir : bases
184202
foreach sub_inc : [
185203
'',
186-
'/SDL2',
204+
'/@0@'.format(sdl),
187205
'/freetype2',
188206
]
189207
full_inc = inc_dir / 'include' + sub_inc
@@ -204,45 +222,45 @@ else
204222
endif
205223

206224
# TODO: add version constraints?
207-
sdl_dep = dependency('sdl2', required: false)
225+
sdl_dep = dependency(sdl, required: false)
208226
if not sdl_dep.found()
209227
sdl_dep = declare_dependency(
210228
include_directories: pg_inc_dirs,
211-
dependencies: cc.find_library('SDL2', dirs: pg_lib_dirs),
229+
dependencies: cc.find_library(sdl, dirs: pg_lib_dirs),
212230
)
213231
endif
214232

215233
# optional
216-
sdl_image_dep = dependency('SDL2_image', required: false)
234+
sdl_image_dep = dependency(sdl_image, required: false)
217235
if not sdl_image_dep.found()
218236
sdl_image_dep = declare_dependency(
219237
include_directories: pg_inc_dirs,
220238
dependencies: cc.find_library(
221-
'SDL2_image',
239+
sdl_image,
222240
dirs: pg_lib_dirs,
223241
required: get_option('image'),
224242
),
225243
)
226244
endif
227245

228-
sdl_mixer_dep = dependency('SDL2_mixer', required: false)
246+
sdl_mixer_dep = dependency(sdl_mixer, required: false)
229247
if not sdl_mixer_dep.found()
230248
sdl_mixer_dep = declare_dependency(
231249
include_directories: pg_inc_dirs,
232250
dependencies: cc.find_library(
233-
'SDL2_mixer',
251+
sdl_mixer,
234252
dirs: pg_lib_dirs,
235253
required: get_option('mixer'),
236254
),
237255
)
238256
endif
239257

240-
sdl_ttf_dep = dependency('SDL2_ttf', required: false)
258+
sdl_ttf_dep = dependency(sdl_ttf, required: false)
241259
if not sdl_ttf_dep.found()
242260
sdl_ttf_dep = declare_dependency(
243261
include_directories: pg_inc_dirs,
244262
dependencies: cc.find_library(
245-
'SDL2_ttf',
263+
sdl_ttf,
246264
dirs: pg_lib_dirs,
247265
required: get_option('font'),
248266
),
@@ -296,10 +314,10 @@ pg_base_deps = [sdl_dep, py_dep]
296314

297315
summary(
298316
{
299-
'SDL2': sdl_dep.found(),
300-
'SDL2_image': sdl_image_dep.found(),
301-
'SDL2_mixer': sdl_mixer_dep.found(),
302-
'SDL2_ttf': sdl_ttf_dep.found(),
317+
sdl: sdl_dep.found(),
318+
sdl_image: sdl_image_dep.found(),
319+
sdl_mixer: sdl_mixer_dep.found(),
320+
sdl_ttf: sdl_ttf_dep.found(),
303321
'freetype2': freetype_dep.found(),
304322
'portmidi': portmidi_dep.found(),
305323
'porttime': portmidi_dep.found() ? porttime_dep.found() : false,

meson_options.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ option('error_docs_missing', type: 'boolean', value: 'false')
3737
# Controls whether to do a coverage build.
3838
# This argument must be used together with the editable install.
3939
option('coverage', type: 'boolean', value: false)
40+
41+
# Controls whether to use SDL3 instead of SDL2. The default is to use SDL2
42+
option('sdl_api', type: 'integer', min: 2, max: 3, value: 2)

src_c/SDL_gfx/SDL_gfxPrimitives.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ LGPL (c) A. Schiffler
1414
#define M_PI 3.1415926535897932384626433832795
1515
#endif
1616

17-
#include "SDL.h"
17+
#ifdef PG_SDL3
18+
#include <SDL3/SDL.h>
19+
#else
20+
#include <SDL.h>
21+
#endif
1822

1923
/* Set up for C function definitions, even when using C++ */
2024
#ifdef __cplusplus

src_c/_pygame.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141
#undef PYPY_VERSION
4242
#endif
4343

44+
#ifdef PG_SDL3
45+
#include <SDL3/SDL.h>
46+
#else
4447
#include <SDL.h>
48+
#endif
4549

4650
#if SDL_VERSION_ATLEAST(3, 0, 0)
4751
#define PG_ShowCursor SDL_ShowCursor

0 commit comments

Comments
 (0)