Fix shared libs and using one source in multiple targets.
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 1c6e15d..956be2e 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -189,6 +189,16 @@
         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 @@
     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 @@
         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 @@
                     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,21 @@
         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
+                fname = os.path.join(t.subdir, s)
+                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, s)] = self.gen_id()
+                self.fileref_ids[(tname, s)] = self.gen_id()
+        
     def generate_source_phase_map(self):
         self.source_phase = {}
         for t in self.build.get_build_targets():
@@ -404,7 +418,7 @@
             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 +431,26 @@
                 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 +480,10 @@
             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 +491,40 @@
                         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)
+                sdict = PbxDict()
+                idval = self.fileref_ids[(tname, s)]
+                fullpath = os.path.join(self.environment.get_source_dir(), s)
+                fileref = self.buildfile_ids[(tname, 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.gen_id()
+                self.targetfile_ids[(tname, s)] = idval
+                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 +592,6 @@
         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 +617,29 @@
         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 +738,7 @@
             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):