aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-04-18 21:25:46 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2021-04-18 21:25:46 +0300
commitda5097fca3c37f9842879f5d54dc795ec813a0d2 (patch)
treed01edac46926289e9b630d989ef9ae9fec8d3d3f
parentaaa8a828cb2b50394457894d70952d92f0fe76bd (diff)
downloadmeson-xcodehalfway.zip
meson-xcodehalfway.tar.gz
meson-xcodehalfway.tar.bz2
Xcode: regenerato project file when build conf changes.xcodehalfway
-rw-r--r--mesonbuild/backend/backends.py16
-rw-r--r--mesonbuild/backend/vs2010backend.py16
-rw-r--r--mesonbuild/backend/xcodebackend.py50
-rw-r--r--mesonbuild/scripts/regen_checker.py2
4 files changed, 62 insertions, 22 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 90d7b79..04f3d23 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -49,6 +49,12 @@ if T.TYPE_CHECKING:
# Assembly files cannot be unitified and neither can LLVM IR files
LANGS_CANT_UNITY = ('d', 'fortran', 'vala')
+class RegenInfo:
+ def __init__(self, source_dir, build_dir, depfiles):
+ self.source_dir = source_dir
+ self.build_dir = build_dir
+ self.depfiles = depfiles
+
class TestProtocol(enum.Enum):
EXITCODE = 0
@@ -1007,6 +1013,16 @@ class Backend:
self.check_clock_skew(deps)
return deps
+ def generate_regen_info(self):
+ deps = self.get_regen_filelist()
+ regeninfo = RegenInfo(self.environment.get_source_dir(),
+ self.environment.get_build_dir(),
+ deps)
+ filename = os.path.join(self.environment.get_scratch_dir(),
+ 'regeninfo.dump')
+ with open(filename, 'wb') as f:
+ pickle.dump(regeninfo, f)
+
def check_clock_skew(self, file_list):
# If a file that leads to reconfiguration has a time
# stamp in the future, it will trigger an eternal reconfigure
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index ee58114..872b1a5 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -80,12 +80,6 @@ def split_o_flags_args(args):
def generate_guid_from_path(path, path_type):
return str(uuid.uuid5(uuid.NAMESPACE_URL, 'meson-vs-' + path_type + ':' + str(path))).upper()
-class RegenInfo:
- def __init__(self, source_dir, build_dir, depfiles):
- self.source_dir = source_dir
- self.build_dir = build_dir
- self.depfiles = depfiles
-
class Vs2010Backend(backends.Backend):
def __init__(self, build: T.Optional[build.Build], interpreter: T.Optional[Interpreter]):
super().__init__(build, interpreter)
@@ -206,16 +200,6 @@ class Vs2010Backend(backends.Backend):
with open(Vs2010Backend.get_regen_stampfile(build_dir), 'w'):
pass
- def generate_regen_info(self):
- deps = self.get_regen_filelist()
- regeninfo = RegenInfo(self.environment.get_source_dir(),
- self.environment.get_build_dir(),
- deps)
- filename = os.path.join(self.environment.get_scratch_dir(),
- 'regeninfo.dump')
- with open(filename, 'wb') as f:
- pickle.dump(regeninfo, f)
-
def get_vcvars_command(self):
has_arch_values = 'VSCMD_ARG_TGT_ARCH' in os.environ and 'VSCMD_ARG_HOST_ARCH' in os.environ
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 70d1b8b..342b1bb 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -189,6 +189,10 @@ class XCodeBackend(backends.Backend):
self.test_id = self.gen_id()
self.test_command_id = self.gen_id()
self.test_buildconf_id = self.gen_id()
+ self.regen_id = self.gen_id()
+ self.regen_command_id = self.gen_id()
+ self.regen_buildconf_id = self.gen_id()
+ self.regen_dependency_id = self.gen_id()
self.top_level_dict = PbxDict()
self.generator_outputs = {}
# In Xcode files are not accessed via their file names, but rather every one of them
@@ -203,9 +207,11 @@ class XCodeBackend(backends.Backend):
self.fileref_ids = {}
def write_pbxfile(self, top_level_dict, ofilename):
- with open(ofilename, 'w') as ofile:
+ tmpname = ofilename + '.tmp'
+ with open(tmpname, 'w', encoding='utf-8') as ofile:
ofile.write('// !$*UTF8*$!\n')
top_level_dict.write(ofile, 0)
+ os.replace(tmpname, ofilename)
def gen_id(self):
return str(uuid.uuid4()).upper().replace('-', '')[:24]
@@ -308,6 +314,7 @@ class XCodeBackend(backends.Backend):
objects_dict.add_comment(PbxComment('End XCConfigurationList section'))
self.generate_suffix(self.top_level_dict)
self.write_pbxfile(self.top_level_dict, self.proj_file)
+ self.generate_regen_info()
def get_xcodetype(self, fname):
xcodetype = XCODETYPEMAP.get(fname.split('.')[-1].lower())
@@ -502,11 +509,12 @@ class XCodeBackend(backends.Backend):
aggregated_targets = []
aggregated_targets.append((self.all_id, 'ALL_BUILD', self.all_buildconf_id, [], target_dependencies + custom_target_dependencies))
aggregated_targets.append((self.test_id, 'RUN_TESTS', self.test_buildconf_id, [self.test_command_id], [self.build_all_tdep_id]))
+ aggregated_targets.append((self.regen_id, 'REGENERATE', self.regen_buildconf_id, [self.regen_command_id], []))
for tname, t in self.build.get_custom_targets().items():
ct_id = self.gen_id()
self.custom_aggregate_targets[tname] = ct_id
build_phases = []
- dependencies = []
+ dependencies = [self.regen_dependency_id]
generator_id = 0
for s in t.sources:
if not isinstance(s, build.GeneratedList):
@@ -949,6 +957,7 @@ class XCodeBackend(backends.Backend):
ntarget_dict.add_item('buildRules', PbxArray())
dep_array = PbxArray()
ntarget_dict.add_item('dependencies', dep_array)
+ dep_array.add_item(self.regen_dependency_id)
# These dependencies only tell Xcode that the deps must be built
# before this one. They don't set up linkage or anything
# like that. Those are set up in the XCBuildConfiguration.
@@ -971,7 +980,6 @@ class XCodeBackend(backends.Backend):
generator_id += 1
-
ntarget_dict.add_item('name', f'"{tname}"')
ntarget_dict.add_item('productName', f'"{tname}"')
ntarget_dict.add_item('productReference', self.target_filemap[tname], tname)
@@ -1007,12 +1015,19 @@ class XCodeBackend(backends.Backend):
project_dict.add_item('targets', targets_arr)
targets_arr.add_item(self.all_id, 'ALL_BUILD')
targets_arr.add_item(self.test_id, 'RUN_TESTS')
+ targets_arr.add_item(self.regen_id, 'REGENERATE')
for t in self.build_targets:
targets_arr.add_item(self.native_targets[t], t)
for t in self.custom_targets:
targets_arr.add_item(self.custom_aggregate_targets[t], t)
def generate_pbx_shell_build_phase(self, objects_dict):
+ self.generate_test_shell_build_phase(objects_dict)
+ self.generate_regen_shell_build_phase(objects_dict)
+ self.generate_custom_target_shell_build_phases(objects_dict)
+ self.generate_generator_target_shell_build_phases(objects_dict)
+
+ def generate_test_shell_build_phase(self, objects_dict):
shell_dict = PbxDict()
objects_dict.add_item(self.test_command_id, shell_dict, 'ShellScript')
shell_dict.add_item('isa', 'PBXShellScriptBuildPhase')
@@ -1026,8 +1041,21 @@ class XCodeBackend(backends.Backend):
cmdstr = ' '.join(["'%s'" % i for i in cmd])
shell_dict.add_item('shellScript', f'"{cmdstr}"')
shell_dict.add_item('showEnvVarsInLog', 0)
- self.generate_custom_target_shell_build_phases(objects_dict)
- self.generate_generator_target_shell_build_phases(objects_dict)
+
+ def generate_regen_shell_build_phase(self, objects_dict):
+ shell_dict = PbxDict()
+ objects_dict.add_item(self.regen_command_id, shell_dict, 'ShellScript')
+ shell_dict.add_item('isa', 'PBXShellScriptBuildPhase')
+ shell_dict.add_item('buildActionMask', 2147483647)
+ shell_dict.add_item('files', PbxArray())
+ shell_dict.add_item('inputPaths', PbxArray())
+ shell_dict.add_item('outputPaths', PbxArray())
+ shell_dict.add_item('runOnlyForDeploymentPostprocessing', 0)
+ shell_dict.add_item('shellPath', '/bin/sh')
+ cmd = mesonlib.get_meson_command() + ['--internal', 'regencheck', os.path.join(self.environment.get_build_dir(), 'meson-private')]
+ cmdstr = ' '.join(["'%s'" % i for i in cmd])
+ shell_dict.add_item('shellScript', f'"{cmdstr}"')
+ shell_dict.add_item('showEnvVarsInLog', 0)
def generate_custom_target_shell_build_phases(self, objects_dict):
# Custom targets are shell build phases in Xcode terminology.
@@ -1160,6 +1188,7 @@ class XCodeBackend(backends.Backend):
all_dict.add_item('isa', 'PBXTargetDependency')
all_dict.add_item('target', self.all_id)
targets = []
+ targets.append((self.regen_dependency_id, self.regen_id, 'REGEN', None))
for t in self.build_targets:
idval = self.pbx_dep_map[t] # VERIFY: is this correct?
targets.append((idval, self.native_targets[t], t, self.containerproxy_map[t]))
@@ -1449,6 +1478,17 @@ class XCodeBackend(backends.Backend):
test_dict.add_item('defaultConfigurationIsVisible', 0)
test_dict.add_item('defaultConfigurationName', self.buildtype)
+ # Regen target
+ regen_dict = PbxDict()
+ objects_dict.add_item(self.regen_buildconf_id, test_dict, 'Build configuration list for PBXAggregateTarget "REGENERATE"')
+ regen_dict.add_item('isa', 'XCConfigurationList')
+ conf_arr = PbxArray()
+ regen_dict.add_item('buildConfigurations', conf_arr)
+ for buildtype in self.buildtypes:
+ conf_arr.add_item(self.test_configurations[buildtype], buildtype)
+ regen_dict.add_item('defaultConfigurationIsVisible', 0)
+ regen_dict.add_item('defaultConfigurationName', self.buildtype)
+
for target_name in self.build_targets:
t_dict = PbxDict()
listid = self.buildconflistmap[target_name]
diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py
index 1187783..c96bdc1 100644
--- a/mesonbuild/scripts/regen_checker.py
+++ b/mesonbuild/scripts/regen_checker.py
@@ -16,7 +16,7 @@ import sys, os
import pickle, subprocess
import typing as T
from ..coredata import CoreData
-from ..backend.vs2010backend import RegenInfo
+from ..backend.backends import RegenInfo
from ..mesonlib import OptionKey
# This could also be used for XCode.