Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options support to contrib ports (contrib ports part 3) #21276

Merged
merged 15 commits into from
Feb 8, 2024
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"]'
ypujante marked this conversation as resolved.
Show resolved Hide resolved
])

@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
sbc100 marked this conversation as resolved.
Show resolved Hide resolved
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]
ypujante marked this conversation as resolved.
Show resolved Hide resolved
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:
ypujante marked this conversation as resolved.
Show resolved Hide resolved
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',
ypujante marked this conversation as resolved.
Show resolved Hide resolved
'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)'
Loading