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-19 17:59:40 +0300
commit6f76fce90436b503b841599b675155e4093d8855 (patch)
tree8a98a5f01ae3788135497101b6360e601ba2cf33
parent045893bb183b289376c45d2f8d1e43de1af93b35 (diff)
downloadmeson-6f76fce90436b503b841599b675155e4093d8855.zip
meson-6f76fce90436b503b841599b675155e4093d8855.tar.gz
meson-6f76fce90436b503b841599b675155e4093d8855.tar.bz2
Xcode: regenerato project file when build conf changes.
-rw-r--r--mesonbuild/backend/backends.py16
-rw-r--r--mesonbuild/backend/vs2010backend.py17
-rw-r--r--mesonbuild/backend/xcodebackend.py65
-rw-r--r--mesonbuild/scripts/regen_checker.py2
4 files changed, 75 insertions, 25 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..6b5fd2d 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -14,7 +14,6 @@
import copy
import os
-import pickle
import xml.dom.minidom
import xml.etree.ElementTree as ET
import uuid
@@ -80,12 +79,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 +199,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..432f234 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())
@@ -500,13 +507,25 @@ class XCodeBackend(backends.Backend):
target_dependencies = list(map(lambda t: self.pbx_dep_map[t], self.build_targets))
custom_target_dependencies = [self.pbx_custom_dep_map[t] for t in self.custom_targets]
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.all_id, 'ALL_BUILD',
+ self.all_buildconf_id,
+ [],
+ [self.regen_dependency_id] + target_dependencies + custom_target_dependencies))
+ aggregated_targets.append((self.test_id,
+ 'RUN_TESTS',
+ self.test_buildconf_id,
+ [self.test_command_id],
+ [self.regen_dependency_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 +968,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 +991,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 +1026,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 +1052,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 +1199,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 +1489,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.