mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-26 04:09:35 +03:00
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@kitware.com>
This commit is contained in:
committed by
Brad King
parent
93c89bc75c
commit
eec93bceec
@@ -64,7 +64,7 @@ Imported Libraries
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED
|
add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
|
||||||
[GLOBAL])
|
[GLOBAL])
|
||||||
|
|
||||||
An :ref:`IMPORTED library target <Imported Targets>` references a library
|
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``).
|
that would not affect linking of a normal library (e.g. ``.txt``).
|
||||||
They may contain custom commands generating such sources, but not
|
They may contain custom commands generating such sources, but not
|
||||||
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Object libraries
|
``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` commands. Object libraries
|
||||||
cannot be imported, exported, installed, or linked. Some native build
|
cannot be linked. Some native build systems may not like targets that
|
||||||
systems may not like targets that have only object files, so consider
|
have only object files, so consider adding at least one real source file
|
||||||
adding at least one real source file to any target that references
|
to any target that references ``$<TARGET_OBJECTS:objlib>``.
|
||||||
``$<TARGET_OBJECTS:objlib>``.
|
|
||||||
|
|
||||||
Alias Libraries
|
Alias Libraries
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|||||||
+12
-11
@@ -73,7 +73,7 @@ Installing Targets
|
|||||||
::
|
::
|
||||||
|
|
||||||
install(TARGETS targets... [EXPORT <export-name>]
|
install(TARGETS targets... [EXPORT <export-name>]
|
||||||
[[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
|
[[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
|
||||||
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
|
||||||
[DESTINATION <dir>]
|
[DESTINATION <dir>]
|
||||||
[PERMISSIONS permissions...]
|
[PERMISSIONS permissions...]
|
||||||
@@ -86,10 +86,10 @@ Installing Targets
|
|||||||
)
|
)
|
||||||
|
|
||||||
The ``TARGETS`` form specifies rules for installing targets from a
|
The ``TARGETS`` form specifies rules for installing targets from a
|
||||||
project. There are five kinds of target files that may be installed:
|
project. There are six kinds of target files that may be installed:
|
||||||
``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE``.
|
``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, ``FRAMEWORK``, and
|
||||||
Executables are treated as ``RUNTIME`` targets, except that those
|
``BUNDLE``. Executables are treated as ``RUNTIME`` targets, except that
|
||||||
marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
|
those marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
|
||||||
targets on OS X. Static libraries are treated as ``ARCHIVE`` targets,
|
targets on OS X. Static libraries are treated as ``ARCHIVE`` targets,
|
||||||
except that those marked with the ``FRAMEWORK`` property are treated
|
except that those marked with the ``FRAMEWORK`` property are treated
|
||||||
as ``FRAMEWORK`` targets on OS X.
|
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
|
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
|
part of a shared library is treated as a ``RUNTIME`` target and the
|
||||||
corresponding import library is treated as an ``ARCHIVE`` target.
|
corresponding import library is treated as an ``ARCHIVE`` target.
|
||||||
All Windows-based systems including Cygwin are DLL platforms.
|
All Windows-based systems including Cygwin are DLL platforms. Object
|
||||||
The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, and ``FRAMEWORK`` arguments
|
libraries are always treated as ``OBJECTS`` targets.
|
||||||
change the type of target to which the subsequent properties apply.
|
The ``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``OBJECTS``, and ``FRAMEWORK``
|
||||||
If none is given the installation properties apply to all target
|
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
|
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
|
installed (which can be used to install just a DLL or just an import
|
||||||
library).
|
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
|
The ``EXPORT`` option associates the installed target files with an
|
||||||
export called ``<export-name>``. It must appear before any ``RUNTIME``,
|
export called ``<export-name>``. It must appear before any ``RUNTIME``,
|
||||||
``LIBRARY``, or ``ARCHIVE`` options. To actually install the export
|
``LIBRARY``, ``ARCHIVE``, or ``OBJECTS`` options. To actually install the
|
||||||
file itself, call ``install(EXPORT)``, documented below.
|
export file itself, call ``install(EXPORT)``, documented below.
|
||||||
|
|
||||||
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
||||||
set to ``TRUE`` has undefined behavior.
|
set to ``TRUE`` has undefined behavior.
|
||||||
|
|||||||
@@ -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)
|
add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)
|
||||||
|
|
||||||
``OBJECT`` libraries may only be used locally as sources in a buildsystem --
|
``OBJECT`` libraries may not be used in the right hand side of
|
||||||
they may not be installed, exported, or used in the right hand side of
|
|
||||||
:command:`target_link_libraries`. They also may not be used as the ``TARGET``
|
: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
|
Although object libraries may not be named directly in calls to
|
||||||
the :command:`target_link_libraries` command, they can be "linked"
|
the :command:`target_link_libraries` command, they can be "linked"
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ Properties on Targets
|
|||||||
/prop_tgt/IMPORTED_LOCATION
|
/prop_tgt/IMPORTED_LOCATION
|
||||||
/prop_tgt/IMPORTED_NO_SONAME_CONFIG
|
/prop_tgt/IMPORTED_NO_SONAME_CONFIG
|
||||||
/prop_tgt/IMPORTED_NO_SONAME
|
/prop_tgt/IMPORTED_NO_SONAME
|
||||||
|
/prop_tgt/IMPORTED_OBJECTS_CONFIG
|
||||||
|
/prop_tgt/IMPORTED_OBJECTS
|
||||||
/prop_tgt/IMPORTED
|
/prop_tgt/IMPORTED
|
||||||
/prop_tgt/IMPORTED_SONAME_CONFIG
|
/prop_tgt/IMPORTED_SONAME_CONFIG
|
||||||
/prop_tgt/IMPORTED_SONAME
|
/prop_tgt/IMPORTED_SONAME
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
add_library-TARGET_OBJECTS
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
* The :command:`add_library` command ``IMPORTED`` option learned to support
|
||||||
|
:ref:`Object Libraries`.
|
||||||
@@ -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`.
|
||||||
@@ -297,10 +297,15 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (type == cmStateEnums::OBJECT_LIBRARY) {
|
if (type == cmStateEnums::OBJECT_LIBRARY) {
|
||||||
this->Makefile->IssueMessage(
|
std::string reason;
|
||||||
cmake::FATAL_ERROR,
|
if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
|
||||||
"The OBJECT library type may not be used for IMPORTED libraries.");
|
&reason)) {
|
||||||
return true;
|
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 (type == cmStateEnums::INTERFACE_LIBRARY) {
|
||||||
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
|
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
#include "cmExportBuildFileGenerator.h"
|
#include "cmExportBuildFileGenerator.h"
|
||||||
|
|
||||||
|
#include "cmAlgorithms.h"
|
||||||
#include "cmExportSet.h"
|
#include "cmExportSet.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
#include "cmGeneratorTarget.h"
|
#include "cmGeneratorTarget.h"
|
||||||
@@ -21,6 +22,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
class cmSourceFile;
|
||||||
|
|
||||||
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
|
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
|
||||||
{
|
{
|
||||||
this->LG = CM_NULLPTR;
|
this->LG = CM_NULLPTR;
|
||||||
@@ -171,27 +174,48 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
|
|||||||
// Get the makefile in which to lookup target information.
|
// Get the makefile in which to lookup target information.
|
||||||
cmMakefile* mf = target->Makefile;
|
cmMakefile* mf = target->Makefile;
|
||||||
|
|
||||||
// Add the main target file.
|
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
||||||
{
|
std::string prop = "IMPORTED_OBJECTS";
|
||||||
std::string prop = "IMPORTED_LOCATION";
|
|
||||||
prop += suffix;
|
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.
|
// Compute all the object files inside this target and setup
|
||||||
if (target->HasImportLibrary() &&
|
// IMPORTED_OBJECTS as a list of object files
|
||||||
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
|
std::vector<cmSourceFile const*> objectSources;
|
||||||
std::string prop = "IMPORTED_IMPLIB";
|
target->GetObjectSources(objectSources, config);
|
||||||
prop += suffix;
|
std::string const obj_dir = target->GetObjectDirectory(config);
|
||||||
std::string value = target->GetFullPath(config, true);
|
std::vector<std::string> objects;
|
||||||
target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
|
for (std::vector<cmSourceFile const*>::const_iterator si =
|
||||||
properties[prop] = value;
|
objectSources.begin();
|
||||||
|
si != objectSources.end(); ++si) {
|
||||||
|
const std::string& obj = target->GetObjectName(*si);
|
||||||
|
objects.push_back(obj_dir + obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,11 +149,15 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
|||||||
|
|
||||||
if (cmTarget* target = gg->FindTarget(*currentTarget)) {
|
if (cmTarget* target = gg->FindTarget(*currentTarget)) {
|
||||||
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
||||||
std::ostringstream e;
|
std::string reason;
|
||||||
e << "given OBJECT library \"" << *currentTarget
|
if (!this->Makefile->GetGlobalGenerator()
|
||||||
<< "\" which may not be exported.";
|
->HasKnownObjectFileLocation(&reason)) {
|
||||||
this->SetError(e.str());
|
std::ostringstream e;
|
||||||
return false;
|
e << "given OBJECT library \"" << *currentTarget
|
||||||
|
<< "\" which may not be exported" << reason << ".";
|
||||||
|
this->SetError(e.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (target->GetType() == cmStateEnums::UTILITY) {
|
if (target->GetType() == cmStateEnums::UTILITY) {
|
||||||
this->SetError("given custom target \"" + *currentTarget +
|
this->SetError("given custom target \"" + *currentTarget +
|
||||||
|
|||||||
@@ -441,6 +441,11 @@ void getCompatibleInterfaceProperties(cmGeneratorTarget* target,
|
|||||||
std::set<std::string>& ifaceProperties,
|
std::set<std::string>& ifaceProperties,
|
||||||
const std::string& config)
|
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);
|
cmComputeLinkInformation* info = target->GetLinkInformation(config);
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
@@ -927,6 +932,9 @@ void cmExportFileGenerator::GenerateImportTargetCode(
|
|||||||
case cmStateEnums::UNKNOWN_LIBRARY:
|
case cmStateEnums::UNKNOWN_LIBRARY:
|
||||||
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
|
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
|
||||||
break;
|
break;
|
||||||
|
case cmStateEnums::OBJECT_LIBRARY:
|
||||||
|
os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
|
||||||
|
break;
|
||||||
case cmStateEnums::INTERFACE_LIBRARY:
|
case cmStateEnums::INTERFACE_LIBRARY:
|
||||||
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
|
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -331,6 +331,8 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
|
|||||||
properties, importedLocations);
|
properties, importedLocations);
|
||||||
this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator,
|
this->SetImportLocationProperty(config, suffix, te->RuntimeGenerator,
|
||||||
properties, importedLocations);
|
properties, importedLocations);
|
||||||
|
this->SetImportLocationProperty(config, suffix, te->ObjectsGenerator,
|
||||||
|
properties, importedLocations);
|
||||||
this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
|
this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
|
||||||
properties, importedLocations);
|
properties, importedLocations);
|
||||||
this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
|
this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
|
||||||
@@ -397,6 +399,23 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
|
|||||||
// Store the property.
|
// Store the property.
|
||||||
properties[prop] = value;
|
properties[prop] = value;
|
||||||
importedLocations.insert(prop);
|
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 {
|
} else {
|
||||||
// Construct the property name.
|
// Construct the property name.
|
||||||
std::string prop = "IMPORTED_LOCATION";
|
std::string prop = "IMPORTED_LOCATION";
|
||||||
|
|||||||
@@ -1257,24 +1257,35 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> objects;
|
std::vector<std::string> objects;
|
||||||
gt->GetTargetObjectNames(context->Config, objects);
|
|
||||||
|
|
||||||
std::string obj_dir;
|
if (gt->IsImported()) {
|
||||||
if (context->EvaluateForBuildsystem) {
|
const char* loc = CM_NULLPTR;
|
||||||
// Use object file directory with buildsystem placeholder.
|
const char* imp = CM_NULLPTR;
|
||||||
obj_dir = gt->ObjectDirectory;
|
std::string suffix;
|
||||||
// Here we assume that the set of object files produced
|
if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
|
||||||
// by an object library does not vary with configuration
|
cmSystemTools::ExpandListArgument(loc, objects);
|
||||||
// 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;
|
context->HadContextSensitiveCondition = true;
|
||||||
}
|
} else {
|
||||||
|
gt->GetTargetObjectNames(context->Config, objects);
|
||||||
|
|
||||||
for (std::vector<std::string>::iterator oi = objects.begin();
|
std::string obj_dir;
|
||||||
oi != objects.end(); ++oi) {
|
if (context->EvaluateForBuildsystem) {
|
||||||
*oi = obj_dir + *oi;
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the cmSourceFile instances in the referencing directory.
|
// Create the cmSourceFile instances in the referencing directory.
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
cmCAStringVector archiveArgVector(&argHelper, "ARCHIVE", &group);
|
cmCAStringVector archiveArgVector(&argHelper, "ARCHIVE", &group);
|
||||||
cmCAStringVector libraryArgVector(&argHelper, "LIBRARY", &group);
|
cmCAStringVector libraryArgVector(&argHelper, "LIBRARY", &group);
|
||||||
cmCAStringVector runtimeArgVector(&argHelper, "RUNTIME", &group);
|
cmCAStringVector runtimeArgVector(&argHelper, "RUNTIME", &group);
|
||||||
|
cmCAStringVector objectArgVector(&argHelper, "OBJECTS", &group);
|
||||||
cmCAStringVector frameworkArgVector(&argHelper, "FRAMEWORK", &group);
|
cmCAStringVector frameworkArgVector(&argHelper, "FRAMEWORK", &group);
|
||||||
cmCAStringVector bundleArgVector(&argHelper, "BUNDLE", &group);
|
cmCAStringVector bundleArgVector(&argHelper, "BUNDLE", &group);
|
||||||
cmCAStringVector includesArgVector(&argHelper, "INCLUDES", &group);
|
cmCAStringVector includesArgVector(&argHelper, "INCLUDES", &group);
|
||||||
@@ -234,6 +235,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
|
cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
|
cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
|
cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
|
||||||
|
cmInstallCommandArguments objectArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
|
cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
|
cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
|
cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
|
||||||
@@ -246,6 +248,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
archiveArgs.Parse(&archiveArgVector.GetVector(), &unknownArgs);
|
archiveArgs.Parse(&archiveArgVector.GetVector(), &unknownArgs);
|
||||||
libraryArgs.Parse(&libraryArgVector.GetVector(), &unknownArgs);
|
libraryArgs.Parse(&libraryArgVector.GetVector(), &unknownArgs);
|
||||||
runtimeArgs.Parse(&runtimeArgVector.GetVector(), &unknownArgs);
|
runtimeArgs.Parse(&runtimeArgVector.GetVector(), &unknownArgs);
|
||||||
|
objectArgs.Parse(&objectArgVector.GetVector(), &unknownArgs);
|
||||||
frameworkArgs.Parse(&frameworkArgVector.GetVector(), &unknownArgs);
|
frameworkArgs.Parse(&frameworkArgVector.GetVector(), &unknownArgs);
|
||||||
bundleArgs.Parse(&bundleArgVector.GetVector(), &unknownArgs);
|
bundleArgs.Parse(&bundleArgVector.GetVector(), &unknownArgs);
|
||||||
privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
|
privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
|
||||||
@@ -265,6 +268,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
archiveArgs.SetGenericArguments(&genericArgs);
|
archiveArgs.SetGenericArguments(&genericArgs);
|
||||||
libraryArgs.SetGenericArguments(&genericArgs);
|
libraryArgs.SetGenericArguments(&genericArgs);
|
||||||
runtimeArgs.SetGenericArguments(&genericArgs);
|
runtimeArgs.SetGenericArguments(&genericArgs);
|
||||||
|
objectArgs.SetGenericArguments(&genericArgs);
|
||||||
frameworkArgs.SetGenericArguments(&genericArgs);
|
frameworkArgs.SetGenericArguments(&genericArgs);
|
||||||
bundleArgs.SetGenericArguments(&genericArgs);
|
bundleArgs.SetGenericArguments(&genericArgs);
|
||||||
privateHeaderArgs.SetGenericArguments(&genericArgs);
|
privateHeaderArgs.SetGenericArguments(&genericArgs);
|
||||||
@@ -274,6 +278,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
success = success && archiveArgs.Finalize();
|
success = success && archiveArgs.Finalize();
|
||||||
success = success && libraryArgs.Finalize();
|
success = success && libraryArgs.Finalize();
|
||||||
success = success && runtimeArgs.Finalize();
|
success = success && runtimeArgs.Finalize();
|
||||||
|
success = success && objectArgs.Finalize();
|
||||||
success = success && frameworkArgs.Finalize();
|
success = success && frameworkArgs.Finalize();
|
||||||
success = success && bundleArgs.Finalize();
|
success = success && bundleArgs.Finalize();
|
||||||
success = success && privateHeaderArgs.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
|
// Enforce argument rules too complex to specify for the
|
||||||
// general-purpose parser.
|
// general-purpose parser.
|
||||||
if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
|
if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
|
||||||
frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
|
objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
|
||||||
privateHeaderArgs.GetNamelinkOnly() ||
|
bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
|
||||||
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
|
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
|
||||||
this->SetError(
|
this->SetError(
|
||||||
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
|
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
|
||||||
@@ -296,8 +301,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
|
if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
|
||||||
frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
|
objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
|
||||||
privateHeaderArgs.GetNamelinkSkip() ||
|
bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
|
||||||
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
|
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
|
||||||
this->SetError(
|
this->SetError(
|
||||||
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
|
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
|
||||||
@@ -356,11 +361,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
||||||
std::ostringstream e;
|
std::string reason;
|
||||||
e << "TARGETS given OBJECT library \"" << (*targetIt)
|
if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
|
||||||
<< "\" which may not be installed.";
|
&reason)) {
|
||||||
this->SetError(e.str());
|
std::ostringstream e;
|
||||||
return false;
|
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.
|
// Store the target in the list to be installed.
|
||||||
targets.push_back(target);
|
targets.push_back(target);
|
||||||
@@ -379,6 +388,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
bool installsArchive = false;
|
bool installsArchive = false;
|
||||||
bool installsLibrary = false;
|
bool installsLibrary = false;
|
||||||
bool installsRuntime = false;
|
bool installsRuntime = false;
|
||||||
|
bool installsObject = false;
|
||||||
bool installsFramework = false;
|
bool installsFramework = false;
|
||||||
bool installsBundle = false;
|
bool installsBundle = false;
|
||||||
bool installsPrivateHeader = false;
|
bool installsPrivateHeader = false;
|
||||||
@@ -393,6 +403,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
cmInstallTargetGenerator* archiveGenerator = CM_NULLPTR;
|
cmInstallTargetGenerator* archiveGenerator = CM_NULLPTR;
|
||||||
cmInstallTargetGenerator* libraryGenerator = CM_NULLPTR;
|
cmInstallTargetGenerator* libraryGenerator = CM_NULLPTR;
|
||||||
cmInstallTargetGenerator* runtimeGenerator = CM_NULLPTR;
|
cmInstallTargetGenerator* runtimeGenerator = CM_NULLPTR;
|
||||||
|
cmInstallTargetGenerator* objectGenerator = CM_NULLPTR;
|
||||||
cmInstallTargetGenerator* frameworkGenerator = CM_NULLPTR;
|
cmInstallTargetGenerator* frameworkGenerator = CM_NULLPTR;
|
||||||
cmInstallTargetGenerator* bundleGenerator = CM_NULLPTR;
|
cmInstallTargetGenerator* bundleGenerator = CM_NULLPTR;
|
||||||
cmInstallFilesGenerator* privateHeaderGenerator = CM_NULLPTR;
|
cmInstallFilesGenerator* privateHeaderGenerator = CM_NULLPTR;
|
||||||
@@ -522,6 +533,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} break;
|
} 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: {
|
case cmStateEnums::EXECUTABLE: {
|
||||||
if (target.IsAppBundleOnApple()) {
|
if (target.IsAppBundleOnApple()) {
|
||||||
// Application bundles use the BUNDLE properties.
|
// Application bundles use the BUNDLE properties.
|
||||||
@@ -664,6 +689,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
installsArchive = installsArchive || archiveGenerator != CM_NULLPTR;
|
installsArchive = installsArchive || archiveGenerator != CM_NULLPTR;
|
||||||
installsLibrary = installsLibrary || libraryGenerator != CM_NULLPTR;
|
installsLibrary = installsLibrary || libraryGenerator != CM_NULLPTR;
|
||||||
installsRuntime = installsRuntime || runtimeGenerator != CM_NULLPTR;
|
installsRuntime = installsRuntime || runtimeGenerator != CM_NULLPTR;
|
||||||
|
installsObject = installsObject || objectGenerator != CM_NULLPTR;
|
||||||
installsFramework = installsFramework || frameworkGenerator != CM_NULLPTR;
|
installsFramework = installsFramework || frameworkGenerator != CM_NULLPTR;
|
||||||
installsBundle = installsBundle || bundleGenerator != CM_NULLPTR;
|
installsBundle = installsBundle || bundleGenerator != CM_NULLPTR;
|
||||||
installsPrivateHeader =
|
installsPrivateHeader =
|
||||||
@@ -675,6 +701,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
this->Makefile->AddInstallGenerator(archiveGenerator);
|
this->Makefile->AddInstallGenerator(archiveGenerator);
|
||||||
this->Makefile->AddInstallGenerator(libraryGenerator);
|
this->Makefile->AddInstallGenerator(libraryGenerator);
|
||||||
this->Makefile->AddInstallGenerator(runtimeGenerator);
|
this->Makefile->AddInstallGenerator(runtimeGenerator);
|
||||||
|
this->Makefile->AddInstallGenerator(objectGenerator);
|
||||||
this->Makefile->AddInstallGenerator(frameworkGenerator);
|
this->Makefile->AddInstallGenerator(frameworkGenerator);
|
||||||
this->Makefile->AddInstallGenerator(bundleGenerator);
|
this->Makefile->AddInstallGenerator(bundleGenerator);
|
||||||
this->Makefile->AddInstallGenerator(privateHeaderGenerator);
|
this->Makefile->AddInstallGenerator(privateHeaderGenerator);
|
||||||
@@ -692,6 +719,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
te->HeaderGenerator = publicHeaderGenerator;
|
te->HeaderGenerator = publicHeaderGenerator;
|
||||||
te->LibraryGenerator = libraryGenerator;
|
te->LibraryGenerator = libraryGenerator;
|
||||||
te->RuntimeGenerator = runtimeGenerator;
|
te->RuntimeGenerator = runtimeGenerator;
|
||||||
|
te->ObjectsGenerator = objectGenerator;
|
||||||
this->Makefile->GetGlobalGenerator()
|
this->Makefile->GetGlobalGenerator()
|
||||||
->GetExportSets()[exports.GetString()]
|
->GetExportSets()[exports.GetString()]
|
||||||
->AddTargetExport(te);
|
->AddTargetExport(te);
|
||||||
@@ -715,6 +743,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
|
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||||
runtimeArgs.GetComponent().c_str());
|
runtimeArgs.GetComponent().c_str());
|
||||||
}
|
}
|
||||||
|
if (installsObject) {
|
||||||
|
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||||
|
objectArgs.GetComponent().c_str());
|
||||||
|
}
|
||||||
if (installsFramework) {
|
if (installsFramework) {
|
||||||
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
|
this->Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||||
frameworkArgs.GetComponent().c_str());
|
frameworkArgs.GetComponent().c_str());
|
||||||
|
|||||||
@@ -81,7 +81,11 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
|
|||||||
assert(false &&
|
assert(false &&
|
||||||
"INTERFACE_LIBRARY targets have no installable outputs.");
|
"INTERFACE_LIBRARY targets have no installable outputs.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmStateEnums::OBJECT_LIBRARY:
|
case cmStateEnums::OBJECT_LIBRARY:
|
||||||
|
this->GenerateScriptForConfigObjectLibrary(os, config, indent);
|
||||||
|
return;
|
||||||
|
|
||||||
case cmStateEnums::UTILITY:
|
case cmStateEnums::UTILITY:
|
||||||
case cmStateEnums::GLOBAL_TARGET:
|
case cmStateEnums::GLOBAL_TARGET:
|
||||||
case cmStateEnums::UNKNOWN_LIBRARY:
|
case cmStateEnums::UNKNOWN_LIBRARY:
|
||||||
@@ -318,6 +322,49 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
|
|||||||
&cmInstallTargetGenerator::PostReplacementTweaks);
|
&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 cmInstallTargetGenerator::GetDestination(
|
||||||
std::string const& config) const
|
std::string const& config) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ public:
|
|||||||
|
|
||||||
std::string GetInstallFilename(const std::string& config) const;
|
std::string GetInstallFilename(const std::string& config) const;
|
||||||
|
|
||||||
|
void GetInstallObjectNames(std::string const& config,
|
||||||
|
std::vector<std::string>& objects) const;
|
||||||
|
|
||||||
enum NameType
|
enum NameType
|
||||||
{
|
{
|
||||||
NameNormal,
|
NameNormal,
|
||||||
@@ -65,6 +68,9 @@ protected:
|
|||||||
void GenerateScript(std::ostream& os) CM_OVERRIDE;
|
void GenerateScript(std::ostream& os) CM_OVERRIDE;
|
||||||
void GenerateScriptForConfig(std::ostream& os, const std::string& config,
|
void GenerateScriptForConfig(std::ostream& os, const std::string& config,
|
||||||
Indent const& indent) CM_OVERRIDE;
|
Indent const& indent) CM_OVERRIDE;
|
||||||
|
void GenerateScriptForConfigObjectLibrary(std::ostream& os,
|
||||||
|
const std::string& config,
|
||||||
|
Indent const& indent);
|
||||||
typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&,
|
typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&,
|
||||||
Indent const&,
|
Indent const&,
|
||||||
const std::string&,
|
const std::string&,
|
||||||
|
|||||||
+19
-11
@@ -1354,11 +1354,9 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
|
|||||||
|
|
||||||
// Lookup/compute/cache the import information for this
|
// Lookup/compute/cache the import information for this
|
||||||
// configuration.
|
// configuration.
|
||||||
std::string config_upper;
|
std::string desired_config = config;
|
||||||
if (!config.empty()) {
|
if (config.empty()) {
|
||||||
config_upper = cmSystemTools::UpperCase(config);
|
desired_config = "NOCONFIG";
|
||||||
} else {
|
|
||||||
config_upper = "NOCONFIG";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
@@ -1368,7 +1366,7 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
|
|||||||
std::string suffix;
|
std::string suffix;
|
||||||
|
|
||||||
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
|
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
|
||||||
this->GetMappedConfig(config_upper, &loc, &imp, suffix)) {
|
this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
|
||||||
if (!pimplib) {
|
if (!pimplib) {
|
||||||
if (loc) {
|
if (loc) {
|
||||||
result = loc;
|
result = loc;
|
||||||
@@ -1451,18 +1449,28 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
|
|||||||
const char** loc, const char** imp,
|
const char** loc, const char** imp,
|
||||||
std::string& suffix) const
|
std::string& suffix) const
|
||||||
{
|
{
|
||||||
std::string const locPropBase =
|
std::string config_upper;
|
||||||
this->GetType() == cmStateEnums::INTERFACE_LIBRARY ? "IMPORTED_LIBNAME"
|
if (!desired_config.empty()) {
|
||||||
: "IMPORTED_LOCATION";
|
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.
|
// Track the configuration-specific property suffix.
|
||||||
suffix = "_";
|
suffix = "_";
|
||||||
suffix += desired_config;
|
suffix += config_upper;
|
||||||
|
|
||||||
std::vector<std::string> mappedConfigs;
|
std::vector<std::string> mappedConfigs;
|
||||||
{
|
{
|
||||||
std::string mapProp = "MAP_IMPORTED_CONFIG_";
|
std::string mapProp = "MAP_IMPORTED_CONFIG_";
|
||||||
mapProp += desired_config;
|
mapProp += config_upper;
|
||||||
if (const char* mapValue = this->GetProperty(mapProp)) {
|
if (const char* mapValue = this->GetProperty(mapProp)) {
|
||||||
cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
|
cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
cmInstallTargetGenerator* ArchiveGenerator;
|
cmInstallTargetGenerator* ArchiveGenerator;
|
||||||
cmInstallTargetGenerator* RuntimeGenerator;
|
cmInstallTargetGenerator* RuntimeGenerator;
|
||||||
cmInstallTargetGenerator* LibraryGenerator;
|
cmInstallTargetGenerator* LibraryGenerator;
|
||||||
|
cmInstallTargetGenerator* ObjectsGenerator;
|
||||||
cmInstallTargetGenerator* FrameworkGenerator;
|
cmInstallTargetGenerator* FrameworkGenerator;
|
||||||
cmInstallTargetGenerator* BundleGenerator;
|
cmInstallTargetGenerator* BundleGenerator;
|
||||||
cmInstallFilesGenerator* HeaderGenerator;
|
cmInstallFilesGenerator* HeaderGenerator;
|
||||||
|
|||||||
@@ -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_RELEASE testLib7R-$<CONFIG>)
|
||||||
set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<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
|
# Test using the target_link_libraries command to set the
|
||||||
# LINK_INTERFACE_LIBRARIES* properties. We construct two libraries
|
# LINK_INTERFACE_LIBRARIES* properties. We construct two libraries
|
||||||
# providing the same two symbols. In each library one of the symbols
|
# providing the same two symbols. In each library one of the symbols
|
||||||
@@ -474,7 +483,7 @@ install(
|
|||||||
TARGETS
|
TARGETS
|
||||||
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
|
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe4
|
||||||
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLib6 testLib7
|
testLib6 testLib7 ${maybe_testLib8}
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
testLibNoSONAME
|
testLibNoSONAME
|
||||||
cmp0022NEW cmp0022OLD
|
cmp0022NEW cmp0022OLD
|
||||||
@@ -483,6 +492,7 @@ install(
|
|||||||
RUNTIME DESTINATION $<1:bin>
|
RUNTIME DESTINATION $<1:bin>
|
||||||
LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
|
LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
|
||||||
ARCHIVE DESTINATION $<1:lib>
|
ARCHIVE DESTINATION $<1:lib>
|
||||||
|
OBJECTS DESTINATION $<1:lib>
|
||||||
FRAMEWORK DESTINATION Frameworks
|
FRAMEWORK DESTINATION Frameworks
|
||||||
BUNDLE DESTINATION Applications
|
BUNDLE DESTINATION Applications
|
||||||
)
|
)
|
||||||
@@ -535,6 +545,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
|
|||||||
FILE ExportBuildTree.cmake
|
FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
|
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
|
||||||
|
${maybe_testLib8}
|
||||||
testLib4lib testLib4libdbg testLib4libopt
|
testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
testLibNoSONAME
|
testLibNoSONAME
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
int testLib8C(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
int testLib8A(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
int testLib8B(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -228,6 +228,16 @@ target_link_libraries(imp_lib1 exp_testLib2)
|
|||||||
add_library(imp_lib1b STATIC imp_lib1.c)
|
add_library(imp_lib1b STATIC imp_lib1.c)
|
||||||
target_link_libraries(imp_lib1b bld_testLib2)
|
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,
|
# Test that handling imported targets, including transitive dependencies,
|
||||||
# works in CheckFunctionExists (...and hopefully all other try_compile() checks
|
# works in CheckFunctionExists (...and hopefully all other try_compile() checks
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
int testLib8A(void);
|
||||||
|
int testLib8B(void);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return (testLib8A() + testLib8B());
|
||||||
|
}
|
||||||
@@ -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\)
|
|
||||||
@@ -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\)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
add_library(A OBJECT a.c)
|
||||||
|
export(TARGETS A FILE AExport.cmake)
|
||||||
@@ -1 +1,12 @@
|
|||||||
|
|
||||||
add_library(A OBJECT IMPORTED)
|
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)
|
||||||
|
|||||||
+3
-2
@@ -1,4 +1,5 @@
|
|||||||
CMake Error at Import.cmake:1 \(add_library\):
|
CMake Error at ImportNotSupported.cmake:[0-9]+ \(add_library\):
|
||||||
The OBJECT library type may not be used for IMPORTED libraries.
|
The OBJECT library type may not be used for IMPORTED libraries under Xcode
|
||||||
|
with multiple architectures.
|
||||||
Call Stack \(most recent call first\):
|
Call Stack \(most recent call first\):
|
||||||
CMakeLists.txt:3 \(include\)
|
CMakeLists.txt:3 \(include\)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
add_library(A OBJECT IMPORTED)
|
||||||
+3
-2
@@ -1,4 +1,5 @@
|
|||||||
CMake Error at Install.cmake:2 \(install\):
|
CMake Error at InstallNotSupported.cmake:[0-9]+ \(install\):
|
||||||
install TARGETS given OBJECT library "A" which may not be installed.
|
install TARGETS given OBJECT library "A" which may not be installed under
|
||||||
|
Xcode with multiple architectures.
|
||||||
Call Stack \(most recent call first\):
|
Call Stack \(most recent call first\):
|
||||||
CMakeLists.txt:3 \(include\)
|
CMakeLists.txt:3 \(include\)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
add_library(A OBJECT a.c)
|
||||||
|
install(TARGETS A DESTINATION lib)
|
||||||
@@ -5,9 +5,15 @@ run_cmake(BadSourceExpression2)
|
|||||||
run_cmake(BadSourceExpression3)
|
run_cmake(BadSourceExpression3)
|
||||||
run_cmake(BadObjSource1)
|
run_cmake(BadObjSource1)
|
||||||
run_cmake(BadObjSource2)
|
run_cmake(BadObjSource2)
|
||||||
run_cmake(Export)
|
if(RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
|
||||||
run_cmake(Import)
|
run_cmake(ExportNotSupported)
|
||||||
run_cmake(Install)
|
run_cmake(ImportNotSupported)
|
||||||
|
run_cmake(InstallNotSupported)
|
||||||
|
else()
|
||||||
|
run_cmake(Export)
|
||||||
|
run_cmake(Import)
|
||||||
|
run_cmake(Install)
|
||||||
|
endif()
|
||||||
run_cmake(LinkObjLHS)
|
run_cmake(LinkObjLHS)
|
||||||
run_cmake(LinkObjRHS1)
|
run_cmake(LinkObjRHS1)
|
||||||
run_cmake(LinkObjRHS2)
|
run_cmake(LinkObjRHS2)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
int b(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user