wrapper: add common development wrapper
This commit is contained in:
parent
7aa94d3206
commit
b8f984f3e7
105
wrapper.py.in
Executable file
105
wrapper.py.in
Executable file
@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Runs an application in a manner that allows it to discover various engine
|
||||
resources that may be in unexpected locations.
|
||||
|
||||
In particular: this allows running an application 'in-tree' under a debugger
|
||||
with dependencies and resources out of line.
|
||||
|
||||
The base assumption is that this is probably a special circumstance and hence
|
||||
should be run reasonably verbose but not interfere with a probable debugger
|
||||
session.
|
||||
"""
|
||||
|
||||
import platform
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# We need these ASAN options set so that nVidia's driver doesn't force an
|
||||
# immediate halt.
|
||||
#
|
||||
# invalid_pointer_pairs gives overly verbose reports from deep within some
|
||||
# core dependencies so it's not enabled by default.
|
||||
asan_options = {
|
||||
'protect_shadow_gap': 0,
|
||||
'detect_stack_use_after_return': 1,
|
||||
#'detect_invalid_pointer_pairs': 1,
|
||||
}
|
||||
|
||||
|
||||
# A path that contains our application, the resources, and the runtime
|
||||
# configuration.
|
||||
#
|
||||
# It is probably assumed that the root will directly contain a 'config.json';
|
||||
# but there's a definitely an assumption that we won't travel deeper into a
|
||||
# hierarchy without foreknowledge that we're dealing with a good path, so don't
|
||||
# set this to something stupid like '/'.
|
||||
#
|
||||
# By default we find the first path below us that contains a 'config.json'
|
||||
# file under the assumption this script sits within a game directory structure.
|
||||
|
||||
def find_root(init, default):
|
||||
cursor = init
|
||||
|
||||
while True:
|
||||
if os.path.isfile(os.path.join(cursor, 'config.json')):
|
||||
return cursor
|
||||
|
||||
parent = os.path.dirname(cursor)
|
||||
if parent == cursor:
|
||||
return default
|
||||
|
||||
cursor = parent
|
||||
|
||||
root = os.path.abspath(os.path.dirname(__file__))
|
||||
root = find_root(root, default=root)
|
||||
|
||||
|
||||
defaults = {
|
||||
# don't break terrifically often, given we're probably running a debugger,
|
||||
# but write a lot of information to the console.
|
||||
'BREAK_LEVEL': 'CRITICAL',
|
||||
'LOG_LEVEL': 'DEBUG',
|
||||
|
||||
'CL_VENDOR_IGNORE': 'intel64.icd',
|
||||
|
||||
'ROOT': root,
|
||||
|
||||
'ASAN_OPTIONS': ':'.join (f"{k}={v}" for k,v in asan_options.items())
|
||||
}
|
||||
|
||||
# Overwrite our defaults with the current environment. This ensures a user can
|
||||
# override any of the above variables easily from the commandline.
|
||||
|
||||
env = defaults.copy()
|
||||
env.update(os.environ)
|
||||
|
||||
# Windows has its own unique rules for library lookups. We record the
|
||||
# environment variable which effects path lookups and the separator and the
|
||||
# target directory for Windows and for every single other system we're likely
|
||||
# to ever deal with...
|
||||
if platform.system() == 'Windows':
|
||||
separator = ';'
|
||||
depsdir = ['bin']
|
||||
searchvar = 'PATH'
|
||||
else:
|
||||
separator = ':'
|
||||
depsdir = ['lib', 'lib64']
|
||||
searchvar = 'LD_LIBRARY_PATH'
|
||||
|
||||
|
||||
# append the in-tree dependencies to the library path
|
||||
search = separator.join(
|
||||
"@CMAKE_CURRENT_BINARY_DIR@/deps/" + i for i in depsdir
|
||||
)
|
||||
|
||||
if searchvar in env:
|
||||
env[searchvar] = search + separator + env[searchvar]
|
||||
else:
|
||||
env[searchvar] = search
|
||||
|
||||
# It's probably unnecessary to pipe std
|
||||
res = subprocess.run(sys.argv[1:], env=env, stderr=sys.stderr, stdout=sys.stdout)
|
||||
sys.exit(res.returncode)
|
Loading…
Reference in New Issue
Block a user