diff options
Diffstat (limited to 'mesonbuild/mupgrade.py')
-rw-r--r-- | mesonbuild/mupgrade.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/mesonbuild/mupgrade.py b/mesonbuild/mupgrade.py new file mode 100644 index 0000000..7a97497 --- /dev/null +++ b/mesonbuild/mupgrade.py @@ -0,0 +1,93 @@ +# Copyright 2018 The Meson development team + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys, os +import json +import subprocess +import shlex +from .mesonlib import meson_command +from .compilers.compilers import compiler_envvars + +dump_format_version = 1 + +def upgrade(state_file): + d = json.load(open(state_file, 'r')) + version = d.get('dump_format_version', 'missing') + if version != dump_format_version: + sys.exit('Can not upgrade because state dump file format is not compatible: %d != %d.' % (version, dump_format_version)) + state = d['state'] + env = os.environ.copy() + for c in state['compilers']: + ename = compiler_envvars[c[0]] + eval = ' '.join([shlex.quote(x) for x in c[1]]) + env[ename] = eval + cmd_args = [state['source_root'], + state['build_root']] + if 'cross_file' in state: + cmd_args += ['--cross-file', state['cross_file']] + for o in state['options']: + cmd_args.append('-D%s=%s' % (o[0], o[1])) + pc = subprocess.run(meson_command + cmd_args) + if pc.returncode != 0: + sys.exit(1) # The output from above should be enough to debug any issues. + +def do_upgrade(potential_builddirs): + for bd in potential_builddirs: + state_file = os.path.join(bd, 'meson-private', 'upgrade-state.json') + corefile = os.path.join(bd, 'meson-private', 'coredata.dat') + corefile_bak = corefile + '~' + if os.path.exists(state_file): + was_success = False + try: + os.replace(corefile, corefile_bak) + upgrade(state_file) + was_success = True + finally: + if not was_success: + try: + os.replace(corefile_bak, corefile) + except Exception as e: + print('Could not restore original state: %s\nYou probably need to wipe the builddir' % str(e)) + return + sys.exit('Could not find upgrade state file. Can not upgrade') + +def build_opt_array(environment): + options = [] + for optclass in environment.coredata.get_all_option_classes(): + for k, v in optclass.items(): + options.append((k, str(v.value))) + return options + +def build_compiler_array(build): + result = [] + # Only native ones, cross compilers come from the cross file. + for k, v in build.compilers.items(): + result.append((k, v.exelist)) + return result + +def build_state_dict(environment, build): + result = {} + result['source_root'] = environment.get_source_dir() + result['build_root'] = environment.get_build_dir() + if environment.coredata.cross_file: + result['cross_file'] = environment.coredata.cross_file + result['options'] = build_opt_array(environment) + result['compilers'] = build_compiler_array(build) + return result + +def create_dump_dict(environment, build): + s = {} + s['dump_format_version'] = dump_format_version + s['state'] = build_state_dict(environment, build) + return s |