diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 931363c835843c58e453aea00211298f83c04601..a41d48499b46ba1e631e2936bfaa0784bdcaa605 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -191,6 +191,7 @@ Properties on Targets
    /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION
+   /prop_tgt/IOS_INSTALL_COMBINED
    /prop_tgt/JOB_POOL_COMPILE
    /prop_tgt/JOB_POOL_LINK
    /prop_tgt/LABELS
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 211690050a660b3c1578b57f32b475bcb395d88a..3f4957283d96b5dae9e4a29cfb693a2a65034792 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -257,6 +257,7 @@ Variables that Control the Build
    /variable/CMAKE_INSTALL_NAME_DIR
    /variable/CMAKE_INSTALL_RPATH
    /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
+   /variable/CMAKE_IOS_INSTALL_COMBINED
    /variable/CMAKE_LANG_COMPILER_LAUNCHER
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
    /variable/CMAKE_LANG_VISIBILITY_PRESET
diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
new file mode 100644
index 0000000000000000000000000000000000000000..59f67a7ebe61479f0313ed0703e96e324b6f99e9
--- /dev/null
+++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
@@ -0,0 +1,11 @@
+IOS_INSTALL_COMBINED
+--------------------
+
+Build a combined (device and simulator) target when installing.
+
+When this property is set to set to false (which is the default) then it will
+either be built with the device SDK or the simulator SDK depending on the SDK
+set. But if this property is set to true then the target will at install time
+also be built for the corresponding SDK and combined into one library.
+
+This feature requires at least Xcode version 6.
diff --git a/Help/release/dev/ios-universal.rst b/Help/release/dev/ios-universal.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f96abede3c82f9a44d9a4680d5a575fd4e110ed2
--- /dev/null
+++ b/Help/release/dev/ios-universal.rst
@@ -0,0 +1,7 @@
+ios-universal
+-------------
+
+* When building for embedded Apple platforms like iOS CMake learned to build and
+  install combined targets which contain both a device and a simulator build.
+  This behavior can be enabled by setting the :prop_tgt:`IOS_INSTALL_COMBINED`
+  target property.
diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c5cb9b647dce22ad94b95df98fb4412b108d88a0
--- /dev/null
+++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
@@ -0,0 +1,8 @@
+CMAKE_IOS_INSTALL_COMBINED
+--------------------------
+
+Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets.
+
+This variable is used to initialize the :prop_tgt:`IOS_INSTALL_COMBINED`
+property on all the targets.  See that target property for additional
+information.
diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..f052a3bf178f3fd6f5c7c2ed18a61eccd1956d25
--- /dev/null
+++ b/Modules/CMakeIOSInstallCombined.cmake
@@ -0,0 +1,297 @@
+
+#=============================================================================
+# Copyright 2014-2015 Ruslan Baratov, Gregor Jasny
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# Function to print messages of this module
+function(_ios_install_combined_message)
+  message("[iOS combined] " ${ARGN})
+endfunction()
+
+# Get build settings for the current target/config/SDK by running
+# `xcodebuild -sdk ... -showBuildSettings` and parsing it's output
+function(_ios_install_combined_get_build_setting sdk variable resultvar)
+  if("${sdk}" STREQUAL "")
+    message(FATAL_ERROR "`sdk` is empty")
+  endif()
+
+  if("${variable}" STREQUAL "")
+    message(FATAL_ERROR "`variable` is empty")
+  endif()
+
+  if("${resultvar}" STREQUAL "")
+    message(FATAL_ERROR "`resultvar` is empty")
+  endif()
+
+  set(
+      cmd
+      xcodebuild -showBuildSettings
+      -sdk "${sdk}"
+      -target "${CURRENT_TARGET}"
+      -config "${CURRENT_CONFIG}"
+  )
+
+  execute_process(
+      COMMAND ${cmd}
+      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+      RESULT_VARIABLE result
+      OUTPUT_VARIABLE output
+  )
+
+  if(NOT result EQUAL 0)
+    message(FATAL_ERROR "Command failed (${result}): ${cmd}")
+  endif()
+
+  if(NOT output MATCHES " ${variable} = ([^\n]*)")
+    message(FATAL_ERROR "${variable} not found.")
+  endif()
+
+  set("${resultvar}" "${CMAKE_MATCH_1}" PARENT_SCOPE)
+endfunction()
+
+# Get architectures of given SDK (iphonesimulator/iphoneos)
+function(_ios_install_combined_get_valid_archs sdk resultvar)
+  cmake_policy(SET CMP0007 NEW)
+
+  if("${resultvar}" STREQUAL "")
+    message(FATAL_ERROR "`resultvar` is empty")
+  endif()
+
+  _ios_install_combined_get_build_setting("${sdk}" "VALID_ARCHS" valid_archs)
+
+  separate_arguments(valid_archs)
+  list(REMOVE_ITEM valid_archs "") # remove empty elements
+  list(REMOVE_DUPLICATES valid_archs)
+
+  set("${resultvar}" "${valid_archs}" PARENT_SCOPE)
+endfunction()
+
+# Final target can contain more architectures that specified by SDK. This
+# function will run 'lipo -info' and parse output. Result will be returned
+# as a CMake list.
+function(_ios_install_combined_get_real_archs filename resultvar)
+  set(cmd "${_lipo_path}" -info "${filename}")
+  execute_process(
+      COMMAND ${cmd}
+      RESULT_VARIABLE result
+      OUTPUT_VARIABLE output
+      ERROR_VARIABLE output
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_STRIP_TRAILING_WHITESPACE
+  )
+  if(NOT result EQUAL 0)
+    message(
+        FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+    )
+  endif()
+
+  if(NOT output MATCHES "(Architectures in the fat file: [^\n]+ are|Non-fat file: [^\n]+ is architecture): ([^\n]*)")
+    message(FATAL_ERROR "Could not detect architecture from: ${output}")
+  endif()
+
+  separate_arguments(CMAKE_MATCH_2)
+  set(${resultvar} ${CMAKE_MATCH_2} PARENT_SCOPE)
+endfunction()
+
+# Run build command for the given SDK
+function(_ios_install_combined_build sdk)
+  if("${sdk}" STREQUAL "")
+    message(FATAL_ERROR "`sdk` is empty")
+  endif()
+
+  _ios_install_combined_message("Build `${CURRENT_TARGET}` for `${sdk}`")
+
+  execute_process(
+      COMMAND
+      "${CMAKE_COMMAND}"
+      --build
+      .
+      --target "${CURRENT_TARGET}"
+      --config ${CURRENT_CONFIG}
+      --
+      -sdk "${sdk}"
+      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+      RESULT_VARIABLE result
+  )
+
+  if(NOT result EQUAL 0)
+    message(FATAL_ERROR "Build failed")
+  endif()
+endfunction()
+
+# Remove given architecture from file. This step needed only in rare cases
+# when target was built in "unusual" way. Emit warning message.
+function(_ios_install_combined_remove_arch lib arch)
+  _ios_install_combined_message(
+    "Warning! Unexpected architecture `${arch}` detected and will be removed "
+    "from file `${lib}`")
+  set(cmd "${_lipo_path}" -remove ${arch} -output ${lib} ${lib})
+  execute_process(
+      COMMAND ${cmd}
+      RESULT_VARIABLE result
+      OUTPUT_VARIABLE output
+      ERROR_VARIABLE output
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_STRIP_TRAILING_WHITESPACE
+  )
+  if(NOT result EQUAL 0)
+    message(
+        FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+    )
+  endif()
+endfunction()
+
+# Check that 'lib' contains only 'archs' architectures (remove others).
+function(_ios_install_combined_keep_archs lib archs)
+  _ios_install_combined_get_real_archs("${lib}" real_archs)
+  set(archs_to_remove ${real_archs})
+  list(REMOVE_ITEM archs_to_remove ${archs})
+  foreach(x ${archs_to_remove})
+    _ios_install_combined_remove_arch("${lib}" "${x}")
+  endforeach()
+endfunction()
+
+function(_ios_install_combined_detect_sdks this_sdk_var corr_sdk_var)
+  cmake_policy(SET CMP0057 NEW)
+
+  set(this_sdk "$ENV{PLATFORM_NAME}")
+  if("${this_sdk}" STREQUAL "")
+    message(FATAL_ERROR "Environment variable PLATFORM_NAME is empty")
+  endif()
+
+  set(all_platforms "$ENV{SUPPORTED_PLATFORMS}")
+  if("${all_platforms}" STREQUAL "")
+    message(FATAL_ERROR "Environment variable SUPPORTED_PLATFORMS is empty")
+  endif()
+
+  separate_arguments(all_platforms)
+  if(NOT this_sdk IN_LIST all_platforms)
+    message(FATAL_ERROR "`${this_sdk}` not found in `${all_platforms}`")
+  endif()
+
+  list(REMOVE_ITEM all_platforms "" "${this_sdk}")
+  list(LENGTH all_platforms all_platforms_length)
+  if(NOT all_platforms_length EQUAL 1)
+    message(FATAL_ERROR "Expected one element: ${all_platforms}")
+  endif()
+
+  set(${this_sdk_var} "${this_sdk}" PARENT_SCOPE)
+  set(${corr_sdk_var} "${all_platforms}" PARENT_SCOPE)
+endfunction()
+
+# Create combined binary for the given target.
+#
+# Preconditions:
+#  * Target already installed at ${destination}
+#    for the ${PLATFORM_NAME} platform
+#
+# This function will:
+#  * Run build for the lacking platform, i.e. opposite to the ${PLATFORM_NAME}
+#  * Fuse both libraries by running lipo
+function(ios_install_combined target destination)
+  if("${target}" STREQUAL "")
+    message(FATAL_ERROR "`target` is empty")
+  endif()
+
+  if("${destination}" STREQUAL "")
+    message(FATAL_ERROR "`destination` is empty")
+  endif()
+
+  if(NOT IS_ABSOLUTE "${destination}")
+    message(FATAL_ERROR "`destination` is not absolute: ${destination}")
+  endif()
+
+  if(IS_DIRECTORY "${destination}" OR IS_SYMLINK "${destination}")
+    message(FATAL_ERROR "`destination` is no regular file: ${destination}")
+  endif()
+
+  if("${CMAKE_BINARY_DIR}" STREQUAL "")
+    message(FATAL_ERROR "`CMAKE_BINARY_DIR` is empty")
+  endif()
+
+  if(NOT IS_DIRECTORY "${CMAKE_BINARY_DIR}")
+    message(FATAL_ERROR "Is not a directory: ${CMAKE_BINARY_DIR}")
+  endif()
+
+  if("${CMAKE_INSTALL_CONFIG_NAME}" STREQUAL "")
+    message(FATAL_ERROR "CMAKE_INSTALL_CONFIG_NAME is empty")
+  endif()
+
+  set(cmd xcrun -f lipo)
+  execute_process(
+      COMMAND ${cmd}
+      RESULT_VARIABLE result
+      OUTPUT_VARIABLE output
+      ERROR_VARIABLE output
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_STRIP_TRAILING_WHITESPACE
+  )
+  if(NOT result EQUAL 0)
+    message(
+        FATAL_ERROR "Command failed (${result}): ${cmd}\n\nOutput:\n${output}"
+    )
+  endif()
+  set(_lipo_path ${output})
+
+  set(CURRENT_CONFIG "${CMAKE_INSTALL_CONFIG_NAME}")
+  set(CURRENT_TARGET "${target}")
+
+  _ios_install_combined_message("Target: ${CURRENT_TARGET}")
+  _ios_install_combined_message("Config: ${CURRENT_CONFIG}")
+  _ios_install_combined_message("Destination: ${destination}")
+
+  # Get SDKs
+  _ios_install_combined_detect_sdks(this_sdk corr_sdk)
+
+  # Get architectures of the target
+  _ios_install_combined_get_valid_archs("${corr_sdk}" corr_valid_archs)
+  _ios_install_combined_get_valid_archs("${this_sdk}" this_valid_archs)
+
+  # Return if there are no valid architectures for the SDK.
+  # (note that library already installed)
+  if("${corr_valid_archs}" STREQUAL "")
+    _ios_install_combined_message(
+        "No architectures detected for `${corr_sdk}` (skip)"
+    )
+    return()
+  endif()
+
+  # Trigger build of corresponding target
+  _ios_install_combined_build("${corr_sdk}")
+
+  # Get location of the library in build directory
+  _ios_install_combined_get_build_setting(
+    "${corr_sdk}" "CONFIGURATION_BUILD_DIR" corr_build_dir)
+  _ios_install_combined_get_build_setting(
+    "${corr_sdk}" "EXECUTABLE_PATH" corr_executable_path)
+  set(corr "${corr_build_dir}/${corr_executable_path}")
+
+  _ios_install_combined_keep_archs("${corr}" "${corr_valid_archs}")
+  _ios_install_combined_keep_archs("${destination}" "${this_valid_archs}")
+
+  _ios_install_combined_message("Current: ${destination}")
+  _ios_install_combined_message("Corresponding: ${corr}")
+
+  set(cmd "${_lipo_path}" -create ${corr} ${destination} -output ${destination})
+
+  execute_process(
+      COMMAND ${cmd}
+      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+      RESULT_VARIABLE result
+  )
+
+  if(NOT result EQUAL 0)
+    message(FATAL_ERROR "Command failed: ${cmd}")
+  endif()
+
+  _ios_install_combined_message("Install done: ${destination}")
+endfunction()
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 59d06f6e0c99e64a0f972566bf6eee0b4820da7e..1158a27d5ae2cceca493ddf7f533f43eb1d44f41 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -152,13 +152,19 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
       // Handle OSX Bundles.
       if(this->Target->IsAppBundleOnApple())
         {
+        cmMakefile const* mf = this->Target->Target->GetMakefile();
+
         // Install the whole app bundle directory.
         type = cmInstallType_DIRECTORY;
         literal_args += " USE_SOURCE_PERMISSIONS";
         from1 += ".app";
 
         // Tweaks apply to the binary inside the bundle.
-        to1 += ".app/Contents/MacOS/";
+        to1 += ".app/";
+        if(!mf->PlatformIsAppleIos())
+          {
+          to1 += "Contents/MacOS/";
+          }
         to1 += targetName;
         }
       else
@@ -525,6 +531,7 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
 {
   this->AddInstallNamePatchRule(os, indent, config, file);
   this->AddChrpathPatchRule(os, indent, config, file);
+  this->AddUniversalInstallRule(os, indent, file);
   this->AddRanlibRule(os, indent, file);
   this->AddStripRule(os, indent, file);
 }
@@ -861,3 +868,46 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
   os << indent << "execute_process(COMMAND \""
      << ranlib << "\" \"" << toDestDirPath << "\")\n";
 }
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddUniversalInstallRule(std::ostream& os,
+                          Indent const& indent,
+                          const std::string& toDestDirPath)
+{
+  cmMakefile const* mf = this->Target->Target->GetMakefile();
+
+  if(!mf->PlatformIsAppleIos() || !mf->IsOn("XCODE"))
+    {
+    return;
+    }
+
+  const char* xcodeVersion = mf->GetDefinition("XCODE_VERSION");
+  if(!xcodeVersion || cmSystemTools::VersionCompareGreater("6", xcodeVersion))
+    {
+    return;
+    }
+
+  switch(this->Target->GetType())
+    {
+    case cmState::EXECUTABLE:
+    case cmState::STATIC_LIBRARY:
+    case cmState::SHARED_LIBRARY:
+    case cmState::MODULE_LIBRARY:
+      break;
+
+    default:
+      return;
+    }
+
+  if(!this->Target->Target->GetPropertyAsBool("IOS_INSTALL_COMBINED"))
+   {
+   return;
+   }
+
+  os << indent << "include(CMakeIOSInstallCombined)\n";
+  os << indent << "ios_install_combined("
+               << "\"" << this->Target->Target->GetName() << "\" "
+               << "\"" << toDestDirPath << "\")\n";
+}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index ec89c05eaa317288cbafde64078ad5bb0a230934..18b3130825390112fb32a9ddae486e681c8ba49c 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -101,6 +101,8 @@ protected:
                     const std::string& toDestDirPath);
   void AddRanlibRule(std::ostream& os, Indent const& indent,
                      const std::string& toDestDirPath);
+  void AddUniversalInstallRule(std::ostream& os, Indent const& indent,
+                               const std::string& toDestDirPath);
 
   std::string TargetName;
   cmGeneratorTarget* Target;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9ea1a34e6c17334fa2b14f51f1a2414f688cf9aa..1986e5fd31d1da5233643188bfb85cb57de84804 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -132,6 +132,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
     this->SetPropertyDefault("GNUtoMS", 0);
     this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
+    this->SetPropertyDefault("IOS_INSTALL_COMBINED", 0);
     this->SetPropertyDefault("AUTOMOC", 0);
     this->SetPropertyDefault("AUTOUIC", 0);
     this->SetPropertyDefault("AUTORCC", 0);
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index f89d620636d9491a51af12a1e2ffd14b5c6c44aa..acc00758046f4b8f37f9ffa493c85979cf7ce5fd 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -94,3 +94,39 @@ if(NOT XCODE_VERSION VERSION_LESS 7)
   run_cmake(XcodeTbdStub)
   unset(RunCMake_TEST_OPTIONS)
 endif()
+
+if(NOT XCODE_VERSION VERSION_LESS 6)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombined-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OPTIONS
+    "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install"
+    "-DCMAKE_IOS_INSTALL_COMBINED=YES")
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeIOSInstallCombined)
+  run_cmake_command(XcodeIOSInstallCombined-build ${CMAKE_COMMAND} --build .)
+  run_cmake_command(XcodeIOSInstallCombined-install ${CMAKE_COMMAND} --build . --target install)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeIOSInstallCombinedPrune-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OPTIONS
+    "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/_install"
+    "-DCMAKE_IOS_INSTALL_COMBINED=YES")
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(XcodeIOSInstallCombinedPrune)
+  run_cmake_command(XcodeIOSInstallCombinedPrune-build ${CMAKE_COMMAND} --build .)
+  run_cmake_command(XcodeIOSInstallCombinedPrune-install ${CMAKE_COMMAND} --build . --target install)
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+  unset(RunCMake_TEST_OPTIONS)
+endif()
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..a1c06718f287d26c5dd1c9466ebdc4ed4aea65b2
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined-install-check.cmake
@@ -0,0 +1,30 @@
+function(verify_architectures file)
+  execute_process(
+    COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file}
+    OUTPUT_VARIABLE otool_out
+    ERROR_VARIABLE otool_err
+    RESULT_VARIABLE otool_result)
+  if(NOT otool_result EQUAL "0")
+    message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}")
+    return()
+  endif()
+
+  string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out})
+  string(REPLACE "architecture " "" actual "${architectures}")
+  list(SORT actual)
+
+  set(expected arm64 armv7 i386 x86_64)
+
+  if(NOT actual STREQUAL expected)
+    message(SEND_ERROR
+      "The actual library contains the architectures:\n ${actual} \n"
+      "which do not match expected ones:\n ${expected} \n"
+      "otool output:\n${otool_out}")
+  endif()
+endfunction()
+
+verify_architectures(bin/foo_app.app/foo_app)
+verify_architectures(lib/libfoo_static.a)
+verify_architectures(lib/libfoo_shared.dylib)
+verify_architectures(lib/foo_bundle.bundle/foo_bundle)
+verify_architectures(lib/foo_framework.framework/foo_framework)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fc830b19e21c9fe957a4ef6b2d6d535cffe2d1ff
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombined.cmake
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(IOSInstallCombined CXX)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
+set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
+
+set(CMAKE_OSX_ARCHITECTURES "armv7;arm64;i386;x86_64")
+
+add_executable(foo_app MACOSX_BUNDLE main.cpp)
+install(TARGETS foo_app BUNDLE DESTINATION bin)
+
+add_library(foo_static STATIC foo.cpp)
+install(TARGETS foo_static ARCHIVE DESTINATION lib)
+
+add_library(foo_shared SHARED foo.cpp)
+install(TARGETS foo_shared LIBRARY DESTINATION lib)
+
+add_library(foo_bundle MODULE foo.cpp)
+set_target_properties(foo_bundle PROPERTIES BUNDLE TRUE)
+install(TARGETS foo_bundle LIBRARY DESTINATION lib)
+
+add_library(foo_framework SHARED foo.cpp)
+set_target_properties(foo_framework PROPERTIES FRAMEWORK TRUE)
+install(TARGETS foo_framework FRAMEWORK DESTINATION lib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..83da17da7ed78d52b871a99e1658c46b1d9498f3
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-check.cmake
@@ -0,0 +1,26 @@
+function(verify_architectures file)
+  execute_process(
+    COMMAND xcrun otool -vf ${RunCMake_TEST_BINARY_DIR}/_install/${file}
+    OUTPUT_VARIABLE otool_out
+    ERROR_VARIABLE otool_err
+    RESULT_VARIABLE otool_result)
+  if(NOT otool_result EQUAL "0")
+    message(SEND_ERROR "Could not retrieve fat headers: ${otool_err}")
+    return()
+  endif()
+
+  string(REGEX MATCHALL "architecture [^ \n\t]+" architectures ${otool_out})
+  string(REPLACE "architecture " "" actual "${architectures}")
+  list(SORT actual)
+
+  set(expected armv7 x86_64)
+
+  if(NOT actual STREQUAL expected)
+    message(SEND_ERROR
+      "The actual library contains the architectures:\n ${actual} \n"
+      "which do not match expected ones:\n ${expected} \n"
+      "otool output:\n${otool_out}")
+  endif()
+endfunction()
+
+verify_architectures(lib/libfoo.dylib)
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt
new file mode 100644
index 0000000000000000000000000000000000000000..28edadc6beecdcc077d9997dc43cd7c8bea1c5e3
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune-install-stdout.txt
@@ -0,0 +1,2 @@
+.*Unexpected architecture `i386` detected.*
+.*Unexpected architecture `arm64` detected.*
\ No newline at end of file
diff --git a/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b47d3a597363907644a1bf9c283c055b5a702e69
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeIOSInstallCombinedPrune.cmake
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.3)
+
+project(XcodeIOSInstallCombinedPrune CXX)
+
+set(CMAKE_OSX_SYSROOT iphoneos)
+set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
+set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
+
+add_library(foo SHARED foo.cpp)
+install(TARGETS foo DESTINATION lib)
+
+add_library(baz SHARED foo.cpp)
+set_target_properties(
+  foo baz
+  PROPERTIES
+  XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] armv7
+  XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] armv7
+  XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] x86_64
+  XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] x86_64
+)
+
+add_library(boo SHARED foo.cpp)
+set_target_properties(
+  boo
+  PROPERTIES
+  XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] arm64
+  XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] arm64
+  XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] i386
+  XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] i386
+)
+
+add_custom_command(
+  TARGET foo
+  POST_BUILD
+  COMMAND lipo -create $<TARGET_FILE:baz> $<TARGET_FILE:boo> -output $<TARGET_FILE:foo>
+)
diff --git a/Tests/RunCMake/XcodeProject/main.cpp b/Tests/RunCMake/XcodeProject/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1695921f2b3a7e02de08a1c6e39c1e2aec34ad60
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/main.cpp
@@ -0,0 +1,3 @@
+int main(int argc, const char * argv[]) {
+    return 0;
+}