diff --git a/engine/platform/nswitch/sys_nswitch.c b/engine/platform/nswitch/sys_nswitch.c index 8165f211..61203e1a 100644 --- a/engine/platform/nswitch/sys_nswitch.c +++ b/engine/platform/nswitch/sys_nswitch.c @@ -28,52 +28,37 @@ static int nxlink_sock = -1; /* HACKHACK: force-export stuff required by the dynamic libs */ -// libunwind stuff for C++ exceptions, required by filesystem_stdio -extern void *_Unwind_GetIPInfo; -extern void *_Unwind_Resume_or_Rethrow; -extern void *_Unwind_GetRegionStart; +// this is required by some std::filesystem crap in libstdc++ +// we don't have it defined in our libc +long pathconf( const char *path, int name ) { return -1; } + +// part of libunwind; required by any dynamic lib that uses C++ exceptions extern void *_Unwind_Resume; -extern void *_Unwind_DeleteException; -extern void *_Unwind_RaiseException; -extern void *_Unwind_SetIP; -extern void *_Unwind_GetTextRelBase; -extern void *_Unwind_GetLanguageSpecificData; -extern void *_Unwind_SetGR; -extern void *_Unwind_GetDataRelBase; // these are macros in our libc, so we need to wrap them -static int tolower_fn(int c) { return tolower(c); } -static int toupper_fn(int c) { return toupper(c); } -static int isalnum_fn(int c) { return isalnum(c); } -static int isalpha_fn(int c) { return isalpha(c); } +static int tolower_fn( int c ) { return tolower( c ); } +static int toupper_fn( int c ) { return toupper( c ); } +static int isalnum_fn( int c ) { return isalnum( c ); } +static int isalpha_fn( int c ) { return isalpha( c ); } static const solder_export_t aux_exports[] = { - SOLDER_EXPORT("tolower", tolower_fn), - SOLDER_EXPORT("toupper", toupper_fn), - SOLDER_EXPORT("isalnum", isalnum_fn), - SOLDER_EXPORT("isalpha", isalpha_fn), - SOLDER_EXPORT_SYMBOL(mkdir), - SOLDER_EXPORT_SYMBOL(remove), - SOLDER_EXPORT_SYMBOL(rename), - SOLDER_EXPORT_SYMBOL(fsync), - SOLDER_EXPORT_SYMBOL(strchrnul), - SOLDER_EXPORT_SYMBOL(stpcpy), - SOLDER_EXPORT_SYMBOL(_Unwind_GetIPInfo), - SOLDER_EXPORT_SYMBOL(_Unwind_Resume_or_Rethrow), - SOLDER_EXPORT_SYMBOL(_Unwind_GetRegionStart), - SOLDER_EXPORT_SYMBOL(_Unwind_Resume), - SOLDER_EXPORT_SYMBOL(_Unwind_DeleteException), - SOLDER_EXPORT_SYMBOL(_Unwind_RaiseException), - SOLDER_EXPORT_SYMBOL(_Unwind_SetIP), - SOLDER_EXPORT_SYMBOL(_Unwind_GetTextRelBase), - SOLDER_EXPORT_SYMBOL(_Unwind_GetLanguageSpecificData), - SOLDER_EXPORT_SYMBOL(_Unwind_SetGR), - SOLDER_EXPORT_SYMBOL(_Unwind_GetDataRelBase), + SOLDER_EXPORT( "tolower", tolower_fn ), + SOLDER_EXPORT( "toupper", toupper_fn ), + SOLDER_EXPORT( "isalnum", isalnum_fn ), + SOLDER_EXPORT( "isalpha", isalpha_fn ), + SOLDER_EXPORT_SYMBOL( mkdir ), + SOLDER_EXPORT_SYMBOL( remove ), + SOLDER_EXPORT_SYMBOL( rename ), + SOLDER_EXPORT_SYMBOL( pathconf ), + SOLDER_EXPORT_SYMBOL( fsync ), + SOLDER_EXPORT_SYMBOL( strchrnul ), + SOLDER_EXPORT_SYMBOL( stpcpy ), + SOLDER_EXPORT_SYMBOL( _Unwind_Resume ), }; const solder_export_t *__solder_aux_exports = aux_exports; -const size_t __solder_num_aux_exports = sizeof(aux_exports) / sizeof(*aux_exports); +const size_t __solder_num_aux_exports = sizeof( aux_exports ) / sizeof( *aux_exports ); /* end of export crap */ diff --git a/engine/wscript b/engine/wscript index 1639147e..d4b32f73 100644 --- a/engine/wscript +++ b/engine/wscript @@ -49,13 +49,21 @@ def configure(conf): if not conf.check_cc( fragment='int main(){ int i = socket();}', lib = 'wattcpwl', mandatory=False ): conf.define('XASH_NO_NETWORK',1) elif conf.env.DEST_OS == 'nswitch': + # re-enable undefined reference errors + conf.env.CXXFLAGS += ['-Wl,--no-undefined'] + conf.env.CFLAGS += ['-Wl,--no-undefined'] + # allow the SDL2 sanity check to complete properly by linking in libstdc++ and lm normally + conf.env.LDFLAGS += ['-lstdc++', '-lm'] conf.load('sdl2') if not conf.env.HAVE_SDL2: conf.fatal('SDL2 not availiable! Install switch-sdl2!') conf.define('XASH_SDL', 2) - # disallow undefined symbols - conf.env.append_unique('CXXFLAGS', '-Wl,--no-undefined') - conf.env.append_unique('CFLAGS', '-Wl,--no-undefined') + # HACK: now link in the entirety of libstdc++ so that dynamic libs could use all of it without manual exporting + # we can't do this right away because std::filesystem will complain about not having pathconf(), + # which we have defined in sys_nswitch.c + conf.env.LDFLAGS.remove('-lstdc++') + conf.env.LDFLAGS.remove('-lm') + conf.env.LDFLAGS += ['-Wl,--whole-archive', '-lstdc++', '-Wl,--no-whole-archive', '-lm'] elif conf.options.FBDEV_SW: # unused, XASH_LINUX without XASH_SDL gives fbdev & alsa support # conf.define('XASH_FBDEV', 1) diff --git a/scripts/waifulib/xcompile.py b/scripts/waifulib/xcompile.py index f2fa4091..34700ddd 100644 --- a/scripts/waifulib/xcompile.py +++ b/scripts/waifulib/xcompile.py @@ -427,8 +427,9 @@ class NintendoSwitch: return linkflags def ldflags(self): - # system libraries implicitly require math and C++ standard library - ldflags = ['-lm', '-lstdc++'] + # NOTE: shared libraries should be built without standard libs, so that they could import their contents from the NRO, + # but executables, including the SDL2 sanity check, will generally require libstdc++ and libm, which we will add manually + ldflags = [] # ['-lm', '-lstdc++'] return ldflags def options(opt): diff --git a/wscript b/wscript index 541c8adc..03105e6c 100644 --- a/wscript +++ b/wscript @@ -246,8 +246,8 @@ def configure(conf): cflags, linkflags = conf.get_optimization_flags() # on the Switch, allow undefined symbols by default, which is needed for libsolder to work - # we'll specifically disallow for the engine executable - # additionally, shared libs are linked without libc + # we'll specifically disallow them for the engine executable + # additionally, shared libs are linked without standard libs, we'll add those back in the engine wscript if conf.env.DEST_OS == 'nswitch': linkflags.remove('-Wl,--no-undefined') conf.env.append_unique('LINKFLAGS_cshlib', ['-nostdlib', '-nostartfiles']) @@ -303,7 +303,9 @@ def configure(conf): if conf.env.DEST_OS != 'win32': if conf.env.DEST_OS == 'nswitch': - conf.check_cfg(package='solder', args='--cflags --libs', uselib_store='SOLDER') + conf.check_cfg(package='solder', args='--cflags --libs', uselib_store='SOLDER', mandatory=True) + if conf.env.HAVE_SOLDER and conf.env.LIB_SOLDER and conf.options.BUILD_TYPE == 'debug': + conf.env.LIB_SOLDER[0] += 'd' # load libsolderd in debug mode else: conf.check_cc(lib='dl', mandatory=False)