aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2018-10-25 12:19:23 -0400
committerXavier Claessens <xavier.claessens@collabora.com>2018-11-06 16:37:13 -0500
commit43101489cd7b310996badaef19638ec3adbec532 (patch)
tree80571c19bb3ff6c3b7cd42995555b875795cfe65
parent11e3011a6bf0adeb51582c590c90b0f4dccb4df8 (diff)
downloadmeson-43101489cd7b310996badaef19638ec3adbec532.zip
meson-43101489cd7b310996badaef19638ec3adbec532.tar.gz
meson-43101489cd7b310996badaef19638ec3adbec532.tar.bz2
Recover when coredata cannot be loaded
Write command line options into a separate file to be able to reconfigure from scatch in the case coredata cannot be loaded. The most common case is when we are reconfiguring with a newer meson version. This means that we should try as much as possible to maintain backward compatibility for the cmd_line.txt file format. The main difference with a normal reconfigure is it will use new default options values and will read again environment variables like CFLAGS, etc.
-rw-r--r--mesonbuild/coredata.py43
-rw-r--r--mesonbuild/environment.py29
-rw-r--r--mesonbuild/mconf.py1
-rw-r--r--mesonbuild/msetup.py4
4 files changed, 68 insertions, 9 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 819481b..cdfed7c 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -22,6 +22,7 @@ from .mesonlib import default_libdir, default_libexecdir, default_prefix
from .wrap import WrapMode
import ast
import argparse
+import configparser
version = '0.48.999'
backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode']
@@ -459,6 +460,45 @@ class CoreData:
sub = 'In subproject {}: '.format(subproject) if subproject else ''
mlog.warning('{}Unknown options: "{}"'.format(sub, unknown_options))
+def get_cmd_line_file(build_dir):
+ return os.path.join(build_dir, 'meson-private', 'cmd_line.txt')
+
+def read_cmd_line_file(build_dir, options):
+ filename = get_cmd_line_file(build_dir)
+ config = configparser.ConfigParser()
+ config.read(filename)
+
+ # Do a copy because config is not really a dict. options.cmd_line_options
+ # overrides values from the file.
+ d = dict(config['options'])
+ d.update(options.cmd_line_options)
+ options.cmd_line_options = d
+
+ properties = config['properties']
+ if options.cross_file is None:
+ options.cross_file = properties.get('cross_file', None)
+
+def write_cmd_line_file(build_dir, options):
+ filename = get_cmd_line_file(build_dir)
+ config = configparser.ConfigParser()
+
+ properties = {}
+ if options.cross_file is not None:
+ properties['cross_file'] = options.cross_file
+
+ config['options'] = options.cmd_line_options
+ config['properties'] = properties
+ with open(filename, 'w') as f:
+ config.write(f)
+
+def update_cmd_line_file(build_dir, options):
+ filename = get_cmd_line_file(build_dir)
+ config = configparser.ConfigParser()
+ config.read(filename)
+ config['options'].update(options.cmd_line_options)
+ with open(filename, 'w') as f:
+ config.write(f)
+
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)
@@ -470,7 +510,8 @@ 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.' %
+ raise MesonException('Build directory has been generated with Meson version %s, '
+ 'which is incompatible with current version %s.\n' %
(obj.version, version))
return obj
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index a002aa1..8891b5c 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -17,7 +17,7 @@ import configparser, os, platform, re, sys, shlex, shutil, subprocess
from . import coredata
from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker
from . import mesonlib
-from .mesonlib import EnvironmentException, PerMachine, Popen_safe
+from .mesonlib import MesonException, EnvironmentException, PerMachine, Popen_safe
from . import mlog
from . import compilers
@@ -317,13 +317,17 @@ class Environment:
self.coredata = coredata.load(self.get_build_dir())
self.first_invocation = False
except FileNotFoundError:
- # WARNING: Don't use any values from coredata in __init__. It gets
- # re-initialized with project options by the interpreter during
- # build file parsing.
- self.coredata = coredata.CoreData(options)
- # Used by the regenchecker script, which runs meson
- self.coredata.meson_command = mesonlib.meson_command
- self.first_invocation = True
+ self.create_new_coredata(options)
+ except MesonException as e:
+ # If we stored previous command line options, we can recover from
+ # a broken/outdated coredata.
+ if os.path.isfile(coredata.get_cmd_line_file(self.build_dir)):
+ mlog.warning('Regenerating configuration from scratch.')
+ mlog.log('Reason:', mlog.red(str(e)))
+ coredata.read_cmd_line_file(self.build_dir, options)
+ self.create_new_coredata(options)
+ else:
+ raise e
self.exe_wrapper = None
self.machines = MachineInfos()
@@ -389,6 +393,15 @@ class Environment:
else:
self.native_strip_bin = ['strip']
+ def create_new_coredata(self, options):
+ # WARNING: Don't use any values from coredata in __init__. It gets
+ # re-initialized with project options by the interpreter during
+ # build file parsing.
+ self.coredata = coredata.CoreData(options)
+ # Used by the regenchecker script, which runs meson
+ self.coredata.meson_command = mesonlib.meson_command
+ self.first_invocation = True
+
def is_cross_build(self):
return self.cross_info is not None
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 576c574..d0f837d 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -153,6 +153,7 @@ def run(options):
save = False
if len(options.cmd_line_options) > 0:
c.set_options(options.cmd_line_options)
+ coredata.update_cmd_line_file(builddir, options)
save = True
elif options.clearcache:
c.clear_cache()
diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py
index 4256272..df6ba46 100644
--- a/mesonbuild/msetup.py
+++ b/mesonbuild/msetup.py
@@ -168,6 +168,10 @@ class MesonApp:
build.save(b, dumpfile)
# Post-conf scripts must be run after writing coredata or else introspection fails.
intr.backend.run_postconf_scripts()
+ if env.first_invocation:
+ coredata.write_cmd_line_file(self.build_dir, self.options)
+ else:
+ coredata.update_cmd_line_file(self.build_dir, self.options)
except:
if 'cdf' in locals():
old_cdf = cdf + '.prev'