summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Help/command/add_library.rst9
-rw-r--r--Help/command/install.rst23
-rw-r--r--Help/manual/cmake-buildsystem.7.rst6
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/prop_tgt/IMPORTED_OBJECTS.rst11
-rw-r--r--Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst7
-rw-r--r--Help/release/dev/add_library-TARGET_OBJECTS.rst5
-rw-r--r--Help/release/dev/install-TARGET_OBJECTS.rst8
-rw-r--r--Source/cmAddLibraryCommand.cxx13
-rw-r--r--Source/cmExportBuildFileGenerator.cxx60
-rw-r--r--Source/cmExportCommand.cxx14
-rw-r--r--Source/cmExportFileGenerator.cxx8
-rw-r--r--Source/cmExportInstallFileGenerator.cxx19
-rw-r--r--Source/cmGeneratorExpressionNode.cxx43
-rw-r--r--Source/cmInstallCommand.cxx50
-rw-r--r--Source/cmInstallTargetGenerator.cxx47
-rw-r--r--Source/cmInstallTargetGenerator.h6
-rw-r--r--Source/cmTarget.cxx30
-rw-r--r--Source/cmTargetExport.h1
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt13
-rw-r--r--Tests/ExportImport/Export/sub/testLib8C.c4
-rw-r--r--Tests/ExportImport/Export/testLib8A.c4
-rw-r--r--Tests/ExportImport/Export/testLib8B.c4
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt10
-rw-r--r--Tests/ExportImport/Import/A/imp_testLib8.c8
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Export-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportNotSupported.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import.cmake11
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Import-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt (renamed from Tests/RunCMake/ObjectLibrary/Import-stderr.txt)5
-rw-r--r--Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt (renamed from Tests/RunCMake/ObjectLibrary/Install-result.txt)0
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt (renamed from Tests/RunCMake/ObjectLibrary/Install-stderr.txt)5
-rw-r--r--Tests/RunCMake/ObjectLibrary/InstallNotSupported.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/ObjectLibrary/b.c4
38 files changed, 362 insertions, 94 deletions
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index af75a3970a..3a76040b79 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 70087a42b7..58438b7638 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 65d87bf1ae..95f5b87357 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 27c75dc274..31b23897d3 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 0000000000..222e6cc022
--- /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 0000000000..4419ed1d1f
--- /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 0000000000..964064ec4b
--- /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 0000000000..dbcf6357d2
--- /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 9ae4ace4a6..0bdf9636ed 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 539d8541e4..978a7a1a21 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 691048b812..38cd511ea6 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 5875f9e96f..ae3ec3bc4d 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 3b76a87222..16bd5e84ec 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 1215737812..77a49628f2 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 c8923b088e..ba554aa048 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 5b43a1d588..6ecf42da36 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 e6b11b8465..6aaa3bab8e 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 d29a8bd20b..d6f2f0dba6 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 7b5339f0ae..9304eabbb3 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 f504c7be02..eeae3f0068 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 0000000000..a5568c73f4
--- /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 0000000000..c64655a5dd
--- /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 0000000000..1be6c9cd03
--- /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 5ce962861a..01960ea19b 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 0000000000..2749b178cf
--- /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 bdadca488a..0000000000
--- 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
index d00491fd7e..d00491fd7e 100644
--- a/Tests/RunCMake/ObjectLibrary/Export-result.txt
+++ b/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 0000000000..542015984f
--- /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 0000000000..a3f104e297
--- /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 806b44a25e..42f4468664 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
index d00491fd7e..d00491fd7e 100644
--- a/Tests/RunCMake/ObjectLibrary/Import-result.txt
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt b/Tests/RunCMake/ObjectLibrary/ImportNotSupported-stderr.txt
index 74b496ab89..0fadac2081 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/ImportNotSupported.cmake b/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
new file mode 100644
index 0000000000..806b44a25e
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ImportNotSupported.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT IMPORTED)
diff --git a/Tests/RunCMake/ObjectLibrary/Install-result.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
index d00491fd7e..d00491fd7e 100644
--- a/Tests/RunCMake/ObjectLibrary/Install-result.txt
+++ b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-result.txt
diff --git a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt b/Tests/RunCMake/ObjectLibrary/InstallNotSupported-stderr.txt
index d2f9f4a37a..35a0e4fdf9 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 0000000000..c1d214bd4b
--- /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 e932693345..fe708ce979 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 0000000000..6751907b6f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/b.c
@@ -0,0 +1,4 @@
+int b(void)
+{
+ return 0;
+}