[Cmake-commits] CMake branch, master, updated. v3.8.0-809-g44f0d2d

Kitware Robot kwrobot at kitware.com
Wed Apr 19 10:55:05 EDT 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  44f0d2d9913595e214048b6d5a2b9ab2e9d1cf46 (commit)
       via  9db9bb27ea3f3dd3db3913c2bc2233f03018d5b0 (commit)
       via  a7e0453a3238cbd617cf2fff7388fd3d879dfd65 (commit)
       via  334efdebb8c69e6327fecb42ed1ae3cfcdb1cad6 (commit)
       via  c79e7e09a83cb6cd8bfde600ce492f0429236a02 (commit)
       via  9e338b57b7a7094b150e10512e6fd758e19eac8c (commit)
       via  2790ffc96f4e52017718bd1ce3fe1ef70ccae2d2 (commit)
       via  f1e51ec3a5b3ed54dec054aa422fdd7a81b078b3 (commit)
       via  eb08e1febba1cdc71bea2aee6431b5ed8f711af2 (commit)
       via  8dd997526370c4d1232bcde46e0eb2a751dfa3fd (commit)
       via  a0091a697e275a86a493e4fd87902a0eb9067d55 (commit)
       via  eeb58c5c34a888acbb422e66ff7895cb35c9322a (commit)
       via  3ed9f63551c2b51af60088b85625c4ce71512aa8 (commit)
       via  eec93bceec5411e4409b5e3ee5dc301fca6fcbfd (commit)
       via  93c89bc75ceee599ba7c08b8fe1ac5104942054f (commit)
       via  ac0cf7ff4f5a846381593cf28ebbc9cfaf107149 (commit)
       via  8577978c580d09abc56fa39f387a3991c91c31ba (commit)
       via  26cfd039a9479959da1d893bcee5b2aa879da6c0 (commit)
       via  25f3f22a1a952b98e7dc6772ef5fedd4932d0901 (commit)
       via  d596c5504e8ee9e1cc51ddbf7a29815dd07fc05f (commit)
       via  930042f2d95e83047231457f4d9134c74b8744fc (commit)
       via  3ab4681efa6db7339af36218fffea165ad1186f3 (commit)
       via  86979bb533a7835fc20f87b1f9d74590ebec4915 (commit)
      from  89310b0b2025c0ceee7a3e6c50da88b6e2cf92ca (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=44f0d2d9913595e214048b6d5a2b9ab2e9d1cf46
commit 44f0d2d9913595e214048b6d5a2b9ab2e9d1cf46
Merge: 9db9bb2 eec93bc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 19 14:47:28 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Wed Apr 19 10:47:31 2017 -0400

    Merge topic 'objlib-extend'
    
    eec93bce Allow OBJECT libraries to be installed, exported, and imported
    93c89bc7 Genex: Allow TARGET_OBJECTS to be used everywhere
    ac0cf7ff Genex: Reject TARGET_OBJECTS on non-object libraries earlier
    8577978c Tests: ExportImport C code should use explicit (void) in prototypes
    26cfd039 cmInstallTargetGenerator: Re-order GenerateScriptForConfig logic
    25f3f22a cmGlobalGenerator: Add method to check if object file location is known
    d596c550 cmGeneratorTarget: Add method to get the object file directory
    930042f2 cmGeneratorTarget: Factor out a GetTargetObjectNames method
    ...
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !712


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9db9bb27ea3f3dd3db3913c2bc2233f03018d5b0
commit 9db9bb27ea3f3dd3db3913c2bc2233f03018d5b0
Merge: a7e0453 eeb58c5
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 19 14:43:03 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Wed Apr 19 10:47:00 2017 -0400

    Merge topic 'test-CheckIPOSupported'
    
    eeb58c5c Tests: Add cases for typical CheckIPOSupported usage
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !700


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a7e0453a3238cbd617cf2fff7388fd3d879dfd65
commit a7e0453a3238cbd617cf2fff7388fd3d879dfd65
Merge: 334efde 9e338b5
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 19 14:42:33 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Wed Apr 19 10:46:10 2017 -0400

    Merge topic 'fix-CMakeTestAllGenerators'
    
    9e338b57 Tests: Drop machine-specific logic from CMakeTestAllGenerators
    2790ffc9 Tests: Run CMakeTestAllGenerators serially
    f1e51ec3 Tests: Fix CMakeTestAllGenerators generator list
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !720


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=334efdebb8c69e6327fecb42ed1ae3cfcdb1cad6
commit 334efdebb8c69e6327fecb42ed1ae3cfcdb1cad6
Merge: c79e7e0 eb08e1f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 19 14:42:23 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Wed Apr 19 10:45:41 2017 -0400

    Merge topic 'doc-CMAKE_MATCH_n'
    
    eb08e1fe Help: Document CMAKE_MATCH_<n> variables
    8dd99752 Help: Link from if(MATCHES) to regex specification docs
    a0091a69 Help: Format string() command regex specification docs
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !719


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c79e7e09a83cb6cd8bfde600ce492f0429236a02
commit c79e7e09a83cb6cd8bfde600ce492f0429236a02
Merge: 89310b0 3ed9f63
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 19 14:43:24 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Wed Apr 19 10:45:03 2017 -0400

    Merge topic 'findmpi-add-imported-targets'
    
    3ed9f635 FindMPI: Add test case
    86979bb5 FindMPI: Add IMPORTED targets
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !707


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e338b57b7a7094b150e10512e6fd758e19eac8c
commit 9e338b57b7a7094b150e10512e6fd758e19eac8c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 15:12:22 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 15:12:22 2017 -0400

    Tests: Drop machine-specific logic from CMakeTestAllGenerators
    
    Drop hard-coded paths from this test.  If we later need machine-specific
    environment entries we can add dedicated infrastructure for it to be
    configured locally.

diff --git a/Tests/CMakeTestAllGenerators/RunCMake.cmake b/Tests/CMakeTestAllGenerators/RunCMake.cmake
index 768c689..bfbb3a5 100644
--- a/Tests/CMakeTestAllGenerators/RunCMake.cmake
+++ b/Tests/CMakeTestAllGenerators/RunCMake.cmake
@@ -41,28 +41,6 @@ message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
 
 message(STATUS "CMake generators='${generators}'")
 
-# If we'll be testing any of the MinGW Makefiles generators, adjust the
-# ENV{PATH} to make sure libgmp-10.dll can be loaded as needed. But only if
-# the testing machine has a default MinGW install... (If you have a
-# non-default install, append to the PATH before running the test...)
-#
-if(generators MATCHES "MinGW Makefiles")
-  if(EXISTS "C:/MinGW/bin/libgmp-10.dll")
-    string(TOLOWER "$ENV{PATH}" path)
-    if(NOT path MATCHES "/mingw/bin")
-      if(UNIX)
-        set(sep ":")
-        set(mingw_bin "/mingw/bin")
-      else()
-        set(sep ";")
-        set(mingw_bin "C:/MinGW/bin")
-      endif()
-      set(ENV{PATH} "$ENV{PATH}${sep}${mingw_bin}")
-      message(STATUS "info: appending '${sep}${mingw_bin}' to the PATH")
-    endif()
-  endif()
-endif()
-
 # First setup a source tree to run CMake on.
 #
 execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2790ffc96f4e52017718bd1ce3fe1ef70ccae2d2
commit 2790ffc96f4e52017718bd1ce3fe1ef70ccae2d2
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 15:10:17 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 15:10:17 2017 -0400

    Tests: Run CMakeTestAllGenerators serially
    
    This test may take a long time because it runs many other tools.
    Do not make it compete with other tests for resources.

diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 910ff39..4269de1 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1158,6 +1158,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
       )
     list(APPEND TEST_BUILD_DIRS
       "${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators")
+    # This test runs a lot of processes.  Do not make them compete
+    # for resources with other tests.
+    set_property(TEST CMakeTestAllGenerators PROPERTY RUN_SERIAL 1)
   endif()
 
   if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f1e51ec3a5b3ed54dec054aa422fdd7a81b078b3
commit f1e51ec3a5b3ed54dec054aa422fdd7a81b078b3
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 15:05:59 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 15:05:59 2017 -0400

    Tests: Fix CMakeTestAllGenerators generator list
    
    Since `cmake --help` output now uses `[arch]` placeholders for the VS
    generators, this test has been extracting invalid generator names.
    Switch to using `cmake -E capabilities` to get a more robust listing of
    the generators that does not depend on parsing human-readable help
    output.

diff --git a/Tests/CMakeTestAllGenerators/RunCMake.cmake b/Tests/CMakeTestAllGenerators/RunCMake.cmake
index 6d27d3b..768c689 100644
--- a/Tests/CMakeTestAllGenerators/RunCMake.cmake
+++ b/Tests/CMakeTestAllGenerators/RunCMake.cmake
@@ -9,42 +9,23 @@ endif()
 # Analyze 'cmake --help' output for list of available generators:
 #
 execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${dir})
-execute_process(COMMAND ${CMAKE_COMMAND} --help
+execute_process(COMMAND ${CMAKE_COMMAND} -E capabilities
   RESULT_VARIABLE result
   OUTPUT_VARIABLE stdout
   ERROR_VARIABLE stderr
   WORKING_DIRECTORY ${dir})
 
-string(REPLACE ";" "\\;" stdout "${stdout}")
-string(REPLACE "\n" "E;" stdout "${stdout}")
-
-set(collecting 0)
 set(generators)
-foreach(eline ${stdout})
-  string(REGEX REPLACE "^(.*)E$" "\\1" line "${eline}")
-  if(collecting AND NOT line STREQUAL "")
-    if(line MATCHES "=")
-      string(REGEX REPLACE "^  (.+)= (.*)$" "\\1" gen "${line}")
-      if(gen MATCHES "[A-Za-z]")
-        string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
-        if(gen)
-          set(generators ${generators} ${gen})
-        endif()
-      endif()
-    else()
-      if(line MATCHES "^  [A-Za-z0-9]")
-        string(REGEX REPLACE "^  (.+)$" "\\1" gen "${line}")
-        string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
-        if(gen)
-          set(generators ${generators} ${gen})
-        endif()
-      endif()
+string(REGEX MATCHALL [["name":"[^"]+","platformSupport"]] generators_json "${stdout}")
+foreach(gen_json IN LISTS generators_json)
+  if("${gen_json}" MATCHES [["name":"([^"]+)"]])
+    set(gen "${CMAKE_MATCH_1}")
+    if(NOT gen MATCHES " (Win64|IA64|ARM)$")
+      list(APPEND generators "${gen}")
     endif()
   endif()
-  if(line STREQUAL "The following generators are available on this platform:")
-    set(collecting 1)
-  endif()
 endforeach()
+list(REMOVE_DUPLICATES generators)
 
 # Also call with one non-existent generator:
 #

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=eb08e1febba1cdc71bea2aee6431b5ed8f711af2
commit eb08e1febba1cdc71bea2aee6431b5ed8f711af2
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 14:45:49 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 14:45:49 2017 -0400

    Help: Document CMAKE_MATCH_<n> variables

diff --git a/Help/command/if.rst b/Help/command/if.rst
index f0a9588..edd343d 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -104,6 +104,7 @@ Possible expressions are:
 ``if(<variable|string> MATCHES regex)``
  True if the given string or variable's value matches the given regular
  expression.  See :ref:`Regex Specification` for regex format.
+ ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
 
 ``if(<variable|string> LESS <variable|string>)``
  True if the given string or variable's value is a valid number and less
diff --git a/Help/command/string.rst b/Help/command/string.rst
index fe38c99..4f0c45c 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -113,7 +113,7 @@ The following characters have special meaning in regular expressions:
   in the ``REGEX REPLACE`` operation. Additionally it is saved
   by all regular expression-related commands, including
   e.g. :command:`if(MATCHES)`, in the variables
-  ``CMAKE_MATCH_<n>`` for ``<n>`` 0..9.
+  :variable:`CMAKE_MATCH_<n>` for ``<n>`` 0..9.
 
 ``*``, ``+`` and ``?`` have higher precedence than concatenation.  ``|``
 has lower precedence than concatenation.  This means that the regular
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 7347bcc..4317f67 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -56,6 +56,7 @@ Variables that Provide Information
    /variable/CMAKE_MAJOR_VERSION
    /variable/CMAKE_MAKE_PROGRAM
    /variable/CMAKE_MATCH_COUNT
+   /variable/CMAKE_MATCH_n
    /variable/CMAKE_MINIMUM_REQUIRED_VERSION
    /variable/CMAKE_MINOR_VERSION
    /variable/CMAKE_PARENT_LIST_FILE
diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst
index 8b1c036..355e834 100644
--- a/Help/variable/CMAKE_MATCH_COUNT.rst
+++ b/Help/variable/CMAKE_MATCH_COUNT.rst
@@ -3,6 +3,7 @@ CMAKE_MATCH_COUNT
 
 The number of matches with the last regular expression.
 
-When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>``
-variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds
-the number of match expressions when these are filled.
+When a regular expression match is used, CMake fills in
+:variable:`CMAKE_MATCH_<n>` variables with the match contents.
+The ``CMAKE_MATCH_COUNT`` variable holds the number of match
+expressions when these are filled.
diff --git a/Help/variable/CMAKE_MATCH_n.rst b/Help/variable/CMAKE_MATCH_n.rst
new file mode 100644
index 0000000..c7dd623
--- /dev/null
+++ b/Help/variable/CMAKE_MATCH_n.rst
@@ -0,0 +1,10 @@
+CMAKE_MATCH_<n>
+---------------
+
+Capture group ``<n>`` matched by the last regular expression, for groups
+0 through 9.  Group 0 is the entire match.  Groups 1 through 9 are the
+subexpressions captured by ``()`` syntax.
+
+When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>``
+variables with the match contents.  The :variable:`CMAKE_MATCH_COUNT`
+variable holds the number of match expressions when these are filled.

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8dd997526370c4d1232bcde46e0eb2a751dfa3fd
commit 8dd997526370c4d1232bcde46e0eb2a751dfa3fd
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 14:45:04 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 14:45:04 2017 -0400

    Help: Link from if(MATCHES) to regex specification docs

diff --git a/Help/command/if.rst b/Help/command/if.rst
index 2a087d0..f0a9588 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -103,7 +103,7 @@ Possible expressions are:
 
 ``if(<variable|string> MATCHES regex)``
  True if the given string or variable's value matches the given regular
- expression.
+ expression.  See :ref:`Regex Specification` for regex format.
 
 ``if(<variable|string> LESS <variable|string>)``
  True if the given string or variable's value is a valid number and less
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 7199178..fe38c99 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -77,6 +77,8 @@ The replace expression may refer to paren-delimited subexpressions of the
 match using ``\1``, ``\2``, ..., ``\9``.  Note that two backslashes (``\\1``)
 are required in CMake code to get a backslash through argument parsing.
 
+.. _`Regex Specification`:
+
 Regex Specification
 """""""""""""""""""
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a0091a697e275a86a493e4fd87902a0eb9067d55
commit a0091a697e275a86a493e4fd87902a0eb9067d55
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 14:42:09 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 14:44:50 2017 -0400

    Help: Format string() command regex specification docs

diff --git a/Help/command/string.rst b/Help/command/string.rst
index 698a91d..7199178 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -82,26 +82,36 @@ Regex Specification
 
 The following characters have special meaning in regular expressions:
 
-::
-
-   ^         Matches at beginning of input
-   $         Matches at end of input
-   .         Matches any single character
-   [ ]       Matches any character(s) inside the brackets
-   [^ ]      Matches any character(s) not inside the brackets
-    -        Inside brackets, specifies an inclusive range between
-             characters on either side e.g. [a-f] is [abcdef]
-             To match a literal - using brackets, make it the first
-             or the last character e.g. [+*/-] matches basic
-             mathematical operators.
-   *         Matches preceding pattern zero or more times
-   +         Matches preceding pattern one or more times
-   ?         Matches preceding pattern zero or once only
-   |         Matches a pattern on either side of the |
-   ()        Saves a matched subexpression, which can be referenced
-             in the REGEX REPLACE operation. Additionally it is saved
-             by all regular expression-related commands, including
-             e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).
+``^``
+  Matches at beginning of input
+``$``
+  Matches at end of input
+``.``
+  Matches any single character
+``[ ]``
+  Matches any character(s) inside the brackets
+``[^ ]``
+  Matches any character(s) not inside the brackets
+``-``
+  Inside brackets, specifies an inclusive range between
+  characters on either side e.g. ``[a-f]`` is ``[abcdef]``
+  To match a literal ``-`` using brackets, make it the first
+  or the last character e.g. ``[+*/-]`` matches basic
+  mathematical operators.
+``*``
+  Matches preceding pattern zero or more times
+``+``
+  Matches preceding pattern one or more times
+``?``
+  Matches preceding pattern zero or once only
+``|``
+  Matches a pattern on either side of the ``|``
+``()``
+  Saves a matched subexpression, which can be referenced
+  in the ``REGEX REPLACE`` operation. Additionally it is saved
+  by all regular expression-related commands, including
+  e.g. :command:`if(MATCHES)`, in the variables
+  ``CMAKE_MATCH_<n>`` for ``<n>`` 0..9.
 
 ``*``, ``+`` and ``?`` have higher precedence than concatenation.  ``|``
 has lower precedence than concatenation.  This means that the regular

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=eeb58c5c34a888acbb422e66ff7895cb35c9322a
commit eeb58c5c34a888acbb422e66ff7895cb35c9322a
Author:     Ruslan Baratov <ruslan_baratov at yahoo.com>
AuthorDate: Thu Apr 13 23:05:16 2017 +0800
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 11:54:33 2017 -0400

    Tests: Add cases for typical CheckIPOSupported usage

diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 910ff39..baa6813 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -477,6 +477,17 @@ if(BUILD_TESTING)
 
   ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize)
 
+  set(Module.CheckIPOSupported-C_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_C=${CMake_TEST_IPO_WORKS_C})
+  ADD_TEST_MACRO(Module.CheckIPOSupported-C CheckIPOSupported-C)
+
+  set(Module.CheckIPOSupported-CXX_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_CXX=${CMake_TEST_IPO_WORKS_CXX})
+  ADD_TEST_MACRO(Module.CheckIPOSupported-CXX CheckIPOSupported-CXX)
+
+  if(CMAKE_Fortran_COMPILER)
+    set(Module.CheckIPOSupported-Fortran_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_Fortran=${CMake_TEST_IPO_WORKS_Fortran})
+    ADD_TEST_MACRO(Module.CheckIPOSupported-Fortran CheckIPOSupported-Fortran)
+  endif()
+
   add_test(Module.ExternalData ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/Module/ExternalData"
diff --git a/Tests/Module/CheckIPOSupported-C/CMakeLists.txt b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt
new file mode 100644
index 0000000..607dcd3
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-C LANGUAGES C)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+  set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_C)
+  message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.c)
+add_executable(CheckIPOSupported-C main.c)
+target_link_libraries(CheckIPOSupported-C PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-C COMMAND CheckIPOSupported-C)
diff --git a/Tests/Module/CheckIPOSupported-C/foo.c b/Tests/Module/CheckIPOSupported-C/foo.c
new file mode 100644
index 0000000..1e56597
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/foo.c
@@ -0,0 +1,4 @@
+int foo()
+{
+  return 0x42;
+}
diff --git a/Tests/Module/CheckIPOSupported-C/main.c b/Tests/Module/CheckIPOSupported-C/main.c
new file mode 100644
index 0000000..99204ab
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-C/main.c
@@ -0,0 +1,9 @@
+int foo();
+
+int main()
+{
+  if (foo() == 0) {
+    return 1;
+  }
+  return 0;
+}
diff --git a/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt
new file mode 100644
index 0000000..2dede93
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-CXX LANGUAGES CXX)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+  set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_CXX)
+  message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.cpp)
+add_executable(CheckIPOSupported-CXX main.cpp)
+target_link_libraries(CheckIPOSupported-CXX PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-CXX COMMAND CheckIPOSupported-CXX)
diff --git a/Tests/Module/CheckIPOSupported-CXX/foo.cpp b/Tests/Module/CheckIPOSupported-CXX/foo.cpp
new file mode 100644
index 0000000..1e56597
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/foo.cpp
@@ -0,0 +1,4 @@
+int foo()
+{
+  return 0x42;
+}
diff --git a/Tests/Module/CheckIPOSupported-CXX/main.cpp b/Tests/Module/CheckIPOSupported-CXX/main.cpp
new file mode 100644
index 0000000..99204ab
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CXX/main.cpp
@@ -0,0 +1,9 @@
+int foo();
+
+int main()
+{
+  if (foo() == 0) {
+    return 1;
+  }
+  return 0;
+}
diff --git a/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt b/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt
new file mode 100644
index 0000000..dee5c25
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-Fortran LANGUAGES Fortran)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported)
+if(ipo_supported)
+  set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+elseif(CMake_TEST_IPO_WORKS_Fortran)
+  message(FATAL_ERROR "IPO expected to work")
+endif()
+
+add_library(foo foo.f)
+add_executable(CheckIPOSupported-Fortran main.f)
+target_link_libraries(CheckIPOSupported-Fortran PUBLIC foo)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-Fortran COMMAND CheckIPOSupported-Fortran)
diff --git a/Tests/Module/CheckIPOSupported-Fortran/foo.f b/Tests/Module/CheckIPOSupported-Fortran/foo.f
new file mode 100644
index 0000000..945d2d5
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/foo.f
@@ -0,0 +1,2 @@
+	SUBROUTINE FOO
+	END
diff --git a/Tests/Module/CheckIPOSupported-Fortran/main.f b/Tests/Module/CheckIPOSupported-Fortran/main.f
new file mode 100644
index 0000000..9d1de9f
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-Fortran/main.f
@@ -0,0 +1,3 @@
+	PROGRAM BOO
+	CALL FOO()
+	END

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3ed9f63551c2b51af60088b85625c4ce71512aa8
commit 3ed9f63551c2b51af60088b85625c4ce71512aa8
Author:     Christian Pfeiffer <cpfeiffer at live.de>
AuthorDate: Tue Apr 18 17:43:25 2017 +0200
Commit:     Christian Pfeiffer <cpfeiffer at live.de>
CommitDate: Tue Apr 18 17:43:25 2017 +0200

    FindMPI: Add test case

diff --git a/Help/release/dev/FindMPI-add-imported-targets.rst b/Help/release/dev/FindMPI-add-imported-targets.rst
new file mode 100644
index 0000000..c0a7bfc
--- /dev/null
+++ b/Help/release/dev/FindMPI-add-imported-targets.rst
@@ -0,0 +1,4 @@
+FindMPI-add-imported-targets
+------------------------------
+
+* The :module:`FindMPI` module now provides imported targets.
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 910ff39..491d974 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1411,6 +1411,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     add_subdirectory(FindOpenSSL)
   endif()
 
+  if(CMake_TEST_FindMPI)
+    add_subdirectory(FindMPI)
+  endif()
+
   if(CMake_TEST_FindPNG)
     add_subdirectory(FindPNG)
   endif()
diff --git a/Tests/FindMPI/CMakeLists.txt b/Tests/FindMPI/CMakeLists.txt
new file mode 100644
index 0000000..121d978
--- /dev/null
+++ b/Tests/FindMPI/CMakeLists.txt
@@ -0,0 +1,21 @@
+foreach(c C CXX Fortran)
+  if(CMake_TEST_FindMPI_${c})
+    set(CMake_TEST_FindMPI_FLAG_${c} 1)
+  else()
+    set(CMake_TEST_FindMPI_FLAG_${c} 0)
+  endif()
+endforeach()
+
+add_test(NAME FindMPI.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindMPI/Test"
+  "${CMake_BINARY_DIR}/Tests/FindMPI/Test"
+  ${build_generator_args}
+  --build-project TestFindMPI
+  --build-options ${build_options}
+  -DMPI_TEST_C=${CMake_TEST_FindMPI_FLAG_C}
+  -DMPI_TEST_CXX=${CMake_TEST_FindMPI_FLAG_CXX}
+  -DMPI_TEST_Fortran=${CMake_TEST_FindMPI_FLAG_Fortran}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindMPI/Test/CMakeLists.txt b/Tests/FindMPI/Test/CMakeLists.txt
new file mode 100644
index 0000000..6f177f9
--- /dev/null
+++ b/Tests/FindMPI/Test/CMakeLists.txt
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.8)
+project(TestFindMPI)
+include(CTest)
+
+macro(source_code_mapper_helper LANG_NAME)
+  if("${LANG_NAME}" STREQUAL "C")
+    set(MPITEST_SOURCE_FILE "main.c")
+  elseif("${LANG_NAME}" STREQUAL "CXX")
+    configure_file("main.c" "main.cxx" COPYONLY)
+    set(MPITEST_SOURCE_FILE "main.cxx")
+  elseif("${LANG_NAME}" STREQUAL "Fortran")
+    set(MPITEST_SOURCE_FILE "main.f90")
+  endif()
+endmacro()
+
+foreach(c C CXX Fortran)
+  if("${MPI_TEST_${c}}")
+    message("Testing ${c}")
+    enable_language(${c})
+  endif()
+endforeach()
+
+find_package(MPI REQUIRED)
+
+foreach(c C CXX Fortran)
+  if(NOT "${MPI_TEST_${c}}")
+    continue()
+  endif()
+  source_code_mapper_helper(${c})
+  add_executable(test_tgt_${c} ${MPITEST_SOURCE_FILE})
+  target_link_libraries(test_tgt_${c} MPI::MPI_${c})
+  add_test(NAME test_tgt_${c} COMMAND test_tgt_${c})
+
+  add_executable(test_var_${c} ${MPITEST_SOURCE_FILE})
+  target_include_directories(test_var_${c} PRIVATE "${MPI_${c}_INCLUDE_PATH}")
+  target_link_libraries(test_var_${c} PRIVATE "${MPI_${c}_LINK_FLAGS}" "${MPI_${c}_LIBRARIES}")
+  set(copied_MPI_${c}_OPTIONS "${MPI_${c}_COMPILE_FLAGS}")
+  separate_arguments(copied_MPI_${c}_OPTIONS)
+  target_compile_options(test_var_${c} PRIVATE "${copied_MPI_${c}_OPTIONS}")
+  add_test(NAME test_var_${c} COMMAND test_var_${c})
+endforeach()
diff --git a/Tests/FindMPI/Test/main.c b/Tests/FindMPI/Test/main.c
new file mode 100644
index 0000000..7b7f175
--- /dev/null
+++ b/Tests/FindMPI/Test/main.c
@@ -0,0 +1,7 @@
+#include <mpi.h>
+
+int main(int argc, char** argv)
+{
+  MPI_Init(&argc, &argv);
+  MPI_Finalize();
+}
diff --git a/Tests/FindMPI/Test/main.f90 b/Tests/FindMPI/Test/main.f90
new file mode 100644
index 0000000..6fb6fd3
--- /dev/null
+++ b/Tests/FindMPI/Test/main.f90
@@ -0,0 +1,7 @@
+program mpi_test
+  include 'mpif.h'
+  integer ierror
+
+  call MPI_INIT(ierror)
+  call MPI_FINALIZE(ierror)
+end program mpi_test

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=eec93bceec5411e4409b5e3ee5dc301fca6fcbfd
commit eec93bceec5411e4409b5e3ee5dc301fca6fcbfd
Author:     Robert Maynard <robert.maynard at kitware.com>
AuthorDate: Thu Mar 23 09:32:08 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 11:36:10 2017 -0400

    Allow OBJECT libraries to be installed, exported, and imported
    
    Teach install() and export() to handle the actual object files.
    Disallow this on Xcode with multiple architectures because it
    still cannot be cleanly supported there.
    
    Co-Author: Brad King <brad.king at kitware.com>

diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index af75a39..3a76040 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -64,7 +64,7 @@ Imported Libraries
 
 ::
 
-  add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED
+  add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
               [GLOBAL])
 
 An :ref:`IMPORTED library target <Imported Targets>` references a library
@@ -106,10 +106,9 @@ may contain only sources that compile, header files, and other files
 that would not affect linking of a normal library (e.g. ``.txt``).
 They may contain custom commands generating such sources, but not
 ``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands.  Object libraries
-cannot be imported, exported, installed, or linked.  Some native build
-systems may not like targets that have only object files, so consider
-adding at least one real source file to any target that references
-``$<TARGET_OBJECTS:objlib>``.
+cannot be linked.  Some native build systems may not like targets that
+have only object files, so consider adding at least one real source file
+to any target that references ``$<TARGET_OBJECTS:objlib>``.
 
 Alias Libraries
 ^^^^^^^^^^^^^^^
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 70087a4..58438b7 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -73,7 +73,7 @@ Installing Targets
 ::
 
   install(TARGETS targets... [EXPORT <export-name>]
-          [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
+          [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
             PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
            [DESTINATION <dir>]
            [PERMISSIONS permissions...]
@@ -86,10 +86,10 @@ Installing Targets
           )
 
 The ``TARGETS`` form specifies rules for installing targets from a
-project.  There are five kinds of target files that may be installed:
-``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE``.
-Executables are treated as ``RUNTIME`` targets, except that those
-marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
+project.  There are six kinds of target files that may be installed:
+``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, ``FRAMEWORK``, and
+``BUNDLE``. Executables are treated as ``RUNTIME`` targets, except that
+those marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
 targets on OS X.  Static libraries are treated as ``ARCHIVE`` targets,
 except that those marked with the ``FRAMEWORK`` property are treated
 as ``FRAMEWORK`` targets on OS X.
@@ -99,10 +99,11 @@ targets, except that those marked with the ``FRAMEWORK`` property are
 treated as ``FRAMEWORK`` targets on OS X.  For DLL platforms the DLL
 part of a shared library is treated as a ``RUNTIME`` target and the
 corresponding import library is treated as an ``ARCHIVE`` target.
-All Windows-based systems including Cygwin are DLL platforms.
-The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, and ``FRAMEWORK`` arguments
-change the type of target to which the subsequent properties apply.
-If none is given the installation properties apply to all target
+All Windows-based systems including Cygwin are DLL platforms. Object
+libraries are always treated as ``OBJECTS`` targets.
+The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, and ``FRAMEWORK``
+arguments change the type of target to which the subsequent properties
+apply. If none is given the installation properties apply to all target
 types.  If only one is given then only targets of that type will be
 installed (which can be used to install just a DLL or just an import
 library).
@@ -165,8 +166,8 @@ the ``mySharedLib`` DLL will be installed to ``<prefix>/bin`` and
 
 The ``EXPORT`` option associates the installed target files with an
 export called ``<export-name>``.  It must appear before any ``RUNTIME``,
-``LIBRARY``, or ``ARCHIVE`` options.  To actually install the export
-file itself, call ``install(EXPORT)``, documented below.
+``LIBRARY``, ``ARCHIVE``, or ``OBJECTS`` options.  To actually install the
+export file itself, call ``install(EXPORT)``, documented below.
 
 Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
 set to ``TRUE`` has undefined behavior.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 65d87bf..95f5b87 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -125,10 +125,10 @@ The object files collection can be used as source inputs to other targets:
 
   add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
 
-``OBJECT`` libraries may only be used locally as sources in a buildsystem --
-they may not be installed, exported, or used in the right hand side of
+``OBJECT`` libraries may not be used in the right hand side of
 :command:`target_link_libraries`.  They also may not be used as the ``TARGET``
-in a use of the :command:`add_custom_command(TARGET)` command signature.
+in a use of the :command:`add_custom_command(TARGET)` command signature.  They
+may be installed, and will be exported as an INTERFACE library.
 
 Although object libraries may not be named directly in calls to
 the :command:`target_link_libraries` command, they can be "linked"
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 27c75dc..31b2389 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -194,6 +194,8 @@ Properties on Targets
    /prop_tgt/IMPORTED_LOCATION
    /prop_tgt/IMPORTED_NO_SONAME_CONFIG
    /prop_tgt/IMPORTED_NO_SONAME
+   /prop_tgt/IMPORTED_OBJECTS_CONFIG
+   /prop_tgt/IMPORTED_OBJECTS
    /prop_tgt/IMPORTED
    /prop_tgt/IMPORTED_SONAME_CONFIG
    /prop_tgt/IMPORTED_SONAME
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS.rst b/Help/prop_tgt/IMPORTED_OBJECTS.rst
new file mode 100644
index 0000000..222e6cc
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_OBJECTS.rst
@@ -0,0 +1,11 @@
+IMPORTED_OBJECTS
+----------------
+
+:ref:`;-list <CMake Language Lists>` of absolute paths to the object
+files on disk for an :ref:`imported <Imported targets>`
+:ref:`object library <object libraries>`.
+
+Ignored for non-imported targets.
+
+Projects may skip ``IMPORTED_OBJECTS`` if the configuration-specific
+property :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>` is set instead.
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
new file mode 100644
index 0000000..4419ed1
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
@@ -0,0 +1,7 @@
+IMPORTED_OBJECTS_<CONFIG>
+-------------------------
+
+<CONFIG>-specific version of :prop_tgt:`IMPORTED_OBJECTS` property.
+
+Configuration names correspond to those provided by the project from
+which the target is imported.
diff --git a/Help/release/dev/add_library-TARGET_OBJECTS.rst b/Help/release/dev/add_library-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..964064e
--- /dev/null
+++ b/Help/release/dev/add_library-TARGET_OBJECTS.rst
@@ -0,0 +1,5 @@
+add_library-TARGET_OBJECTS
+--------------------------
+
+* The :command:`add_library` command ``IMPORTED`` option learned to support
+  :ref:`Object Libraries`.
diff --git a/Help/release/dev/install-TARGET_OBJECTS.rst b/Help/release/dev/install-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..dbcf635
--- /dev/null
+++ b/Help/release/dev/install-TARGET_OBJECTS.rst
@@ -0,0 +1,8 @@
+install-TARGET_OBJECTS
+----------------------
+
+* The :command:`install(TARGETS)` command learned a new ``OBJECTS`` option to
+  specify where to install :ref:`Object Libraries`.
+
+* The :command:`install(EXPORT)` command learned how to export
+  :ref:`Object Libraries`.
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 9ae4ace..0bdf963 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -297,10 +297,15 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
       return false;
     }
     if (type == cmStateEnums::OBJECT_LIBRARY) {
-      this->Makefile->IssueMessage(
-        cmake::FATAL_ERROR,
-        "The OBJECT library type may not be used for IMPORTED libraries.");
-      return true;
+      std::string reason;
+      if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
+            &reason)) {
+        this->Makefile->IssueMessage(
+          cmake::FATAL_ERROR,
+          "The OBJECT library type may not be used for IMPORTED libraries" +
+            reason + ".");
+        return true;
+      }
     }
     if (type == cmStateEnums::INTERFACE_LIBRARY) {
       if (!cmGeneratorExpression::IsValidTargetName(libName)) {
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 539d854..978a7a1 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmExportBuildFileGenerator.h"
 
+#include "cmAlgorithms.h"
 #include "cmExportSet.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
@@ -21,6 +22,8 @@
 #include <sstream>
 #include <utility>
 
+class cmSourceFile;
+
 cmExportBuildFileGenerator::cmExportBuildFileGenerator()
 {
   this->LG = CM_NULLPTR;
@@ -171,27 +174,48 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
   // Get the makefile in which to lookup target information.
   cmMakefile* mf = target->Makefile;
 
-  // Add the main target file.
-  {
-    std::string prop = "IMPORTED_LOCATION";
+  if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+    std::string prop = "IMPORTED_OBJECTS";
     prop += suffix;
-    std::string value;
-    if (target->IsAppBundleOnApple()) {
-      value = target->GetFullPath(config, false);
-    } else {
-      value = target->GetFullPath(config, false, true);
+
+    // Compute all the object files inside this target and setup
+    // IMPORTED_OBJECTS as a list of object files
+    std::vector<cmSourceFile const*> objectSources;
+    target->GetObjectSources(objectSources, config);
+    std::string const obj_dir = target->GetObjectDirectory(config);
+    std::vector<std::string> objects;
+    for (std::vector<cmSourceFile const*>::const_iterator si =
+           objectSources.begin();
+         si != objectSources.end(); ++si) {
+      const std::string& obj = target->GetObjectName(*si);
+      objects.push_back(obj_dir + obj);
     }
-    properties[prop] = value;
-  }
 
-  // Add the import library for windows DLLs.
-  if (target->HasImportLibrary() &&
-      mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
-    std::string prop = "IMPORTED_IMPLIB";
-    prop += suffix;
-    std::string value = target->GetFullPath(config, true);
-    target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
-    properties[prop] = value;
+    // Store the property.
+    properties[prop] = cmJoin(objects, ";");
+  } else {
+    // Add the main target file.
+    {
+      std::string prop = "IMPORTED_LOCATION";
+      prop += suffix;
+      std::string value;
+      if (target->IsAppBundleOnApple()) {
+        value = target->GetFullPath(config, false);
+      } else {
+        value = target->GetFullPath(config, false, true);
+      }
+      properties[prop] = value;
+    }
+
+    // Add the import library for windows DLLs.
+    if (target->HasImportLibrary() &&
+        mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+      std::string prop = "IMPORTED_IMPLIB";
+      prop += suffix;
+      std::string value = target->GetFullPath(config, true);
+      target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+      properties[prop] = value;
+    }
   }
 }
 
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 691048b..38cd511 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -149,11 +149,15 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
 
       if (cmTarget* target = gg->FindTarget(*currentTarget)) {
         if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-          std::ostringstream e;
-          e << "given OBJECT library \"" << *currentTarget
-            << "\" which may not be exported.";
-          this->SetError(e.str());
-          return false;
+          std::string reason;
+          if (!this->Makefile->GetGlobalGenerator()
+                 ->HasKnownObjectFileLocation(&reason)) {
+            std::ostringstream e;
+            e << "given OBJECT library \"" << *currentTarget
+              << "\" which may not be exported" << reason << ".";
+            this->SetError(e.str());
+            return false;
+          }
         }
         if (target->GetType() == cmStateEnums::UTILITY) {
           this->SetError("given custom target \"" + *currentTarget +
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 5875f9e..ae3ec3b 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -441,6 +441,11 @@ void getCompatibleInterfaceProperties(cmGeneratorTarget* target,
                                       std::set<std::string>& ifaceProperties,
                                       const std::string& config)
 {
+  if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+    // object libraries have no link information, so nothing to compute
+    return;
+  }
+
   cmComputeLinkInformation* info = target->GetLinkInformation(config);
 
   if (!info) {
@@ -927,6 +932,9 @@ void cmExportFileGenerator::GenerateImportTargetCode(
     case cmStateEnums::UNKNOWN_LIBRARY:
       os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
       break;
+    case cmStateEnums::OBJECT_LIBRARY:
+      os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
+      break;
     case cmStateEnums::INTERFACE_LIBRARY:
       os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
       break;
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 3b76a87..16bd5e8 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -331,6 +331,8 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
                                     properties, importedLocations);
     this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator,
                                     properties, importedLocations);
+    this->SetImportLocationProperty(config, suffix, te->ObjectsGenerator,
+                                    properties, importedLocations);
     this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
                                     properties, importedLocations);
     this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
@@ -397,6 +399,23 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
     // Store the property.
     properties[prop] = value;
     importedLocations.insert(prop);
+  } else if (itgen->GetTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+    // Construct the property name.
+    std::string prop = "IMPORTED_OBJECTS";
+    prop += suffix;
+
+    // Compute all the object files inside this target and setup
+    // IMPORTED_OBJECTS as a list of object files
+    std::vector<std::string> objects;
+    itgen->GetInstallObjectNames(config, objects);
+    for (std::vector<std::string>::iterator i = objects.begin();
+         i != objects.end(); ++i) {
+      *i = value + *i;
+    }
+
+    // Store the property.
+    properties[prop] = cmJoin(objects, ";");
+    importedLocations.insert(prop);
   } else {
     // Construct the property name.
     std::string prop = "IMPORTED_LOCATION";
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 1215737..77a4962 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1257,24 +1257,35 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
     }
 
     std::vector<std::string> objects;
-    gt->GetTargetObjectNames(context->Config, objects);
-
-    std::string obj_dir;
-    if (context->EvaluateForBuildsystem) {
-      // Use object file directory with buildsystem placeholder.
-      obj_dir = gt->ObjectDirectory;
-      // Here we assume that the set of object files produced
-      // by an object library does not vary with configuration
-      // and do not set HadContextSensitiveCondition to true.
-    } else {
-      // Use object file directory with per-config location.
-      obj_dir = gt->GetObjectDirectory(context->Config);
+
+    if (gt->IsImported()) {
+      const char* loc = CM_NULLPTR;
+      const char* imp = CM_NULLPTR;
+      std::string suffix;
+      if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
+        cmSystemTools::ExpandListArgument(loc, objects);
+      }
       context->HadContextSensitiveCondition = true;
-    }
+    } else {
+      gt->GetTargetObjectNames(context->Config, objects);
+
+      std::string obj_dir;
+      if (context->EvaluateForBuildsystem) {
+        // Use object file directory with buildsystem placeholder.
+        obj_dir = gt->ObjectDirectory;
+        // Here we assume that the set of object files produced
+        // by an object library does not vary with configuration
+        // and do not set HadContextSensitiveCondition to true.
+      } else {
+        // Use object file directory with per-config location.
+        obj_dir = gt->GetObjectDirectory(context->Config);
+        context->HadContextSensitiveCondition = true;
+      }
 
-    for (std::vector<std::string>::iterator oi = objects.begin();
-         oi != objects.end(); ++oi) {
-      *oi = obj_dir + *oi;
+      for (std::vector<std::string>::iterator oi = objects.begin();
+           oi != objects.end(); ++oi) {
+        *oi = obj_dir + *oi;
+      }
     }
 
     // Create the cmSourceFile instances in the referencing directory.
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index c8923b0..ba554aa 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -206,6 +206,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   cmCAStringVector archiveArgVector(&argHelper, "ARCHIVE", &group);
   cmCAStringVector libraryArgVector(&argHelper, "LIBRARY", &group);
   cmCAStringVector runtimeArgVector(&argHelper, "RUNTIME", &group);
+  cmCAStringVector objectArgVector(&argHelper, "OBJECTS", &group);
   cmCAStringVector frameworkArgVector(&argHelper, "FRAMEWORK", &group);
   cmCAStringVector bundleArgVector(&argHelper, "BUNDLE", &group);
   cmCAStringVector includesArgVector(&argHelper, "INCLUDES", &group);
@@ -234,6 +235,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
   cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
   cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
+  cmInstallCommandArguments objectArgs(this->DefaultComponentName);
   cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
   cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
   cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
@@ -246,6 +248,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   archiveArgs.Parse(&archiveArgVector.GetVector(), &unknownArgs);
   libraryArgs.Parse(&libraryArgVector.GetVector(), &unknownArgs);
   runtimeArgs.Parse(&runtimeArgVector.GetVector(), &unknownArgs);
+  objectArgs.Parse(&objectArgVector.GetVector(), &unknownArgs);
   frameworkArgs.Parse(&frameworkArgVector.GetVector(), &unknownArgs);
   bundleArgs.Parse(&bundleArgVector.GetVector(), &unknownArgs);
   privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
@@ -265,6 +268,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   archiveArgs.SetGenericArguments(&genericArgs);
   libraryArgs.SetGenericArguments(&genericArgs);
   runtimeArgs.SetGenericArguments(&genericArgs);
+  objectArgs.SetGenericArguments(&genericArgs);
   frameworkArgs.SetGenericArguments(&genericArgs);
   bundleArgs.SetGenericArguments(&genericArgs);
   privateHeaderArgs.SetGenericArguments(&genericArgs);
@@ -274,6 +278,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   success = success && archiveArgs.Finalize();
   success = success && libraryArgs.Finalize();
   success = success && runtimeArgs.Finalize();
+  success = success && objectArgs.Finalize();
   success = success && frameworkArgs.Finalize();
   success = success && bundleArgs.Finalize();
   success = success && privateHeaderArgs.Finalize();
@@ -287,8 +292,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   // Enforce argument rules too complex to specify for the
   // general-purpose parser.
   if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
-      frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
-      privateHeaderArgs.GetNamelinkOnly() ||
+      objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
+      bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
       publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
     this->SetError(
       "TARGETS given NAMELINK_ONLY option not in LIBRARY group.  "
@@ -296,8 +301,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
     return false;
   }
   if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
-      frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
-      privateHeaderArgs.GetNamelinkSkip() ||
+      objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
+      bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
       publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
     this->SetError(
       "TARGETS given NAMELINK_SKIP option not in LIBRARY group.  "
@@ -356,11 +361,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
         return false;
       }
       if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-        std::ostringstream e;
-        e << "TARGETS given OBJECT library \"" << (*targetIt)
-          << "\" which may not be installed.";
-        this->SetError(e.str());
-        return false;
+        std::string reason;
+        if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
+              &reason)) {
+          std::ostringstream e;
+          e << "TARGETS given OBJECT library \"" << (*targetIt)
+            << "\" which may not be installed" << reason << ".";
+          this->SetError(e.str());
+          return false;
+        }
       }
       // Store the target in the list to be installed.
       targets.push_back(target);
@@ -379,6 +388,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
   bool installsArchive = false;
   bool installsLibrary = false;
   bool installsRuntime = false;
+  bool installsObject = false;
   bool installsFramework = false;
   bool installsBundle = false;
   bool installsPrivateHeader = false;
@@ -393,6 +403,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
     cmInstallTargetGenerator* archiveGenerator = CM_NULLPTR;
     cmInstallTargetGenerator* libraryGenerator = CM_NULLPTR;
     cmInstallTargetGenerator* runtimeGenerator = CM_NULLPTR;
+    cmInstallTargetGenerator* objectGenerator = CM_NULLPTR;
     cmInstallTargetGenerator* frameworkGenerator = CM_NULLPTR;
     cmInstallTargetGenerator* bundleGenerator = CM_NULLPTR;
     cmInstallFilesGenerator* privateHeaderGenerator = CM_NULLPTR;
@@ -522,6 +533,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
           return false;
         }
       } break;
+      case cmStateEnums::OBJECT_LIBRARY: {
+        // Objects use OBJECT properties.
+        if (!objectArgs.GetDestination().empty()) {
+          objectGenerator =
+            CreateInstallTargetGenerator(target, objectArgs, false);
+        } else {
+          std::ostringstream e;
+          e << "TARGETS given no OBJECTS DESTINATION for object library "
+               "target \""
+            << target.GetName() << "\".";
+          this->SetError(e.str());
+          return false;
+        }
+      } break;
       case cmStateEnums::EXECUTABLE: {
         if (target.IsAppBundleOnApple()) {
           // Application bundles use the BUNDLE properties.
@@ -664,6 +689,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
     installsArchive = installsArchive || archiveGenerator != CM_NULLPTR;
     installsLibrary = installsLibrary || libraryGenerator != CM_NULLPTR;
     installsRuntime = installsRuntime || runtimeGenerator != CM_NULLPTR;
+    installsObject = installsObject || objectGenerator != CM_NULLPTR;
     installsFramework = installsFramework || frameworkGenerator != CM_NULLPTR;
     installsBundle = installsBundle || bundleGenerator != CM_NULLPTR;
     installsPrivateHeader =
@@ -675,6 +701,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
     this->Makefile->AddInstallGenerator(archiveGenerator);
     this->Makefile->AddInstallGenerator(libraryGenerator);
     this->Makefile->AddInstallGenerator(runtimeGenerator);
+    this->Makefile->AddInstallGenerator(objectGenerator);
     this->Makefile->AddInstallGenerator(frameworkGenerator);
     this->Makefile->AddInstallGenerator(bundleGenerator);
     this->Makefile->AddInstallGenerator(privateHeaderGenerator);
@@ -692,6 +719,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
       te->HeaderGenerator = publicHeaderGenerator;
       te->LibraryGenerator = libraryGenerator;
       te->RuntimeGenerator = runtimeGenerator;
+      te->ObjectsGenerator = objectGenerator;
       this->Makefile->GetGlobalGenerator()
         ->GetExportSets()[exports.GetString()]
         ->AddTargetExport(te);
@@ -715,6 +743,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
     this->Makefile->GetGlobalGenerator()->AddInstallComponent(
       runtimeArgs.GetComponent().c_str());
   }
+  if (installsObject) {
+    this->Makefile->GetGlobalGenerator()->AddInstallComponent(
+      objectArgs.GetComponent().c_str());
+  }
   if (installsFramework) {
     this->Makefile->GetGlobalGenerator()->AddInstallComponent(
       frameworkArgs.GetComponent().c_str());
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 5b43a1d..6ecf42d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -81,7 +81,11 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
       assert(false &&
              "INTERFACE_LIBRARY targets have no installable outputs.");
       break;
+
     case cmStateEnums::OBJECT_LIBRARY:
+      this->GenerateScriptForConfigObjectLibrary(os, config, indent);
+      return;
+
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
     case cmStateEnums::UNKNOWN_LIBRARY:
@@ -318,6 +322,49 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
                  &cmInstallTargetGenerator::PostReplacementTweaks);
 }
 
+static std::string computeInstallObjectDir(cmGeneratorTarget* gt,
+                                           std::string const& config)
+{
+  std::string objectDir = "objects";
+  if (!config.empty()) {
+    objectDir += "-";
+    objectDir += config;
+  }
+  objectDir += "/";
+  objectDir += gt->GetName();
+  return objectDir;
+}
+
+void cmInstallTargetGenerator::GenerateScriptForConfigObjectLibrary(
+  std::ostream& os, const std::string& config, Indent const& indent)
+{
+  // Compute all the object files inside this target
+  std::vector<std::string> objects;
+  this->Target->GetTargetObjectNames(config, objects);
+
+  std::string const dest = this->GetDestination(config) + "/" +
+    computeInstallObjectDir(this->Target, config);
+
+  std::string const obj_dir = this->Target->GetObjectDirectory(config);
+  std::string const literal_args = " FILES_FROM_DIR \"" + obj_dir + "\"";
+
+  const char* no_dir_permissions = CM_NULLPTR;
+  const char* no_rename = CM_NULLPTR;
+  this->AddInstallRule(os, dest, cmInstallType_FILES, objects, this->Optional,
+                       this->FilePermissions.c_str(), no_dir_permissions,
+                       no_rename, literal_args.c_str(), indent);
+}
+
+void cmInstallTargetGenerator::GetInstallObjectNames(
+  std::string const& config, std::vector<std::string>& objects) const
+{
+  this->Target->GetTargetObjectNames(config, objects);
+  for (std::vector<std::string>::iterator i = objects.begin();
+       i != objects.end(); ++i) {
+    *i = computeInstallObjectDir(this->Target, config) + "/" + *i;
+  }
+}
+
 std::string cmInstallTargetGenerator::GetDestination(
   std::string const& config) const
 {
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index e6b11b8..6aaa3ba 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -41,6 +41,9 @@ public:
 
   std::string GetInstallFilename(const std::string& config) const;
 
+  void GetInstallObjectNames(std::string const& config,
+                             std::vector<std::string>& objects) const;
+
   enum NameType
   {
     NameNormal,
@@ -65,6 +68,9 @@ protected:
   void GenerateScript(std::ostream& os) CM_OVERRIDE;
   void GenerateScriptForConfig(std::ostream& os, const std::string& config,
                                Indent const& indent) CM_OVERRIDE;
+  void GenerateScriptForConfigObjectLibrary(std::ostream& os,
+                                            const std::string& config,
+                                            Indent const& indent);
   typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&,
                                                         Indent const&,
                                                         const std::string&,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d29a8bd..d6f2f0d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1354,11 +1354,9 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
 
   // Lookup/compute/cache the import information for this
   // configuration.
-  std::string config_upper;
-  if (!config.empty()) {
-    config_upper = cmSystemTools::UpperCase(config);
-  } else {
-    config_upper = "NOCONFIG";
+  std::string desired_config = config;
+  if (config.empty()) {
+    desired_config = "NOCONFIG";
   }
 
   std::string result;
@@ -1368,7 +1366,7 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
   std::string suffix;
 
   if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetMappedConfig(config_upper, &loc, &imp, suffix)) {
+      this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
     if (!pimplib) {
       if (loc) {
         result = loc;
@@ -1451,18 +1449,28 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
                                const char** loc, const char** imp,
                                std::string& suffix) const
 {
-  std::string const locPropBase =
-    this->GetType() == cmStateEnums::INTERFACE_LIBRARY ? "IMPORTED_LIBNAME"
-                                                       : "IMPORTED_LOCATION";
+  std::string config_upper;
+  if (!desired_config.empty()) {
+    config_upper = cmSystemTools::UpperCase(desired_config);
+  }
+
+  std::string locPropBase;
+  if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    locPropBase = "IMPORTED_LIBNAME";
+  } else if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+    locPropBase = "IMPORTED_OBJECTS";
+  } else {
+    locPropBase = "IMPORTED_LOCATION";
+  }
 
   // Track the configuration-specific property suffix.
   suffix = "_";
-  suffix += desired_config;
+  suffix += config_upper;
 
   std::vector<std::string> mappedConfigs;
   {
     std::string mapProp = "MAP_IMPORTED_CONFIG_";
-    mapProp += desired_config;
+    mapProp += config_upper;
     if (const char* mapValue = this->GetProperty(mapProp)) {
       cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
     }
diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h
index 7b5339f..9304eab 100644
--- a/Source/cmTargetExport.h
+++ b/Source/cmTargetExport.h
@@ -26,6 +26,7 @@ public:
   cmInstallTargetGenerator* ArchiveGenerator;
   cmInstallTargetGenerator* RuntimeGenerator;
   cmInstallTargetGenerator* LibraryGenerator;
+  cmInstallTargetGenerator* ObjectsGenerator;
   cmInstallTargetGenerator* FrameworkGenerator;
   cmInstallTargetGenerator* BundleGenerator;
   cmInstallFilesGenerator* HeaderGenerator;
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index f504c7b..eeae3f0 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -79,6 +79,15 @@ set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_DEBUG testLib7D-$<CONFIG>)
 set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_RELEASE testLib7R-$<CONFIG>)
 set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<CONFIG>)
 
+# Test exporting OBJECT targets
+add_library(testLib8 OBJECT testLib8A.c testLib8B.c sub/testLib8C.c)
+
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+  set(maybe_testLib8 testLib8)
+else()
+  set(maybe_testLib8 "")
+endif()
+
 # Test using the target_link_libraries command to set the
 # LINK_INTERFACE_LIBRARIES* properties.  We construct two libraries
 # providing the same two symbols.  In each library one of the symbols
@@ -474,7 +483,7 @@ install(
   TARGETS
   testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
   testExe2lib testLib4lib testLib4libdbg testLib4libopt
-  testLib6 testLib7
+  testLib6 testLib7 ${maybe_testLib8}
   testLibCycleA testLibCycleB
   testLibNoSONAME
   cmp0022NEW cmp0022OLD
@@ -483,6 +492,7 @@ install(
   RUNTIME DESTINATION $<1:bin>
   LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
   ARCHIVE DESTINATION $<1:lib>
+  OBJECTS DESTINATION $<1:lib>
   FRAMEWORK DESTINATION Frameworks
   BUNDLE DESTINATION Applications
   )
@@ -535,6 +545,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
   FILE ExportBuildTree.cmake
   )
 export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
+  ${maybe_testLib8}
   testLib4lib testLib4libdbg testLib4libopt
   testLibCycleA testLibCycleB
   testLibNoSONAME
diff --git a/Tests/ExportImport/Export/sub/testLib8C.c b/Tests/ExportImport/Export/sub/testLib8C.c
new file mode 100644
index 0000000..a5568c7
--- /dev/null
+++ b/Tests/ExportImport/Export/sub/testLib8C.c
@@ -0,0 +1,4 @@
+int testLib8C(void)
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib8A.c b/Tests/ExportImport/Export/testLib8A.c
new file mode 100644
index 0000000..c64655a
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib8A.c
@@ -0,0 +1,4 @@
+int testLib8A(void)
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib8B.c b/Tests/ExportImport/Export/testLib8B.c
new file mode 100644
index 0000000..1be6c9c
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib8B.c
@@ -0,0 +1,4 @@
+int testLib8B(void)
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 5ce9628..01960ea 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -228,6 +228,16 @@ target_link_libraries(imp_lib1 exp_testLib2)
 add_library(imp_lib1b STATIC imp_lib1.c)
 target_link_libraries(imp_lib1b bld_testLib2)
 
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+  # Create a executable that is using objects imported from the install tree
+  add_executable(imp_testLib8 imp_testLib8.c $<TARGET_OBJECTS:exp_testLib8>)
+
+  if(NOT CMAKE_GENERATOR STREQUAL "Xcode" OR NOT XCODE_VERSION VERSION_LESS 5)
+    # Create a executable that is using objects imported from the build tree
+    add_executable(imp_testLib8b imp_testLib8.c $<TARGET_OBJECTS:bld_testLib8>)
+  endif()
+endif()
+
 #-----------------------------------------------------------------------------
 # Test that handling imported targets, including transitive dependencies,
 # works in CheckFunctionExists (...and hopefully all other try_compile() checks
diff --git a/Tests/ExportImport/Import/A/imp_testLib8.c b/Tests/ExportImport/Import/A/imp_testLib8.c
new file mode 100644
index 0000000..2749b17
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_testLib8.c
@@ -0,0 +1,8 @@
+
+int testLib8A(void);
+int testLib8B(void);
+
+int main()
+{
+  return (testLib8A() + testLib8B());
+}
diff --git a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
deleted file mode 100644
index bdadca4..0000000
--- a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error at Export.cmake:2 \(export\):
-  export given OBJECT library "A" which may not be exported.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Export-result.txt b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt
similarity index 100%
rename from Tests/RunCMake/ObjectLibrary/Export-result.txt
rename to Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt
new file mode 100644
index 0000000..5420159
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at ExportNotSupported.cmake:[0-9]+ \(export\):
+  export given OBJECT library "A" which may not be exported under Xcode with
+  multiple architectures.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake
new file mode 100644
index 0000000..a3f104e
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+export(TARGETS A FILE AExport.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/Import.cmake b/Tests/RunCMake/ObjectLibrary/Import.cmake
index 806b44a..42f4468 100644
--- a/Tests/RunCMake/ObjectLibrary/Import.cmake
+++ b/Tests/RunCMake/ObjectLibrary/Import.cmake
@@ -1 +1,12 @@
+
 add_library(A OBJECT IMPORTED)
+
+# We don't actually build this example so just configure dummy
+# object files to test.  They do not have to exist.
+set_property(TARGET A APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+set_target_properties(A PROPERTIES
+  IMPORTED_OBJECTS_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/does_not_exist.o"
+  IMPORTED_OBJECTS "${CMAKE_CURRENT_BINARY_DIR}/does_not_exist.o"
+  )
+
+add_library(B $<TARGET_OBJECTS:A> b.c)
diff --git a/Tests/RunCMake/ObjectLibrary/Import-result.txt b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt
similarity index 100%
rename from Tests/RunCMake/ObjectLibrary/Import-result.txt
rename to Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
similarity index 55%
rename from Tests/RunCMake/ObjectLibrary/Import-stderr.txt
rename to Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
index 74b496a..0fadac2 100644
--- a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
@@ -1,4 +1,5 @@
-CMake Error at Import.cmake:1 \(add_library\):
-  The OBJECT library type may not be used for IMPORTED libraries.
+CMake Error at ImportNotSupported.cmake:[0-9]+ \(add_library\):
+  The OBJECT library type may not be used for IMPORTED libraries under Xcode
+  with multiple architectures.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Import.cmake b/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
similarity index 100%
copy from Tests/RunCMake/ObjectLibrary/Import.cmake
copy to Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
diff --git a/Tests/RunCMake/ObjectLibrary/Install-result.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
similarity index 100%
rename from Tests/RunCMake/ObjectLibrary/Install-result.txt
rename to Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
similarity index 54%
rename from Tests/RunCMake/ObjectLibrary/Install-stderr.txt
rename to Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
index d2f9f4a..35a0e4f 100644
--- a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
@@ -1,4 +1,5 @@
-CMake Error at Install.cmake:2 \(install\):
-  install TARGETS given OBJECT library "A" which may not be installed.
+CMake Error at InstallNotSupported.cmake:[0-9]+ \(install\):
+  install TARGETS given OBJECT library "A" which may not be installed under
+  Xcode with multiple architectures.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake
new file mode 100644
index 0000000..c1d214b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+install(TARGETS A DESTINATION lib)
diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
index e932693..fe708ce 100644
--- a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
@@ -5,9 +5,15 @@ run_cmake(BadSourceExpression2)
 run_cmake(BadSourceExpression3)
 run_cmake(BadObjSource1)
 run_cmake(BadObjSource2)
-run_cmake(Export)
-run_cmake(Import)
-run_cmake(Install)
+if(RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
+  run_cmake(ExportNotSupported)
+  run_cmake(ImportNotSupported)
+  run_cmake(InstallNotSupported)
+else()
+  run_cmake(Export)
+  run_cmake(Import)
+  run_cmake(Install)
+endif()
 run_cmake(LinkObjLHS)
 run_cmake(LinkObjRHS1)
 run_cmake(LinkObjRHS2)
diff --git a/Tests/RunCMake/ObjectLibrary/b.c b/Tests/RunCMake/ObjectLibrary/b.c
new file mode 100644
index 0000000..6751907
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/b.c
@@ -0,0 +1,4 @@
+int b(void)
+{
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=93c89bc75ceee599ba7c08b8fe1ac5104942054f
commit 93c89bc75ceee599ba7c08b8fe1ac5104942054f
Author:     Robert Maynard <robert.maynard at kitware.com>
AuthorDate: Mon Jan 23 14:13:49 2017 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 11:36:09 2017 -0400

    Genex: Allow TARGET_OBJECTS to be used everywhere
    
    Previously the `TARGET_OBJECTS` generator expression was limited
    only to use in a buildsystem context so that Xcode's placeholders
    in object file paths can be evaluated.  Lift this restriction so
    that the expression can at least be used in most settings.
    
    Co-Author: Brad King <brad.king at kitware.com>

diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 2e6a803..65d87bf 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -136,6 +136,12 @@ indirectly by using an :ref:`Interface Library <Interface Libraries>`
 whose :prop_tgt:`INTERFACE_SOURCES` target property is set to name
 ``$<TARGET_OBJECTS:objlib>``.
 
+Although object libraries may not be used as the ``TARGET``
+in a use of the :command:`add_custom_command(TARGET)` command signature,
+the list of objects can be used by :command:`add_custom_command(OUTPUT)` or
+:command:`file(GENERATE)` by using ``$<TARGET_OBJECTS:objlib>``.
+
+
 Build Specification and Usage Requirements
 ==========================================
 
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 3eac45f..bddb174 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -290,9 +290,7 @@ Available output expressions are:
   Content of ``...`` converted to a C identifier.
 ``$<TARGET_OBJECTS:objLib>``
   List of objects resulting from build of ``objLib``. ``objLib`` must be an
-  object of type ``OBJECT_LIBRARY``.  This expression may only be used in
-  the sources of :command:`add_library` and :command:`add_executable`
-  commands.
+  object of type ``OBJECT_LIBRARY``.
 ``$<SHELL_PATH:...>``
   Content of ``...`` converted to shell path style. For example, slashes are
   converted to backslashes in Windows shells and drive letters are converted
diff --git a/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst b/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..c4a9ee8
--- /dev/null
+++ b/Help/release/dev/add_custom_command-TARGET_OBJECTS.rst
@@ -0,0 +1,6 @@
+add_custom_command-TARGET_OBJECTS
+---------------------------------
+
+* The :command:`add_custom_command` command learned to evaluate the
+  ``TARGET_OBJECTS``
+  :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..853a803
--- /dev/null
+++ b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
@@ -0,0 +1,6 @@
+file-GENERATE-TARGET_OBJECTS
+----------------------------
+
+* The :command:`file(GENERATE)` subcommand learned to evaluate the
+  ``TARGET_OBJECTS``
+  :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index dc54488..1526454 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -64,8 +64,10 @@ void cmGeneratorExpressionEvaluationFile::Generate(
       return;
     }
     std::ostringstream e;
-    e << "Evaluation file to be written multiple times for different "
-         "configurations or languages with different content:\n  "
+    e << "Evaluation file to be written multiple times with different "
+         "content. "
+         "This is generally caused by the content evaluating the "
+         "configuration type, language, or location of object files:\n "
       << outputFileName;
     lg->IssueMessage(cmake::FATAL_ERROR, e.str());
     return;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 65949a3..1215737 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1243,20 +1243,38 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       return std::string();
     }
     if (!context->EvaluateForBuildsystem) {
-      std::ostringstream e;
-      e << "The evaluation of the TARGET_OBJECTS generator expression "
-           "is only suitable for consumption by CMake.  It is not suitable "
-           "for writing out elsewhere.";
-      reportError(context, content->GetOriginalExpression(), e.str());
-      return std::string();
+      cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+      std::string reason;
+      if (!gg->HasKnownObjectFileLocation(&reason)) {
+        std::ostringstream e;
+        e << "The evaluation of the TARGET_OBJECTS generator expression "
+             "is only suitable for consumption by CMake (limited"
+          << reason << ").  "
+                       "It is not suitable for writing out elsewhere.";
+        reportError(context, content->GetOriginalExpression(), e.str());
+        return std::string();
+      }
     }
 
     std::vector<std::string> objects;
     gt->GetTargetObjectNames(context->Config, objects);
 
+    std::string obj_dir;
+    if (context->EvaluateForBuildsystem) {
+      // Use object file directory with buildsystem placeholder.
+      obj_dir = gt->ObjectDirectory;
+      // Here we assume that the set of object files produced
+      // by an object library does not vary with configuration
+      // and do not set HadContextSensitiveCondition to true.
+    } else {
+      // Use object file directory with per-config location.
+      obj_dir = gt->GetObjectDirectory(context->Config);
+      context->HadContextSensitiveCondition = true;
+    }
+
     for (std::vector<std::string>::iterator oi = objects.begin();
          oi != objects.end(); ++oi) {
-      *oi = gt->ObjectDirectory + *oi;
+      *oi = obj_dir + *oi;
     }
 
     // Create the cmSourceFile instances in the referencing directory.
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index adc87cd..8ac3419 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -292,3 +292,19 @@ set(CMP0044_TYPE NEW)
 add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-NEW)
 set(CMP0044_TYPE OLD)
 add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-OLD)
+
+if(NOT CMAKE_GENERATOR STREQUAL Xcode OR NOT CMAKE_OSX_ARCHITECTURES MATCHES "[;$]")
+  add_library(objlib OBJECT objlib1.c objlib2.c)
+  file(GENERATE
+    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/objlib_files_$<CONFIGURATION>"
+    CONTENT "$<JOIN:$<TARGET_OBJECTS:objlib>,\n>\n"
+  )
+
+  add_custom_target(check_object_files ALL
+    COMMAND ${CMAKE_COMMAND}
+      "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/objlib_files_$<CONFIGURATION>"
+      -DEXPECTED_NUM_OBJECTFILES=2
+      -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+    DEPENDS objlib
+  )
+endif()
diff --git a/Tests/GeneratorExpression/check_object_files.cmake b/Tests/GeneratorExpression/check_object_files.cmake
new file mode 100644
index 0000000..cfccd29
--- /dev/null
+++ b/Tests/GeneratorExpression/check_object_files.cmake
@@ -0,0 +1,26 @@
+
+if (NOT EXISTS ${OBJLIB_LISTFILE})
+  message(SEND_ERROR "Object listing file \"${OBJLIB_LISTFILE}\" not found!")
+endif()
+
+file(STRINGS ${OBJLIB_LISTFILE} objlib_files ENCODING UTF-8)
+
+list(LENGTH objlib_files num_objectfiles)
+if (NOT EXPECTED_NUM_OBJECTFILES EQUAL num_objectfiles)
+  message(SEND_ERROR "Unexpected number of entries in object list file (${num_objectfiles} instead of ${EXPECTED_NUM_OBJECTFILES})")
+endif()
+
+foreach(objlib_file ${objlib_files})
+  set(file_exists False)
+  if (EXISTS ${objlib_file})
+    set(file_exists True)
+  endif()
+
+  if (NOT file_exists)
+    if(attempts)
+      list(REMOVE_DUPLICATES attempts)
+      set(tried "  Tried ${attempts}")
+    endif()
+    message(SEND_ERROR "File \"${objlib_file}\" does not exist!${tried}")
+  endif()
+endforeach()
diff --git a/Tests/GeneratorExpression/objlib1.c b/Tests/GeneratorExpression/objlib1.c
new file mode 100644
index 0000000..98a95a4
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib1.c
@@ -0,0 +1,4 @@
+
+void objlib1()
+{
+}
diff --git a/Tests/GeneratorExpression/objlib2.c b/Tests/GeneratorExpression/objlib2.c
new file mode 100644
index 0000000..b2c1050
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib2.c
@@ -0,0 +1,4 @@
+
+void objlib2()
+{
+}
diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
index 0abb7df..a242180 100644
--- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
@@ -1,5 +1,6 @@
 CMake Error in CMakeLists.txt:
-  Evaluation file to be written multiple times for different configurations
-  or languages with different content:
+  Evaluation file to be written multiple times with different content.  This
+  is generally caused by the content evaluating the configuration type,
+  language, or location of object files:
 
   .*output.txt
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
index d807450..daa7c49 100644
--- a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake
@@ -1,3 +1,4 @@
+enable_language(CXX)
 
 file(GENERATE
   OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_OBJECTS:foo>>somefile.cpp"

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ac0cf7ff4f5a846381593cf28ebbc9cfaf107149
commit ac0cf7ff4f5a846381593cf28ebbc9cfaf107149
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 18 10:05:04 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 10:29:36 2017 -0400

    Genex: Reject TARGET_OBJECTS on non-object libraries earlier
    
    Move the diagnostic that rejects the TARGET_OBJECTS generator expression
    in non-buildsystem context until after the check for whether the named
    target is an object library.  This order will makes more sense than the
    previous order once TARGET_OBJECTS is allowed in non-buildsystem
    context.

diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 29ad5d1..65949a3 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1226,15 +1226,6 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
                        cmGeneratorExpressionDAGChecker* /*dagChecker*/) const
     CM_OVERRIDE
   {
-    if (!context->EvaluateForBuildsystem) {
-      std::ostringstream e;
-      e << "The evaluation of the TARGET_OBJECTS generator expression "
-           "is only suitable for consumption by CMake.  It is not suitable "
-           "for writing out elsewhere.";
-      reportError(context, content->GetOriginalExpression(), e.str());
-      return std::string();
-    }
-
     std::string tgtName = parameters.front();
     cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
     if (!gt) {
@@ -1251,6 +1242,14 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       reportError(context, content->GetOriginalExpression(), e.str());
       return std::string();
     }
+    if (!context->EvaluateForBuildsystem) {
+      std::ostringstream e;
+      e << "The evaluation of the TARGET_OBJECTS generator expression "
+           "is only suitable for consumption by CMake.  It is not suitable "
+           "for writing out elsewhere.";
+      reportError(context, content->GetOriginalExpression(), e.str());
+      return std::string();
+    }
 
     std::vector<std::string> objects;
     gt->GetTargetObjectNames(context->Config, objects);
diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
index d3aa973..b08ef5a 100644
--- a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt
@@ -1,9 +1,8 @@
-CMake Error at OutputNameMatchesObjects.cmake:2 \(file\):
+CMake Error at OutputNameMatchesObjects.cmake:[0-9]+ \(file\):
   Error evaluating generator expression:
 
     \$<TARGET_OBJECTS:foo>
 
-  The evaluation of the TARGET_OBJECTS generator expression is only suitable
-  for consumption by CMake.  It is not suitable for writing out elsewhere.
+  Objects of target "foo" referenced but is not an OBJECT library.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:6 \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
deleted file mode 100644
index b78189e..0000000
--- a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-(CMake Error at BadContext.cmake:4 \(file\):
-  Error evaluating generator expression:
-
-    \$<TARGET_OBJECTS:NoTarget>
-
-  The evaluation of the TARGET_OBJECTS generator expression is only suitable
-  for consumption by CMake.  It is not suitable for writing out elsewhere.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-*)+
-(CMake Error at BadContext.cmake:5 \(file\):
-  Error evaluating generator expression:
-
-    \$<TARGET_OBJECTS:NoTarget>
-
-  The evaluation of the TARGET_OBJECTS generator expression is only suitable
-  for consumption by CMake.  It is not suitable for writing out elsewhere.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-*)+
-CMake Error:
-  Error evaluating generator expression:
-
-    \$<TARGET_OBJECTS:NoTarget>
-
-  The evaluation of the TARGET_OBJECTS generator expression is only suitable
-  for consumption by CMake.  It is not suitable for writing out elsewhere.
diff --git a/Tests/RunCMake/TargetObjects/BadContext-result.txt b/Tests/RunCMake/TargetObjects/NoTarget-result.txt
similarity index 100%
copy from Tests/RunCMake/TargetObjects/BadContext-result.txt
copy to Tests/RunCMake/TargetObjects/NoTarget-result.txt
diff --git a/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
new file mode 100644
index 0000000..eadccaf
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
@@ -0,0 +1,24 @@
+(CMake Error at NoTarget.cmake:4 \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:NoTarget>
+
+  Objects of target "NoTarget" referenced but no such target exists.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+*)+
+(CMake Error at NoTarget.cmake:5 \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:NoTarget>
+
+  Objects of target "NoTarget" referenced but no such target exists.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+*)+
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:NoTarget>
+
+  Objects of target "NoTarget" referenced but no such target exists.
diff --git a/Tests/RunCMake/TargetObjects/BadContext.cmake b/Tests/RunCMake/TargetObjects/NoTarget.cmake
similarity index 100%
rename from Tests/RunCMake/TargetObjects/BadContext.cmake
rename to Tests/RunCMake/TargetObjects/NoTarget.cmake
diff --git a/Tests/RunCMake/TargetObjects/BadContext-result.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
similarity index 100%
rename from Tests/RunCMake/TargetObjects/BadContext-result.txt
rename to Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
new file mode 100644
index 0000000..a66794c
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NotObjlibTarget.cmake:3 \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:StaticLib>
+
+  Objects of target "StaticLib" referenced but is not an OBJECT library.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
new file mode 100644
index 0000000..8e5fdd0
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
@@ -0,0 +1,3 @@
+add_library(StaticLib empty.cpp)
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>)
diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
index 85c76e2..30b9fee 100644
--- a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
 include(RunCMake)
 
-run_cmake(BadContext)
+run_cmake(NoTarget)
+run_cmake(NotObjlibTarget)
diff --git a/Tests/RunCMake/TargetObjects/empty.cpp b/Tests/RunCMake/TargetObjects/empty.cpp
new file mode 100644
index 0000000..4086dcc
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/empty.cpp
@@ -0,0 +1,4 @@
+int empty()
+{
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8577978c580d09abc56fa39f387a3991c91c31ba
commit 8577978c580d09abc56fa39f387a3991c91c31ba
Author:     Robert Maynard <robert.maynard at kitware.com>
AuthorDate: Thu Mar 23 13:56:24 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 09:03:34 2017 -0400

    Tests: ExportImport C code should use explicit (void) in prototypes

diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c
index 83a9bb5..3488439 100644
--- a/Tests/ExportImport/Import/A/imp_testExe1.c
+++ b/Tests/ExportImport/Import/A/imp_testExe1.c
@@ -1,15 +1,15 @@
-extern int generated_by_testExe1();
-extern int generated_by_testExe3();
-extern int generated_by_testExe4();
-extern int testLib2();
-extern int testLib3();
-extern int testLib4();
-extern int testLib4lib();
-extern int testLib5();
-extern int testLib6();
-extern int testLib7();
-extern int testLibCycleA1();
-extern int testLibPerConfigDest();
+extern int generated_by_testExe1(void);
+extern int generated_by_testExe3(void);
+extern int generated_by_testExe4(void);
+extern int testLib2(void);
+extern int testLib3(void);
+extern int testLib4(void);
+extern int testLib4lib(void);
+extern int testLib5(void);
+extern int testLib6(void);
+extern int testLib7(void);
+extern int testLibCycleA1(void);
+extern int testLibPerConfigDest(void);
 
 /* Switch a symbol between debug and optimized builds to make sure the
    proper library is found from the testLib4 link interface.  */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=26cfd039a9479959da1d893bcee5b2aa879da6c0
commit 26cfd039a9479959da1d893bcee5b2aa879da6c0
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 11 14:33:19 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 09:03:33 2017 -0400

    cmInstallTargetGenerator: Re-order GenerateScriptForConfig logic
    
    Do not populate some local variables before switching on the target
    type.

diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 88fcc56..5b43a1d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -60,25 +60,6 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
 void cmInstallTargetGenerator::GenerateScriptForConfig(
   std::ostream& os, const std::string& config, Indent const& indent)
 {
-  // Compute the build tree directory from which to copy the target.
-  std::string fromDirConfig;
-  if (this->Target->NeedRelinkBeforeInstall(config)) {
-    fromDirConfig =
-      this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
-    fromDirConfig += cmake::GetCMakeFilesDirectory();
-    fromDirConfig += "/CMakeRelink.dir/";
-  } else {
-    fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
-    fromDirConfig += "/";
-  }
-  std::string toDir =
-    this->ConvertToAbsoluteDestination(this->GetDestination(config));
-  toDir += "/";
-
-  // Compute the list of files to install for this target.
-  std::vector<std::string> filesFrom;
-  std::vector<std::string> filesTo;
-  std::string literal_args;
   cmStateEnums::TargetType targetType = this->Target->GetType();
   cmInstallType type = cmInstallType();
   switch (targetType) {
@@ -109,6 +90,28 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
         "cmInstallTargetGenerator created with non-installable target.");
       return;
   }
+
+  // Compute the build tree directory from which to copy the target.
+  std::string fromDirConfig;
+  if (this->Target->NeedRelinkBeforeInstall(config)) {
+    fromDirConfig =
+      this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory();
+    fromDirConfig += cmake::GetCMakeFilesDirectory();
+    fromDirConfig += "/CMakeRelink.dir/";
+  } else {
+    fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+    fromDirConfig += "/";
+  }
+
+  std::string toDir =
+    this->ConvertToAbsoluteDestination(this->GetDestination(config));
+  toDir += "/";
+
+  // Compute the list of files to install for this target.
+  std::vector<std::string> filesFrom;
+  std::vector<std::string> filesTo;
+  std::string literal_args;
+
   if (targetType == cmStateEnums::EXECUTABLE) {
     // There is a bug in cmInstallCommand if this fails.
     assert(this->NamelinkMode == NamelinkModeNone);

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=25f3f22a1a952b98e7dc6772ef5fedd4932d0901
commit 25f3f22a1a952b98e7dc6772ef5fedd4932d0901
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 11 14:08:19 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 09:03:33 2017 -0400

    cmGlobalGenerator: Add method to check if object file location is known
    
    Add a `HasKnownObjectFileLocation` method returning whether we know the
    exact location of object files produced by the native build system.
    This is true everywhere except on Xcode when an architecture placeholder
    is used.

diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 4200b21..aa2dd22 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -331,6 +331,11 @@ public:
       i.e. "Can I build Debug and Release in the same tree?" */
   virtual bool IsMultiConfig() const { return false; }
 
+  /** Return true if we know the exact location of object files.
+      If false, store the reason in the given string.
+      This is meaningful only after EnableLanguage has been called.  */
+  virtual bool HasKnownObjectFileLocation(std::string*) const { return true; }
+
   virtual bool UseFolderProperty() const;
 
   virtual bool IsIPOSupported() const { return false; }
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index ecc3e31..8c1c0e7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3720,6 +3720,18 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const
   return true;
 }
 
+bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation(
+  std::string* reason) const
+{
+  if (this->ObjectDirArch.find('$') != std::string::npos) {
+    if (reason != CM_NULLPTR) {
+      *reason = " under Xcode with multiple architectures";
+    }
+    return false;
+  }
+  return true;
+}
+
 bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
 {
   const char* epnValue =
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 982dabd..a733d5c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -87,6 +87,8 @@ public:
       i.e. "Can I build Debug and Release in the same tree?" */
   bool IsMultiConfig() const CM_OVERRIDE;
 
+  bool HasKnownObjectFileLocation(std::string* reason) const CM_OVERRIDE;
+
   bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE;
 
   bool ShouldStripResourcePath(cmMakefile*) const CM_OVERRIDE;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d596c5504e8ee9e1cc51ddbf7a29815dd07fc05f
commit d596c5504e8ee9e1cc51ddbf7a29815dd07fc05f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 11 14:12:52 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 09:03:33 2017 -0400

    cmGeneratorTarget: Add method to get the object file directory
    
    Add a `GetObjectDirectory` method to get the target's object file
    directory for a specific configuration.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 4ce1eca..005323f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3254,6 +3254,19 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
   return prefix + base + ".pdb";
 }
 
+std::string cmGeneratorTarget::GetObjectDirectory(
+  std::string const& config) const
+{
+  std::string obj_dir =
+    this->GlobalGenerator->ExpandCFGIntDir(this->ObjectDirectory, config);
+#if defined(__APPLE__)
+  // find and replace $(PROJECT_NAME) xcode placeholder
+  const std::string projectName = this->LocalGenerator->GetProjectName();
+  cmSystemTools::ReplaceString(obj_dir, "$(PROJECT_NAME)", projectName);
+#endif
+  return obj_dir;
+}
+
 void cmGeneratorTarget::GetTargetObjectNames(
   std::string const& config, std::vector<std::string>& objects) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index bad67d0..5b903de 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -369,6 +369,10 @@ public:
       time config name placeholder if needed for the generator.  */
   std::string ObjectDirectory;
 
+  /** Full path with trailing slash to the top-level directory
+      holding object files for the given configuration.  */
+  std::string GetObjectDirectory(std::string const& config) const;
+
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=930042f2d95e83047231457f4d9134c74b8744fc
commit 930042f2d95e83047231457f4d9134c74b8744fc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Apr 11 14:42:39 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Apr 18 09:03:32 2017 -0400

    cmGeneratorTarget: Factor out a GetTargetObjectNames method

diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 8fee119..29ad5d1 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -33,8 +33,6 @@
 #include <string.h>
 #include <utility>
 
-class cmSourceFile;
-
 std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
   std::string const& prop, cmLocalGenerator* lg,
   cmGeneratorExpressionContext* context, cmGeneratorTarget const* headTarget,
@@ -1254,38 +1252,22 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       return std::string();
     }
 
-    std::vector<cmSourceFile const*> objectSources;
-    gt->GetObjectSources(objectSources, context->Config);
-    std::map<cmSourceFile const*, std::string> mapping;
+    std::vector<std::string> objects;
+    gt->GetTargetObjectNames(context->Config, objects);
 
-    for (std::vector<cmSourceFile const*>::const_iterator it =
-           objectSources.begin();
-         it != objectSources.end(); ++it) {
-      mapping[*it];
+    for (std::vector<std::string>::iterator oi = objects.begin();
+         oi != objects.end(); ++oi) {
+      *oi = gt->ObjectDirectory + *oi;
     }
 
-    gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
-
+    // Create the cmSourceFile instances in the referencing directory.
     cmMakefile* mf = context->LG->GetMakefile();
-
-    std::string obj_dir = gt->ObjectDirectory;
-    std::string result;
-    const char* sep = "";
-    for (std::vector<cmSourceFile const*>::const_iterator it =
-           objectSources.begin();
-         it != objectSources.end(); ++it) {
-      // Find the object file name corresponding to this source file.
-      std::map<cmSourceFile const*, std::string>::const_iterator map_it =
-        mapping.find(*it);
-      // It must exist because we populated the mapping just above.
-      assert(!map_it->second.empty());
-      result += sep;
-      std::string objFile = obj_dir + map_it->second;
-      mf->AddTargetObject(tgtName, objFile);
-      result += objFile;
-      sep = ";";
+    for (std::vector<std::string>::iterator oi = objects.begin();
+         oi != objects.end(); ++oi) {
+      mf->AddTargetObject(tgtName, *oi);
     }
-    return result;
+
+    return cmJoin(objects, ";");
   }
 } targetObjectsNode;
 
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 35b2603..4ce1eca 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3254,6 +3254,33 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
   return prefix + base + ".pdb";
 }
 
+void cmGeneratorTarget::GetTargetObjectNames(
+  std::string const& config, std::vector<std::string>& objects) const
+{
+  std::vector<cmSourceFile const*> objectSources;
+  this->GetObjectSources(objectSources, config);
+  std::map<cmSourceFile const*, std::string> mapping;
+
+  for (std::vector<cmSourceFile const*>::const_iterator it =
+         objectSources.begin();
+       it != objectSources.end(); ++it) {
+    mapping[*it];
+  }
+
+  this->LocalGenerator->ComputeObjectFilenames(mapping, this);
+
+  for (std::vector<cmSourceFile const*>::const_iterator it =
+         objectSources.begin();
+       it != objectSources.end(); ++it) {
+    // Find the object file name corresponding to this source file.
+    std::map<cmSourceFile const*, std::string>::const_iterator map_it =
+      mapping.find(*it);
+    // It must exist because we populated the mapping just above.
+    assert(!map_it->second.empty());
+    objects.push_back(map_it->second);
+  }
+}
+
 bool cmGeneratorTarget::StrictTargetComparison::operator()(
   cmGeneratorTarget const* t1, cmGeneratorTarget const* t2) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2ea2f2f..bad67d0 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -209,6 +209,11 @@ public:
                                 bool realname) const;
   std::string NormalGetRealName(const std::string& config) const;
 
+  /** Get the names of an object library's object files underneath
+      its object file directory.  */
+  void GetTargetObjectNames(std::string const& config,
+                            std::vector<std::string>& objects) const;
+
   /** What hierarchy level should the reported directory contain */
   enum BundleDirectoryLevel
   {

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3ab4681efa6db7339af36218fffea165ad1186f3
commit 3ab4681efa6db7339af36218fffea165ad1186f3
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Apr 12 13:17:31 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Apr 17 10:54:00 2017 -0400

    cmGeneratorTarget: Drop default GetLinkerLanguage config argument
    
    Update one remaining call site to avoid using the default.

diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index d4f48fe..2ea2f2f 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -534,7 +534,7 @@ public:
   std::string GetPDBDirectory(const std::string& config) const;
 
   ///! Return the preferred linker language for this target
-  std::string GetLinkerLanguage(const std::string& config = "") const;
+  std::string GetLinkerLanguage(const std::string& config) const;
 
   /** Does this target have a GNU implib to convert to MS format?  */
   bool HasImplibGNUtoMS() const;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index fbfc1ed..f0f04a8 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1881,7 +1881,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
   std::string lang =
     this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
   std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
-  const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage();
+  const std::string& linkLanguage =
+    this->GeneratorTarget->GetLinkerLanguage("");
   bool needForceLang = false;
   // source file does not match its extension language
   if (lang != sourceLang) {

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=86979bb533a7835fc20f87b1f9d74590ebec4915
commit 86979bb533a7835fc20f87b1f9d74590ebec4915
Author:     Christian Pfeiffer <cpfeiffer at live.de>
AuthorDate: Sun Apr 16 01:12:55 2017 +0200
Commit:     Christian Pfeiffer <cpfeiffer at live.de>
CommitDate: Sun Apr 16 01:12:55 2017 +0200

    FindMPI: Add IMPORTED targets

diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index ff2c4de..32164a1 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -29,6 +29,12 @@
 #    MPI_<lang>_LINK_FLAGS      Linking flags for MPI programs
 #    MPI_<lang>_LIBRARIES       All libraries to link MPI programs against
 #
+# Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
+#
+# ::
+#
+#    MPI::MPI_<lang>            Target for using MPI from <lang>
+#
 # Additionally, FindMPI sets the following variables for running MPI
 # programs from the command line:
 #
@@ -621,6 +627,29 @@ foreach (lang C CXX Fortran)
     else()
       find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
     endif()
+
+    if(MPI_${lang}_FOUND)
+      if(NOT TARGET MPI::MPI_${lang})
+        add_library(MPI::MPI_${lang} INTERFACE IMPORTED)
+      endif()
+      if(MPI_${lang}_COMPILE_FLAGS)
+        set(_MPI_${lang}_COMPILE_OPTIONS "${MPI_${lang}_COMPILE_FLAGS}")
+        separate_arguments(_MPI_${lang}_COMPILE_OPTIONS)
+        set_property(TARGET MPI::MPI_${lang} PROPERTY
+          INTERFACE_COMPILE_OPTIONS "${_MPI_${lang}_COMPILE_OPTIONS}")
+      endif()
+
+      unset(_MPI_${lang}_LINK_LINE)
+      if(MPI_${lang}_LINK_FLAGS)
+        list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LINK_FLAGS}")
+      endif()
+      list(APPEND _MPI_${lang}_LINK_LINE "${MPI_${lang}_LIBRARIES}")
+      set_property(TARGET MPI::MPI_${lang} PROPERTY
+        INTERFACE_LINK_LIBRARIES "${_MPI_${lang}_LINK_LINE}")
+
+      set_property(TARGET MPI::MPI_${lang} PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${MPI_${lang}_INCLUDE_PATH}")
+    endif()
   endif()
 endforeach()
 

-----------------------------------------------------------------------

Summary of changes:
 Help/command/add_library.rst                       |    9 +-
 Help/command/if.rst                                |    3 +-
 Help/command/install.rst                           |   23 ++---
 Help/command/string.rst                            |   52 +++++++-----
 Help/manual/cmake-buildsystem.7.rst                |   12 ++-
 Help/manual/cmake-generator-expressions.7.rst      |    4 +-
 Help/manual/cmake-properties.7.rst                 |    2 +
 Help/manual/cmake-variables.7.rst                  |    1 +
 Help/prop_tgt/IMPORTED_OBJECTS.rst                 |   11 +++
 Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst          |    7 ++
 Help/release/dev/FindMPI-add-imported-targets.rst  |    4 +
 .../dev/add_custom_command-TARGET_OBJECTS.rst      |    6 ++
 Help/release/dev/add_library-TARGET_OBJECTS.rst    |    5 ++
 Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst  |    6 ++
 Help/release/dev/install-TARGET_OBJECTS.rst        |    8 ++
 Help/variable/CMAKE_MATCH_COUNT.rst                |    7 +-
 Help/variable/CMAKE_MATCH_n.rst                    |   10 +++
 Modules/FindMPI.cmake                              |   29 +++++++
 Source/cmAddLibraryCommand.cxx                     |   13 ++-
 Source/cmExportBuildFileGenerator.cxx              |   60 +++++++++----
 Source/cmExportCommand.cxx                         |   14 ++--
 Source/cmExportFileGenerator.cxx                   |    8 ++
 Source/cmExportInstallFileGenerator.cxx            |   19 +++++
 Source/cmGeneratorExpressionEvaluationFile.cxx     |    6 +-
 Source/cmGeneratorExpressionNode.cxx               |   86 ++++++++++---------
 Source/cmGeneratorTarget.cxx                       |   40 +++++++++
 Source/cmGeneratorTarget.h                         |   11 ++-
 Source/cmGlobalGenerator.h                         |    5 ++
 Source/cmGlobalXCodeGenerator.cxx                  |   12 +++
 Source/cmGlobalXCodeGenerator.h                    |    2 +
 Source/cmInstallCommand.cxx                        |   50 +++++++++--
 Source/cmInstallTargetGenerator.cxx                |   88 +++++++++++++++-----
 Source/cmInstallTargetGenerator.h                  |    6 ++
 Source/cmTarget.cxx                                |   30 ++++---
 Source/cmTargetExport.h                            |    1 +
 Source/cmVisualStudio10TargetGenerator.cxx         |    3 +-
 Tests/CMakeLists.txt                               |   18 ++++
 Tests/CMakeTestAllGenerators/RunCMake.cmake        |   57 ++-----------
 Tests/ExportImport/Export/CMakeLists.txt           |   13 ++-
 Tests/ExportImport/Export/sub/testLib8C.c          |    4 +
 Tests/ExportImport/Export/testLib8A.c              |    4 +
 Tests/ExportImport/Export/testLib8B.c              |    4 +
 Tests/ExportImport/Import/A/CMakeLists.txt         |   10 +++
 Tests/ExportImport/Import/A/imp_testExe1.c         |   24 +++---
 Tests/ExportImport/Import/A/imp_testLib8.c         |    8 ++
 Tests/FindMPI/CMakeLists.txt                       |   21 +++++
 Tests/FindMPI/Test/CMakeLists.txt                  |   41 +++++++++
 Tests/FindMPI/Test/main.c                          |    7 ++
 Tests/FindMPI/Test/main.f90                        |    7 ++
 Tests/GeneratorExpression/CMakeLists.txt           |   16 ++++
 Tests/GeneratorExpression/check_object_files.cmake |   26 ++++++
 Tests/GeneratorExpression/objlib1.c                |    4 +
 Tests/GeneratorExpression/objlib2.c                |    4 +
 Tests/Module/CheckIPOSupported-C/CMakeLists.txt    |   19 +++++
 .../Module/CheckIPOSupported-C}/foo.c              |    0
 Tests/Module/CheckIPOSupported-C/main.c            |    9 ++
 Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt  |   19 +++++
 .../Module/CheckIPOSupported-CXX}/foo.cpp          |    0
 Tests/Module/CheckIPOSupported-CXX/main.cpp        |    9 ++
 .../CheckIPOSupported-Fortran/CMakeLists.txt       |   19 +++++
 .../Module/CheckIPOSupported-Fortran}/foo.f        |    0
 .../Module/CheckIPOSupported-Fortran}/main.f       |    0
 .../File_Generate/OutputConflict-stderr.txt        |    5 +-
 .../OutputNameMatchesObjects-stderr.txt            |    7 +-
 .../File_Generate/OutputNameMatchesObjects.cmake   |    1 +
 Tests/RunCMake/ObjectLibrary/Export-result.txt     |    1 -
 Tests/RunCMake/ObjectLibrary/Export-stderr.txt     |    4 -
 .../ExportNotSupported-result.txt}                 |    0
 .../ObjectLibrary/ExportNotSupported-stderr.txt    |    5 ++
 .../{Export.cmake => ExportNotSupported.cmake}     |    0
 Tests/RunCMake/ObjectLibrary/Import-result.txt     |    1 -
 Tests/RunCMake/ObjectLibrary/Import.cmake          |   11 +++
 .../ImportNotSupported-result.txt}                 |    0
 ...rt-stderr.txt => ImportNotSupported-stderr.txt} |    5 +-
 .../{Import.cmake => ImportNotSupported.cmake}     |    0
 Tests/RunCMake/ObjectLibrary/Install-result.txt    |    1 -
 .../InstallNotSupported-result.txt}                |    0
 ...l-stderr.txt => InstallNotSupported-stderr.txt} |    5 +-
 .../{Install.cmake => InstallNotSupported.cmake}   |    0
 Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake    |   12 ++-
 Tests/RunCMake/ObjectLibrary/b.c                   |    4 +
 Tests/RunCMake/TargetObjects/BadContext-result.txt |    1 -
 Tests/RunCMake/TargetObjects/BadContext-stderr.txt |   27 ------
 .../NoTarget-result.txt}                           |    0
 Tests/RunCMake/TargetObjects/NoTarget-stderr.txt   |   24 ++++++
 .../{BadContext.cmake => NoTarget.cmake}           |    0
 .../NotObjlibTarget-result.txt}                    |    0
 .../TargetObjects/NotObjlibTarget-stderr.txt       |    8 ++
 Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake |    3 +
 Tests/RunCMake/TargetObjects/RunCMakeTest.cmake    |    3 +-
 Tests/RunCMake/TargetObjects/empty.cpp             |    4 +
 91 files changed, 863 insertions(+), 265 deletions(-)
 create mode 100644 Help/prop_tgt/IMPORTED_OBJECTS.rst
 create mode 100644 Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
 create mode 100644 Help/release/dev/FindMPI-add-imported-targets.rst
 create mode 100644 Help/release/dev/add_custom_command-TARGET_OBJECTS.rst
 create mode 100644 Help/release/dev/add_library-TARGET_OBJECTS.rst
 create mode 100644 Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
 create mode 100644 Help/release/dev/install-TARGET_OBJECTS.rst
 create mode 100644 Help/variable/CMAKE_MATCH_n.rst
 create mode 100644 Tests/ExportImport/Export/sub/testLib8C.c
 create mode 100644 Tests/ExportImport/Export/testLib8A.c
 create mode 100644 Tests/ExportImport/Export/testLib8B.c
 create mode 100644 Tests/ExportImport/Import/A/imp_testLib8.c
 create mode 100644 Tests/FindMPI/CMakeLists.txt
 create mode 100644 Tests/FindMPI/Test/CMakeLists.txt
 create mode 100644 Tests/FindMPI/Test/main.c
 create mode 100644 Tests/FindMPI/Test/main.f90
 create mode 100644 Tests/GeneratorExpression/check_object_files.cmake
 create mode 100644 Tests/GeneratorExpression/objlib1.c
 create mode 100644 Tests/GeneratorExpression/objlib2.c
 create mode 100644 Tests/Module/CheckIPOSupported-C/CMakeLists.txt
 copy {Modules/CheckIPOSupported => Tests/Module/CheckIPOSupported-C}/foo.c (100%)
 create mode 100644 Tests/Module/CheckIPOSupported-C/main.c
 create mode 100644 Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt
 copy {Modules/CheckIPOSupported => Tests/Module/CheckIPOSupported-CXX}/foo.cpp (100%)
 create mode 100644 Tests/Module/CheckIPOSupported-CXX/main.cpp
 create mode 100644 Tests/Module/CheckIPOSupported-Fortran/CMakeLists.txt
 copy {Modules/CheckIPOSupported => Tests/Module/CheckIPOSupported-Fortran}/foo.f (100%)
 copy {Modules/CheckIPOSupported => Tests/Module/CheckIPOSupported-Fortran}/main.f (100%)
 delete mode 100644 Tests/RunCMake/ObjectLibrary/Export-result.txt
 delete mode 100644 Tests/RunCMake/ObjectLibrary/Export-stderr.txt
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => ObjectLibrary/ExportNotSupported-result.txt} (100%)
 create mode 100644 Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt
 copy Tests/RunCMake/ObjectLibrary/{Export.cmake => ExportNotSupported.cmake} (100%)
 delete mode 100644 Tests/RunCMake/ObjectLibrary/Import-result.txt
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => ObjectLibrary/ImportNotSupported-result.txt} (100%)
 rename Tests/RunCMake/ObjectLibrary/{Import-stderr.txt => ImportNotSupported-stderr.txt} (55%)
 copy Tests/RunCMake/ObjectLibrary/{Import.cmake => ImportNotSupported.cmake} (100%)
 delete mode 100644 Tests/RunCMake/ObjectLibrary/Install-result.txt
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => ObjectLibrary/InstallNotSupported-result.txt} (100%)
 rename Tests/RunCMake/ObjectLibrary/{Install-stderr.txt => InstallNotSupported-stderr.txt} (54%)
 copy Tests/RunCMake/ObjectLibrary/{Install.cmake => InstallNotSupported.cmake} (100%)
 create mode 100644 Tests/RunCMake/ObjectLibrary/b.c
 delete mode 100644 Tests/RunCMake/TargetObjects/BadContext-result.txt
 delete mode 100644 Tests/RunCMake/TargetObjects/BadContext-stderr.txt
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => TargetObjects/NoTarget-result.txt} (100%)
 create mode 100644 Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
 rename Tests/RunCMake/TargetObjects/{BadContext.cmake => NoTarget.cmake} (100%)
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => TargetObjects/NotObjlibTarget-result.txt} (100%)
 create mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
 create mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
 create mode 100644 Tests/RunCMake/TargetObjects/empty.cpp


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list