Can upgrade build directory from an old version.

builddirupgrade
Jussi Pakkanen 6 years ago
parent efba193872
commit e3b0145e73
  1. 10
      mesonbuild/backend/backends.py
  2. 1
      mesonbuild/backend/ninjabackend.py
  3. 3
      mesonbuild/backend/vs2010backend.py
  4. 3
      mesonbuild/backend/xcodebackend.py
  5. 14
      mesonbuild/compilers/compilers.py
  6. 15
      mesonbuild/coredata.py
  7. 2
      mesonbuild/environment.py
  8. 4
      mesonbuild/mesonmain.py
  9. 93
      mesonbuild/mupgrade.py

@ -24,6 +24,7 @@ from ..mesonlib import MesonException, OrderedSet
from ..mesonlib import classify_unity_sources
from ..mesonlib import File
from ..compilers import CompilerArgs
from ..mupgrade import create_dump_dict
from collections import OrderedDict
import shlex
@ -120,6 +121,7 @@ class OptionOverrideProxy:
# This class contains the basic functionality that is needed by all backends.
# Feel free to move stuff in and out of it as you see fit.
class Backend:
def __init__(self, build):
self.build = build
self.environment = build.environment
@ -922,3 +924,11 @@ class Backend:
for s in self.build.postconf_scripts:
cmd = s['exe'] + s['args']
subprocess.check_call(cmd, env=child_env)
def dump_state_file(self):
import json
build_dir = self.environment.get_build_dir()
dumpfile = os.path.join(build_dir, 'meson-private', 'upgrade-state.json')
s = create_dump_dict(self.environment, self.build)
with open(dumpfile, 'w') as f:
json.dump(s, f)

@ -238,6 +238,7 @@ int dummy;
# fully created.
os.replace(tempfilename, outfilename)
self.generate_compdb()
self.dump_state_file()
# http://clang.llvm.org/docs/JSONCompilationDatabase.html
def generate_compdb(self):

@ -1,4 +1,4 @@
# Copyright 2014-2016 The Meson development team
# Copyright 2014-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.
@ -167,6 +167,7 @@ class Vs2010Backend(backends.Backend):
self.generate_solution(sln_filename, projlist)
self.generate_regen_info()
Vs2010Backend.touch_regen_timestamp(self.environment.get_build_dir())
self.dump_state_file()
@staticmethod
def get_regen_stampfile(build_dir):

@ -1,4 +1,4 @@
# Copyright 2014-2016 The Meson development team
# Copyright 2014-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.
@ -103,6 +103,7 @@ class XCodeBackend(backends.Backend):
self.generate_xc_build_configuration()
self.generate_xc_configurationList()
self.generate_suffix()
self.dump_state_file()
def get_xcodetype(self, fname):
return self.xcodetypemap[fname.split('.')[-1]]

@ -1,4 +1,4 @@
# Copyright 2012-2017 The Meson development team
# Copyright 2012-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.
@ -72,6 +72,18 @@ cflags_mapping = {'c': 'CFLAGS',
'vala': 'VALAFLAGS',
'rust': 'RUSTFLAGS'}
compiler_envvars = {'c': 'CC',
'cpp': 'CXX',
'java': 'JAVAC',
'd': 'DC',
'objc': 'OBJC',
'objcpp': 'OBJCXX',
'fortran': 'FC',
'rust': 'RUSTC',
'vala': 'VALAC',
'cs': 'CSC',
}
# All these are only for C-linkable languages; see `clink_langs` above.
def sort_clink(lang):

@ -410,9 +410,16 @@ class CoreData:
sub = 'In subproject {}: '.format(subproject) if subproject else ''
mlog.warning('{}Unknown options: "{}"'.format(sub, unknown_options))
def get_all_option_classes(self):
return (self.backend_options,
self.user_options,
self.compiler_options,
self.base_options)
def load(build_dir):
filename = os.path.join(build_dir, 'meson-private', 'coredata.dat')
load_fail_msg = 'Coredata file {!r} is corrupted. Try with a fresh build tree.'.format(filename)
state_file_exists = os.path.isfile(os.path.join(build_dir, 'meson-private', 'upgrade_state.json'))
try:
with open(filename, 'rb') as f:
obj = pickle.load(f)
@ -421,8 +428,12 @@ def load(build_dir):
if not isinstance(obj, CoreData):
raise MesonException(load_fail_msg)
if obj.version != version:
raise MesonException('Build directory has been generated with Meson version %s, which is incompatible with current version %s.\nPlease delete this build directory AND create a new one.' %
(obj.version, version))
msg = 'Build directory has been generated with Meson version %s, which is incompatible with current version %s.\n'
if state_file_exists:
msg += 'Upgrade the build directory by invoking the "upgrade-builddir" target.'
else:
msg += 'Please delete this build directory AND create a new one.'
raise MesonException(msg % (obj.version, version))
return obj
def save(obj, build_dir):

@ -1,4 +1,4 @@
# Copyright 2012-2016 The Meson development team
# Copyright 2012-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.

@ -307,6 +307,10 @@ def run(original_args, mainfile):
sys.argv[1:] = remaining_args[1:]
runpy.run_path(script_file, run_name='__main__')
sys.exit(0)
elif cmd_name == 'upgrade-builddir':
from . import mupgrade
mupgrade.do_upgrade(args[1:] + ['.'])
sys.exit(0)
# No special command? Do the basic setup/reconf.
if len(args) >= 2 and args[0] == '--internal':

@ -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
Loading…
Cancel
Save