mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-09 21:52:05 +08:00
Nintendo Switch support (again)
This commit is contained in:
@@ -169,4 +169,8 @@ def get_optimization_flags(conf):
|
||||
if conf.options.POLLY:
|
||||
cflags += conf.get_flags_by_compiler(POLLY_CFLAGS, conf.env.COMPILER_CC)
|
||||
|
||||
if conf.env.DEST_OS == 'nswitch' and conf.options.BUILD_TYPE == 'debug':
|
||||
# enable remote debugger
|
||||
cflags.append('-DNSWITCH_DEBUG')
|
||||
|
||||
return cflags, linkflags
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# encoding: utf-8
|
||||
# nswitch.py -- switch NRO task
|
||||
# Copyright (C) 2018 a1batross
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
from waflib.Tools import ccroot
|
||||
from waflib import *
|
||||
|
||||
def configure(conf):
|
||||
conf.find_program('elf2nro')
|
||||
|
||||
v = conf.env
|
||||
|
||||
v.ELF2NRO_NACP_F = ['--nacp=']
|
||||
v.ELF2NRO_ICON_F = ['--icon=']
|
||||
|
||||
class elf2nro(Task.Task):
|
||||
color = 'RED'
|
||||
run_str = '${ELF2NRO} ${ELFFILE} ${TGT} ${ELF2NRO_NACP_F?NACP}${NACP} ${ELF2NRO_ICON_F?ICON}${ICON}'
|
||||
|
||||
def keyword(self):
|
||||
if Logs.colors_lst['USE']: # red/blue switch colors :)
|
||||
return '%sConverting to NRO' % Logs.colors_lst['CYAN']
|
||||
return 'Converting to NRO'
|
||||
|
||||
@TaskGen.feature('cxxprogram')
|
||||
@TaskGen.after_method('apply_link')
|
||||
def apply_nro(self):
|
||||
elffile = self.link_task.outputs[0]
|
||||
|
||||
nodes = [elffile]
|
||||
|
||||
def add_source_file(ctx, nodes, f):
|
||||
if f:
|
||||
if isinstance(f, str):
|
||||
node = ctx.path.make_node(f)
|
||||
elif isinstance(f, Node.Node):
|
||||
node = f
|
||||
|
||||
nodes += [node]
|
||||
return node
|
||||
return None
|
||||
|
||||
nacpfile = add_source_file(self, nodes, getattr(self, 'nacp', None))
|
||||
iconfile = add_source_file(self, nodes, getattr(self, 'icon', None))
|
||||
self.env.ELFFILE = str(elffile)
|
||||
if nacpfile: self.env.NACP = str(nacpfile)
|
||||
if iconfile: self.env.ICON = str(iconfile)
|
||||
|
||||
tsk = self.nro_task = self.create_task('elf2nro', nodes)
|
||||
self.nro_task.set_outputs(nodes[0].change_ext('.nro'))
|
||||
|
||||
inst_to = getattr(self, 'nro_install_path', None)
|
||||
if inst_to:
|
||||
self.add_install_files(install_to=inst_to,
|
||||
install_from=tsk.outputs[:], chmod=Utils.O755, task=tsk)
|
||||
@@ -30,6 +30,8 @@ ANDROID_NDK_API_MIN = { 10: 3, 19: 16, 20: 16, 23: 16, 25: 19 } # minimal API le
|
||||
ANDROID_STPCPY_API_MIN = 21 # stpcpy() introduced in SDK 21
|
||||
ANDROID_64BIT_API_MIN = 21 # minimal API level that supports 64-bit targets
|
||||
|
||||
NSWITCH_ENVVARS = ['DEVKITPRO']
|
||||
|
||||
# This class does support ONLY r10e and r19c/r20 NDK
|
||||
class Android:
|
||||
ctx = None # waf context
|
||||
@@ -348,6 +350,87 @@ class Android:
|
||||
ldflags += ['-march=armv5te']
|
||||
return ldflags
|
||||
|
||||
class NintendoSwitch:
|
||||
ctx = None # waf context
|
||||
arch = "aarch64"
|
||||
dkp_dir = None
|
||||
portlibs_dir = None
|
||||
dka64_dir = None
|
||||
libnx_dir = None
|
||||
|
||||
def __init__(self, ctx):
|
||||
self.ctx = ctx
|
||||
|
||||
for i in NSWITCH_ENVVARS:
|
||||
self.dkp_dir = os.getenv(i)
|
||||
if self.dkp_dir != None:
|
||||
break
|
||||
else:
|
||||
ctx.fatal('Set %s environment variable pointing to the DEVKITPRO home!' %
|
||||
' or '.join(NSWITCH_ENVVARS))
|
||||
|
||||
self.dkp_dir = os.path.abspath(self.dkp_dir)
|
||||
|
||||
self.dka64_dir = os.path.join(self.dkp_dir, 'devkitA64')
|
||||
if not os.path.exists(self.dka64_dir):
|
||||
ctx.fatal('devkitA64 not found in `%s`. Install devkitA64!' % self.dka64_dir)
|
||||
|
||||
self.libnx_dir = os.path.join(self.dkp_dir, 'libnx')
|
||||
if not os.path.exists(self.libnx_dir):
|
||||
ctx.fatal('libnx not found in `%s`. Install libnx!' % self.libnx_dir)
|
||||
|
||||
self.portlibs_dir = os.path.join(self.dkp_dir, 'portlibs', 'switch')
|
||||
if not os.path.exists(self.portlibs_dir):
|
||||
ctx.fatal('No Switch libraries found in `%s`!' % self.portlibs_dir)
|
||||
|
||||
def gen_toolchain_prefix(self):
|
||||
return 'aarch64-none-elf-'
|
||||
|
||||
def gen_gcc_toolchain_path(self):
|
||||
return os.path.join(self.dka64_dir, 'bin', self.gen_toolchain_prefix())
|
||||
|
||||
def cc(self):
|
||||
return self.gen_gcc_toolchain_path() + 'gcc'
|
||||
|
||||
def cxx(self):
|
||||
return self.gen_gcc_toolchain_path() + 'g++'
|
||||
|
||||
def strip(self):
|
||||
return self.gen_gcc_toolchain_path() + 'strip'
|
||||
|
||||
def pkgconfig(self):
|
||||
# counter-intuitively, this motherfucker is in $DEVKITPRO/portlibs/switch/bin
|
||||
return os.path.join(self.portlibs_dir, 'bin', self.gen_toolchain_prefix() + 'pkg-config')
|
||||
|
||||
def cflags(self, cxx = False):
|
||||
cflags = []
|
||||
# arch flags
|
||||
cflags += ['-D__SWITCH__', '-march=armv8-a+crc+crypto', '-mtune=cortex-a57', '-mtp=soft', '-ftls-model=local-exec', '-fPIE']
|
||||
# help the linker out
|
||||
cflags += ['-ffunction-sections', '-fdata-sections']
|
||||
# base include dirs
|
||||
cflags += ['-isystem %s/include' % self.libnx_dir, '-I%s/include' % self.portlibs_dir]
|
||||
# the game wants GNU extensions
|
||||
if cxx:
|
||||
cflags += ['-std=gnu++17', '-D_GNU_SOURCE']
|
||||
else:
|
||||
cflags += ['-std=gnu11', '-D_GNU_SOURCE']
|
||||
return cflags
|
||||
|
||||
# they go before object list
|
||||
def linkflags(self):
|
||||
linkflags = ['-fPIE', '-specs=%s/switch.specs' % self.libnx_dir]
|
||||
# libsolder only supports sysv hashes and we need to build everything with -rdynamic
|
||||
linkflags += ['-Wl,--hash-style=sysv', '-rdynamic']
|
||||
# avoid pulling in and exposing mesa's internals, that crashes it for some god forsaken reason
|
||||
linkflags += ['-Wl,--exclude-libs=libglapi.a', '-Wl,--exclude-libs=libdrm_nouveau.a']
|
||||
return linkflags
|
||||
|
||||
def ldflags(self):
|
||||
# system libraries implicitly require math and C++ standard library
|
||||
ldflags = ['-lm', '-lstdc++']
|
||||
return ldflags
|
||||
|
||||
def options(opt):
|
||||
xc = opt.add_option_group('Cross compile options')
|
||||
xc.add_option('--android', action='store', dest='ANDROID_OPTS', default=None,
|
||||
@@ -356,6 +439,8 @@ def options(opt):
|
||||
help='enable building for Motorola MAGX [default: %default]')
|
||||
xc.add_option('--enable-msvc-wine', action='store_true', dest='MSVC_WINE', default=False,
|
||||
help='enable building with MSVC using Wine [default: %default]')
|
||||
xc.add_option('--nswitch', action='store_true', dest='NSWITCH', default = False,
|
||||
help ='enable building for Nintendo Switch [default: %default]')
|
||||
|
||||
def configure(conf):
|
||||
if conf.options.ANDROID_OPTS:
|
||||
@@ -408,10 +493,23 @@ def configure(conf):
|
||||
conf.env.DEST_OS = 'win32'
|
||||
conf.env.DEST_CPU = conf.env.MSVC_TARGETS[0]
|
||||
conf.env.COMPILER_CXX = conf.env.COMPILER_CC = 'msvc'
|
||||
elif conf.options.NSWITCH:
|
||||
conf.nswitch = nswitch = NintendoSwitch(conf)
|
||||
conf.environ['CC'] = nswitch.cc()
|
||||
conf.environ['CXX'] = nswitch.cxx()
|
||||
conf.environ['STRIP'] = nswitch.strip()
|
||||
conf.env.PKGCONFIG = nswitch.pkgconfig()
|
||||
conf.env.CFLAGS += nswitch.cflags()
|
||||
conf.env.CXXFLAGS += nswitch.cflags(True)
|
||||
conf.env.LINKFLAGS += nswitch.linkflags()
|
||||
conf.env.LDFLAGS += nswitch.ldflags()
|
||||
conf.env.HAVE_M = True
|
||||
conf.env.LIB_M = ['m']
|
||||
conf.env.DEST_OS = 'nswitch'
|
||||
|
||||
conf.env.MAGX = conf.options.MAGX
|
||||
conf.env.MSVC_WINE = conf.options.MSVC_WINE
|
||||
MACRO_TO_DESTOS = OrderedDict({ '__ANDROID__' : 'android' })
|
||||
MACRO_TO_DESTOS = OrderedDict({ '__ANDROID__' : 'android', '__SWITCH__' : 'nswitch' })
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user