Skip to content

Commit

Permalink
Add multi-threaded versions of sdl2_image and sdl2_ttf
Browse files Browse the repository at this point in the history
Because some possible dependencies of these libraries have `-mt`
variants (specifically png and harfbuzz) we also needs to declare `-mt`
variant of these libraries.

The reason for this is a little complex: When we find the set of
transitive dependencies of given library we select the correct variant
of each library.  This means that if we are building with `-pthread`
then we select and include the `-mt` variants of all dependencies.
However if libsdl2_image or libsdl2_ttf themselves then need to be built
we end up building them without `-pthread` which means that emcc
subprocesses will try to select and build the single threaded variants
of the dependencies.  This is mostly a serious problem because we don't
allow for nested calls to emcc (we assume all dependencies have been
already built before we try to build a given library and the we error
out with `EM_CACHE_IS_LOCKED` if that is not the case).

Testing this fix requires the cache to be setup just right so I'm not
sure its worth it.

Fixes: #22941, #20204
  • Loading branch information
sbc100 committed Nov 18, 2024
1 parent d4687ce commit 610dcf9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 11 deletions.
2 changes: 1 addition & 1 deletion test/test_sanity.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ def test_embuilder_wildcards(self):
def test_embuilder_with_use_port_syntax(self):
restore_and_set_up()
self.run_process([EMBUILDER, 'build', 'sdl2_image:formats=png,jpg', '--force'])
self.assertExists(os.path.join(config.CACHE, 'sysroot', 'lib', 'wasm32-emscripten', 'libSDL2_image_jpg-png.a'))
self.assertExists(os.path.join(config.CACHE, 'sysroot', 'lib', 'wasm32-emscripten', 'libSDL2_image-jpg-png.a'))
self.assertContained('error building port `sdl2_image:formats=invalid` | invalid is not a supported format', self.do([EMBUILDER, 'build', 'sdl2_image:formats=invalid', '--force']))

def test_embuilder_external_ports(self):
Expand Down
23 changes: 15 additions & 8 deletions tools/ports/sdl2_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

deps = ['sdl2']
variants = {
'sdl2_image_jpg': {'SDL2_IMAGE_FORMATS': ["jpg"]},
'sdl2_image_png': {'SDL2_IMAGE_FORMATS': ["png"]},
'sdl2_image-jpg': {'SDL2_IMAGE_FORMATS': ["jpg"]},
'sdl2_image-png': {'SDL2_IMAGE_FORMATS': ["png"]},
'sdl2_image-jpg-mt': {'SDL2_IMAGE_FORMATS': ["jpg"], 'PTHREADS': 1},
'sdl2_image-png-mt': {'SDL2_IMAGE_FORMATS': ["png"], 'PTHREADS': 1},
}

OPTIONS = {
Expand Down Expand Up @@ -41,7 +43,9 @@ def get_lib_name(settings):

libname = 'libSDL2_image'
if formats != '':
libname += '_' + formats
libname += '-' + formats
if settings.PTHREADS:
libname += '-mt'
return libname + '.a'


Expand All @@ -58,20 +62,23 @@ def create(final):
IMG_tif.c IMG_xcf.c IMG_xpm.c IMG_xv.c IMG_webp.c IMG_ImageIO.m
IMG_avif.c IMG_jxl.c IMG_svg.c IMG_qoi.c'''.split()

defs = ['-O2', '-sUSE_SDL=2', '-Wno-format-security']
flags = ['-O2', '-sUSE_SDL=2', '-Wno-format-security']

formats = get_formats(settings)

for fmt in formats:
defs.append('-DLOAD_' + fmt.upper())
flags.append('-DLOAD_' + fmt.upper())

if 'png' in formats:
defs += ['-sUSE_LIBPNG']
flags += ['-sUSE_LIBPNG']

if 'jpg' in formats:
defs += ['-sUSE_LIBJPEG']
flags += ['-sUSE_LIBJPEG']

ports.build_port(src_dir, final, 'sdl2_image', flags=defs, srcs=srcs)
if settings.PTHREADS:
flags += ['-pthread']

ports.build_port(src_dir, final, 'sdl2_image', flags=flags, srcs=srcs)

return [shared.cache.get_lib(libname, create, what='port')]

Expand Down
12 changes: 10 additions & 2 deletions tools/ports/sdl2_ttf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,33 @@

deps = ['freetype', 'sdl2', 'harfbuzz']

variants = {'sdl2_ttf-mt': {'PTHREADS': 1}}


def needed(settings):
return settings.USE_SDL_TTF == 2


def get_lib_name(settings):
return 'libSDL2_ttf' + ('-mt' if settings.PTHREADS else '') + '.a'


def get(ports, settings, shared):
ports.fetch_project('sdl2_ttf', f'https://github.com/libsdl-org/SDL_ttf/archive/{TAG}.zip', sha512hash=HASH)

def create(final):
src_root = ports.get_dir('sdl2_ttf', 'SDL_ttf-' + TAG)
ports.install_headers(src_root, target='SDL2')
flags = ['-DTTF_USE_HARFBUZZ=1', '-sUSE_SDL=2', '-sUSE_FREETYPE', '-sUSE_HARFBUZZ']
if settings.PTHREADS:
flags += ['-pthread']
ports.build_port(src_root, final, 'sdl2_ttf', flags=flags, srcs=['SDL_ttf.c'])

return [shared.cache.get_lib('libSDL2_ttf.a', create, what='port')]
return [shared.cache.get_lib(get_lib_name(settings), create, what='port')]


def clear(ports, settings, shared):
shared.cache.erase_lib('libSDL2_ttf.a')
shared.cache.erase_lib(get_lib_name(settings))


def process_dependencies(settings):
Expand Down

0 comments on commit 610dcf9

Please sign in to comment.