scripts: waifulib: add tool for building with Emscripten's Clang wrapper

This commit is contained in:
Alibek Omarov
2025-06-14 15:18:53 +05:00
parent 1bf5909023
commit e22dadc36f
2 changed files with 113 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- coding: utf-8 vi:ts=4:noexpandtab
from waflib.Tools import ccroot, gcc, gxx
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method
from waflib import Utils
@conf
def get_emscripten_version(conf, cc):
k = conf.get_cc_version(cc, clang=True)
if '__EMSCRIPTEN__' not in k:
conf.fatal('Could not determine the emscripten compiler version')
conf.env.DEST_OS = 'emscripten'
conf.env.DEST_CPU = 'wasm'
@conf
def find_emcc(conf):
cc = conf.find_program(['emcc'], var='CC')
conf.get_emscripten_version(cc)
conf.env.CC_NAME = 'clang'
@conf
def find_emxx(conf):
cxx = conf.find_program(['em++'], var='CXX')
conf.get_emscripten_version(cxx)
conf.env.CXX_NAME = 'clang'
@conf
def gcc_modifier_emscripten(conf):
v = conf.env
conf.env.cshlib_PATTERN = 'lib%s.wasm'
conf.env.cprogram_PATTERN = '%s.html'
conf.env.CFLAGS_cshlib = ['-fPIC', '-sSIDE_MODULE=1']
conf.env.CFLAGS_cstlib = ['-fPIC']
conf.env.CFLAGS_cprogram = ['-sMAIN_MODULE=1']
conf.env.LINKFLAGS_cshlib = ['-sSIDE_MODULE=1']
conf.env.LINKFLAGS_cprogram = ['-sMAIN_MODULE=1']
@conf
def gxx_modifier_emscripten(conf):
v = conf.env
conf.env.cxxshlib_PATTERN = 'lib%s.wasm'
conf.env.cxxprogram_PATTERN = '%s.html'
conf.env.CXXFLAGS_cxxshlib = ['-fPIC', '-sSIDE_MODULE=1']
conf.env.CXXFLAGS_cxxstlib = ['-fPIC']
conf.env.CXXFLAGS_cxxprogram = ['-sMAIN_MODULE=1']
conf.env.LINKFLAGS_cxxshlib = ['-sSIDE_MODULE=1']
conf.env.LINKFLAGS_cxxprogram = ['-sMAIN_MODULE=1']
@feature('cxxprogram', 'cprogram')
@after_method('apply_link')
def apply_indexhtml(self):
if self.env.DEST_OS != 'emscripten':
return
tsk = self.link_task
node = tsk.outputs[0]
tsk.outputs.append(node.change_ext('.js'))
tsk.outputs.append(node.change_ext('.wasm'))
if '--preload-file' in getattr(self, 'linkflags', []) + self.env.LINKFLAGS:
tsk.outputs.append(node.change_ext('.data'))
inst_to = getattr(self, 'special_install_path', None)
if inst_to:
self.add_install_as(install_to=inst_to + '/index.html',
install_from=tsk.outputs[0], chmod=Utils.O644, task=tsk)
self.add_install_files(install_to=inst_to,
install_from=tsk.outputs[1:], chmod=Utils.O644, task=tsk)
def configure(conf):
if not conf.env.CC:
conf.find_emcc()
conf.gcc_common_flags()
conf.gcc_modifier_platform()
conf.cc_load_tools()
conf.cc_add_flags()
conf.link_add_flags()
if not conf.env.AR:
conf.find_program(['emar'], var='AR')
conf.find_ar()
if not conf.env.CXX:
conf.find_emxx()
conf.gxx_common_flags()
conf.gxx_modifier_platform()
conf.cxx_load_tools()
conf.cxx_add_flags()
conf.link_add_flags()

View File

@@ -539,6 +539,8 @@ def options(opt):
help='enable building for PlayStation Vita [default: %(default)s]')
xc.add_option('--sailfish', action='store', dest='SAILFISH', default = None,
help='enable building for Sailfish/Aurora')
xc.add_option('--emscripten', action='store_true', dest='EMSCRIPTEN', default = None,
help='enable building for Emscripten')
def configure(conf):
if conf.options.ANDROID_OPTS:
@@ -627,11 +629,21 @@ def configure(conf):
conf.env.LIB_M = ['m']
conf.env.VRTLD = ['vrtld']
conf.env.DEST_OS = 'psvita'
elif conf.options.EMSCRIPTEN:
# Emscripten compiler is just wrapper to clang
# But we need to setup platform modifiers, they all are contained inside c_emscripten.py for now
# In future, that could be upstreamed to waf itself and this wouldn't be needed
conf.environ['CC'] = 'emcc'
conf.environ['CXX'] = 'em++'
conf.environ['AR'] = 'emar'
conf.environ['STRIP'] = 'emstrip'
conf.environ['OBJCOPY'] = 'llvm-objcopy'
conf.load('c_emscripten')
conf.env.MAGX = conf.options.MAGX
conf.env.MSVC_WINE = conf.options.MSVC_WINE
conf.env.SAILFISH = conf.options.SAILFISH
MACRO_TO_DESTOS = OrderedDict({ '__ANDROID__' : 'android', '__SWITCH__' : 'nswitch', '__vita__' : 'psvita', '__wasi__': 'wasi' })
MACRO_TO_DESTOS = OrderedDict({ '__ANDROID__' : 'android', '__SWITCH__' : 'nswitch', '__vita__' : 'psvita', '__wasi__': 'wasi', '__EMSCRIPTEN__' : 'emscripten' })
for k in c_config.MACRO_TO_DESTOS:
MACRO_TO_DESTOS[k] = c_config.MACRO_TO_DESTOS[k] # ordering is important
c_config.MACRO_TO_DESTOS = MACRO_TO_DESTOS