Browse Source

nswitch: do not link libstdc++ into dynamic libraries

instead only link it to the main executable with --whole-archive, letting the dynamic libs import anything they want from it
pull/2/head
fgsfds 1 year ago
parent
commit
69607d7890
  1. 59
      engine/platform/nswitch/sys_nswitch.c
  2. 14
      engine/wscript
  3. 5
      scripts/waifulib/xcompile.py
  4. 8
      wscript

59
engine/platform/nswitch/sys_nswitch.c

@ -28,52 +28,37 @@ static int nxlink_sock = -1; @@ -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 */

14
engine/wscript

@ -49,13 +49,21 @@ def configure(conf): @@ -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)

5
scripts/waifulib/xcompile.py

@ -427,8 +427,9 @@ class NintendoSwitch: @@ -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):

8
wscript

@ -246,8 +246,8 @@ def configure(conf): @@ -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): @@ -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)

Loading…
Cancel
Save