aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-04-06 21:06:05 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2021-04-07 17:01:55 +0300
commit0b50c5705f6e7abc12155f2ecdb6acc4730a5922 (patch)
treefc1b138b5472001b750191c18f019ec0c8ae74fb
parent3b16e390094fbd0a7b6004d1c54e8d79414cca7a (diff)
downloadmeson-0b50c5705f6e7abc12155f2ecdb6acc4730a5922.zip
meson-0b50c5705f6e7abc12155f2ecdb6acc4730a5922.tar.gz
meson-0b50c5705f6e7abc12155f2ecdb6acc4730a5922.tar.bz2
Fix shared libs and using one source in multiple targets.
-rw-r--r--mesonbuild/backend/xcodebackend.py146
1 files changed, 89 insertions, 57 deletions
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 1c6e15d..9ba7e46 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -189,6 +189,16 @@ class XCodeBackend(backends.Backend):
self.test_command_id = self.gen_id()
self.test_buildconf_id = self.gen_id()
self.top_level_dict = PbxDict()
+ # In Xcode files are not accessed via their file names, but rather every one of them
+ # gets an unique id. More precisely they get one unique id per target they are used
+ # in. If you generate only one id per file and use them, compilation will work but the
+ # UI will only show the file in one target but not the others. Thus they key is
+ # a tuple containing the target and filename.
+ self.buildfile_ids = {}
+ # That is not enough, though. Each target/file combination also gets a unique id
+ # in the file reference section. Because why not. This means that a source file
+ # that is used in two targets gets a total of four unique ID numbers.
+ self.fileref_ids = {}
def write_pbxfile(self, top_level_dict, ofilename):
with open(ofilename, 'w') as ofile:
@@ -212,7 +222,6 @@ class XCodeBackend(backends.Backend):
def generate(self):
test_data = self.serialize_tests()[0]
self.generate_filemap()
- self.generate_buildmap()
self.generate_buildstylemap()
self.generate_build_phase_map()
self.generate_build_configuration_map()
@@ -226,6 +235,7 @@ class XCodeBackend(backends.Backend):
self.generate_target_dependency_map()
self.generate_pbxdep_map()
self.generate_containerproxy_map()
+ self.generate_target_file_maps()
self.proj_dir = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.xcodeproj')
os.makedirs(self.proj_dir, exist_ok=True)
self.proj_file = os.path.join(self.proj_dir, 'project.pbxproj')
@@ -296,17 +306,6 @@ class XCodeBackend(backends.Backend):
self.filemap[o] = self.gen_id()
self.target_filemap[name] = self.gen_id()
- def generate_buildmap(self):
- self.buildmap = {}
- for t in self.build.get_build_targets().values():
- for s in t.sources:
- s = os.path.join(s.subdir, s.fname)
- self.buildmap[s] = self.gen_id()
- for o in t.objects:
- o = os.path.join(t.subdir, o)
- if isinstance(o, str):
- self.buildmap[o] = self.gen_id()
-
def generate_buildstylemap(self):
self.buildstylemap = {self.buildtype: self.gen_id()}
@@ -371,6 +370,20 @@ class XCodeBackend(backends.Backend):
for t in self.build.get_build_targets():
self.containerproxy_map[t] = self.gen_id()
+ def generate_target_file_maps(self):
+ for tname, t in self.build.get_build_targets().items():
+ for s in t.sources:
+ if isinstance(s, mesonlib.File):
+ s = os.path.join(s.subdir, s.fname)
+ if not isinstance(s, str):
+ continue
+ self.buildfile_ids[(tname, s)] = self.gen_id()
+ self.fileref_ids[(tname, s)] = self.gen_id()
+ for o in t.objects:
+ o = os.path.join(t.subdir, o)
+ self.buildfile_ids[(tname, o)] = self.gen_id()
+ self.fileref_ids[(tname, o)] = self.gen_id()
+
def generate_source_phase_map(self):
self.source_phase = {}
for t in self.build.get_build_targets():
@@ -404,7 +417,7 @@ class XCodeBackend(backends.Backend):
objects_dict.add_item(t[0], agt_dict, name)
def generate_pbx_build_file(self, objects_dict):
- for t in self.build.get_build_targets().values():
+ for tname, t in self.build.get_build_targets().items():
for dep in t.get_external_deps():
if isinstance(dep, dependencies.AppleFrameworks):
for f in dep.frameworks:
@@ -417,25 +430,26 @@ class XCodeBackend(backends.Backend):
if isinstance(s, mesonlib.File):
s = os.path.join(s.subdir, s.fname)
- if isinstance(s, str):
- s = os.path.join(t.subdir, s)
- sdict = PbxDict()
- idval = self.buildmap[s]
- fullpath = os.path.join(self.environment.get_source_dir(), s)
- fileref = self.filemap[s]
- fullpath2 = fullpath
- compiler_args = ''
- sdict.add_item('isa', 'PBXBuildFile')
- sdict.add_item('fileRef', fileref, fullpath2)
- settingdict = PbxDict()
- settingdict.add_item('COMPILER_FLAGS', '"' + compiler_args + '"')
- sdict.add_item('settings', settingdict)
- objects_dict.add_item(idval, sdict)
+ if not isinstance(s, str):
+ continue
+ s = os.path.join(t.subdir, s)
+ sdict = PbxDict()
+ idval = self.buildfile_ids[(tname, s)]
+ fileref = self.fileref_ids[(tname, s)]
+ fullpath = os.path.join(self.environment.get_source_dir(), s)
+ compiler_args = ''
+ sdict.add_item('isa', 'PBXBuildFile')
+ sdict.add_item('fileRef', fileref, fullpath)
+ settingdict = PbxDict()
+ settingdict.add_item('COMPILER_FLAGS', '"' + compiler_args + '"')
+ sdict.add_item('settings', settingdict)
+ objects_dict.add_item(idval, sdict)
for o in t.objects:
o = os.path.join(t.subdir, o)
- idval = self.buildmap[o]
- fileref = self.filemap[o]
+ idval = self.buildfile_ids[(tname, o)]
+ fileref = self.fileref_ids[(tname, s)]
+ self.targetfile_ids[(tname, s)] = idval
fullpath = os.path.join(self.environment.get_source_dir(), o)
fullpath2 = fullpath
o_dict = PbxDict()
@@ -465,11 +479,10 @@ class XCodeBackend(backends.Backend):
proxy_dict.add_item('remoteInfo', '"' + t + '"')
def generate_pbx_file_reference(self, objects_dict):
- for t in self.build.get_build_targets().values():
+ for tname, t in self.build.get_build_targets().items():
for dep in t.get_external_deps():
if isinstance(dep, dependencies.AppleFrameworks):
for f in dep.frameworks:
- # FIXME not ported
fw_dict = PbxDict()
objects_dict.add_item(self.native_frameworks_fileref[f], fw_dict, f)
fw_dict.add_item('isa', 'PBXFileReference')
@@ -477,19 +490,37 @@ class XCodeBackend(backends.Backend):
fw_dict.add_item('name', f'{f}.framework')
fw_dict.add_item('path', f'System/Library/Frameworks/{f}.framework')
fw_dict.add_item('sourceTree', 'SDKROOT')
- for fname, idval in self.filemap.items():
- src_dict = PbxDict()
- fullpath = os.path.join(self.environment.get_source_dir(), fname)
- xcodetype = self.get_xcodetype(fname)
- name = os.path.basename(fname)
- path = fname
- objects_dict.add_item(idval, src_dict, fullpath)
- src_dict.add_item('isa', 'PBXFileReference')
- src_dict.add_item('explicitFileType', '"' + xcodetype + '"')
- src_dict.add_item('fileEncoding', '4')
- src_dict.add_item('name', '"' + name + '"')
- src_dict.add_item('path', '"' + path + '"')
- src_dict.add_item('sourceTree', 'SOURCE_ROOT')
+ for s in t.sources:
+ if isinstance(s, mesonlib.File):
+ s = os.path.join(s.subdir, s.fname)
+
+ if not isinstance(s, str):
+ continue
+ s = os.path.join(t.subdir, s)
+ idval = self.fileref_ids[(tname, s)]
+ fullpath = os.path.join(self.environment.get_source_dir(), s)
+ src_dict = PbxDict()
+ xcodetype = self.get_xcodetype(s)
+ name = os.path.basename(s)
+ path = s
+ objects_dict.add_item(idval, src_dict, fullpath)
+ src_dict.add_item('isa', 'PBXFileReference')
+ src_dict.add_item('explicitFileType', '"' + xcodetype + '"')
+ src_dict.add_item('fileEncoding', '4')
+ src_dict.add_item('name', '"' + name + '"')
+ src_dict.add_item('path', '"' + path + '"')
+ src_dict.add_item('sourceTree', 'SOURCE_ROOT')
+
+ for o in t.objects:
+ o = os.path.join(t.subdir, o)
+ idval = self.fileref_ids[(tname, o)]
+ fileref = self.filemap[o]
+ fullpath = os.path.join(self.environment.get_source_dir(), o)
+ fullpath2 = fullpath
+ o_dict = PbxDict()
+ objects_dict.add_item(idval, o_dict, fullpath)
+ o_dict.add_item('isa', 'PBXBuildFile')
+ o_dict.add_item('fileRef', fileref, fullpath2)
for tname, idval in self.target_filemap.items():
target_dict = PbxDict()
objects_dict.add_item(idval, target_dict, tname)
@@ -557,7 +588,6 @@ class XCodeBackend(backends.Backend):
source_dict.add_item('name', 'Sources')
source_dict.add_item('sourceTree', '"<group>"')
-
resource_dict = PbxDict()
objects_dict.add_item(resources_id, resource_dict, 'Resources')
resource_dict.add_item('isa', 'PBXGroup')
@@ -583,27 +613,29 @@ class XCodeBackend(backends.Backend):
frameworks_dict.add_item('sourceTree', '"<group>"')
# Targets
- for t in self.build.get_build_targets():
+ for tname, t in self.build.get_build_targets().items():
target_dict = PbxDict()
- objects_dict.add_item(groupmap[t], target_dict, t)
+ objects_dict.add_item(groupmap[tname], target_dict, tname)
target_dict.add_item('isa', 'PBXGroup')
target_children = PbxArray()
target_dict.add_item('children', target_children)
- target_children.add_item(target_src_map[t], 'Source files')
+ target_children.add_item(target_src_map[tname], 'Source files')
target_dict.add_item('name', f'"{t}"')
target_dict.add_item('sourceTree', '"<group>"')
source_files_dict = PbxDict()
- objects_dict.add_item(target_src_map[t], source_files_dict, 'Source files')
+ objects_dict.add_item(target_src_map[tname], source_files_dict, 'Source files')
source_files_dict.add_item('isa', 'PBXGroup')
source_file_children = PbxArray()
source_files_dict.add_item('children', source_file_children)
- for s in self.build.get_build_targets()[t].sources:
- s = os.path.join(s.subdir, s.fname)
- if isinstance(s, str):
- source_file_children.add_item(self.filemap[s], s)
- for o in self.build.get_build_targets()[t].objects:
- o = os.path.join(self.build.get_build_targets()[t].subdir, o)
- source_file_children.add_item(self.filemap[o], o)
+ for s in t.sources:
+ if isinstance(s, mesonlib.File):
+ s = os.path.join(t.subdir, s.fname)
+ if not isinstance(s, str):
+ continue
+ source_file_children.add_item(self.fileref_ids[(tname, s)], s)
+ for o in t.objects:
+ o = os.path.join(t.subdir, o)
+ source_file_children.add_item(self.fileref_ids[(tname, o)], o)
source_files_dict.add_item('name', '"Source files"')
source_files_dict.add_item('sourceTree', '"<group>"')
@@ -702,7 +734,7 @@ class XCodeBackend(backends.Backend):
for s in self.build.get_build_targets()[name].sources:
s = os.path.join(s.subdir, s.fname)
if not self.environment.is_header(s):
- file_arr.add_item(self.buildmap[s], os.path.join(self.environment.get_source_dir(), s))
+ file_arr.add_item(self.buildfile_ids[(name, s)], os.path.join(self.environment.get_source_dir(), s))
phase_dict.add_item('runOnlyForDeploymentPostprocessing', 0)
def generate_pbx_target_dependency(self, objects_dict):