Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3025,7 +3025,7 @@ def test_sdl2_image_formats(self):
self.btest_exit('test_sdl2_image.c', 600, args=[
'--preload-file', 'screenshot.jpg',
'-DSCREENSHOT_DIRNAME="/"', '-DSCREENSHOT_BASENAME="screenshot.jpg"', '-DBITSPERPIXEL=24', '-DNO_PRELOADED',
'-sUSE_SDL=2', '-sUSE_SDL_IMAGE=2', '-sSDL2_IMAGE_FORMATS=["jpg"]'
'--use-port=sdl2', '--use-port=sdl2_image?formats=["jpg"]'
])

@no_wasm64('SDL2 + wasm64')
Expand Down
2 changes: 1 addition & 1 deletion test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -2372,7 +2372,7 @@ def test_sdl2_ttf(self):
def test_contrib_ports(self):
# Verify that contrib ports can be used (using the only contrib port available ATM, but can be replaced
# with a different contrib port when there is another one
self.emcc(test_file('other/test_contrib_ports.cpp'), ['--use-port=contrib.glfw3'])
self.emcc(test_file('other/test_contrib_ports.cpp'), ['--use-port=contrib.glfw3?disableWarning=true'])

def test_link_memcpy(self):
# memcpy can show up *after* optimizations, so after our opportunity to link in libc, so it must be special-cased
Expand Down
12 changes: 11 additions & 1 deletion tools/ports/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,20 @@ def add_deps(node):
add_deps(port)


def handle_use_port_arg(settings, name):
def handle_use_port_arg(settings, arg):
args = arg.split('?', 1)
name, options = args[0], args[1] if len(args) == 2 else None
if name not in ports_by_name:
utils.exit_with_error(f'Invalid port name: {name} used with --use-port')
ports_needed.add(name)
if options:
port = ports_by_name[name]
if not hasattr(port, 'handle_options'):
utils.exit_with_error(f'Invalid options for port {name}: No options available')
else:
error = port.handle_options(options)
if error is not None:
utils.exit_with_error(f'Invalid options for port {name}: {error}')


def get_needed_ports(settings):
Expand Down
67 changes: 60 additions & 7 deletions tools/ports/contrib/glfw3.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,44 @@
# found in the LICENSE file.

import os

TAG = '1.0.4'
HASH = 'c3c96718e5d2b37df434a46c4a93ddfd9a768330d33f0d6ce2d08c139752894c2421cdd0fefb800fe41fafc2bbe58c8f22b8aa2849dc4fc6dde686037215cfad'
from urllib.parse import parse_qs

# contrib port information (required)
URL = 'https://github.com/pongasoft/emscripten-glfw'
DESCRIPTION = 'This project is an emscripten port of GLFW written in C++ for the web/webassembly platform'
LICENSE = 'Apache 2.0 license'

OPTIONS = {
'tag': 'The git tag to use a different release',
'hash': 'The sha512 of the release associated to the tag (can be omitted)',
'disableWarning': 'Boolean to disable warnings emitted by the library',
'disableJoystick': 'Boolean to disable support for joystick entirely',
'disableMultiWindow': 'Boolean to disable multi window support which makes the code smaller and faster'
}

# user options (from --use-port)
opts = {
'tag': '1.0.4',
'hash': 'c3c96718e5d2b37df434a46c4a93ddfd9a768330d33f0d6ce2d08c139752894c2421cdd0fefb800fe41fafc2bbe58c8f22b8aa2849dc4fc6dde686037215cfad',
'disableWarning': False,
'disableJoystick': False,
'disableMultiWindow': False
}


def get_lib_name(settings):
return 'lib_contrib.glfw3.a'
return (f'lib_contrib.glfw3_{opts["tag"]}' +
('-nw' if opts['disableWarning'] else '') +
('-nj' if opts['disableJoystick'] else '') +
('-sw' if opts['disableMultiWindow'] else '') +
'.a')


def get(ports, settings, shared):
# get the port
ports.fetch_project('contrib.glfw3', f'https://github.com/pongasoft/emscripten-glfw/releases/download/v{TAG}/emscripten-glfw3-{TAG}.zip', sha512hash=HASH)
ports.fetch_project('contrib.glfw3',
f'https://github.com/pongasoft/emscripten-glfw/releases/download/v{opts["tag"]}/emscripten-glfw3-{opts["tag"]}.zip',
sha512hash=opts['hash'])

def create(final):
root_path = os.path.join(ports.get_dir(), 'contrib.glfw3')
Expand All @@ -29,8 +50,16 @@ def create(final):
for source_include_path in source_include_paths:
ports.install_headers(source_include_path, target='GLFW')

# this should be an option but better to disable for now...
flags = ['-DEMSCRIPTEN_GLFW3_DISABLE_WARNING']
flags = []

if opts['disableWarning']:
flags += ['-DEMSCRIPTEN_GLFW3_DISABLE_WARNING']

if opts['disableJoystick']:
flags += ['-DEMSCRIPTEN_GLFW3_DISABLE_JOYSTICK']

if opts['disableMultiWindow']:
flags += ['-DEMSCRIPTEN_GLFW3_DISABLE_MULTI_WINDOW_SUPPORT']

ports.build_port(source_path, final, 'contrib.glfw3', includes=source_include_paths, flags=flags)

Expand All @@ -52,3 +81,27 @@ def linker_setup(ports, settings):
# includes
def process_args(ports):
return ['-isystem', ports.get_include_dir('contrib.glfw3')]


def handle_options(options):
try:
oqs = parse_qs(options, strict_parsing=True)
except ValueError as error:
return f'{options} is not valid: {error}. Available options are {OPTIONS}.'

if not set(oqs.keys()).issubset(OPTIONS.keys()):
return f'{options} is not valid. Available options are {OPTIONS}.'

for option, values in oqs.items():
value = values[-1] # ignore multiple definitions (last one wins)
if isinstance(opts[option], bool):
if value.lower() in {'true', 'false'}:
opts[option] = value.lower() == 'true'
else:
return f'{option} is expecting a boolean, got {value}'
else:
opts[option] = value

# in the event that only 'tag' is provided, clear 'hash'
if 'tag' in oqs and 'hash' not in oqs:
opts['hash'] = None
35 changes: 28 additions & 7 deletions tools/ports/sdl2_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# found in the LICENSE file.

import os
import re

TAG = 'release-2.6.0'
HASH = '2175d11a90211871f2289c8d57b31fe830e4b46af7361925c2c30cd521c1c677d2ee244feb682b6d3909cf085129255934751848fc81b480ea410952d990ffe0'
Expand All @@ -14,14 +15,22 @@
'sdl2_image_png': {'SDL2_IMAGE_FORMATS': ["png"]},
}

# user options (from --use-port)
opts = {
'formats': set()
}


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


def get_formats(settings):
return set(settings.SDL2_IMAGE_FORMATS).union(opts['formats'])


def get_lib_name(settings):
settings.SDL2_IMAGE_FORMATS.sort()
formats = '-'.join(settings.SDL2_IMAGE_FORMATS)
formats = '-'.join(sorted(get_formats(settings)))

libname = 'libSDL2_image'
if formats != '':
Expand All @@ -44,13 +53,15 @@ def create(final):

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

for fmt in settings.SDL2_IMAGE_FORMATS:
formats = get_formats(settings)

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

if 'png' in settings.SDL2_IMAGE_FORMATS:
if 'png' in formats:
defs += ['-sUSE_LIBPNG']

if 'jpg' in settings.SDL2_IMAGE_FORMATS:
if 'jpg' in formats:
defs += ['-sUSE_LIBJPEG']

ports.build_port(src_dir, final, 'sdl2_image', flags=defs, srcs=srcs)
Expand All @@ -64,13 +75,23 @@ def clear(ports, settings, shared):

def process_dependencies(settings):
settings.USE_SDL = 2
if 'png' in settings.SDL2_IMAGE_FORMATS:
formats = get_formats(settings)
if 'png' in formats:
deps.append('libpng')
settings.USE_LIBPNG = 1
if 'jpg' in settings.SDL2_IMAGE_FORMATS:
if 'jpg' in formats:
deps.append('libjpeg')
settings.USE_LIBJPEG = 1


def handle_options(options):
if options.startswith('formats='):
options = options.split('=', 1)[1]
opts['formats'] = {format.lower() for format in re.findall(r'\b\w+\b', options)}
else:
return f'{options} is not supported (syntax is --use-port=sdl2_image?formats=[x,y,z])'
return None


def show():
return 'sdl2_image (-sUSE_SDL_IMAGE=2 or --use-port=sdl2_image; zlib license)'