diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index f595e098c..3482f3d78 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -262,9 +262,13 @@ class Backend:
             return self.environment.coredata.validate_option_value(option_name, override)
         return self.environment.coredata.get_option(option_name.evolve(subproject=target.subproject))
 
-    def get_source_dir_include_args(self, target, compiler):
+    def get_source_dir_include_args(self, target, compiler, *, absolute_path=False):
         curdir = target.get_subdir()
-        tmppath = os.path.normpath(os.path.join(self.build_to_src, curdir))
+        if absolute_path:
+            lead = self.source_dir
+        else:
+            lead = self.build_to_src
+        tmppath = os.path.normpath(os.path.join(lead, curdir))
         return compiler.get_include_args(tmppath, False)
 
     def get_build_dir_include_args(self, target, compiler, *, absolute_path=False):
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 3923c14de..2bd6acf85 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -1030,6 +1030,7 @@ class XCodeBackend(backends.Backend):
                         # add the root build dir to the search path. So add an absolute path instead.
                         # This may break reproducible builds, in which case patches are welcome.
                         lang_cargs += self.get_build_dir_include_args(target, compiler, absolute_path=True)
+                        lang_cargs += self.get_source_dir_include_args(target, compiler, absolute_path=True)
                     langargs[langname] = args
                     langargs[langname] += lang_cargs
             symroot = os.path.join(self.environment.get_build_dir(), target.subdir)
@@ -1080,7 +1081,11 @@ class XCodeBackend(backends.Backend):
             settings_dict.add_item('PRODUCT_NAME', product_name)
             settings_dict.add_item('SECTORDER_FLAGS', '""')
             settings_dict.add_item('SYMROOT', f'"{symroot}"')
-            settings_dict.add_item('SYSTEM_HEADER_SEARCH_PATHS', '"{}"'.format(self.environment.get_build_dir()))
+            sysheader_arr = PbxArray()
+            # XCode will change every -I flag that points inside these directories
+            # to an -isystem. Thus set nothing in it since we control our own
+            # include flags.
+            settings_dict.add_item('SYSTEM_HEADER_SEARCH_PATHS', sysheader_arr)
             settings_dict.add_item('USE_HEADERMAP', 'NO')
             warn_array = PbxArray()
             settings_dict.add_item('WARNING_CFLAGS', warn_array)
@@ -1090,8 +1095,12 @@ class XCodeBackend(backends.Backend):
     def add_otherargs(self, settings_dict, langargs):
         for langname, args in langargs.items():
             if args:
-                # FIXME, proper quoting
-                settings_dict.add_item(f'OTHER_{langname}FLAGS', '"' + ' '.join(args) + '"')
+                quoted_args = []
+                for a in args:
+                    if ' ' in a:
+                        a = r'\"' + a + r'\"'
+                    quoted_args.append(a)
+                settings_dict.add_item(f'OTHER_{langname}FLAGS', '"' + ' '.join(quoted_args) + '"')
 
     def generate_xc_configurationList(self, objects_dict):
         # FIXME: sort items