diff --git a/docs/markdown/Installing.md b/docs/markdown/Installing.md
index 66d090dbf..5abfdd452 100644
--- a/docs/markdown/Installing.md
+++ b/docs/markdown/Installing.md
@@ -115,3 +115,24 @@ command in the build tree:
 ```console
 $ meson install --no-rebuild --only-changed
 ```
+
+## Finer control over install locations
+
+Sometimes it is necessary to only install a subsection of output files
+or install them in different directories. This can be done by
+specifying `install_dir` as an array rather than a single string. The
+array must have as many items as there are outputs and each entry
+specifies how the corresponding output file should be installed. For
+example:
+
+```meson
+custom_target(...
+    output: ['file1', 'file2', 'file3'],
+    install_dir: ['path1', false, 'path3'],
+    ...
+)
+```
+
+In this case `file1` would be installed to `/prefix/path1/file1`,
+`file2` would not be installed at all and `file3` would be installed
+to `/prefix/path3/file3'.
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 7c6625081..5bd810611 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -738,7 +738,7 @@ class XCodeBackend(backends.Backend):
                 ldstr = ' '.join(ldargs)
                 valid = self.buildconfmap[target_name][buildtype]
                 langargs = {}
-                for lang in self.environment.coredata.compilers:
+                for lang in self.environment.coredata.compilers[target.for_machine]:
                     if lang not in langnamemap:
                         continue
                     # Add compile args added using add_project_arguments()
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index b700b003a..e81a8e146 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -123,6 +123,8 @@ def list_installed(installdata):
             res[path] = os.path.join(installdata.prefix, installdir, os.path.basename(path))
         for path, installpath, _ in installdata.man:
             res[path] = os.path.join(installdata.prefix, installpath)
+        for path, installpath, _, _ in installdata.install_subdirs:
+            res[path] = os.path.join(installdata.prefix, installpath)
     return res
 
 def list_targets_from_source(intr: IntrospectionInterpreter):
diff --git a/mesonbuild/scripts/dist.py b/mesonbuild/scripts/dist.py
index 47fde2379..1a62c7068 100644
--- a/mesonbuild/scripts/dist.py
+++ b/mesonbuild/scripts/dist.py
@@ -144,11 +144,15 @@ def create_dist_hg(dist_name, src_root, bld_root, dist_sub, dist_scripts):
     return (xzname, )
 
 
-def check_dist(packagename, meson_command):
+def check_dist(packagename, meson_command, privdir):
     print('Testing distribution package %s' % packagename)
-    unpackdir = tempfile.mkdtemp()
-    builddir = tempfile.mkdtemp()
-    installdir = tempfile.mkdtemp()
+    unpackdir = os.path.join(privdir, 'dist-unpack')
+    builddir = os.path.join(privdir, 'dist-build')
+    installdir = os.path.join(privdir, 'dist-install')
+    for p in (unpackdir, builddir, installdir):
+        if os.path.exists(p):
+            shutil.rmtree(p)
+        os.mkdir(p)
     ninja_bin = detect_ninja()
     try:
         tf = tarfile.open(packagename)
@@ -200,7 +204,7 @@ def run(args):
         return 1
     error_count = 0
     for name in names:
-        rc = check_dist(name, meson_command) # Check only one.
+        rc = check_dist(name, meson_command, priv_dir) # Check only one.
         if rc == 0:
             create_hash(name)
         error_count += rc

Introspection API: missing info about `install_subdir`
`meson-info/intro-installed.json` does not contain any information about files/directories installed via `install_subdir`.

PS: `meson-logs/install-log.txt` contains such info, so it probably could be used as a reference.
diff --git a/run_unittests.py b/run_unittests.py
index 602c6b73e..90e5c9d8b 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1695,6 +1695,34 @@ class AllPlatformTests(BasePlatformTests):
         self.assertPathListEqual(intro[0]['install_filename'], ['/usr/lib/libstat.a'])
         self.assertPathListEqual(intro[1]['install_filename'], ['/usr/bin/prog' + exe_suffix])
 
+    def test_install_subdir_introspection(self):
+        '''
+        Test that the Meson introspection API also contains subdir install information
+        https://github.com/mesonbuild/meson/issues/5556
+        '''
+        testdir = os.path.join(self.common_test_dir, '63 install subdir')
+        self.init(testdir)
+        intro = self.introspect('--installed')
+        expected = {
+            'sub2': 'share/sub2',
+            'subdir/sub1': 'share/sub1',
+            'subdir/sub_elided': 'share',
+            'sub1': 'share/sub1',
+            'sub/sub1': 'share/sub1',
+            'sub_elided': 'share',
+            'nested_elided/sub': 'share',
+        }
+
+        self.assertEqual(len(intro), len(expected))
+
+        # Convert expected to PurePath
+        expected_converted = {PurePath(os.path.join(testdir, key)): PurePath(os.path.join(self.prefix, val)) for key, val in expected.items()}
+        intro_converted = {PurePath(key): PurePath(val) for key, val in intro.items()}
+
+        for src, dst in expected_converted.items():
+            self.assertIn(src, intro_converted)
+            self.assertEqual(dst, intro_converted[src])
+
     def test_install_introspection_multiple_outputs(self):
         '''
         Tests that the Meson introspection API exposes multiple install filenames correctly without crashing

pip install -e .
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y ninja-build
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup==1.2.2
iniconfig==2.1.0
-e git+https://github.com/mesonbuild/meson.git@3f280a81fde8a7771924159d6e1bda7ec364970c#egg=meson
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
tomli==2.2.1

name: meson
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - tomli==2.2.1
prefix: /opt/conda/envs/meson

run_unittests.py::AllPlatformTests::test_install_subdir_introspection
run_unittests.py::DataTests::test_compiler_options_documented run_unittests.py::AllPlatformTests::test_absolute_prefix_libdir run_unittests.py::AllPlatformTests::test_always_prefer_c_compiler_for_asm run_unittests.py::AllPlatformTests::test_check_module_linking run_unittests.py::AllPlatformTests::test_compiler_detection run_unittests.py::AllPlatformTests::test_default_options_prefix run_unittests.py::AllPlatformTests::test_introspect_buildoptions_without_configured_build run_unittests.py::AllPlatformTests::test_introspect_config_update run_unittests.py::AllPlatformTests::test_introspect_dependencies_from_source run_unittests.py::AllPlatformTests::test_introspect_file_dump_equals_all run_unittests.py::AllPlatformTests::test_introspect_json_dump run_unittests.py::AllPlatformTests::test_introspect_meson_info run_unittests.py::AllPlatformTests::test_introspect_targets_from_source run_unittests.py::AllPlatformTests::test_preprocessor_checks_CPPFLAGS run_unittests.py::AllPlatformTests::test_templates run_unittests.py::AllPlatformTests::test_warning_level_0 run_unittests.py::FailureTests::test_boost_BOOST_ROOT_dependency run_unittests.py::FailureTests::test_boost_notfound_dependency run_unittests.py::FailureTests::test_dependency_invalid_method run_unittests.py::FailureTests::test_extraframework_dependency_method run_unittests.py::FailureTests::test_get_variable_on_not_found_project run_unittests.py::FailureTests::test_gnustep_notfound_dependency run_unittests.py::FailureTests::test_llvm_dependency run_unittests.py::FailureTests::test_missing_subproject_not_required_and_required run_unittests.py::FailureTests::test_sdl2_notfound_dependency run_unittests.py::FailureTests::test_using_recent_feature run_unittests.py::FailureTests::test_using_too_recent_feature run_unittests.py::FailureTests::test_using_too_recent_feature_dependency run_unittests.py::FailureTests::test_vcs_tag_featurenew_build_always_stale run_unittests.py::FailureTests::test_wx_notfound_dependency run_unittests.py::LinuxlikeTests::test_build_rpath run_unittests.py::LinuxlikeTests::test_compiler_check_flags_order run_unittests.py::LinuxlikeTests::test_compiler_cpp_stds run_unittests.py::LinuxlikeTests::test_cpp_std_override run_unittests.py::LinuxlikeTests::test_pch_with_address_sanitizer run_unittests.py::RewriterTests::test_default_options_delete run_unittests.py::RewriterTests::test_default_options_set run_unittests.py::RewriterTests::test_kwargs_add run_unittests.py::RewriterTests::test_kwargs_delete run_unittests.py::RewriterTests::test_kwargs_info run_unittests.py::RewriterTests::test_kwargs_remove run_unittests.py::RewriterTests::test_kwargs_remove_regex run_unittests.py::RewriterTests::test_kwargs_set run_unittests.py::RewriterTests::test_target_add_sources run_unittests.py::RewriterTests::test_target_add_sources_abs run_unittests.py::RewriterTests::test_target_remove run_unittests.py::RewriterTests::test_target_remove_sources run_unittests.py::RewriterTests::test_target_same_name_skip run_unittests.py::RewriterTests::test_target_source_list run_unittests.py::RewriterTests::test_target_source_sorting run_unittests.py::RewriterTests::test_tatrget_add run_unittests.py::NativeFileTests::test_cpp_compiler
run_unittests.py::InternalTests::test_compiler_args_class run_unittests.py::InternalTests::test_compiler_args_class_gnuld run_unittests.py::InternalTests::test_extract_as_list run_unittests.py::InternalTests::test_find_library_patterns run_unittests.py::InternalTests::test_listify run_unittests.py::InternalTests::test_mode_symbolic_to_bits run_unittests.py::InternalTests::test_needs_exe_wrapper_override run_unittests.py::InternalTests::test_pkgconfig_module run_unittests.py::InternalTests::test_pkgconfig_parse_libs run_unittests.py::InternalTests::test_string_templates_substitution run_unittests.py::InternalTests::test_version_compare run_unittests.py::InternalTests::test_version_number run_unittests.py::DataTests::test_all_functions_defined_in_ast_interpreter run_unittests.py::DataTests::test_builtin_options_documented run_unittests.py::DataTests::test_cpu_families_documented run_unittests.py::DataTests::test_markdown_files_in_sitemap run_unittests.py::DataTests::test_snippets run_unittests.py::DataTests::test_syntax_highlighting_files run_unittests.py::AllPlatformTests::test_all_forbidden_targets_tested run_unittests.py::AllPlatformTests::test_array_option_bad_change run_unittests.py::AllPlatformTests::test_array_option_change run_unittests.py::AllPlatformTests::test_array_option_empty_equivalents run_unittests.py::AllPlatformTests::test_build_by_default run_unittests.py::AllPlatformTests::test_buildtype_setting run_unittests.py::AllPlatformTests::test_clike_get_library_dirs run_unittests.py::AllPlatformTests::test_command_line run_unittests.py::AllPlatformTests::test_compiler_run_command run_unittests.py::AllPlatformTests::test_configure_file_warnings run_unittests.py::AllPlatformTests::test_conflicting_d_dash_option run_unittests.py::AllPlatformTests::test_cross_file_system_paths run_unittests.py::AllPlatformTests::test_custom_target_changes_cause_rebuild run_unittests.py::AllPlatformTests::test_custom_target_exe_data_deterministic run_unittests.py::AllPlatformTests::test_dash_d_dedup run_unittests.py::AllPlatformTests::test_default_options_prefix_dependent_defaults run_unittests.py::AllPlatformTests::test_dirs run_unittests.py::AllPlatformTests::test_dist_git run_unittests.py::AllPlatformTests::test_dist_git_script run_unittests.py::AllPlatformTests::test_dist_hg run_unittests.py::AllPlatformTests::test_do_conf_file_preserve_newlines run_unittests.py::AllPlatformTests::test_env_ops_dont_stack run_unittests.py::AllPlatformTests::test_feature_check_usage_subprojects run_unittests.py::AllPlatformTests::test_flock run_unittests.py::AllPlatformTests::test_forcefallback run_unittests.py::AllPlatformTests::test_free_stringarray_setting run_unittests.py::AllPlatformTests::test_guessed_linker_dependencies run_unittests.py::AllPlatformTests::test_identical_target_name_in_subdir_flat_layout run_unittests.py::AllPlatformTests::test_identical_target_name_in_subproject_flat_layout run_unittests.py::AllPlatformTests::test_install_introspection run_unittests.py::AllPlatformTests::test_install_introspection_multiple_outputs run_unittests.py::AllPlatformTests::test_internal_include_order run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subproject_dir run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subproject_dir_from_source run_unittests.py::AllPlatformTests::test_introspect_projectinfo_subprojects run_unittests.py::AllPlatformTests::test_introspect_projectinfo_without_configured_build run_unittests.py::AllPlatformTests::test_introspection_target_subproject run_unittests.py::AllPlatformTests::test_libdir_must_be_inside_prefix run_unittests.py::AllPlatformTests::test_minor_version_does_not_reconfigure_wipe run_unittests.py::AllPlatformTests::test_ndebug_if_release_disabled run_unittests.py::AllPlatformTests::test_ndebug_if_release_enabled run_unittests.py::AllPlatformTests::test_permitted_method_kwargs run_unittests.py::AllPlatformTests::test_prebuilt_object run_unittests.py::AllPlatformTests::test_prebuilt_shared_lib run_unittests.py::AllPlatformTests::test_prebuilt_static_lib run_unittests.py::AllPlatformTests::test_prefix_dependent_defaults run_unittests.py::AllPlatformTests::test_reconfigure run_unittests.py::AllPlatformTests::test_rpath_uses_ORIGIN run_unittests.py::AllPlatformTests::test_run_target_files_path run_unittests.py::AllPlatformTests::test_same_d_option_twice run_unittests.py::AllPlatformTests::test_same_d_option_twice_configure run_unittests.py::AllPlatformTests::test_same_dash_option_twice run_unittests.py::AllPlatformTests::test_same_dash_option_twice_configure run_unittests.py::AllPlatformTests::test_same_project_d_option_twice run_unittests.py::AllPlatformTests::test_same_project_d_option_twice_configure run_unittests.py::AllPlatformTests::test_source_changes_cause_rebuild run_unittests.py::AllPlatformTests::test_source_generator_program_cause_rebuild run_unittests.py::AllPlatformTests::test_static_compile_order run_unittests.py::AllPlatformTests::test_static_library_lto run_unittests.py::AllPlatformTests::test_static_library_overwrite run_unittests.py::AllPlatformTests::test_subproject_promotion run_unittests.py::AllPlatformTests::test_subproject_promotion_wrap run_unittests.py::AllPlatformTests::test_suite_selection run_unittests.py::AllPlatformTests::test_target_construct_id_from_path run_unittests.py::AllPlatformTests::test_testsetup_default run_unittests.py::AllPlatformTests::test_testsetup_selection run_unittests.py::AllPlatformTests::test_uninstall run_unittests.py::AllPlatformTests::test_unstable_coredata run_unittests.py::AllPlatformTests::test_warning_location run_unittests.py::AllPlatformTests::test_wipe_from_builddir run_unittests.py::FailureTests::test_dict_forbids_duplicate_keys run_unittests.py::FailureTests::test_dict_forbids_integer_key run_unittests.py::FailureTests::test_dict_requires_key_value_pairs run_unittests.py::FailureTests::test_exception_exit_status run_unittests.py::FailureTests::test_objc_cpp_detection run_unittests.py::FailureTests::test_subproject_variables run_unittests.py::FailureTests::test_version_checked_before_parsing_options run_unittests.py::LinuxlikeTests::test_basic_soname run_unittests.py::LinuxlikeTests::test_compiler_c_stds run_unittests.py::LinuxlikeTests::test_compiler_libs_static_dedup run_unittests.py::LinuxlikeTests::test_cross_find_program run_unittests.py::LinuxlikeTests::test_custom_soname run_unittests.py::LinuxlikeTests::test_deterministic_dep_order run_unittests.py::LinuxlikeTests::test_deterministic_rpath_order run_unittests.py::LinuxlikeTests::test_identity_cross run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks_with_default_umask run_unittests.py::LinuxlikeTests::test_install_subdir_symlinks_with_default_umask_and_mode run_unittests.py::LinuxlikeTests::test_install_umask run_unittests.py::LinuxlikeTests::test_installed_modes run_unittests.py::LinuxlikeTests::test_installed_modes_extended run_unittests.py::LinuxlikeTests::test_installed_soname run_unittests.py::LinuxlikeTests::test_override_with_exe_dep run_unittests.py::LinuxlikeTests::test_pic run_unittests.py::LinuxlikeTests::test_pkg_unfound run_unittests.py::LinuxlikeTests::test_reconfigure run_unittests.py::LinuxlikeTests::test_run_installed run_unittests.py::LinuxlikeTests::test_soname run_unittests.py::LinuxlikeTests::test_std_remains run_unittests.py::LinuxlikeTests::test_unity_subproj run_unittests.py::PythonTests::test_versions run_unittests.py::RewriterTests::test_target_add_subdir run_unittests.py::RewriterTests::test_target_remove_subdir run_unittests.py::RewriterTests::test_target_subdir run_unittests.py::NativeFileTests::test_compile_sys_path run_unittests.py::NativeFileTests::test_find_program run_unittests.py::NativeFileTests::test_multiple_native_files run_unittests.py::NativeFileTests::test_multiple_native_files_override run_unittests.py::NativeFileTests::test_native_file_dirs run_unittests.py::NativeFileTests::test_native_file_dirs_overriden run_unittests.py::NativeFileTests::test_native_file_is_pipe run_unittests.py::NativeFileTests::test_python3_module run_unittests.py::NativeFileTests::test_python_module run_unittests.py::CrossFileTests::test_cross_file_dirs run_unittests.py::CrossFileTests::test_cross_file_dirs_chain run_unittests.py::CrossFileTests::test_cross_file_dirs_overriden run_unittests.py::TAPParserTests::test_diagnostics run_unittests.py::TAPParserTests::test_directive_case run_unittests.py::TAPParserTests::test_directive_explanation run_unittests.py::TAPParserTests::test_empty run_unittests.py::TAPParserTests::test_empty_plan run_unittests.py::TAPParserTests::test_many_early_plan run_unittests.py::TAPParserTests::test_many_late_plan run_unittests.py::TAPParserTests::test_middle_plan run_unittests.py::TAPParserTests::test_one_test_early_plan run_unittests.py::TAPParserTests::test_one_test_late_plan run_unittests.py::TAPParserTests::test_one_test_not_ok run_unittests.py::TAPParserTests::test_one_test_ok run_unittests.py::TAPParserTests::test_one_test_skip run_unittests.py::TAPParserTests::test_one_test_skip_failure run_unittests.py::TAPParserTests::test_one_test_todo run_unittests.py::TAPParserTests::test_one_test_with_name run_unittests.py::TAPParserTests::test_one_test_with_number run_unittests.py::TAPParserTests::test_out_of_order run_unittests.py::TAPParserTests::test_plan_directive run_unittests.py::TAPParserTests::test_too_few run_unittests.py::TAPParserTests::test_too_few_bailout run_unittests.py::TAPParserTests::test_too_many run_unittests.py::TAPParserTests::test_too_many_plans run_unittests.py::TAPParserTests::test_unexpected run_unittests.py::TAPParserTests::test_version run_unittests.py::TAPParserTests::test_yaml
mesonbuild/mintro.py mesonbuild/backend/xcodebackend.py mesonbuild/scripts/dist.py docs/markdown/Installing.md
mesonbuild/mintro.py mesonbuild/backend/xcodebackend.py mesonbuild/scripts/dist.py docs/markdown/Installing.md