Xcode: fix generators that take custom targets as inputs.
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 9635e82..54fc229 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -396,25 +396,36 @@
             for genlist in t.generated:
                 if not isinstance(genlist, build.GeneratedList):
                     continue
-                k = (tname, generator_id)
-                assert(k not in self.shell_targets)
-                self.shell_targets[k] = self.gen_id()
-                ofile_abs = []
-                for i in genlist.get_inputs():
-                    for o_base in genlist.get_outputs_for(i):
-                        o = os.path.join(self.get_target_private_dir(t), o_base)
-                        ofile_abs.append(os.path.join(self.environment.get_build_dir(), o))
-                assert(k not in self.generator_outputs)
-                self.generator_outputs[k] = ofile_abs
-                buildfile_ids = []
-                fileref_ids = []
-                for i in range(len(ofile_abs)):
-                    buildfile_ids.append(self.gen_id())
-                    fileref_ids.append(self.gen_id())
-                self.generator_buildfile_ids[k] = buildfile_ids
-                self.generator_fileref_ids[k] = fileref_ids
+                self.gen_single_target_map(genlist, tname, t, generator_id)
                 generator_id += 1
         # FIXME add outputs.
+        for tname, t in self.custom_targets.items():
+            generator_id = 0
+            for genlist in t.sources:
+                if not isinstance(genlist, build.GeneratedList):
+                    continue
+                self.gen_single_target_map(genlist, tname, t, generator_id)
+                generator_id += 1
+
+    def gen_single_target_map(self, genlist, tname, t, generator_id):
+        k = (tname, generator_id)
+        assert(k not in self.shell_targets)
+        self.shell_targets[k] = self.gen_id()
+        ofile_abs = []
+        for i in genlist.get_inputs():
+            for o_base in genlist.get_outputs_for(i):
+                o = os.path.join(self.get_target_private_dir(t), o_base)
+                ofile_abs.append(os.path.join(self.environment.get_build_dir(), o))
+        assert(k not in self.generator_outputs)
+        self.generator_outputs[k] = ofile_abs
+        buildfile_ids = []
+        fileref_ids = []
+        for i in range(len(ofile_abs)):
+            buildfile_ids.append(self.gen_id())
+            fileref_ids.append(self.gen_id())
+        self.generator_buildfile_ids[k] = buildfile_ids
+        self.generator_fileref_ids[k] = fileref_ids
+
 
     def generate_native_frameworks_map(self):
         self.native_frameworks = {}
@@ -494,7 +505,18 @@
         for tname, t in self.build.get_custom_targets().items():
             ct_id = self.gen_id()
             self.custom_aggregate_targets[tname] = ct_id
-            aggregated_targets.append((ct_id, tname, self.buildconflistmap[tname], [self.shell_targets[tname]], []))
+            build_phases = []
+            dependencies = []
+            generator_id = 0
+            for s in t.sources: 
+                if not isinstance(s, build.GeneratedList):
+                    continue
+                build_phases.append(self.shell_targets[(tname, generator_id)])
+                for d in s.depends:
+                    dependencies.append(self.pbx_custom_dep_map[d.get_id()])
+                generator_id += 1
+            build_phases.append(self.shell_targets[tname])
+            aggregated_targets.append((ct_id, tname, self.buildconflistmap[tname], build_phases, dependencies))
 
         # Sort objects by ID before writing
         sorted_aggregated_targets = sorted(aggregated_targets, key=operator.itemgetter(0))
@@ -573,17 +595,7 @@
             for g in t.generated:
                 if not isinstance(g, build.GeneratedList):
                     continue
-                file_ids = self.generator_buildfile_ids[(tname, generator_id)]
-                ref_ids = self.generator_fileref_ids[tname, generator_id]
-                assert(len(ref_ids) == len(file_ids))
-                for i in range(len(file_ids)):
-                    file_o = file_ids[i]
-                    ref_id = ref_ids[i]
-                    odict = PbxDict()
-                    objects_dict.add_item(file_o, odict)
-                    odict.add_item('isa', 'PBXBuildFile')
-                    odict.add_item('fileRef', ref_id)
-
+                self.create_generator_shellphase(objects_dict, tname, generator_id) 
                 generator_id += 1
 
         # Custom targets are shell build phases in Xcode terminology.
@@ -596,6 +608,24 @@
                 objects_dict.add_item(self.custom_target_output_buildfile[o], custom_dict, f'/* {o} */')
                 custom_dict.add_item('isa', 'PBXBuildFile')
                 custom_dict.add_item('fileRef', self.custom_target_output_fileref[o])
+            generator_id = 0
+            for g in t.sources:
+                if not isinstance(g, build.GeneratedList):
+                    continue
+                self.create_generator_shellphase(objects_dict, tname, generator_id) 
+                generator_id += 1
+
+    def create_generator_shellphase(self, objects_dict, tname, generator_id):
+        file_ids = self.generator_buildfile_ids[(tname, generator_id)]
+        ref_ids = self.generator_fileref_ids[(tname, generator_id)]
+        assert(len(ref_ids) == len(file_ids))
+        for i in range(len(file_ids)):
+            file_o = file_ids[i]
+            ref_id = ref_ids[i]
+            odict = PbxDict()
+            objects_dict.add_item(file_o, odict)
+            odict.add_item('isa', 'PBXBuildFile')
+            odict.add_item('fileRef', ref_id)
 
     def generate_pbx_build_style(self, objects_dict):
         # FIXME: Xcode 9 and later does not uses PBXBuildStyle and it gets removed. Maybe we can remove this part.
@@ -1033,59 +1063,68 @@
             generator_id = 0
             for genlist in t.generated:
                 if isinstance(genlist, build.GeneratedList):
-                    generator = genlist.get_generator()
-                    exe = generator.get_exe()
-                    exe_arr = self.build_target_to_cmd_array(exe)
-                    workdir = self.environment.get_build_dir()
-                    gen_dict = PbxDict()
-                    objects_dict.add_item(self.shell_targets[(tname, generator_id)], gen_dict, '"Generator {}/{}"'.format(generator_id, tname))
-                    infilelist = genlist.get_inputs()
-                    outfilelist = genlist.get_outputs()
-                    gen_dict.add_item('isa', 'PBXShellScriptBuildPhase')
-                    gen_dict.add_item('buildActionMask', 2147483647)
-                    gen_dict.add_item('files', PbxArray())
-                    gen_dict.add_item('inputPaths', PbxArray())
-                    gen_dict.add_item('name', '"Generator {}/{}"'.format(generator_id, tname))    
-                    commands = [["cd", workdir]] # Array of arrays, each one a single command, will get concatenated below.
-                    k = (tname, generator_id)
-                    ofile_abs = self.generator_outputs[k]
-                    outarray = PbxArray()
-                    gen_dict.add_item('outputPaths', outarray)
-                    for of in ofile_abs:
-                        outarray.add_item(of)
-                    for i in infilelist:
-                        # This might be needed to be added to inputPaths. It's not done yet as it is
-                        # unclear whether it is necessary, what actually happens when it is defined
-                        # and currently the build works without it.
-                        #infile_abs = i.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
-                        infilename = i.rel_to_builddir(self.build_to_src)
-                        base_args = generator.get_arglist(infilename)
-                        for o_base in genlist.get_outputs_for(i):
-                            o = os.path.join(self.get_target_private_dir(t), o_base)
-                            args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', o).replace('@BUILD_DIR@', self.get_target_private_dir(t)) for x in base_args]
-                            args = self.replace_outputs(args, self.get_target_private_dir(t), outfilelist)
-                            args = self.replace_extra_args(args, genlist)
-                            if generator.capture:
-                                # When capturing, stdout is the output. Forward it with the shell.
-                                full_command = ['('] + exe_arr + args + ['>', o, ')']
-                            else:
-                                full_command = exe_arr + args
-                            commands.append(full_command)
-                    gen_dict.add_item('runOnlyForDeploymentPostprocessing', 0)
-                    gen_dict.add_item('shellPath', '/bin/sh')
-                    quoted_cmds = []
-                    for cmnd in commands:
-                        q = []
-                        for c in cmnd:
-                            if ' ' in c:
-                                q.append(f'\\"{c}\\"')
-                            else:
-                                q.append(c)
-                        quoted_cmds.append(' '.join(q))
-                    cmdstr = '"'  + ' && '.join(quoted_cmds) + '"'
-                    gen_dict.add_item('shellScript', cmdstr)
-                    gen_dict.add_item('showEnvVarsInLog', 0)
+                    self.generate_single_generator_phase(tname, t, genlist, generator_id, objects_dict)
                     generator_id += 1
+        for tname, t in self.custom_targets.items():
+            generator_id = 0
+            for genlist in t.sources:
+                if isinstance(genlist, build.GeneratedList):
+                    self.generate_single_generator_phase(tname, t, genlist, generator_id, objects_dict)
+                    generator_id += 1
+
+    def generate_single_generator_phase(self, tname, t, genlist, generator_id, objects_dict):
+        generator = genlist.get_generator()
+        exe = generator.get_exe()
+        exe_arr = self.build_target_to_cmd_array(exe)
+        workdir = self.environment.get_build_dir()
+        gen_dict = PbxDict()
+        objects_dict.add_item(self.shell_targets[(tname, generator_id)], gen_dict, '"Generator {}/{}"'.format(generator_id, tname))
+        infilelist = genlist.get_inputs()
+        outfilelist = genlist.get_outputs()
+        gen_dict.add_item('isa', 'PBXShellScriptBuildPhase')
+        gen_dict.add_item('buildActionMask', 2147483647)
+        gen_dict.add_item('files', PbxArray())
+        gen_dict.add_item('inputPaths', PbxArray())
+        gen_dict.add_item('name', '"Generator {}/{}"'.format(generator_id, tname))    
+        commands = [["cd", workdir]] # Array of arrays, each one a single command, will get concatenated below.
+        k = (tname, generator_id)
+        ofile_abs = self.generator_outputs[k]
+        outarray = PbxArray()
+        gen_dict.add_item('outputPaths', outarray)
+        for of in ofile_abs:
+            outarray.add_item(of)
+        for i in infilelist:
+            # This might be needed to be added to inputPaths. It's not done yet as it is
+            # unclear whether it is necessary, what actually happens when it is defined
+            # and currently the build works without it.
+            #infile_abs = i.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
+            infilename = i.rel_to_builddir(self.build_to_src)
+            base_args = generator.get_arglist(infilename)
+            for o_base in genlist.get_outputs_for(i):
+                o = os.path.join(self.get_target_private_dir(t), o_base)
+                args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', o).replace('@BUILD_DIR@', self.get_target_private_dir(t)) for x in base_args]
+                args = self.replace_outputs(args, self.get_target_private_dir(t), outfilelist)
+                args = self.replace_extra_args(args, genlist)
+                if generator.capture:
+                    # When capturing, stdout is the output. Forward it with the shell.
+                    full_command = ['('] + exe_arr + args + ['>', o, ')']
+                else:
+                    full_command = exe_arr + args
+                commands.append(full_command)
+        gen_dict.add_item('runOnlyForDeploymentPostprocessing', 0)
+        gen_dict.add_item('shellPath', '/bin/sh')
+        quoted_cmds = []
+        for cmnd in commands:
+            q = []
+            for c in cmnd:
+                if ' ' in c:
+                    q.append(f'\\"{c}\\"')
+                else:
+                    q.append(c)
+            quoted_cmds.append(' '.join(q))
+        cmdstr = '"'  + ' && '.join(quoted_cmds) + '"'
+        gen_dict.add_item('shellScript', cmdstr)
+        gen_dict.add_item('showEnvVarsInLog', 0)
 
 
     def generate_pbx_sources_build_phase(self, objects_dict):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index ab2866e..69e853f 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1580,10 +1580,15 @@
     def process_files(self, name, files, state, preserve_path_from=None, extra_args=None):
         new = False
         output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args if extra_args is not None else [])
+        #XXX
         for e in unholder(files):
             fs = [e]
+            if isinstance(e, CustomTarget):
+                output.depends.add(e)
+            if isinstance(e, CustomTargetIndex):
+                output.depends.add(e.target)
             if isinstance(e, (CustomTarget, CustomTargetIndex, GeneratedList)):
-                self.depends.append(e)
+                self.depends.append(e) # BUG: this should go in the GeneratedList object, not this object.
                 fs = []
                 for f in e.get_outputs():
                     fs.append(File.from_built_file(state.subdir, f))
@@ -1610,6 +1615,7 @@
     def __init__(self, generator, subdir, preserve_path_from=None, extra_args=None):
         self.generator = unholder(generator)
         self.name = self.generator.exe
+        self.depends = set() # Things this target depends on (because e.g. a custom target was used as input)
         self.subdir = subdir
         self.infilelist = []
         self.outfilelist = []
@@ -2545,7 +2551,7 @@
 class CustomTargetIndex:
 
     """A special opaque object returned by indexing a CustomTarget. This object
-    exists in meson, but acts as a proxy in the backends, making targets depend
+    exists in Meson, but acts as a proxy in the backends, making targets depend
     on the CustomTarget it's derived from, but only adding one source file to
     the sources.
     """