ENH: Updated exporting and importing of targets to support libraries and configurations.
- Created cmExportFileGenerator hierarchy to implement export file generation - Installed exports use per-config import files loaded by a central one. - Include soname of shared libraries in import information - Renamed PREFIX to NAMESPACE in INSTALL(EXPORT) and EXPORT() commands - Move addition of CMAKE_INSTALL_PREFIX to destinations to install generators - Import files compute the installation prefix relative to their location when loaded - Add mapping of importer configurations to importee configurations - Rename IMPORT targets to IMPORTED targets to distinguish from windows import libraries - Scope IMPORTED targets within directories to isolate them - Place all properties created by import files in the IMPORTED namespace - Document INSTALL(EXPORT) and EXPORT() commands. - Document IMPORTED signature of add_executable and add_library - Enable finding of imported targets in cmComputeLinkDepends
This commit is contained in:
parent
a7cb9d1120
commit
5594ad4885
@ -121,6 +121,12 @@ SET(SRCS
|
|||||||
cmExprLexer.cxx
|
cmExprLexer.cxx
|
||||||
cmExprParser.cxx
|
cmExprParser.cxx
|
||||||
cmExprParserHelper.cxx
|
cmExprParserHelper.cxx
|
||||||
|
cmExportBuildFileGenerator.h
|
||||||
|
cmExportBuildFileGenerator.cxx
|
||||||
|
cmExportFileGenerator.h
|
||||||
|
cmExportFileGenerator.cxx
|
||||||
|
cmExportInstallFileGenerator.h
|
||||||
|
cmExportInstallFileGenerator.cxx
|
||||||
cmExtraEclipseCDT4Generator.cxx
|
cmExtraEclipseCDT4Generator.cxx
|
||||||
cmExtraEclipseCDT4Generator.h
|
cmExtraEclipseCDT4Generator.h
|
||||||
cmFileTimeComparison.cxx
|
cmFileTimeComparison.cxx
|
||||||
|
@ -32,7 +32,7 @@ bool cmAddDependenciesCommand
|
|||||||
|
|
||||||
cmTarget* target =
|
cmTarget* target =
|
||||||
this->GetMakefile()->GetLocalGenerator()->
|
this->GetMakefile()->GetLocalGenerator()->
|
||||||
GetGlobalGenerator()->FindTarget(0, target_name.c_str(), false);
|
GetGlobalGenerator()->FindTarget(0, target_name.c_str());
|
||||||
if(target)
|
if(target)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::const_iterator s = args.begin();
|
std::vector<std::string>::const_iterator s = args.begin();
|
||||||
|
@ -51,7 +51,7 @@ bool cmAddExecutableCommand
|
|||||||
++s;
|
++s;
|
||||||
excludeFromAll = true;
|
excludeFromAll = true;
|
||||||
}
|
}
|
||||||
else if(*s == "IMPORT")
|
else if(*s == "IMPORTED")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
importTarget = true;
|
importTarget = true;
|
||||||
@ -62,11 +62,59 @@ bool cmAddExecutableCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (importTarget)
|
// Special modifiers are not allowed with IMPORTED signature.
|
||||||
|
if(importTarget && (use_win32 || use_macbundle || excludeFromAll))
|
||||||
{
|
{
|
||||||
this->Makefile->AddNewTarget(cmTarget::EXECUTABLE, exename.c_str(), true);
|
if(use_win32)
|
||||||
|
{
|
||||||
|
this->SetError("may not be given WIN32 for an IMPORTED target.");
|
||||||
|
}
|
||||||
|
else if(use_macbundle)
|
||||||
|
{
|
||||||
|
this->SetError(
|
||||||
|
"may not be given MACOSX_BUNDLE for an IMPORTED target.");
|
||||||
|
}
|
||||||
|
else // if(excludeFromAll)
|
||||||
|
{
|
||||||
|
this->SetError(
|
||||||
|
"may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for an existing target with this name.
|
||||||
|
cmTarget* existing = this->Makefile->FindTargetToUse(exename.c_str());
|
||||||
|
if(importTarget)
|
||||||
|
{
|
||||||
|
// Make sure the target does not already exist.
|
||||||
|
if(existing)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create imported target \"" << exename
|
||||||
|
<< "\" because another target with the same name already exists.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the imported target.
|
||||||
|
this->Makefile->AddImportedTarget(exename.c_str(), cmTarget::EXECUTABLE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make sure the target does not conflict with an imported target.
|
||||||
|
// This should really enforce global name uniqueness for targets
|
||||||
|
// built within the project too, but that may break compatiblity
|
||||||
|
// with projects in which it was accidentally working.
|
||||||
|
if(existing && existing->IsImported())
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create target \"" << exename
|
||||||
|
<< "\" because an imported target with the same name already exists.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s == args.end())
|
if (s == args.end())
|
||||||
{
|
{
|
||||||
|
@ -90,6 +90,24 @@ public:
|
|||||||
"If EXCLUDE_FROM_ALL is given the target will not be built by default. "
|
"If EXCLUDE_FROM_ALL is given the target will not be built by default. "
|
||||||
"It will be built only if the user explicitly builds the target or "
|
"It will be built only if the user explicitly builds the target or "
|
||||||
"another target that requires the target depends on it."
|
"another target that requires the target depends on it."
|
||||||
|
"\n"
|
||||||
|
"The add_executable command can also create IMPORTED executable "
|
||||||
|
"targets using this signature:\n"
|
||||||
|
" add_executable(<name> IMPORTED)\n"
|
||||||
|
"An IMPORTED executable target references an executable file located "
|
||||||
|
"outside the project. "
|
||||||
|
"No rules are generated to build it. "
|
||||||
|
"The target name has scope in the directory in which it is created "
|
||||||
|
"and below. "
|
||||||
|
"It may be referenced like any target built within the project. "
|
||||||
|
"IMPORTED executables are useful for convenient reference from "
|
||||||
|
"commands like add_custom_command. "
|
||||||
|
"Details about the imported executable are specified by setting "
|
||||||
|
"properties whose names begin in \"IMPORTED_\". "
|
||||||
|
"The most important such property is IMPORTED_LOCATION "
|
||||||
|
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
|
||||||
|
"which specifies the location of the main executable file on disk. "
|
||||||
|
"See documentation of the IMPORTED_* properties for more information."
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ bool cmAddLibraryCommand
|
|||||||
// If the second argument is "SHARED" or "STATIC", then it controls
|
// If the second argument is "SHARED" or "STATIC", then it controls
|
||||||
// the type of library. Otherwise, it is treated as a source or
|
// the type of library. Otherwise, it is treated as a source or
|
||||||
// source list name. There may be two keyword arguments, check for them
|
// source list name. There may be two keyword arguments, check for them
|
||||||
|
bool haveSpecifiedType = false;
|
||||||
while ( s != args.end() )
|
while ( s != args.end() )
|
||||||
{
|
{
|
||||||
std::string libType = *s;
|
std::string libType = *s;
|
||||||
@ -53,23 +54,26 @@ bool cmAddLibraryCommand
|
|||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
type = cmTarget::STATIC_LIBRARY;
|
type = cmTarget::STATIC_LIBRARY;
|
||||||
|
haveSpecifiedType = true;
|
||||||
}
|
}
|
||||||
else if(libType == "SHARED")
|
else if(libType == "SHARED")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
type = cmTarget::SHARED_LIBRARY;
|
type = cmTarget::SHARED_LIBRARY;
|
||||||
|
haveSpecifiedType = true;
|
||||||
}
|
}
|
||||||
else if(libType == "MODULE")
|
else if(libType == "MODULE")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
type = cmTarget::MODULE_LIBRARY;
|
type = cmTarget::MODULE_LIBRARY;
|
||||||
|
haveSpecifiedType = true;
|
||||||
}
|
}
|
||||||
else if(*s == "EXCLUDE_FROM_ALL")
|
else if(*s == "EXCLUDE_FROM_ALL")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
excludeFromAll = true;
|
excludeFromAll = true;
|
||||||
}
|
}
|
||||||
else if(*s == "IMPORT")
|
else if(*s == "IMPORTED")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
importTarget = true;
|
importTarget = true;
|
||||||
@ -98,11 +102,46 @@ bool cmAddLibraryCommand
|
|||||||
type = cmTarget::STATIC_LIBRARY;
|
type = cmTarget::STATIC_LIBRARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (importTarget)
|
// The IMPORTED signature requires a type to be specified explicitly.
|
||||||
|
if(importTarget && !haveSpecifiedType)
|
||||||
{
|
{
|
||||||
this->Makefile->AddNewTarget(type, libName.c_str(), true);
|
this->SetError("called with IMPORTED argument but no library type.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for an existing target with this name.
|
||||||
|
cmTarget* existing = this->Makefile->FindTargetToUse(libName.c_str());
|
||||||
|
if(importTarget)
|
||||||
|
{
|
||||||
|
// Make sure the target does not already exist.
|
||||||
|
if(existing)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create imported target \"" << libName
|
||||||
|
<< "\" because another target with the same name already exists.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the imported target.
|
||||||
|
this->Makefile->AddImportedTarget(libName.c_str(), type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make sure the target does not conflict with an imported target.
|
||||||
|
// This should really enforce global name uniqueness for targets
|
||||||
|
// built within the project too, but that may break compatiblity
|
||||||
|
// with projects in which it was accidentally working.
|
||||||
|
if(existing && existing->IsImported())
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create target \"" << libName
|
||||||
|
<< "\" because an imported target with the same name already exists.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s == args.end())
|
if (s == args.end())
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,26 @@ public:
|
|||||||
"to STATIC.\n"
|
"to STATIC.\n"
|
||||||
"If EXCLUDE_FROM_ALL is given the target will not be built by default. "
|
"If EXCLUDE_FROM_ALL is given the target will not be built by default. "
|
||||||
"It will be built only if the user explicitly builds the target or "
|
"It will be built only if the user explicitly builds the target or "
|
||||||
"another target that requires the target depends on it.";
|
"another target that requires the target depends on it."
|
||||||
|
"\n"
|
||||||
|
"The add_library command can also create IMPORTED library "
|
||||||
|
"targets using this signature:\n"
|
||||||
|
" add_library(<name> <SHARED|STATIC|MODULE> IMPORTED)\n"
|
||||||
|
"An IMPORTED library target references a library file located "
|
||||||
|
"outside the project. "
|
||||||
|
"No rules are generated to build it. "
|
||||||
|
"The target name has scope in the directory in which it is created "
|
||||||
|
"and below. "
|
||||||
|
"It may be referenced like any target built within the project. "
|
||||||
|
"IMPORTED libraries are useful for convenient reference from "
|
||||||
|
"commands like target_link_libraries. "
|
||||||
|
"Details about the imported library are specified by setting "
|
||||||
|
"properties whose names begin in \"IMPORTED_\". "
|
||||||
|
"The most important such property is IMPORTED_LOCATION "
|
||||||
|
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
|
||||||
|
"which specifies the location of the main library file on disk. "
|
||||||
|
"See documentation of the IMPORTED_* properties for more information."
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTypeMacro(cmAddLibraryCommand, cmCommand);
|
cmTypeMacro(cmAddLibraryCommand, cmCommand);
|
||||||
|
@ -158,7 +158,7 @@ std::vector<cmComputeLinkDepends::LinkEntry> const&
|
|||||||
cmComputeLinkDepends::Compute()
|
cmComputeLinkDepends::Compute()
|
||||||
{
|
{
|
||||||
// Follow the link dependencies of the target to be linked.
|
// Follow the link dependencies of the target to be linked.
|
||||||
this->AddLinkEntries(-1, this->Target->GetOriginalLinkLibraries());
|
this->AddTargetLinkEntries(-1, this->Target->GetOriginalLinkLibraries());
|
||||||
|
|
||||||
// Complete the breadth-first search of dependencies.
|
// Complete the breadth-first search of dependencies.
|
||||||
while(!this->BFSQueue.empty())
|
while(!this->BFSQueue.empty())
|
||||||
@ -222,8 +222,7 @@ int cmComputeLinkDepends::AddLinkEntry(std::string const& item)
|
|||||||
int index = lei->second;
|
int index = lei->second;
|
||||||
LinkEntry& entry = this->EntryList[index];
|
LinkEntry& entry = this->EntryList[index];
|
||||||
entry.Item = item;
|
entry.Item = item;
|
||||||
entry.Target =
|
entry.Target = this->Makefile->FindTargetToUse(entry.Item.c_str());
|
||||||
this->GlobalGenerator->FindTarget(0, entry.Item.c_str(), false);
|
|
||||||
|
|
||||||
// If the item has dependencies queue it to follow them.
|
// If the item has dependencies queue it to follow them.
|
||||||
if(entry.Target)
|
if(entry.Target)
|
||||||
@ -264,9 +263,16 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
|
|||||||
if(entry.Target)
|
if(entry.Target)
|
||||||
{
|
{
|
||||||
// Follow the target dependencies.
|
// Follow the target dependencies.
|
||||||
this->AddLinkEntries(depender_index,
|
if(entry.Target->IsImported())
|
||||||
|
{
|
||||||
|
this->AddImportedLinkEntries(depender_index, entry.Target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->AddTargetLinkEntries(depender_index,
|
||||||
entry.Target->GetOriginalLinkLibraries());
|
entry.Target->GetOriginalLinkLibraries());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Follow the old-style dependency list.
|
// Follow the old-style dependency list.
|
||||||
@ -274,6 +280,18 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmComputeLinkDepends::AddImportedLinkEntries(int depender_index,
|
||||||
|
cmTarget* target)
|
||||||
|
{
|
||||||
|
if(std::vector<std::string> const* libs =
|
||||||
|
target->GetImportedLinkLibraries(this->Config))
|
||||||
|
{
|
||||||
|
this->AddLinkEntries(depender_index, *libs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
|
void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
|
||||||
const char* value)
|
const char* value)
|
||||||
{
|
{
|
||||||
@ -283,38 +301,48 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
|
|||||||
std::vector<std::string> deplist;
|
std::vector<std::string> deplist;
|
||||||
cmSystemTools::ExpandListArgument(value, deplist);
|
cmSystemTools::ExpandListArgument(value, deplist);
|
||||||
|
|
||||||
// Construct the vector of type/value pairs from the variable.
|
// Compute which library configuration to link.
|
||||||
LinkLibraryVectorType libs;
|
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
|
||||||
cmTarget::LinkLibraryType linkType = cmTarget::GENERAL;
|
if(this->Config && cmSystemTools::UpperCase(this->Config) == "DEBUG")
|
||||||
|
{
|
||||||
|
linkType = cmTarget::DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for entries meant for this configuration.
|
||||||
|
std::vector<std::string> actual_libs;
|
||||||
|
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
|
||||||
for(std::vector<std::string>::const_iterator di = deplist.begin();
|
for(std::vector<std::string>::const_iterator di = deplist.begin();
|
||||||
di != deplist.end(); ++di)
|
di != deplist.end(); ++di)
|
||||||
{
|
{
|
||||||
if(*di == "debug")
|
if(*di == "debug")
|
||||||
{
|
{
|
||||||
linkType = cmTarget::DEBUG;
|
llt = cmTarget::DEBUG;
|
||||||
}
|
}
|
||||||
else if(*di == "optimized")
|
else if(*di == "optimized")
|
||||||
{
|
{
|
||||||
linkType = cmTarget::OPTIMIZED;
|
llt = cmTarget::OPTIMIZED;
|
||||||
}
|
}
|
||||||
else if(*di == "general")
|
else if(*di == "general")
|
||||||
{
|
{
|
||||||
linkType = cmTarget::GENERAL;
|
llt = cmTarget::GENERAL;
|
||||||
}
|
}
|
||||||
else if(!di->empty())
|
else if(!di->empty())
|
||||||
{
|
{
|
||||||
cmTarget::LibraryID lib(*di, linkType);
|
if(llt == cmTarget::GENERAL || llt == linkType)
|
||||||
libs.push_back(lib);
|
{
|
||||||
|
actual_libs.push_back(*di);
|
||||||
|
}
|
||||||
linkType = cmTarget::GENERAL;
|
linkType = cmTarget::GENERAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the entries from this list.
|
// Add the entries from this list.
|
||||||
this->AddLinkEntries(depender_index, libs);
|
this->AddLinkEntries(depender_index, actual_libs);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmComputeLinkDepends::AddLinkEntries(int depender_index,
|
void
|
||||||
|
cmComputeLinkDepends::AddTargetLinkEntries(int depender_index,
|
||||||
LinkLibraryVectorType const& libs)
|
LinkLibraryVectorType const& libs)
|
||||||
{
|
{
|
||||||
// Compute which library configuration to link.
|
// Compute which library configuration to link.
|
||||||
@ -324,23 +352,42 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
|
|||||||
linkType = cmTarget::DEBUG;
|
linkType = cmTarget::DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track inferred dependency sets implied by this list.
|
// Look for entries meant for this configuration.
|
||||||
std::map<int, DependSet> dependSets;
|
std::vector<std::string> actual_libs;
|
||||||
|
|
||||||
// Loop over the libraries linked directly by the target.
|
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
|
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
|
||||||
li != libs.end(); ++li)
|
li != libs.end(); ++li)
|
||||||
{
|
{
|
||||||
// Skip entries that will resolve to the target getting linked.
|
if(li->second == cmTarget::GENERAL || li->second == linkType)
|
||||||
// Skip libraries not meant for the current configuration.
|
{
|
||||||
if(li->first == this->Target->GetName() || li->first.empty() ||
|
actual_libs.push_back(li->first);
|
||||||
!(li->second == cmTarget::GENERAL || li->second == linkType))
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add these entries.
|
||||||
|
this->AddLinkEntries(depender_index, actual_libs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmComputeLinkDepends::AddLinkEntries(int depender_index,
|
||||||
|
std::vector<std::string> const& libs)
|
||||||
|
{
|
||||||
|
// Track inferred dependency sets implied by this list.
|
||||||
|
std::map<int, DependSet> dependSets;
|
||||||
|
|
||||||
|
// Loop over the libraries linked directly by the depender.
|
||||||
|
for(std::vector<std::string>::const_iterator li = libs.begin();
|
||||||
|
li != libs.end(); ++li)
|
||||||
|
{
|
||||||
|
// Skip entries that will resolve to the target getting linked or
|
||||||
|
// are empty.
|
||||||
|
if(*li == this->Target->GetName() || li->empty())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a link entry for this item.
|
// Add a link entry for this item.
|
||||||
int dependee_index = this->AddLinkEntry(li->first);
|
int dependee_index = this->AddLinkEntry(*li);
|
||||||
|
|
||||||
// The depender must come before the dependee.
|
// The depender must come before the dependee.
|
||||||
if(depender_index >= 0)
|
if(depender_index >= 0)
|
||||||
|
@ -66,9 +66,12 @@ private:
|
|||||||
typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
|
typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
|
||||||
|
|
||||||
int AddLinkEntry(std::string const& item);
|
int AddLinkEntry(std::string const& item);
|
||||||
|
void AddImportedLinkEntries(int depender_index, cmTarget* target);
|
||||||
void AddVarLinkEntries(int depender_index, const char* value);
|
void AddVarLinkEntries(int depender_index, const char* value);
|
||||||
void AddLinkEntries(int depender_index,
|
void AddTargetLinkEntries(int depender_index,
|
||||||
LinkLibraryVectorType const& libs);
|
LinkLibraryVectorType const& libs);
|
||||||
|
void AddLinkEntries(int depender_index,
|
||||||
|
std::vector<std::string> const& libs);
|
||||||
|
|
||||||
// One entry for each unique item.
|
// One entry for each unique item.
|
||||||
std::vector<LinkEntry> EntryList;
|
std::vector<LinkEntry> EntryList;
|
||||||
|
@ -301,11 +301,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
|
|||||||
{
|
{
|
||||||
// Compute the proper name to use to link this library.
|
// Compute the proper name to use to link this library.
|
||||||
const char* config = this->Config;
|
const char* config = this->Config;
|
||||||
bool implib = this->UseImportLibrary;
|
bool impexe = (tgt && tgt->IsExecutableWithExports());
|
||||||
bool impexe = (tgt &&
|
if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
|
||||||
tgt->GetType() == cmTarget::EXECUTABLE &&
|
|
||||||
tgt->GetPropertyAsBool("ENABLE_EXPORTS"));
|
|
||||||
if(impexe && !implib && !this->LoaderFlag)
|
|
||||||
{
|
{
|
||||||
// Skip linking to executables on platforms with no import
|
// Skip linking to executables on platforms with no import
|
||||||
// libraries or loader flags.
|
// libraries or loader flags.
|
||||||
@ -325,13 +322,18 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
|
|||||||
// platform. Add it now.
|
// platform. Add it now.
|
||||||
std::string linkItem;
|
std::string linkItem;
|
||||||
linkItem = this->LoaderFlag;
|
linkItem = this->LoaderFlag;
|
||||||
std::string exe = tgt->GetFullPath(config, implib);
|
std::string exe = tgt->GetFullPath(config, this->UseImportLibrary);
|
||||||
linkItem += exe;
|
linkItem += exe;
|
||||||
this->Items.push_back(Item(linkItem, true));
|
this->Items.push_back(Item(linkItem, true));
|
||||||
this->Depends.push_back(exe);
|
this->Depends.push_back(exe);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Decide whether to use an import library.
|
||||||
|
bool implib =
|
||||||
|
(this->UseImportLibrary &&
|
||||||
|
(impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
|
||||||
|
|
||||||
// Pass the full path to the target file.
|
// Pass the full path to the target file.
|
||||||
std::string lib = tgt->GetFullPath(config, implib);
|
std::string lib = tgt->GetFullPath(config, implib);
|
||||||
this->Depends.push_back(lib);
|
this->Depends.push_back(lib);
|
||||||
@ -950,18 +952,8 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
|
|||||||
|
|
||||||
// Try to get the soname of the library. Only files with this name
|
// Try to get the soname of the library. Only files with this name
|
||||||
// could possibly conflict.
|
// could possibly conflict.
|
||||||
std::string soName;
|
std::string soName = target->GetSOName(this->Config);
|
||||||
const char* soname = 0;
|
const char* soname = soName.empty()? 0 : soName.c_str();
|
||||||
if(!target->IsImported())
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::string realName;
|
|
||||||
std::string impName;
|
|
||||||
std::string pdbName;
|
|
||||||
target->GetLibraryNames(name, soName, realName, impName, pdbName,
|
|
||||||
this->Config);
|
|
||||||
soname = soName.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the library runtime entry.
|
// Add the library runtime entry.
|
||||||
this->AddLibraryRuntimeInfo(fullPath, soname);
|
this->AddLibraryRuntimeInfo(fullPath, soname);
|
||||||
|
117
Source/cmExportBuildFileGenerator.cxx
Normal file
117
Source/cmExportBuildFileGenerator.cxx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#include "cmExportBuildFileGenerator.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
|
{
|
||||||
|
// Create all the imported targets.
|
||||||
|
for(std::vector<cmTarget*>::const_iterator
|
||||||
|
tei = this->Exports->begin();
|
||||||
|
tei != this->Exports->end(); ++tei)
|
||||||
|
{
|
||||||
|
cmTarget* te = *tei;
|
||||||
|
this->ExportedTargets.insert(te);
|
||||||
|
this->GenerateImportTargetCode(os, te);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate import file content for each configuration.
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
ci = this->Configurations.begin();
|
||||||
|
ci != this->Configurations.end(); ++ci)
|
||||||
|
{
|
||||||
|
this->GenerateImportConfig(os, ci->c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportBuildFileGenerator
|
||||||
|
::GenerateImportTargetsConfig(std::ostream& os,
|
||||||
|
const char* config, std::string const& suffix)
|
||||||
|
{
|
||||||
|
for(std::vector<cmTarget*>::const_iterator
|
||||||
|
tei = this->Exports->begin();
|
||||||
|
tei != this->Exports->end(); ++tei)
|
||||||
|
{
|
||||||
|
// Collect import properties for this target.
|
||||||
|
cmTarget* target = *tei;
|
||||||
|
ImportPropertyMap properties;
|
||||||
|
this->SetImportLocationProperty(config, suffix, target, properties);
|
||||||
|
if(!properties.empty())
|
||||||
|
{
|
||||||
|
// Get the rest of the target details.
|
||||||
|
this->SetImportDetailProperties(config, suffix,
|
||||||
|
target, properties);
|
||||||
|
|
||||||
|
// TOOD: PUBLIC_HEADER_LOCATION
|
||||||
|
// this->GenerateImportProperty(config, te->HeaderGenerator,
|
||||||
|
// properties);
|
||||||
|
|
||||||
|
// Generate code in the export file.
|
||||||
|
this->GenerateImportPropertyCode(os, config, target, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportBuildFileGenerator
|
||||||
|
::SetImportLocationProperty(const char* config, std::string const& suffix,
|
||||||
|
cmTarget* target, ImportPropertyMap& properties)
|
||||||
|
{
|
||||||
|
// Get the makefile in which to lookup target information.
|
||||||
|
cmMakefile* mf = target->GetMakefile();
|
||||||
|
|
||||||
|
// Add the main target file.
|
||||||
|
{
|
||||||
|
std::string prop = "IMPORTED_LOCATION";
|
||||||
|
prop += suffix;
|
||||||
|
std::string value = target->GetFullPath(config, false);
|
||||||
|
properties[prop] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether this is a DLL platform.
|
||||||
|
bool dll_platform =
|
||||||
|
(mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
|
||||||
|
|
||||||
|
// Add the import library for windows DLLs.
|
||||||
|
if(dll_platform &&
|
||||||
|
(target->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
target->IsExecutableWithExports()) &&
|
||||||
|
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
|
||||||
|
{
|
||||||
|
std::string prop = "IMPORTED_IMPLIB";
|
||||||
|
prop += suffix;
|
||||||
|
std::string value = target->GetFullPath(config, true);
|
||||||
|
properties[prop] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportBuildFileGenerator
|
||||||
|
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "WARNING: EXPORT(...) includes target " << target->GetName()
|
||||||
|
<< " which links to target \"" << dep
|
||||||
|
<< "\" that is not in the export set.";
|
||||||
|
cmSystemTools::Message(e.str().c_str());
|
||||||
|
}
|
55
Source/cmExportBuildFileGenerator.h
Normal file
55
Source/cmExportBuildFileGenerator.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmExportBuildFileGenerator_h
|
||||||
|
#define cmExportBuildFileGenerator_h
|
||||||
|
|
||||||
|
#include "cmExportFileGenerator.h"
|
||||||
|
|
||||||
|
/** \class cmExportBuildFileGenerator
|
||||||
|
* \brief Generate a file exporting targets from a build tree.
|
||||||
|
*
|
||||||
|
* cmExportBuildFileGenerator generates a file exporting targets from
|
||||||
|
* a build tree. A single file exports information for all
|
||||||
|
* configurations built.
|
||||||
|
*
|
||||||
|
* This is used to implement the EXPORT() command.
|
||||||
|
*/
|
||||||
|
class cmExportBuildFileGenerator: public cmExportFileGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Set the list of targets to export. */
|
||||||
|
void SetExports(std::vector<cmTarget*> const* exports)
|
||||||
|
{ this->Exports = exports; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Implement virtual methods from the superclass.
|
||||||
|
virtual bool GenerateMainFile(std::ostream& os);
|
||||||
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
|
const char* config,
|
||||||
|
std::string const& suffix);
|
||||||
|
virtual void ComplainAboutMissingTarget(cmTarget* target, const char* dep);
|
||||||
|
|
||||||
|
/** Fill in properties indicating built file locations. */
|
||||||
|
void SetImportLocationProperty(const char* config,
|
||||||
|
std::string const& suffix,
|
||||||
|
cmTarget* target,
|
||||||
|
ImportPropertyMap& properties);
|
||||||
|
|
||||||
|
std::vector<cmTarget*> const* Exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -20,14 +20,13 @@
|
|||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
#include <cmsys/auto_ptr.hxx>
|
#include "cmExportBuildFileGenerator.h"
|
||||||
|
|
||||||
cmExportCommand::cmExportCommand()
|
cmExportCommand::cmExportCommand()
|
||||||
:cmCommand()
|
:cmCommand()
|
||||||
,ArgumentGroup()
|
,ArgumentGroup()
|
||||||
,Targets(&Helper, "TARGETS")
|
,Targets(&Helper, "TARGETS")
|
||||||
,Append(&Helper, "APPEND", &ArgumentGroup)
|
,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
|
||||||
,Prefix(&Helper, "PREFIX", &ArgumentGroup)
|
|
||||||
,Filename(&Helper, "FILE", &ArgumentGroup)
|
,Filename(&Helper, "FILE", &ArgumentGroup)
|
||||||
{
|
{
|
||||||
// at first TARGETS
|
// at first TARGETS
|
||||||
@ -53,150 +52,130 @@ bool cmExportCommand
|
|||||||
if (!unknownArgs.empty())
|
if (!unknownArgs.empty())
|
||||||
{
|
{
|
||||||
this->SetError("Unknown arguments.");
|
this->SetError("Unknown arguments.");
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->Targets.WasFound() == false)
|
if (this->Targets.WasFound() == false)
|
||||||
{
|
{
|
||||||
this->SetError("TARGETS option missing.");
|
this->SetError("TARGETS option missing.");
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!this->Filename.WasFound())
|
||||||
if ( !this->Makefile->CanIWriteThisFile(this->Filename.GetString().c_str()) )
|
|
||||||
{
|
{
|
||||||
std::string e = "attempted to write a file: " + this->Filename.GetString()
|
this->SetError("FILE <filename> option missing.");
|
||||||
+ " into a source directory.";
|
|
||||||
this->SetError(e.c_str());
|
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((this->Targets.GetVector().empty())||(this->Filename.GetString().empty()))
|
// Make sure the file has a .cmake extension.
|
||||||
|
if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
|
||||||
|
!= ".cmake")
|
||||||
{
|
{
|
||||||
return true;
|
cmOStringStream e;
|
||||||
|
e << "FILE option given filename \"" << this->Filename.GetString()
|
||||||
|
<< "\" which does not have an extension of \".cmake\".\n";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use copy-if-different if not appending.
|
// Get the file to write.
|
||||||
cmsys::auto_ptr<std::ofstream> foutPtr;
|
std::string fname = this->Filename.GetString();
|
||||||
if(this->Append.IsEnabled())
|
if(cmSystemTools::FileIsFullPath(fname.c_str()))
|
||||||
{
|
{
|
||||||
cmsys::auto_ptr<std::ofstream> ap(
|
if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
|
||||||
new std::ofstream(this->Filename.GetString().c_str(), std::ios::app));
|
{
|
||||||
foutPtr = ap;
|
cmOStringStream e;
|
||||||
|
e << "FILE option given filename \"" << fname
|
||||||
|
<< "\" which is in the source tree.\n";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmsys::auto_ptr<cmGeneratedFileStream> ap(
|
// Interpret relative paths with respect to the current build dir.
|
||||||
new cmGeneratedFileStream(this->Filename.GetString().c_str(), true));
|
fname = this->Makefile->GetCurrentOutputDirectory();
|
||||||
ap->SetCopyIfDifferent(true);
|
fname += "/";
|
||||||
foutPtr = ap;
|
fname += this->Filename.GetString();
|
||||||
}
|
}
|
||||||
std::ostream& fout = *foutPtr.get();
|
|
||||||
|
|
||||||
if (!fout)
|
// If no targets are to be exported we are done.
|
||||||
|
if(this->Targets.GetVector().empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Error Writing ", this->Filename.GetString().c_str());
|
|
||||||
cmSystemTools::ReportLastSystemError("");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the following code may move into an "export generator"
|
// Collect the targets to be exported.
|
||||||
// Compute the set of configurations.
|
std::vector<cmTarget*> targets;
|
||||||
std::vector<std::string> configurationTypes;
|
|
||||||
if(const char* types =
|
|
||||||
this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
|
|
||||||
{
|
|
||||||
cmSystemTools::ExpandListArgument(types, configurationTypes);
|
|
||||||
}
|
|
||||||
if(configurationTypes.empty())
|
|
||||||
{
|
|
||||||
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
|
|
||||||
if (config!=0)
|
|
||||||
{
|
|
||||||
configurationTypes.push_back(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
currentTarget = this->Targets.GetVector().begin();
|
currentTarget = this->Targets.GetVector().begin();
|
||||||
currentTarget != this->Targets.GetVector().end();
|
currentTarget != this->Targets.GetVector().end();
|
||||||
++currentTarget)
|
++currentTarget)
|
||||||
{
|
{
|
||||||
cmTarget* target = this->Makefile->GetLocalGenerator()->
|
if(cmTarget* target =
|
||||||
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str(), true);
|
this->Makefile->GetLocalGenerator()->
|
||||||
if (target == 0)
|
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
|
||||||
{
|
{
|
||||||
std::string e = "detected unknown target: " + *currentTarget;
|
if((target->GetType() == cmTarget::EXECUTABLE) ||
|
||||||
this->SetError(e.c_str());
|
(target->GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
(target->GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||||
|
(target->GetType() == cmTarget::MODULE_LIBRARY))
|
||||||
|
{
|
||||||
|
targets.push_back(target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "given target \"" << *currentTarget
|
||||||
|
<< "\" which is not an executable or library.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "given target \"" << *currentTarget
|
||||||
|
<< "\" which is not built by this project.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup export file generation.
|
||||||
|
cmExportBuildFileGenerator ebfg;
|
||||||
|
ebfg.SetExportFile(fname.c_str());
|
||||||
|
ebfg.SetNamespace(this->Namespace.GetCString());
|
||||||
|
ebfg.SetExports(&targets);
|
||||||
|
|
||||||
|
// Compute the set of configurations exported.
|
||||||
|
if(const char* types =
|
||||||
|
this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> configurationTypes;
|
||||||
|
cmSystemTools::ExpandListArgument(types, configurationTypes);
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
currentTarget = this->Targets.GetVector().begin();
|
ci = configurationTypes.begin();
|
||||||
currentTarget != this->Targets.GetVector().end();
|
ci != configurationTypes.end(); ++ci)
|
||||||
++currentTarget)
|
|
||||||
{
|
{
|
||||||
// Look for a CMake target with the given name, which is an executable
|
ebfg.AddConfiguration(ci->c_str());
|
||||||
// and which can be run
|
}
|
||||||
cmTarget* target = this->Makefile->GetLocalGenerator()->
|
}
|
||||||
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str(), true);
|
else if(const char* config =
|
||||||
if ((target != 0)
|
this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
|
||||||
&& ((target->GetType() == cmTarget::EXECUTABLE)
|
|
||||||
|| (target->GetType() == cmTarget::STATIC_LIBRARY)
|
|
||||||
|| (target->GetType() == cmTarget::SHARED_LIBRARY)
|
|
||||||
|| (target->GetType() == cmTarget::MODULE_LIBRARY)))
|
|
||||||
{
|
{
|
||||||
switch (target->GetType())
|
ebfg.AddConfiguration(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case cmTarget::EXECUTABLE:
|
ebfg.AddConfiguration("");
|
||||||
fout << "ADD_EXECUTABLE("
|
|
||||||
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
|
||||||
<< " IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::STATIC_LIBRARY:
|
|
||||||
fout << "ADD_LIBRARY("
|
|
||||||
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
|
||||||
<< " STATIC IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::SHARED_LIBRARY:
|
|
||||||
fout << "ADD_LIBRARY("
|
|
||||||
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
|
||||||
<< " SHARED IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::MODULE_LIBRARY:
|
|
||||||
fout << "ADD_LIBRARY("
|
|
||||||
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
|
||||||
<< " MODULE IMPORT )\n";
|
|
||||||
break;
|
|
||||||
default: // should never happen
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fout << "SET_TARGET_PROPERTIES(" << this->Prefix.GetString().c_str()
|
// Generate the import file.
|
||||||
<< currentTarget->c_str() << " PROPERTIES \n"
|
if(!ebfg.GenerateImportFile())
|
||||||
<<" LOCATION \""<< target->GetLocation(0)<<"\"\n";
|
|
||||||
for(std::vector<std::string>::const_iterator
|
|
||||||
currentConfig = configurationTypes.begin();
|
|
||||||
currentConfig != configurationTypes.end();
|
|
||||||
++currentConfig)
|
|
||||||
{
|
{
|
||||||
if (!currentConfig->empty())
|
this->SetError("could not write export file.");
|
||||||
{
|
return false;
|
||||||
const char* loc = target->GetLocation(currentConfig->c_str());
|
|
||||||
if (loc && *loc)
|
|
||||||
{
|
|
||||||
fout << " " << currentConfig->c_str()
|
|
||||||
<< "_LOCATION \"" << loc << "\"\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fout << " )\n\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
virtual const char* GetTerseDocumentation()
|
virtual const char* GetTerseDocumentation()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
"Write out the dependency information for all targets of a project.";
|
"Export targets from the build tree for use by outside projects.";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,15 +64,23 @@ public:
|
|||||||
virtual const char* GetFullDocumentation()
|
virtual const char* GetFullDocumentation()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
" export(TARGETS tgt1 ... tgtN [PREFIX <prefix>] FILE <filename> "
|
" export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]\n"
|
||||||
"[APPEND])\n"
|
" FILE <filename>)\n"
|
||||||
"Create a file that can be included into a CMake listfile with the "
|
"Create a file <filename> that may be included by outside projects to "
|
||||||
"INCLUDE command. The file will contain a number of SET commands "
|
"import targets from the current project's build tree. "
|
||||||
"that will set all the variables needed for library dependency "
|
"This is useful during cross-compiling to build utility executables "
|
||||||
"information. This should be the last command in the top level "
|
"that can run on the host platform in one project and then import "
|
||||||
"CMakeLists.txt file of the project. If the APPEND option is "
|
"them into another project being compiled for the target platform. "
|
||||||
"specified, the SET commands will be appended to the given file "
|
"If the NAMESPACE option is given the <namespace> string will be "
|
||||||
"instead of replacing it.";
|
"prepended to all target names written to the file. "
|
||||||
|
"If a library target is included in the export but "
|
||||||
|
"a target to which it links is not included the behavior is "
|
||||||
|
"unspecified."
|
||||||
|
"\n"
|
||||||
|
"The file created by this command is specific to the build tree and "
|
||||||
|
"should never be installed. "
|
||||||
|
"See the install(EXPORT) command to export targets from an "
|
||||||
|
"installation tree.";
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTypeMacro(cmExportCommand, cmCommand);
|
cmTypeMacro(cmExportCommand, cmCommand);
|
||||||
@ -80,8 +88,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
cmCommandArgumentGroup ArgumentGroup;
|
cmCommandArgumentGroup ArgumentGroup;
|
||||||
cmCAStringVector Targets;
|
cmCAStringVector Targets;
|
||||||
cmCAEnabler Append;
|
cmCAString Namespace;
|
||||||
cmCAString Prefix;
|
|
||||||
cmCAString Filename;
|
cmCAString Filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
281
Source/cmExportFileGenerator.cxx
Normal file
281
Source/cmExportFileGenerator.cxx
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#include "cmExportFileGenerator.h"
|
||||||
|
|
||||||
|
#include "cmGeneratedFileStream.h"
|
||||||
|
#include "cmMakefile.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
|
#include "cmTarget.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::AddConfiguration(const char* config)
|
||||||
|
{
|
||||||
|
this->Configurations.push_back(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::SetExportFile(const char* mainFile)
|
||||||
|
{
|
||||||
|
this->MainImportFile = mainFile;
|
||||||
|
this->FileDir =
|
||||||
|
cmSystemTools::GetFilenamePath(this->MainImportFile);
|
||||||
|
this->FileBase =
|
||||||
|
cmSystemTools::GetFilenameWithoutLastExtension(this->MainImportFile);
|
||||||
|
this->FileExt =
|
||||||
|
cmSystemTools::GetFilenameLastExtension(this->MainImportFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmExportFileGenerator::GenerateImportFile()
|
||||||
|
{
|
||||||
|
// Open the output file to generate it.
|
||||||
|
cmGeneratedFileStream exportFileStream(this->MainImportFile.c_str(), true);
|
||||||
|
if(!exportFileStream)
|
||||||
|
{
|
||||||
|
std::string se = cmSystemTools::GetLastSystemError();
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot write to file \"" << this->MainImportFile
|
||||||
|
<< "\": " << se;
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::ostream& os = exportFileStream;
|
||||||
|
|
||||||
|
// Start with the import file header.
|
||||||
|
this->GenerateImportHeaderCode(os);
|
||||||
|
|
||||||
|
// Create all the imported targets.
|
||||||
|
bool result = this->GenerateMainFile(os);
|
||||||
|
|
||||||
|
// End with the import file footer.
|
||||||
|
this->GenerateImportFooterCode(os);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
||||||
|
const char* config)
|
||||||
|
{
|
||||||
|
// Construct the property configuration suffix.
|
||||||
|
std::string suffix = "_";
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
suffix += cmSystemTools::UpperCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
suffix += "NOCONFIG";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the per-config target information.
|
||||||
|
this->GenerateImportTargetsConfig(os, config, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportFileGenerator
|
||||||
|
::SetImportDetailProperties(const char* config, std::string const& suffix,
|
||||||
|
cmTarget* target, ImportPropertyMap& properties)
|
||||||
|
{
|
||||||
|
// Get the makefile in which to lookup target information.
|
||||||
|
cmMakefile* mf = target->GetMakefile();
|
||||||
|
|
||||||
|
// Add the soname for unix shared libraries.
|
||||||
|
if(target->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
target->GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
|
{
|
||||||
|
// Check whether this is a DLL platform.
|
||||||
|
bool dll_platform =
|
||||||
|
(mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
|
||||||
|
if(!dll_platform)
|
||||||
|
{
|
||||||
|
std::string soname = target->GetSOName(config);
|
||||||
|
std::string prop = "IMPORTED_SONAME";
|
||||||
|
prop += suffix;
|
||||||
|
properties[prop] = soname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the transitive link dependencies for this configuration.
|
||||||
|
{
|
||||||
|
// Compute which library configuration to link.
|
||||||
|
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
|
||||||
|
if(config && cmSystemTools::UpperCase(config) == "DEBUG")
|
||||||
|
{
|
||||||
|
linkType = cmTarget::DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the property value.
|
||||||
|
cmTarget::LinkLibraryVectorType const& libs =
|
||||||
|
target->GetOriginalLinkLibraries();
|
||||||
|
std::string link_libs;
|
||||||
|
const char* sep = "";
|
||||||
|
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
|
||||||
|
li != libs.end(); ++li)
|
||||||
|
{
|
||||||
|
// Skip entries that will resolve to the target itself, are empty,
|
||||||
|
// or are not meant for this configuration.
|
||||||
|
if(li->first == target->GetName() || li->first.empty() ||
|
||||||
|
!(li->second == cmTarget::GENERAL || li->second == linkType))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separate this from the previous entry.
|
||||||
|
link_libs += sep;
|
||||||
|
sep = ";";
|
||||||
|
|
||||||
|
// Append this entry.
|
||||||
|
if(cmTarget* tgt = mf->FindTargetToUse(li->first.c_str()))
|
||||||
|
{
|
||||||
|
// This is a target. Make sure it is included in the export.
|
||||||
|
if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||||
|
{
|
||||||
|
// The target is in the export. Append it with the export
|
||||||
|
// namespace.
|
||||||
|
link_libs += this->Namespace;
|
||||||
|
link_libs += li->first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The target is not in the export. This is probably
|
||||||
|
// user-error. Warn but add it anyway.
|
||||||
|
this->ComplainAboutMissingTarget(target, li->first.c_str());
|
||||||
|
link_libs += li->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Append the raw name.
|
||||||
|
link_libs += li->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the property.
|
||||||
|
std::string prop = "IMPORTED_LINK_LIBRARIES";
|
||||||
|
prop += suffix;
|
||||||
|
properties[prop] = link_libs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
|
||||||
|
const char* config)
|
||||||
|
{
|
||||||
|
os << "#----------------------------------------------------------------\n"
|
||||||
|
<< "# Generated CMake target import file";
|
||||||
|
if(config)
|
||||||
|
{
|
||||||
|
os << " for configuration \"" << config << "\".\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << ".\n";
|
||||||
|
}
|
||||||
|
os << "#----------------------------------------------------------------\n"
|
||||||
|
<< "\n";
|
||||||
|
this->GenerateImportVersionCode(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
|
||||||
|
{
|
||||||
|
os << "# Commands beyond this point should not need to know the version.\n"
|
||||||
|
<< "SET(CMAKE_IMPORT_FILE_VERSION)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
|
||||||
|
{
|
||||||
|
// Store an import file format version. This will let us change the
|
||||||
|
// format later while still allowing old import files to work.
|
||||||
|
os << "# Commands may need to know the format version.\n"
|
||||||
|
<< "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportFileGenerator
|
||||||
|
::GenerateImportTargetCode(std::ostream& os, cmTarget* target)
|
||||||
|
{
|
||||||
|
// Construct the imported target name.
|
||||||
|
std::string targetName = this->Namespace;
|
||||||
|
targetName += target->GetName();
|
||||||
|
|
||||||
|
// Create the imported target.
|
||||||
|
os << "# Create imported target " << targetName << "\n";
|
||||||
|
switch(target->GetType())
|
||||||
|
{
|
||||||
|
case cmTarget::EXECUTABLE:
|
||||||
|
os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
|
||||||
|
break;
|
||||||
|
case cmTarget::STATIC_LIBRARY:
|
||||||
|
os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
|
||||||
|
break;
|
||||||
|
case cmTarget::SHARED_LIBRARY:
|
||||||
|
os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
|
||||||
|
break;
|
||||||
|
case cmTarget::MODULE_LIBRARY:
|
||||||
|
os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
|
||||||
|
break;
|
||||||
|
default: // should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(target->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
|
<< " PROPERTY IMPORTED_ENABLE_EXPORTS 1)\n";
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportFileGenerator
|
||||||
|
::GenerateImportPropertyCode(std::ostream& os, const char* config,
|
||||||
|
cmTarget* target,
|
||||||
|
ImportPropertyMap const& properties)
|
||||||
|
{
|
||||||
|
// Construct the imported target name.
|
||||||
|
std::string targetName = this->Namespace;
|
||||||
|
targetName += target->GetName();
|
||||||
|
|
||||||
|
// Set the import properties.
|
||||||
|
os << "# Import target \"" << targetName << "\" for configuration \""
|
||||||
|
<< config << "\"\n";
|
||||||
|
os << "SET_PROPERTY(TARGET " << targetName
|
||||||
|
<< " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
os << cmSystemTools::UpperCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "NOCONFIG";
|
||||||
|
}
|
||||||
|
os << ")\n";
|
||||||
|
os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
|
||||||
|
for(ImportPropertyMap::const_iterator pi = properties.begin();
|
||||||
|
pi != properties.end(); ++pi)
|
||||||
|
{
|
||||||
|
os << " " << pi->first << " \"" << pi->second << "\"\n";
|
||||||
|
}
|
||||||
|
os << " )\n"
|
||||||
|
<< "\n";
|
||||||
|
}
|
96
Source/cmExportFileGenerator.h
Normal file
96
Source/cmExportFileGenerator.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmExportFileGenerator_h
|
||||||
|
#define cmExportFileGenerator_h
|
||||||
|
|
||||||
|
#include "cmCommand.h"
|
||||||
|
|
||||||
|
/** \class cmExportFileGenerator
|
||||||
|
* \brief Generate a file exporting targets from a build or install tree.
|
||||||
|
*
|
||||||
|
* cmExportFileGenerator is the superclass for
|
||||||
|
* cmExportBuildFileGenerator and cmExportInstallFileGenerator. It
|
||||||
|
* contains common code generation routines for the two kinds of
|
||||||
|
* export implementations.
|
||||||
|
*/
|
||||||
|
class cmExportFileGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Set the full path to the export file to generate. */
|
||||||
|
void SetExportFile(const char* mainFile);
|
||||||
|
|
||||||
|
/** Set the namespace in which to place exported target names. */
|
||||||
|
void SetNamespace(const char* ns) { this->Namespace = ns; }
|
||||||
|
|
||||||
|
/** Add a configuration to be exported. */
|
||||||
|
void AddConfiguration(const char* config);
|
||||||
|
|
||||||
|
/** Actually generate the export file. Returns whether there was an
|
||||||
|
error. */
|
||||||
|
bool GenerateImportFile();
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef std::map<cmStdString, cmStdString> ImportPropertyMap;
|
||||||
|
|
||||||
|
// Generate per-configuration target information to the given output
|
||||||
|
// stream.
|
||||||
|
void GenerateImportConfig(std::ostream& os, const char* config);
|
||||||
|
|
||||||
|
// Methods to implement export file code generation.
|
||||||
|
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
|
||||||
|
void GenerateImportFooterCode(std::ostream& os);
|
||||||
|
void GenerateImportVersionCode(std::ostream& os);
|
||||||
|
void GenerateImportTargetCode(std::ostream& os, cmTarget* target);
|
||||||
|
void GenerateImportPropertyCode(std::ostream& os, const char* config,
|
||||||
|
cmTarget* target,
|
||||||
|
ImportPropertyMap const& properties);
|
||||||
|
|
||||||
|
// Collect properties with detailed information about targets beyond
|
||||||
|
// their location on disk.
|
||||||
|
void SetImportDetailProperties(const char* config,
|
||||||
|
std::string const& suffix, cmTarget* target,
|
||||||
|
ImportPropertyMap& properties);
|
||||||
|
|
||||||
|
/** Each subclass knows how to generate its kind of export file. */
|
||||||
|
virtual bool GenerateMainFile(std::ostream& os) = 0;
|
||||||
|
|
||||||
|
/** Each subclass knows where the target files are located. */
|
||||||
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
|
const char* config,
|
||||||
|
std::string const& suffix) = 0;
|
||||||
|
|
||||||
|
/** Each subclass knows how to complain about a target that is
|
||||||
|
missing from an export set. */
|
||||||
|
virtual void ComplainAboutMissingTarget(cmTarget*, const char* dep) = 0;
|
||||||
|
|
||||||
|
// The namespace in which the exports are placed in the generated file.
|
||||||
|
std::string Namespace;
|
||||||
|
|
||||||
|
// The set of configurations to export.
|
||||||
|
std::vector<std::string> Configurations;
|
||||||
|
|
||||||
|
// The file to generate.
|
||||||
|
std::string MainImportFile;
|
||||||
|
std::string FileDir;
|
||||||
|
std::string FileBase;
|
||||||
|
std::string FileExt;
|
||||||
|
|
||||||
|
// The set of targets included in the export.
|
||||||
|
std::set<cmTarget*> ExportedTargets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
259
Source/cmExportInstallFileGenerator.cxx
Normal file
259
Source/cmExportInstallFileGenerator.cxx
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#include "cmExportInstallFileGenerator.h"
|
||||||
|
|
||||||
|
#include "cmGeneratedFileStream.h"
|
||||||
|
#include "cmInstallExportGenerator.h"
|
||||||
|
#include "cmInstallTargetGenerator.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmExportInstallFileGenerator
|
||||||
|
::cmExportInstallFileGenerator(cmInstallExportGenerator* iegen):
|
||||||
|
InstallExportGenerator(iegen)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
|
{
|
||||||
|
// Create all the imported targets.
|
||||||
|
for(std::vector<cmTargetExport*>::const_iterator
|
||||||
|
tei = this->ExportSet->begin();
|
||||||
|
tei != this->ExportSet->end(); ++tei)
|
||||||
|
{
|
||||||
|
cmTargetExport* te = *tei;
|
||||||
|
this->ExportedTargets.insert(te->Target);
|
||||||
|
this->GenerateImportTargetCode(os, te->Target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now load per-configuration properties for them.
|
||||||
|
os << "# Load information for each installed configuration.\n"
|
||||||
|
<< "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||||
|
<< "FILE(GLOB CONFIG_FILES \"${_DIR}/"
|
||||||
|
<< this->FileBase << "-*" << this->FileExt << "\")\n"
|
||||||
|
<< "FOREACH(f ${CONFIG_FILES})\n"
|
||||||
|
<< " INCLUDE(${f})\n"
|
||||||
|
<< "ENDFOREACH(f)\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
// Generate an import file for each configuration.
|
||||||
|
bool result = true;
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
ci = this->Configurations.begin();
|
||||||
|
ci != this->Configurations.end(); ++ci)
|
||||||
|
{
|
||||||
|
if(!this->GenerateImportFileConfig(ci->c_str()))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
||||||
|
{
|
||||||
|
// Skip configurations not enabled for this export.
|
||||||
|
if(!this->InstallExportGenerator->InstallsForConfig(config))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the name of the file to generate.
|
||||||
|
std::string fileName = this->FileDir;
|
||||||
|
fileName += "/";
|
||||||
|
fileName += this->FileBase;
|
||||||
|
fileName += "-";
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
fileName += cmSystemTools::LowerCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileName += "noconfig";
|
||||||
|
}
|
||||||
|
fileName += this->FileExt;
|
||||||
|
|
||||||
|
// Open the output file to generate it.
|
||||||
|
cmGeneratedFileStream exportFileStream(fileName.c_str(), true);
|
||||||
|
if(!exportFileStream)
|
||||||
|
{
|
||||||
|
std::string se = cmSystemTools::GetLastSystemError();
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot write to file \"" << fileName.c_str()
|
||||||
|
<< "\": " << se;
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::ostream& os = exportFileStream;
|
||||||
|
|
||||||
|
// Start with the import file header.
|
||||||
|
this->GenerateImportHeaderCode(os, config);
|
||||||
|
|
||||||
|
// Generate the per-config target information.
|
||||||
|
this->GenerateImportConfig(os, config);
|
||||||
|
|
||||||
|
// End with the import file footer.
|
||||||
|
this->GenerateImportFooterCode(os);
|
||||||
|
|
||||||
|
// Record this per-config import file.
|
||||||
|
this->ConfigImportFiles[config] = fileName;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportInstallFileGenerator
|
||||||
|
::GenerateImportTargetsConfig(std::ostream& os,
|
||||||
|
const char* config, std::string const& suffix)
|
||||||
|
{
|
||||||
|
// Add code to compute the installation prefix relative to the
|
||||||
|
// import file location.
|
||||||
|
const char* installDest = this->InstallExportGenerator->GetDestination();
|
||||||
|
if(!cmSystemTools::FileIsFullPath(installDest))
|
||||||
|
{
|
||||||
|
std::string dest = installDest;
|
||||||
|
os << "# Compute the installation prefix relative to this file.\n"
|
||||||
|
<< "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
|
||||||
|
<< "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||||
|
while(!dest.empty())
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
"GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
|
||||||
|
dest = cmSystemTools::GetFilenamePath(dest);
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
|
||||||
|
// Import location properties may reference this variable.
|
||||||
|
this->ImportPrefix = "${_IMPORT_PREFIX}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add each target in the set to the export.
|
||||||
|
for(std::vector<cmTargetExport*>::const_iterator
|
||||||
|
tei = this->ExportSet->begin();
|
||||||
|
tei != this->ExportSet->end(); ++tei)
|
||||||
|
{
|
||||||
|
// Collect import properties for this target.
|
||||||
|
cmTargetExport* te = *tei;
|
||||||
|
ImportPropertyMap properties;
|
||||||
|
this->SetImportLocationProperty(config, suffix,
|
||||||
|
te->ArchiveGenerator, properties);
|
||||||
|
this->SetImportLocationProperty(config, suffix,
|
||||||
|
te->LibraryGenerator, properties);
|
||||||
|
this->SetImportLocationProperty(config, suffix,
|
||||||
|
te->RuntimeGenerator, properties);
|
||||||
|
|
||||||
|
// TODO: Frameworks?
|
||||||
|
// TODO: Bundles?
|
||||||
|
|
||||||
|
// If any file location was set for the target add it to the
|
||||||
|
// import file.
|
||||||
|
if(!properties.empty())
|
||||||
|
{
|
||||||
|
// Get the rest of the target details.
|
||||||
|
this->SetImportDetailProperties(config, suffix,
|
||||||
|
te->Target, properties);
|
||||||
|
|
||||||
|
// TOOD: PUBLIC_HEADER_LOCATION
|
||||||
|
// this->GenerateImportProperty(config, te->HeaderGenerator,
|
||||||
|
// properties);
|
||||||
|
|
||||||
|
// Generate code in the export file.
|
||||||
|
this->GenerateImportPropertyCode(os, config, te->Target, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the import prefix variable.
|
||||||
|
if(!this->ImportPrefix.empty())
|
||||||
|
{
|
||||||
|
os << "# Cleanup temporary variables.\n"
|
||||||
|
<< "SET(_IMPORT_PREFIX)\n"
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportInstallFileGenerator
|
||||||
|
::SetImportLocationProperty(const char* config, std::string const& suffix,
|
||||||
|
cmInstallTargetGenerator* itgen,
|
||||||
|
ImportPropertyMap& properties)
|
||||||
|
{
|
||||||
|
// Skip rules that do not match this configuration.
|
||||||
|
if(!(itgen && itgen->InstallsForConfig(config)))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Construct the property name.
|
||||||
|
std::string prop = (itgen->IsImportLibrary()?
|
||||||
|
"IMPORTED_IMPLIB" : "IMPORTED_LOCATION");
|
||||||
|
prop += suffix;
|
||||||
|
|
||||||
|
// Construct the installed location of the target.
|
||||||
|
std::string dest = itgen->GetDestination();
|
||||||
|
std::string value;
|
||||||
|
if(!cmSystemTools::FileIsFullPath(dest.c_str()))
|
||||||
|
{
|
||||||
|
// The target is installed relative to the installation prefix.
|
||||||
|
if(this->ImportPrefix.empty())
|
||||||
|
{
|
||||||
|
this->ComplainAboutImportPrefix(itgen);
|
||||||
|
}
|
||||||
|
value = this->ImportPrefix;
|
||||||
|
}
|
||||||
|
value += dest;
|
||||||
|
value += "/";
|
||||||
|
|
||||||
|
// Append the installed file name.
|
||||||
|
value += itgen->GetInstallFilename(config);
|
||||||
|
|
||||||
|
// Store the property.
|
||||||
|
properties[prop] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportInstallFileGenerator
|
||||||
|
::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
|
||||||
|
{
|
||||||
|
const char* installDest = this->InstallExportGenerator->GetDestination();
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "INSTALL(EXPORT \"" << this->Name << "\") given absolute "
|
||||||
|
<< "DESTINATION \"" << installDest << "\" but the export "
|
||||||
|
<< "references an installation of target \""
|
||||||
|
<< itgen->GetTarget()->GetName() << "\" which has relative "
|
||||||
|
<< "DESTINATION \"" << itgen->GetDestination() << "\".";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportInstallFileGenerator
|
||||||
|
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "WARNING: INSTALL(EXPORT \"" << this->Name << "\" ...) "
|
||||||
|
<< "includes target " << target->GetName()
|
||||||
|
<< " which links to target \"" << dep
|
||||||
|
<< "\" that is not in the export set.";
|
||||||
|
cmSystemTools::Message(e.str().c_str());
|
||||||
|
}
|
122
Source/cmExportInstallFileGenerator.h
Normal file
122
Source/cmExportInstallFileGenerator.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmExportInstallFileGenerator_h
|
||||||
|
#define cmExportInstallFileGenerator_h
|
||||||
|
|
||||||
|
#include "cmExportFileGenerator.h"
|
||||||
|
|
||||||
|
class cmInstallExportGenerator;
|
||||||
|
class cmInstallFilesGenerator;
|
||||||
|
class cmInstallTargetGenerator;
|
||||||
|
class cmTargetExport;
|
||||||
|
|
||||||
|
/** \class cmExportInstallFileGenerator
|
||||||
|
* \brief Generate a file exporting targets from an install tree.
|
||||||
|
*
|
||||||
|
* cmExportInstallFileGenerator generates files exporting targets from
|
||||||
|
* install an installation tree. The files are placed in a temporary
|
||||||
|
* location for installation by cmInstallExportGenerator. One main
|
||||||
|
* file is generated that creates the imported targets and loads
|
||||||
|
* per-configuration files. Target locations and settings for each
|
||||||
|
* configuration are written to these per-configuration files. After
|
||||||
|
* installation the main file loads the configurations that have been
|
||||||
|
* installed.
|
||||||
|
*
|
||||||
|
* This is used to implement the INSTALL(EXPORT) command.
|
||||||
|
*/
|
||||||
|
class cmExportInstallFileGenerator: public cmExportFileGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Construct with the export installer that will install the
|
||||||
|
files. */
|
||||||
|
cmExportInstallFileGenerator(cmInstallExportGenerator* iegen);
|
||||||
|
|
||||||
|
/** Set the name of the export associated with the files. This is
|
||||||
|
the name given to the install(EXPORT) command mode. */
|
||||||
|
void SetName(const char* name) { this->Name = name; }
|
||||||
|
|
||||||
|
/** Set the set of targets to be exported. These are the targets
|
||||||
|
associated with the export name. */
|
||||||
|
void SetExportSet(std::vector<cmTargetExport*> const* eSet)
|
||||||
|
{ this->ExportSet = eSet; }
|
||||||
|
|
||||||
|
/** Get the per-config file generated for each configuraiton. This
|
||||||
|
maps from the configuration name to the file temporary location
|
||||||
|
for installation. */
|
||||||
|
std::map<cmStdString, cmStdString> const& GetConfigImportFiles()
|
||||||
|
{ return this->ConfigImportFiles; }
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Implement virtual methods from the superclass.
|
||||||
|
virtual bool GenerateMainFile(std::ostream& os);
|
||||||
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
|
const char* config,
|
||||||
|
std::string const& suffix);
|
||||||
|
virtual void ComplainAboutMissingTarget(cmTarget* target, const char* dep);
|
||||||
|
|
||||||
|
/** Generate a per-configuration file for the targets. */
|
||||||
|
bool GenerateImportFileConfig(const char* config);
|
||||||
|
|
||||||
|
/** Fill in properties indicating installed file locations. */
|
||||||
|
void SetImportLocationProperty(const char* config,
|
||||||
|
std::string const& suffix,
|
||||||
|
cmInstallTargetGenerator* itgen,
|
||||||
|
ImportPropertyMap& properties);
|
||||||
|
|
||||||
|
void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
|
||||||
|
|
||||||
|
cmInstallExportGenerator* InstallExportGenerator;
|
||||||
|
std::string Name;
|
||||||
|
std::vector<cmTargetExport*> const* ExportSet;
|
||||||
|
|
||||||
|
std::string ImportPrefix;
|
||||||
|
|
||||||
|
// The import file generated for each configuration.
|
||||||
|
std::map<cmStdString, cmStdString> ConfigImportFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
cmTargetExport is used in cmGlobalGenerator to collect the install
|
||||||
|
generators for targets associated with an export.
|
||||||
|
*/
|
||||||
|
class cmTargetExport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmTargetExport(cmTarget* tgt,
|
||||||
|
cmInstallTargetGenerator* archive,
|
||||||
|
cmInstallTargetGenerator* runtime,
|
||||||
|
cmInstallTargetGenerator* library,
|
||||||
|
cmInstallTargetGenerator* framework,
|
||||||
|
cmInstallTargetGenerator* bundle,
|
||||||
|
cmInstallFilesGenerator* headers
|
||||||
|
) : Target(tgt), ArchiveGenerator(archive),
|
||||||
|
RuntimeGenerator(runtime), LibraryGenerator(library),
|
||||||
|
FrameworkGenerator(framework), BundleGenerator(bundle),
|
||||||
|
HeaderGenerator(headers) {}
|
||||||
|
|
||||||
|
cmTarget* Target;
|
||||||
|
cmInstallTargetGenerator* ArchiveGenerator;
|
||||||
|
cmInstallTargetGenerator* RuntimeGenerator;
|
||||||
|
cmInstallTargetGenerator* LibraryGenerator;
|
||||||
|
cmInstallTargetGenerator* FrameworkGenerator;
|
||||||
|
cmInstallTargetGenerator* BundleGenerator;
|
||||||
|
cmInstallFilesGenerator* HeaderGenerator;
|
||||||
|
private:
|
||||||
|
cmTargetExport();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -260,9 +260,7 @@ bool cmGetPropertyCommand::HandleTargetMode()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cmTarget* target =
|
if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
|
||||||
->FindTarget(0, this->Name.c_str(), true))
|
|
||||||
{
|
{
|
||||||
return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
|
return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,7 @@ bool cmGetTargetPropertyCommand
|
|||||||
std::string var = args[0].c_str();
|
std::string var = args[0].c_str();
|
||||||
const char* targetName = args[1].c_str();
|
const char* targetName = args[1].c_str();
|
||||||
|
|
||||||
cmTarget *tgt = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
|
||||||
->FindTarget(0, targetName, true);
|
|
||||||
if (tgt)
|
|
||||||
{
|
{
|
||||||
cmTarget& target = *tgt;
|
cmTarget& target = *tgt;
|
||||||
const char *prop = target.GetProperty(args[2].c_str());
|
const char *prop = target.GetProperty(args[2].c_str());
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
#include "cmVersion.h"
|
#include "cmVersion.h"
|
||||||
#include "cmInstallExportGenerator.h"
|
#include "cmExportInstallFileGenerator.h"
|
||||||
|
|
||||||
#include <cmsys/Directory.hxx>
|
#include <cmsys/Directory.hxx>
|
||||||
|
|
||||||
@ -693,7 +693,6 @@ void cmGlobalGenerator::Configure()
|
|||||||
this->LocalGenerators.clear();
|
this->LocalGenerators.clear();
|
||||||
this->TargetDependencies.clear();
|
this->TargetDependencies.clear();
|
||||||
this->TotalTargets.clear();
|
this->TotalTargets.clear();
|
||||||
this->ImportedTotalTargets.clear();
|
|
||||||
this->LocalGeneratorToTargetMap.clear();
|
this->LocalGeneratorToTargetMap.clear();
|
||||||
this->ProjectMap.clear();
|
this->ProjectMap.clear();
|
||||||
|
|
||||||
@ -1321,9 +1320,8 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
|
|||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmTarget* cmGlobalGenerator::FindTarget(const char* project,
|
cmTarget*
|
||||||
const char* name,
|
cmGlobalGenerator::FindTarget(const char* project, const char* name)
|
||||||
bool useImportedTargets)
|
|
||||||
{
|
{
|
||||||
// if project specific
|
// if project specific
|
||||||
if(project)
|
if(project)
|
||||||
@ -1331,8 +1329,7 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
|
|||||||
std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
|
std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
|
||||||
for(unsigned int i = 0; i < gens->size(); ++i)
|
for(unsigned int i = 0; i < gens->size(); ++i)
|
||||||
{
|
{
|
||||||
cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
|
cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name);
|
||||||
useImportedTargets);
|
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
@ -1348,16 +1345,6 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
|
|||||||
{
|
{
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( useImportedTargets )
|
|
||||||
{
|
|
||||||
std::map<cmStdString,cmTarget *>::iterator importedTarget =
|
|
||||||
this->ImportedTotalTargets.find ( name );
|
|
||||||
if ( importedTarget != this->ImportedTotalTargets.end() )
|
|
||||||
{
|
|
||||||
return importedTarget->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1370,7 +1357,7 @@ bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cmTarget* tgt = this->FindTarget(0, libname.c_str(), true))
|
if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
|
||||||
{
|
{
|
||||||
if(tgt->GetType() == cmTarget::SHARED_LIBRARY &&
|
if(tgt->GetType() == cmTarget::SHARED_LIBRARY &&
|
||||||
tgt->GetPropertyAsBool("FRAMEWORK"))
|
tgt->GetPropertyAsBool("FRAMEWORK"))
|
||||||
@ -1758,12 +1745,12 @@ cmGlobalGenerator::ConsiderTargetDepends(cmTarget const* depender,
|
|||||||
{
|
{
|
||||||
// Check the target's makefile first.
|
// Check the target's makefile first.
|
||||||
cmTarget const* dependee =
|
cmTarget const* dependee =
|
||||||
depender->GetMakefile()->FindTarget(dependee_name, false);
|
depender->GetMakefile()->FindTarget(dependee_name);
|
||||||
|
|
||||||
// Then search globally.
|
// Then search globally.
|
||||||
if(!dependee)
|
if(!dependee)
|
||||||
{
|
{
|
||||||
dependee = this->FindTarget(0, dependee_name, false);
|
dependee = this->FindTarget(0, dependee_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found then skip then the dependee.
|
// If not found then skip then the dependee.
|
||||||
@ -1842,14 +1829,8 @@ cmGlobalGenerator
|
|||||||
|
|
||||||
void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
|
void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
|
||||||
{
|
{
|
||||||
if (v.second.IsImported())
|
assert(!v.second.IsImported());
|
||||||
{
|
|
||||||
this->ImportedTotalTargets[v.first] = &v.second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->TotalTargets[v.first] = &v.second;
|
this->TotalTargets[v.first] = &v.second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
|
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
|
||||||
|
@ -186,9 +186,7 @@ public:
|
|||||||
void FindMakeProgram(cmMakefile*);
|
void FindMakeProgram(cmMakefile*);
|
||||||
|
|
||||||
///! Find a target by name by searching the local generators.
|
///! Find a target by name by searching the local generators.
|
||||||
cmTarget* FindTarget(const char* project,
|
cmTarget* FindTarget(const char* project, const char* name);
|
||||||
const char* name,
|
|
||||||
bool useImportedTargets);
|
|
||||||
|
|
||||||
/** Determine if a name resolves to a framework on disk or a built target
|
/** Determine if a name resolves to a framework on disk or a built target
|
||||||
that is a framework. */
|
that is a framework. */
|
||||||
@ -299,7 +297,6 @@ private:
|
|||||||
|
|
||||||
// this is used to improve performance
|
// this is used to improve performance
|
||||||
std::map<cmStdString,cmTarget *> TotalTargets;
|
std::map<cmStdString,cmTarget *> TotalTargets;
|
||||||
std::map<cmStdString,cmTarget *> ImportedTotalTargets;
|
|
||||||
|
|
||||||
cmExternalMakefileProjectGenerator* ExtraGenerator;
|
cmExternalMakefileProjectGenerator* ExtraGenerator;
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout,
|
|||||||
if(j->first != dspname)
|
if(j->first != dspname)
|
||||||
{
|
{
|
||||||
// is the library part of this DSW ? If so add dependency
|
// is the library part of this DSW ? If so add dependency
|
||||||
if(this->FindTarget(0, j->first.c_str(), false))
|
if(this->FindTarget(0, j->first.c_str()))
|
||||||
{
|
{
|
||||||
fout << "Begin Project Dependency\n";
|
fout << "Begin Project Dependency\n";
|
||||||
fout << "Project_Dep_Name " << j->first.c_str() << "\n";
|
fout << "Project_Dep_Name " << j->first.c_str() << "\n";
|
||||||
|
@ -338,8 +338,7 @@ cmGlobalVisualStudio71Generator
|
|||||||
if(j->first != dspname)
|
if(j->first != dspname)
|
||||||
{
|
{
|
||||||
// is the library part of this SLN ? If so add dependency
|
// is the library part of this SLN ? If so add dependency
|
||||||
if(this->FindTarget(this->CurrentProject.c_str(),
|
if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str()))
|
||||||
j->first.c_str(), false))
|
|
||||||
{
|
{
|
||||||
fout << "\t\t{" << this->GetGUID(j->first.c_str()) << "} = {"
|
fout << "\t\t{" << this->GetGUID(j->first.c_str()) << "} = {"
|
||||||
<< this->GetGUID(j->first.c_str()) << "}\n";
|
<< this->GetGUID(j->first.c_str()) << "}\n";
|
||||||
|
@ -611,8 +611,7 @@ cmGlobalVisualStudio7Generator
|
|||||||
if(j->first != dspname)
|
if(j->first != dspname)
|
||||||
{
|
{
|
||||||
// is the library part of this SLN ? If so add dependency
|
// is the library part of this SLN ? If so add dependency
|
||||||
if(this->FindTarget(this->CurrentProject.c_str(),
|
if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str()))
|
||||||
j->first.c_str(), false))
|
|
||||||
{
|
{
|
||||||
std::string guid = this->GetGUID(j->first.c_str());
|
std::string guid = this->GetGUID(j->first.c_str());
|
||||||
if(guid.size() == 0)
|
if(guid.size() == 0)
|
||||||
|
@ -138,7 +138,7 @@ void cmGlobalVisualStudio8Generator::Generate()
|
|||||||
mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
|
mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
|
||||||
no_working_directory, no_depends,
|
no_working_directory, no_depends,
|
||||||
noCommandLines);
|
noCommandLines);
|
||||||
cmTarget* tgt = mf->FindTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false);
|
cmTarget* tgt = mf->FindTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
|
||||||
if(!tgt)
|
if(!tgt)
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Error adding target "
|
cmSystemTools::Error("Error adding target "
|
||||||
|
@ -270,7 +270,7 @@ cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget(cmTarget& target)
|
|||||||
target.GetUtilities().begin();
|
target.GetUtilities().begin();
|
||||||
ui != target.GetUtilities().end(); ++ui)
|
ui != target.GetUtilities().end(); ++ui)
|
||||||
{
|
{
|
||||||
if(cmTarget* depTarget = this->FindTarget(0, ui->c_str(), false))
|
if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
|
||||||
{
|
{
|
||||||
if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
|
if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||||
depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
|
depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
@ -315,7 +315,7 @@ cmGlobalVisualStudioGenerator::CreateUtilityDependTarget(cmTarget& target)
|
|||||||
this->CreateGUID(altNameStr.c_str());
|
this->CreateGUID(altNameStr.c_str());
|
||||||
|
|
||||||
// The intermediate target should depend on the original target.
|
// The intermediate target should depend on the original target.
|
||||||
if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str(), false))
|
if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str()))
|
||||||
{
|
{
|
||||||
alt->AddUtility(target.GetName());
|
alt->AddUtility(target.GetName());
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
|
|||||||
{
|
{
|
||||||
// The depender is a target that links. Lookup the dependee to
|
// The depender is a target that links. Lookup the dependee to
|
||||||
// see if it provides an alternative dependency name.
|
// see if it provides an alternative dependency name.
|
||||||
if(cmTarget* depTarget = this->FindTarget(0, name, false))
|
if(cmTarget* depTarget = this->FindTarget(0, name))
|
||||||
{
|
{
|
||||||
// Check for an alternative name created by FixUtilityDepends.
|
// Check for an alternative name created by FixUtilityDepends.
|
||||||
if(const char* altName =
|
if(const char* altName =
|
||||||
|
@ -279,7 +279,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
|||||||
mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
|
mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
|
||||||
no_working_directory,
|
no_working_directory,
|
||||||
"echo", "Build all projects");
|
"echo", "Build all projects");
|
||||||
cmTarget* allbuild = mf->FindTarget("ALL_BUILD", false);
|
cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
|
||||||
|
|
||||||
// Add XCODE depend helper
|
// Add XCODE depend helper
|
||||||
std::string dir = mf->GetCurrentOutputDirectory();
|
std::string dir = mf->GetCurrentOutputDirectory();
|
||||||
@ -1346,7 +1346,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||||||
std::string pnprefix;
|
std::string pnprefix;
|
||||||
std::string pnbase;
|
std::string pnbase;
|
||||||
std::string pnsuffix;
|
std::string pnsuffix;
|
||||||
target.GetFullName(pnprefix, pnbase, pnsuffix, configName);
|
target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
|
||||||
|
|
||||||
// Store the product name for all target types.
|
// Store the product name for all target types.
|
||||||
buildSettings->AddAttribute("PRODUCT_NAME",
|
buildSettings->AddAttribute("PRODUCT_NAME",
|
||||||
@ -2046,7 +2046,7 @@ void cmGlobalXCodeGenerator
|
|||||||
{
|
{
|
||||||
// Add this dependency.
|
// Add this dependency.
|
||||||
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
||||||
lib->first.c_str(), false);
|
lib->first.c_str());
|
||||||
cmXCodeObject* dptarget = this->FindXCodeTarget(t);
|
cmXCodeObject* dptarget = this->FindXCodeTarget(t);
|
||||||
if(dptarget)
|
if(dptarget)
|
||||||
{
|
{
|
||||||
@ -2062,7 +2062,7 @@ void cmGlobalXCodeGenerator
|
|||||||
i != cmtarget->GetUtilities().end(); ++i)
|
i != cmtarget->GetUtilities().end(); ++i)
|
||||||
{
|
{
|
||||||
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
||||||
i->c_str(), false);
|
i->c_str());
|
||||||
// if the target is in this project then make target depend
|
// if the target is in this project then make target depend
|
||||||
// on it. It may not be in this project if this is a sub
|
// on it. It may not be in this project if this is a sub
|
||||||
// project from the top.
|
// project from the top.
|
||||||
|
@ -51,8 +51,7 @@ bool cmIncludeExternalMSProjectCommand
|
|||||||
|
|
||||||
// Create a target instance for this utility.
|
// Create a target instance for this utility.
|
||||||
cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY,
|
cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY,
|
||||||
utility_name.c_str(),
|
utility_name.c_str());
|
||||||
false);
|
|
||||||
target->SetProperty("EXCLUDE_FROM_ALL","FALSE");
|
target->SetProperty("EXCLUDE_FROM_ALL","FALSE");
|
||||||
std::vector<std::string> no_outputs;
|
std::vector<std::string> no_outputs;
|
||||||
cmCustomCommandLines commandLines;
|
cmCustomCommandLines commandLines;
|
||||||
|
@ -300,7 +300,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
++targetIt)
|
++targetIt)
|
||||||
{
|
{
|
||||||
// Lookup this target in the current directory.
|
// Lookup this target in the current directory.
|
||||||
if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str(), false))
|
if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
|
||||||
{
|
{
|
||||||
// Found the target. Check its type.
|
// Found the target. Check its type.
|
||||||
if(target->GetType() != cmTarget::EXECUTABLE &&
|
if(target->GetType() != cmTarget::EXECUTABLE &&
|
||||||
@ -489,7 +489,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
// library. Install it to the archive destination if it
|
// library. Install it to the archive destination if it
|
||||||
// exists.
|
// exists.
|
||||||
if(dll_platform && !archiveArgs.GetDestination().empty() &&
|
if(dll_platform && !archiveArgs.GetDestination().empty() &&
|
||||||
target.GetPropertyAsBool("ENABLE_EXPORTS"))
|
target.IsExecutableWithExports())
|
||||||
{
|
{
|
||||||
// The import library uses the ARCHIVE properties.
|
// The import library uses the ARCHIVE properties.
|
||||||
archiveGenerator = CreateInstallTargetGenerator(target,
|
archiveGenerator = CreateInstallTargetGenerator(target,
|
||||||
@ -1069,13 +1069,9 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute destination path.
|
|
||||||
std::string dest;
|
|
||||||
cmInstallCommandArguments::ComputeDestination(destination, dest);
|
|
||||||
|
|
||||||
// Create the directory install generator.
|
// Create the directory install generator.
|
||||||
this->Makefile->AddInstallGenerator(
|
this->Makefile->AddInstallGenerator(
|
||||||
new cmInstallDirectoryGenerator(dirs, dest.c_str(),
|
new cmInstallDirectoryGenerator(dirs, destination,
|
||||||
permissions_file.c_str(),
|
permissions_file.c_str(),
|
||||||
permissions_dir.c_str(),
|
permissions_dir.c_str(),
|
||||||
configurations,
|
configurations,
|
||||||
@ -1095,12 +1091,12 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
|
|||||||
{
|
{
|
||||||
// This is the EXPORT mode.
|
// This is the EXPORT mode.
|
||||||
cmInstallCommandArguments ica;
|
cmInstallCommandArguments ica;
|
||||||
cmCAStringVector exports(&ica.Parser, "EXPORT");
|
cmCAString exp(&ica.Parser, "EXPORT");
|
||||||
cmCAString prefix(&ica.Parser, "PREFIX", &ica.ArgumentGroup);
|
cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
|
||||||
cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
|
cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
|
||||||
exports.Follows(0);
|
exp.Follows(0);
|
||||||
|
|
||||||
ica.ArgumentGroup.Follows(&exports);
|
ica.ArgumentGroup.Follows(&exp);
|
||||||
std::vector<std::string> unknownArgs;
|
std::vector<std::string> unknownArgs;
|
||||||
ica.Parse(&args, &unknownArgs);
|
ica.Parse(&args, &unknownArgs);
|
||||||
|
|
||||||
@ -1118,43 +1114,65 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmakeDir = this->Makefile->GetHomeOutputDirectory();
|
// Make sure there is a destination.
|
||||||
cmakeDir += cmake::GetCMakeFilesDirectory();
|
if(ica.GetDestination().empty())
|
||||||
for(std::vector<std::string>::const_iterator
|
|
||||||
exportIt = exports.GetVector().begin();
|
|
||||||
exportIt != exports.GetVector().end();
|
|
||||||
++exportIt)
|
|
||||||
{
|
|
||||||
const std::vector<cmTargetExport*>* exportSet = this->
|
|
||||||
Makefile->GetLocalGenerator()->GetGlobalGenerator()->
|
|
||||||
GetExportSet(exportIt->c_str());
|
|
||||||
if (exportSet == 0)
|
|
||||||
{
|
{
|
||||||
|
// A destination is required.
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "EXPORT given unknown export name \"" << exportIt->c_str() << "\".";
|
e << args[0] << " given no DESTINATION!";
|
||||||
this->SetError(e.str().c_str());
|
this->SetError(e.str().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the file name.
|
||||||
|
std::string fname = filename.GetString();
|
||||||
|
if(fname.find_first_of(":/\\") != fname.npos)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << args[0] << " given invalid export file name \"" << fname << "\". "
|
||||||
|
<< "The FILE argument may not contain a path. "
|
||||||
|
<< "Specify the path in the DESTINATION argument.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the file extension.
|
||||||
|
if(!fname.empty() &&
|
||||||
|
cmSystemTools::GetFilenameLastExtension(fname) != ".cmake")
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << args[0] << " given invalid export file name \"" << fname << "\". "
|
||||||
|
<< "The FILE argument must specify a name ending in \".cmake\".";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the file name.
|
||||||
|
if(fname.empty())
|
||||||
|
{
|
||||||
|
fname = exp.GetString();
|
||||||
|
fname += ".cmake";
|
||||||
|
|
||||||
|
if(fname.find_first_of(":/\\") != fname.npos)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << args[0] << " given export name \"" << exp.GetString() << "\". "
|
||||||
|
<< "This name cannot be safely converted to a file name. "
|
||||||
|
<< "Specify a different export name or use the FILE option to set "
|
||||||
|
<< "a file name explicitly.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the export install generator.
|
// Create the export install generator.
|
||||||
cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
|
cmInstallExportGenerator* exportGenerator =
|
||||||
ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
|
new cmInstallExportGenerator(
|
||||||
ica.GetConfigurations(),0 , filename.GetCString(),
|
exp.GetCString(), ica.GetDestination().c_str(),
|
||||||
prefix.GetCString(), cmakeDir.c_str());
|
ica.GetPermissions().c_str(), ica.GetConfigurations(),
|
||||||
|
ica.GetComponent().c_str(), fname.c_str(),
|
||||||
if (exportGenerator->SetExportSet(exportIt->c_str(),exportSet))
|
name_space.GetCString(), this->Makefile);
|
||||||
{
|
|
||||||
this->Makefile->AddInstallGenerator(exportGenerator);
|
this->Makefile->AddInstallGenerator(exportGenerator);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmOStringStream e;
|
|
||||||
e << "EXPORT failed, maybe a target is exported more than once.";
|
|
||||||
this->SetError(e.str().c_str());
|
|
||||||
delete exportGenerator;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
"file to be installed does not exist. "
|
"file to be installed does not exist. "
|
||||||
"\n"
|
"\n"
|
||||||
"The TARGETS signature:\n"
|
"The TARGETS signature:\n"
|
||||||
" install(TARGETS targets...\n"
|
" install(TARGETS targets... [EXPORT <export-name>]\n"
|
||||||
" [[ARCHIVE|LIBRARY|RUNTIME]\n"
|
" [[ARCHIVE|LIBRARY|RUNTIME]\n"
|
||||||
" [DESTINATION <dir>]\n"
|
" [DESTINATION <dir>]\n"
|
||||||
" [PERMISSIONS permissions...]\n"
|
" [PERMISSIONS permissions...]\n"
|
||||||
@ -145,6 +145,12 @@ public:
|
|||||||
"On non-DLL platforms mySharedLib will be installed to <prefix>/lib "
|
"On non-DLL platforms mySharedLib will be installed to <prefix>/lib "
|
||||||
"and /some/full/path."
|
"and /some/full/path."
|
||||||
"\n"
|
"\n"
|
||||||
|
"The EXPORT option associates the installed target files with an "
|
||||||
|
"export called <export-name>. "
|
||||||
|
"It must appear before any RUNTIME, LIBRARY, or ARCHIVE options. "
|
||||||
|
"See documentation of the install(EXPORT ...) signature below for "
|
||||||
|
"details."
|
||||||
|
"\n"
|
||||||
"Installing a target with EXCLUDE_FROM_ALL set to true has "
|
"Installing a target with EXCLUDE_FROM_ALL set to true has "
|
||||||
"undefined behavior."
|
"undefined behavior."
|
||||||
"\n"
|
"\n"
|
||||||
@ -248,6 +254,45 @@ public:
|
|||||||
"For example, the code\n"
|
"For example, the code\n"
|
||||||
" install(CODE \"MESSAGE(\\\"Sample install message.\\\")\")\n"
|
" install(CODE \"MESSAGE(\\\"Sample install message.\\\")\")\n"
|
||||||
"will print a message during installation.\n"
|
"will print a message during installation.\n"
|
||||||
|
""
|
||||||
|
"The EXPORT signature:\n"
|
||||||
|
" install(EXPORT <export-name> DESTINATION <dir>\n"
|
||||||
|
" [NAMESPACE <namespace>] [FILE <name>.cmake]\n"
|
||||||
|
" [PERMISSIONS permissions...]\n"
|
||||||
|
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
||||||
|
" [COMPONENT <component>])\n"
|
||||||
|
"The EXPORT form generates and installs a CMake file containing code "
|
||||||
|
"to import targets from the installation tree into another project. "
|
||||||
|
"Target installations are associated with the export <export-name> "
|
||||||
|
"using the EXPORT option of the install(TARGETS ...) signature "
|
||||||
|
"documented above. The NAMESPACE option will prepend <namespace> to "
|
||||||
|
"the target names as they are written to the import file. "
|
||||||
|
"By default the generated file will be called <export-name>.cmake but "
|
||||||
|
"the FILE option may be used to specify a different name. The value "
|
||||||
|
"given to the FILE option must be a file name with the \".cmake\" "
|
||||||
|
"extension. "
|
||||||
|
"If a CONFIGURATIONS option is given then the file will only be "
|
||||||
|
"installed when one of the named configurations is installed. "
|
||||||
|
"Additionally, the generated import file will reference only the "
|
||||||
|
"matching target configurations. "
|
||||||
|
"If a COMPONENT option is specified that does not match that given "
|
||||||
|
"to the targets associated with <export-name> the behavior is "
|
||||||
|
"undefined. "
|
||||||
|
"If a library target is included in the export but "
|
||||||
|
"a target to which it links is not included the behavior is "
|
||||||
|
"unspecified."
|
||||||
|
"\n"
|
||||||
|
"The EXPORT form is useful to help outside projects use targets built "
|
||||||
|
"and installed by the current project. For example, the code\n"
|
||||||
|
" install(TARGETS myexe EXPORT myproj DESTINATION bin)\n"
|
||||||
|
" install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)\n"
|
||||||
|
"will install the executable myexe to <prefix>/bin and code to import "
|
||||||
|
"it in the file \"<prefix>/lib/myproj/myproj.cmake\". "
|
||||||
|
"An outside project may load this file with the include command "
|
||||||
|
"and reference the myexe executable from the installation tree using "
|
||||||
|
"the imported target name mp_myexe as if the target were built "
|
||||||
|
"in its own tree."
|
||||||
|
"\n"
|
||||||
"NOTE: This command supercedes the INSTALL_TARGETS command and the "
|
"NOTE: This command supercedes the INSTALL_TARGETS command and the "
|
||||||
"target properties PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT. "
|
"target properties PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT. "
|
||||||
"It also replaces the FILES forms of the INSTALL_FILES and "
|
"It also replaces the FILES forms of the INSTALL_FILES and "
|
||||||
|
@ -44,9 +44,9 @@ cmInstallCommandArguments::cmInstallCommandArguments()
|
|||||||
|
|
||||||
const std::string& cmInstallCommandArguments::GetDestination() const
|
const std::string& cmInstallCommandArguments::GetDestination() const
|
||||||
{
|
{
|
||||||
if (!this->AbsDestination.empty())
|
if (!this->DestinationString.empty())
|
||||||
{
|
{
|
||||||
return this->AbsDestination;
|
return this->DestinationString;
|
||||||
}
|
}
|
||||||
if (this->GenericArguments!=0)
|
if (this->GenericArguments!=0)
|
||||||
{
|
{
|
||||||
@ -128,8 +128,8 @@ bool cmInstallCommandArguments::Finalize()
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this->ComputeDestination(this->Destination.GetString(),this->AbsDestination);
|
this->DestinationString = this->Destination.GetString();
|
||||||
|
cmSystemTools::ConvertToUnixSlashes(this->DestinationString);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,23 +174,3 @@ bool cmInstallCommandArguments::CheckPermissions(
|
|||||||
// This is not a valid permission.
|
// This is not a valid permission.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmInstallCommandArguments::ComputeDestination(const std::string& inDest,
|
|
||||||
std::string& absDest)
|
|
||||||
{
|
|
||||||
if((inDest.size()>0) && !(cmSystemTools::FileIsFullPath(inDest.c_str())))
|
|
||||||
{
|
|
||||||
// Relative paths are treated with respect to the installation prefix.
|
|
||||||
absDest = "${CMAKE_INSTALL_PREFIX}/";
|
|
||||||
absDest += inDest;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Full paths are absolute.
|
|
||||||
absDest = inDest;
|
|
||||||
}
|
|
||||||
// Format the path nicely. Note this also removes trailing slashes.
|
|
||||||
cmSystemTools::ConvertToUnixSlashes(absDest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -43,8 +43,6 @@ class cmInstallCommandArguments
|
|||||||
// once HandleDirectoryMode() is also switched to using
|
// once HandleDirectoryMode() is also switched to using
|
||||||
// cmInstallCommandArguments then these two functions can become non-static
|
// cmInstallCommandArguments then these two functions can become non-static
|
||||||
// private member functions without arguments
|
// private member functions without arguments
|
||||||
static void ComputeDestination(const std::string& inDest,
|
|
||||||
std::string& absDest);
|
|
||||||
static bool CheckPermissions(const std::string& onePerm,
|
static bool CheckPermissions(const std::string& onePerm,
|
||||||
std::string& perm);
|
std::string& perm);
|
||||||
cmCommandArgumentsHelper Parser;
|
cmCommandArgumentsHelper Parser;
|
||||||
@ -57,7 +55,7 @@ class cmInstallCommandArguments
|
|||||||
cmCAStringVector Configurations;
|
cmCAStringVector Configurations;
|
||||||
cmCAEnabler Optional;
|
cmCAEnabler Optional;
|
||||||
|
|
||||||
std::string AbsDestination;
|
std::string DestinationString;
|
||||||
std::string PermissionsString;
|
std::string PermissionsString;
|
||||||
|
|
||||||
cmInstallCommandArguments* GenericArguments;
|
cmInstallCommandArguments* GenericArguments;
|
||||||
|
@ -48,8 +48,7 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
|
|||||||
bool not_optional = false;
|
bool not_optional = false;
|
||||||
const char* no_properties = 0;
|
const char* no_properties = 0;
|
||||||
const char* no_rename = 0;
|
const char* no_rename = 0;
|
||||||
this->AddInstallRule(os, this->Destination.c_str(),
|
this->AddInstallRule(os, cmTarget::INSTALL_DIRECTORY,
|
||||||
cmTarget::INSTALL_DIRECTORY,
|
|
||||||
this->Directories,
|
this->Directories,
|
||||||
not_optional, no_properties,
|
not_optional, no_properties,
|
||||||
this->FilePermissions.c_str(),
|
this->FilePermissions.c_str(),
|
||||||
|
@ -14,259 +14,198 @@
|
|||||||
PURPOSE. See the above copyright notices for more information.
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
|
#include "cmInstallExportGenerator.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "cmake.h"
|
||||||
#include "cmInstallTargetGenerator.h"
|
#include "cmInstallTargetGenerator.h"
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmTarget.h"
|
#include "cmTarget.h"
|
||||||
|
#include "cmMakefile.h"
|
||||||
|
#include "cmLocalGenerator.h"
|
||||||
|
#include "cmGlobalGenerator.h"
|
||||||
|
|
||||||
#include "cmInstallExportGenerator.h"
|
|
||||||
#include "cmInstallFilesGenerator.h"
|
#include "cmInstallFilesGenerator.h"
|
||||||
|
|
||||||
|
#include "cmExportInstallFileGenerator.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
cmInstallExportGenerator::cmInstallExportGenerator(
|
cmInstallExportGenerator::cmInstallExportGenerator(
|
||||||
|
const char* name,
|
||||||
const char* destination,
|
const char* destination,
|
||||||
const char* file_permissions,
|
const char* file_permissions,
|
||||||
std::vector<std::string> const& configurations,
|
std::vector<std::string> const& configurations,
|
||||||
const char* component,
|
const char* component,
|
||||||
const char* filename, const char* prefix, const char* tempOutputDir)
|
const char* filename, const char* name_space,
|
||||||
|
cmMakefile* mf)
|
||||||
:cmInstallGenerator(destination, configurations, component)
|
:cmInstallGenerator(destination, configurations, component)
|
||||||
|
,Name(name)
|
||||||
,FilePermissions(file_permissions)
|
,FilePermissions(file_permissions)
|
||||||
,Filename(filename)
|
,FileName(filename)
|
||||||
,Prefix(prefix)
|
,Namespace(name_space)
|
||||||
,TempOutputDir(tempOutputDir)
|
,Makefile(mf)
|
||||||
{
|
{
|
||||||
|
this->EFGen = new cmExportInstallFileGenerator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function which adds the install locations from the generator
|
//----------------------------------------------------------------------------
|
||||||
to the properties for this target.
|
cmInstallExportGenerator::~cmInstallExportGenerator()
|
||||||
*/
|
|
||||||
bool cmInstallExportGenerator::AddInstallLocations(cmTargetWithProperties* twp,
|
|
||||||
cmInstallTargetGenerator* generator,
|
|
||||||
const char* prefix)
|
|
||||||
{
|
{
|
||||||
if (generator == 0) // nothing to do
|
delete this->EFGen;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prefix == 0)
|
|
||||||
{
|
|
||||||
prefix = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string>& configs = generator->GetConfigurations();
|
|
||||||
if (configs.empty())
|
|
||||||
{
|
|
||||||
std::string propertyName = prefix;
|
|
||||||
propertyName += "LOCATION";
|
|
||||||
// check that this property doesn't exist yet and add it then
|
|
||||||
if (twp->Properties.find(propertyName.c_str()) == twp->Properties.end())
|
|
||||||
{
|
|
||||||
std::string destinationFilename = generator->GetDestination();
|
|
||||||
destinationFilename += "/";
|
|
||||||
destinationFilename += generator->GetInstallFilename(0);
|
|
||||||
twp->Properties[propertyName.c_str()] = destinationFilename;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(std::vector<std::string>::const_iterator configIt = configs.begin();
|
|
||||||
configIt != configs.end();
|
|
||||||
++configIt)
|
|
||||||
{
|
|
||||||
std::string propertyName = configIt->c_str();
|
|
||||||
propertyName += "_";
|
|
||||||
propertyName += prefix;
|
|
||||||
propertyName += "LOCATION";
|
|
||||||
// check that this property doesn't exist yet and add it then
|
|
||||||
if (twp->Properties.find(propertyName.c_str()) == twp->Properties.end())
|
|
||||||
{
|
|
||||||
std::string destinationFilename = generator->GetDestination();
|
|
||||||
destinationFilename += "/";
|
|
||||||
destinationFilename +=generator->GetInstallFilename(configIt->c_str());
|
|
||||||
twp->Properties[propertyName.c_str()] = destinationFilename;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool cmInstallExportGenerator::AddInstallLocations(cmTargetWithProperties* twp,
|
void cmInstallExportGenerator::ComputeTempDir()
|
||||||
cmInstallFilesGenerator* generator,
|
|
||||||
const char* propertyName)
|
|
||||||
{
|
{
|
||||||
if (generator == 0) // nothing to do
|
// Choose a temporary directory in which to generate the import
|
||||||
{
|
// files to be installed.
|
||||||
return true;
|
this->TempDir = this->Makefile->GetCurrentOutputDirectory();
|
||||||
}
|
this->TempDir += cmake::GetCMakeFilesDirectory();
|
||||||
|
this->TempDir += "/Export";
|
||||||
if ((propertyName == 0) || (*propertyName == '\0'))
|
if(this->Destination.empty())
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that this property doesn't exist yet and add it then
|
|
||||||
if (twp->Properties.find(propertyName) == twp->Properties.end())
|
|
||||||
{
|
|
||||||
twp->Properties[propertyName] = generator->GetDestination();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool cmInstallExportGenerator::SetExportSet(const char* name,
|
|
||||||
const std::vector<cmTargetExport*>* set)
|
|
||||||
{
|
|
||||||
if ((name == 0) || (*name == 0) || (set==0))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->Name = name;
|
|
||||||
|
|
||||||
/* iterate over all targets in the set.
|
|
||||||
If a cmTargetWithProperties with the same name already exists in this
|
|
||||||
generator, add the new properties to it. If the property already exists,
|
|
||||||
fail with an error.
|
|
||||||
If no cmTargetWithProperties exists, create a new one.
|
|
||||||
*/
|
|
||||||
for(std::vector<cmTargetExport*>::const_iterator it=set->begin();
|
|
||||||
it != set->end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
std::string targetName = (*it)->Target->GetName();
|
|
||||||
|
|
||||||
cmTargetWithProperties* targetWithProps = 0;
|
|
||||||
for(unsigned int i=0; i<this->Targets.size(); i++)
|
|
||||||
{
|
|
||||||
if (targetName == this->Targets[i]->Target->GetName())
|
|
||||||
{
|
|
||||||
targetWithProps = this->Targets[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetWithProps == 0)
|
|
||||||
{
|
|
||||||
targetWithProps = new cmTargetWithProperties((*it)->Target);
|
|
||||||
this->Targets.push_back(targetWithProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->AddInstallLocations(targetWithProps, (*it)->ArchiveGenerator,
|
|
||||||
"ARCHIVE_") == false)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this->AddInstallLocations(targetWithProps, (*it)->RuntimeGenerator,
|
|
||||||
"") == false)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this->AddInstallLocations(targetWithProps, (*it)->LibraryGenerator,
|
|
||||||
"LIBRARY_") == false)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this->AddInstallLocations(targetWithProps, (*it)->HeaderGenerator,
|
|
||||||
"PUBLIC_HEADER_LOCATION") == false)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
|
|
||||||
{
|
|
||||||
// for the case that somebody exports the same set with the same file name
|
|
||||||
// to different locations make the temp filename unique
|
|
||||||
char buf[64];
|
|
||||||
sprintf(buf, "%p", this);
|
|
||||||
this->ExportFilename = this->TempOutputDir;
|
|
||||||
this->ExportFilename += "/";
|
|
||||||
this->ExportFilename += this->Filename;
|
|
||||||
this->ExportFilename += ".";
|
|
||||||
this->ExportFilename += buf;
|
|
||||||
|
|
||||||
cmGeneratedFileStream exportFileStream(this->ExportFilename.c_str());
|
|
||||||
if(!exportFileStream)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* for every target add the IMPORT statements and set the properties
|
|
||||||
of the target. */
|
|
||||||
for(std::vector<cmTargetWithProperties*>::const_iterator
|
|
||||||
targetIt = this->Targets.begin();
|
|
||||||
targetIt != this->Targets.end();
|
|
||||||
++targetIt)
|
|
||||||
{
|
{
|
||||||
switch ((*targetIt)->Target->GetType())
|
this->TempDir += "/";
|
||||||
{
|
|
||||||
case cmTarget::EXECUTABLE:
|
|
||||||
exportFileStream << "ADD_EXECUTABLE(" << this->Prefix.c_str()
|
|
||||||
<< (*targetIt)->Target->GetName()
|
|
||||||
<< " IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::STATIC_LIBRARY:
|
|
||||||
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
|
|
||||||
<< (*targetIt)->Target->GetName()
|
|
||||||
<< " STATIC IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::SHARED_LIBRARY:
|
|
||||||
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
|
|
||||||
<< (*targetIt)->Target->GetName()
|
|
||||||
<< " SHARED IMPORT )\n";
|
|
||||||
break;
|
|
||||||
case cmTarget::MODULE_LIBRARY:
|
|
||||||
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
|
|
||||||
<< (*targetIt)->Target->GetName()
|
|
||||||
<< " MODULE IMPORT )\n";
|
|
||||||
break;
|
|
||||||
default: // should never happen
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exportFileStream << "SET_TARGET_PROPERTIES ( " << this->Prefix.c_str()
|
// Enforce a maximum length.
|
||||||
<< (*targetIt)->Target->GetName() << " PROPERTIES \n";
|
bool useMD5 = false;
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
for (std::map<std::string, std::string>::const_iterator
|
std::string::size_type const max_total_len = 250;
|
||||||
propIt = (*targetIt)->Properties.begin();
|
#else
|
||||||
propIt != (*targetIt)->Properties.end();
|
std::string::size_type const max_total_len = 1000;
|
||||||
++propIt)
|
#endif
|
||||||
|
if(this->TempDir.size() < max_total_len)
|
||||||
{
|
{
|
||||||
exportFileStream << " " << propIt->first
|
// Keep the total path length below the limit.
|
||||||
<< " \"" << propIt->second << "\"\n";
|
std::string::size_type max_len = max_total_len - this->TempDir.size();
|
||||||
|
if(this->Destination.size() > max_len)
|
||||||
|
{
|
||||||
|
useMD5 = true;
|
||||||
}
|
}
|
||||||
exportFileStream << " )\n\n";
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
useMD5 = true;
|
||||||
|
}
|
||||||
|
if(useMD5)
|
||||||
|
{
|
||||||
|
// Replace the destination path with a hash to keep it short.
|
||||||
|
this->TempDir +=
|
||||||
|
cmSystemTools::ComputeStringMD5(this->Destination.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string dest = this->Destination;
|
||||||
|
// Avoid unix full paths.
|
||||||
|
if(dest[0] == '/')
|
||||||
|
{
|
||||||
|
dest[0] = '_';
|
||||||
|
}
|
||||||
|
// Avoid windows full paths by removing colons.
|
||||||
|
cmSystemTools::ReplaceString(dest, ":", "_");
|
||||||
|
// Avoid relative paths that go up the tree.
|
||||||
|
cmSystemTools::ReplaceString(dest, "../", "__/");
|
||||||
|
// Avoid spaces.
|
||||||
|
cmSystemTools::ReplaceString(dest, " ", "_");
|
||||||
|
this->TempDir += dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
|
||||||
|
{
|
||||||
|
// Get the export set requested.
|
||||||
|
ExportSet const* exportSet =
|
||||||
|
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
||||||
|
->GetExportSet(this->Name.c_str());
|
||||||
|
|
||||||
|
// Skip empty sets.
|
||||||
|
if(!exportSet)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\"";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the temporary directory in which to store the files.
|
||||||
|
this->ComputeTempDir();
|
||||||
|
cmSystemTools::MakeDirectory(this->TempDir.c_str());
|
||||||
|
|
||||||
|
// Construct a temporary location for the file.
|
||||||
|
this->MainImportFile = this->TempDir;
|
||||||
|
this->MainImportFile += "/";
|
||||||
|
this->MainImportFile += this->FileName;
|
||||||
|
|
||||||
|
// Generate the import file for this export set.
|
||||||
|
this->EFGen->SetName(this->Name.c_str());
|
||||||
|
this->EFGen->SetExportSet(exportSet);
|
||||||
|
this->EFGen->SetExportFile(this->MainImportFile.c_str());
|
||||||
|
this->EFGen->SetNamespace(this->Namespace.c_str());
|
||||||
|
if(this->ConfigurationTypes->empty())
|
||||||
|
{
|
||||||
|
if(this->ConfigurationName && *this->ConfigurationName)
|
||||||
|
{
|
||||||
|
this->EFGen->AddConfiguration(this->ConfigurationName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->EFGen->AddConfiguration("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
ci = this->ConfigurationTypes->begin();
|
||||||
|
ci != this->ConfigurationTypes->end(); ++ci)
|
||||||
|
{
|
||||||
|
this->EFGen->AddConfiguration(ci->c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->EFGen->GenerateImportFile();
|
||||||
|
|
||||||
// Perform the main install script generation.
|
// Perform the main install script generation.
|
||||||
this->cmInstallGenerator::GenerateScript(os);
|
this->cmInstallGenerator::GenerateScript(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
|
||||||
|
Indent const& indent)
|
||||||
|
{
|
||||||
|
// Create the main install rules first.
|
||||||
|
this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
|
||||||
|
|
||||||
|
// Now create a configuration-specific install rule for the import
|
||||||
|
// file of each configuration.
|
||||||
|
std::vector<std::string> files;
|
||||||
|
for(std::map<cmStdString, cmStdString>::const_iterator
|
||||||
|
i = this->EFGen->GetConfigImportFiles().begin();
|
||||||
|
i != this->EFGen->GetConfigImportFiles().end(); ++i)
|
||||||
|
{
|
||||||
|
files.push_back(i->second);
|
||||||
|
std::string config_test = this->CreateConfigTest(i->first.c_str());
|
||||||
|
os << indent << "IF(" << config_test << ")\n";
|
||||||
|
this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, 0,
|
||||||
|
this->FilePermissions.c_str(), 0, 0, 0,
|
||||||
|
indent.Next());
|
||||||
|
os << indent << "ENDIF(" << config_test << ")\n";
|
||||||
|
files.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
|
void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
|
||||||
Indent const& indent)
|
Indent const& indent)
|
||||||
{
|
{
|
||||||
// install rule for the file created above
|
// Install the main export file.
|
||||||
std::vector<std::string> exportFile;
|
std::vector<std::string> files;
|
||||||
exportFile.push_back(this->ExportFilename);
|
files.push_back(this->MainImportFile);
|
||||||
this->AddInstallRule(os, this->Destination.c_str(), cmTarget::INSTALL_FILES,
|
this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, 0,
|
||||||
exportFile, false, 0,
|
this->FilePermissions.c_str(), 0, 0, 0, indent);
|
||||||
this->FilePermissions.c_str(),
|
|
||||||
0, this->Filename.c_str(), 0, indent);
|
|
||||||
}
|
}
|
||||||
|
@ -19,42 +19,12 @@
|
|||||||
|
|
||||||
#include "cmInstallGenerator.h"
|
#include "cmInstallGenerator.h"
|
||||||
|
|
||||||
class cmTarget;
|
class cmExportInstallFileGenerator;
|
||||||
|
|
||||||
|
|
||||||
class cmInstallTargetGenerator;
|
|
||||||
class cmInstallFilesGenerator;
|
class cmInstallFilesGenerator;
|
||||||
|
class cmInstallTargetGenerator;
|
||||||
/* cmInstallExportTarget is used in cmGlobalGenerator to collect the
|
class cmTarget;
|
||||||
install generators for the exported targets. These are then used by the
|
class cmTargetExport;
|
||||||
cmInstallExportGenerator.
|
class cmMakefile;
|
||||||
*/
|
|
||||||
class cmTargetExport
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmTargetExport(cmTarget* tgt,
|
|
||||||
cmInstallTargetGenerator* archive,
|
|
||||||
cmInstallTargetGenerator* runtime,
|
|
||||||
cmInstallTargetGenerator* library,
|
|
||||||
cmInstallTargetGenerator* framework,
|
|
||||||
cmInstallTargetGenerator* bundle,
|
|
||||||
cmInstallFilesGenerator* headers
|
|
||||||
) : Target(tgt), ArchiveGenerator(archive),
|
|
||||||
RuntimeGenerator(runtime), LibraryGenerator(library),
|
|
||||||
FrameworkGenerator(framework), BundleGenerator(bundle),
|
|
||||||
HeaderGenerator(headers) {}
|
|
||||||
|
|
||||||
cmTarget* Target;
|
|
||||||
cmInstallTargetGenerator* ArchiveGenerator;
|
|
||||||
cmInstallTargetGenerator* RuntimeGenerator;
|
|
||||||
cmInstallTargetGenerator* LibraryGenerator;
|
|
||||||
cmInstallTargetGenerator* FrameworkGenerator;
|
|
||||||
cmInstallTargetGenerator* BundleGenerator;
|
|
||||||
cmInstallFilesGenerator* HeaderGenerator;
|
|
||||||
private:
|
|
||||||
cmTargetExport();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** \class cmInstallExportGenerator
|
/** \class cmInstallExportGenerator
|
||||||
* \brief Generate rules for creating an export files.
|
* \brief Generate rules for creating an export files.
|
||||||
@ -62,45 +32,33 @@ private:
|
|||||||
class cmInstallExportGenerator: public cmInstallGenerator
|
class cmInstallExportGenerator: public cmInstallGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmInstallExportGenerator(const char* dest, const char* file_permissions,
|
cmInstallExportGenerator(const char* name,
|
||||||
|
const char* dest, const char* file_permissions,
|
||||||
const std::vector<std::string>& configurations,
|
const std::vector<std::string>& configurations,
|
||||||
const char* component,
|
const char* component,
|
||||||
const char* filename, const char* prefix,
|
const char* filename, const char* name_space,
|
||||||
const char* tempOutputDir);
|
cmMakefile* mf);
|
||||||
|
~cmInstallExportGenerator();
|
||||||
bool SetExportSet(const char* name,
|
|
||||||
const std::vector<cmTargetExport*>* exportSet);
|
|
||||||
protected:
|
protected:
|
||||||
// internal class which collects all the properties which will be set
|
typedef std::vector<cmTargetExport*> ExportSet;
|
||||||
// in the export file for the target
|
|
||||||
class cmTargetWithProperties
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmTargetWithProperties(cmTarget* target):Target(target) {}
|
|
||||||
cmTarget* Target;
|
|
||||||
std::map<std::string, std::string> Properties;
|
|
||||||
private:
|
|
||||||
cmTargetWithProperties();
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef cmInstallGeneratorIndent Indent;
|
typedef cmInstallGeneratorIndent Indent;
|
||||||
virtual void GenerateScript(std::ostream& os);
|
virtual void GenerateScript(std::ostream& os);
|
||||||
|
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
|
||||||
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
|
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
|
||||||
static bool AddInstallLocations(cmTargetWithProperties *twp,
|
void GenerateImportFile(ExportSet const* exportSet);
|
||||||
cmInstallTargetGenerator* generator,
|
void GenerateImportFile(const char* config, ExportSet const* exportSet);
|
||||||
const char* prefix);
|
void ComputeTempDir();
|
||||||
static bool AddInstallLocations(cmTargetWithProperties* twp,
|
|
||||||
cmInstallFilesGenerator* generator,
|
|
||||||
const char* propertyName);
|
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::string FilePermissions;
|
std::string FilePermissions;
|
||||||
std::string Filename;
|
std::string FileName;
|
||||||
std::string Prefix;
|
std::string Namespace;
|
||||||
std::string TempOutputDir;
|
cmMakefile* Makefile;
|
||||||
std::string ExportFilename;
|
|
||||||
|
|
||||||
std::vector<cmTargetWithProperties*> Targets;
|
std::string TempDir;
|
||||||
|
std::string MainImportFile;
|
||||||
|
cmExportInstallFileGenerator* EFGen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,9 +119,8 @@ void cmInstallFilesCommand::FinalPass()
|
|||||||
void cmInstallFilesCommand::CreateInstallGenerator() const
|
void cmInstallFilesCommand::CreateInstallGenerator() const
|
||||||
{
|
{
|
||||||
// Construct the destination. This command always installs under
|
// Construct the destination. This command always installs under
|
||||||
// the prefix.
|
// the prefix. We skip the leading slash given by the user.
|
||||||
std::string destination = "${CMAKE_INSTALL_PREFIX}";
|
std::string destination = this->Destination.substr(1);
|
||||||
destination += this->Destination;
|
|
||||||
cmSystemTools::ConvertToUnixSlashes(destination);
|
cmSystemTools::ConvertToUnixSlashes(destination);
|
||||||
|
|
||||||
// Use a file install generator.
|
// Use a file install generator.
|
||||||
|
@ -47,7 +47,7 @@ void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
|
|||||||
// Write code to install the files.
|
// Write code to install the files.
|
||||||
const char* no_properties = 0;
|
const char* no_properties = 0;
|
||||||
const char* no_dir_permissions = 0;
|
const char* no_dir_permissions = 0;
|
||||||
this->AddInstallRule(os, this->Destination.c_str(),
|
this->AddInstallRule(os,
|
||||||
(this->Programs
|
(this->Programs
|
||||||
? cmTarget::INSTALL_PROGRAMS
|
? cmTarget::INSTALL_PROGRAMS
|
||||||
: cmTarget::INSTALL_FILES),
|
: cmTarget::INSTALL_FILES),
|
||||||
|
@ -55,7 +55,6 @@ cmInstallGenerator
|
|||||||
void cmInstallGenerator
|
void cmInstallGenerator
|
||||||
::AddInstallRule(
|
::AddInstallRule(
|
||||||
std::ostream& os,
|
std::ostream& os,
|
||||||
const char* dest,
|
|
||||||
int type,
|
int type,
|
||||||
std::vector<std::string> const& files,
|
std::vector<std::string> const& files,
|
||||||
bool optional /* = false */,
|
bool optional /* = false */,
|
||||||
@ -81,6 +80,7 @@ void cmInstallGenerator
|
|||||||
default: stype = "FILE"; break;
|
default: stype = "FILE"; break;
|
||||||
}
|
}
|
||||||
os << indent;
|
os << indent;
|
||||||
|
std::string dest = this->GetInstallDestination();
|
||||||
os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str();
|
os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str();
|
||||||
if(optional)
|
if(optional)
|
||||||
{
|
{
|
||||||
@ -238,3 +238,40 @@ void cmInstallGenerator::GenerateScriptActions(std::ostream&, Indent const&)
|
|||||||
{
|
{
|
||||||
// No actions for this generator.
|
// No actions for this generator.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmInstallGenerator::InstallsForConfig(const char* config)
|
||||||
|
{
|
||||||
|
// If this is not a configuration-specific rule then we install.
|
||||||
|
if(this->Configurations.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a configuration-specific rule. Check if the config
|
||||||
|
// matches this rule.
|
||||||
|
std::string config_upper = cmSystemTools::UpperCase(config?config:"");
|
||||||
|
for(std::vector<std::string>::const_iterator i =
|
||||||
|
this->Configurations.begin();
|
||||||
|
i != this->Configurations.end(); ++i)
|
||||||
|
{
|
||||||
|
if(cmSystemTools::UpperCase(*i) == config_upper)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmInstallGenerator::GetInstallDestination() const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
if(!this->Destination.empty() &&
|
||||||
|
!cmSystemTools::FileIsFullPath(this->Destination.c_str()))
|
||||||
|
{
|
||||||
|
result = "${CMAKE_INSTALL_PREFIX}/";
|
||||||
|
}
|
||||||
|
result += this->Destination;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -62,8 +62,8 @@ public:
|
|||||||
void Generate(std::ostream& os, const char* config,
|
void Generate(std::ostream& os, const char* config,
|
||||||
std::vector<std::string> const& configurationTypes);
|
std::vector<std::string> const& configurationTypes);
|
||||||
|
|
||||||
static void AddInstallRule(
|
void AddInstallRule(
|
||||||
std::ostream& os, const char* dest, int type,
|
std::ostream& os, int type,
|
||||||
std::vector<std::string> const& files,
|
std::vector<std::string> const& files,
|
||||||
bool optional = false,
|
bool optional = false,
|
||||||
const char* properties = 0,
|
const char* properties = 0,
|
||||||
@ -78,6 +78,14 @@ public:
|
|||||||
{ return this->Destination.c_str(); }
|
{ return this->Destination.c_str(); }
|
||||||
const std::vector<std::string>& GetConfigurations() const
|
const std::vector<std::string>& GetConfigurations() const
|
||||||
{ return this->Configurations; }
|
{ return this->Configurations; }
|
||||||
|
|
||||||
|
/** Get the install destination as it should appear in the
|
||||||
|
installation script. */
|
||||||
|
std::string GetInstallDestination() const;
|
||||||
|
|
||||||
|
/** Test if this generator installs something for a given configuration. */
|
||||||
|
bool InstallsForConfig(const char*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef cmInstallGeneratorIndent Indent;
|
typedef cmInstallGeneratorIndent Indent;
|
||||||
virtual void GenerateScript(std::ostream& os);
|
virtual void GenerateScript(std::ostream& os);
|
||||||
|
@ -80,9 +80,8 @@ void cmInstallProgramsCommand::FinalPass()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct the destination. This command always installs under
|
// Construct the destination. This command always installs under
|
||||||
// the prefix.
|
// the prefix. We skip the leading slash given by the user.
|
||||||
std::string destination = "${CMAKE_INSTALL_PREFIX}";
|
std::string destination = this->Destination.substr(1);
|
||||||
destination += this->Destination;
|
|
||||||
cmSystemTools::ConvertToUnixSlashes(destination);
|
cmSystemTools::ConvertToUnixSlashes(destination);
|
||||||
|
|
||||||
// Use a file install generator.
|
// Use a file install generator.
|
||||||
|
@ -113,23 +113,12 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
|
|||||||
|
|
||||||
if(config && *config)
|
if(config && *config)
|
||||||
{
|
{
|
||||||
std::string config_upper = cmSystemTools::UpperCase(config);
|
|
||||||
// Skip this configuration for config-specific installation that
|
// Skip this configuration for config-specific installation that
|
||||||
// does not match it.
|
// does not match it.
|
||||||
if(!this->Configurations.empty())
|
if(!this->InstallsForConfig(config))
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for(std::vector<std::string>::const_iterator i =
|
|
||||||
this->Configurations.begin();
|
|
||||||
!found && i != this->Configurations.end(); ++i)
|
|
||||||
{
|
|
||||||
found = found || (cmSystemTools::UpperCase(*i) == config_upper);
|
|
||||||
}
|
|
||||||
if(!found)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a per-configuration block.
|
// Generate a per-configuration block.
|
||||||
std::string config_test = this->CreateConfigTest(config);
|
std::string config_test = this->CreateConfigTest(config);
|
||||||
@ -154,7 +143,7 @@ cmInstallTargetGenerator
|
|||||||
Indent const& indent)
|
Indent const& indent)
|
||||||
{
|
{
|
||||||
// Compute the full path to the main installed file for this target.
|
// Compute the full path to the main installed file for this target.
|
||||||
std::string toInstallPath = this->Destination;
|
std::string toInstallPath = this->GetInstallDestination();
|
||||||
toInstallPath += "/";
|
toInstallPath += "/";
|
||||||
toInstallPath += this->GetInstallFilename(this->Target, config,
|
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||||
this->ImportLibrary, false);
|
this->ImportLibrary, false);
|
||||||
@ -279,7 +268,7 @@ cmInstallTargetGenerator
|
|||||||
const char* no_rename = 0;
|
const char* no_rename = 0;
|
||||||
const char* no_properties = 0;
|
const char* no_properties = 0;
|
||||||
bool optional = this->Optional || this->ImportLibrary;
|
bool optional = this->Optional || this->ImportLibrary;
|
||||||
this->AddInstallRule(os, this->Destination.c_str(), type, files,
|
this->AddInstallRule(os, type, files,
|
||||||
optional, no_properties,
|
optional, no_properties,
|
||||||
this->FilePermissions.c_str(), no_dir_permissions,
|
this->FilePermissions.c_str(), no_dir_permissions,
|
||||||
no_rename, literal_args.c_str(),
|
no_rename, literal_args.c_str(),
|
||||||
@ -412,7 +401,7 @@ cmInstallTargetGenerator
|
|||||||
{
|
{
|
||||||
if(cmTarget* tgt = this->Target->GetMakefile()->
|
if(cmTarget* tgt = this->Target->GetMakefile()->
|
||||||
GetLocalGenerator()->GetGlobalGenerator()->
|
GetLocalGenerator()->GetGlobalGenerator()->
|
||||||
FindTarget(0, lib.c_str(), false))
|
FindTarget(0, lib.c_str()))
|
||||||
{
|
{
|
||||||
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
|
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,9 @@ public:
|
|||||||
static std::string GetInstallFilename(cmTarget*target, const char* config,
|
static std::string GetInstallFilename(cmTarget*target, const char* config,
|
||||||
bool implib, bool useSOName);
|
bool implib, bool useSOName);
|
||||||
|
|
||||||
|
cmTarget* GetTarget() const { return this->Target; }
|
||||||
|
bool IsImportLibrary() const { return this->ImportLibrary; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef cmInstallGeneratorIndent Indent;
|
typedef cmInstallGeneratorIndent Indent;
|
||||||
virtual void GenerateScript(std::ostream& os);
|
virtual void GenerateScript(std::ostream& os);
|
||||||
|
@ -1809,7 +1809,7 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for a CMake target with the given name.
|
// Look for a CMake target with the given name.
|
||||||
if(cmTarget* target = this->GlobalGenerator->FindTarget(0,name.c_str(),true))
|
if(cmTarget* target = this->Makefile->FindTargetToUse(name.c_str()))
|
||||||
{
|
{
|
||||||
// make sure it is not just a coincidence that the target name
|
// make sure it is not just a coincidence that the target name
|
||||||
// found is part of the inName
|
// found is part of the inName
|
||||||
@ -1876,7 +1876,7 @@ std::string cmLocalGenerator::GetRealLocation(const char* inName,
|
|||||||
std::string outName=inName;
|
std::string outName=inName;
|
||||||
// Look for a CMake target with the given name, which is an executable
|
// Look for a CMake target with the given name, which is an executable
|
||||||
// and which can be run
|
// and which can be run
|
||||||
cmTarget* target = this->GlobalGenerator->FindTarget(0, inName, true);
|
cmTarget* target = this->Makefile->FindTargetToUse(inName);
|
||||||
if ((target != 0)
|
if ((target != 0)
|
||||||
&& (target->GetType() == cmTarget::EXECUTABLE)
|
&& (target->GetType() == cmTarget::EXECUTABLE)
|
||||||
&& ((this->Makefile->IsOn("CMAKE_CROSSCOMPILING") == false)
|
&& ((this->Makefile->IsOn("CMAKE_CROSSCOMPILING") == false)
|
||||||
@ -2348,8 +2348,8 @@ cmLocalGenerator
|
|||||||
{
|
{
|
||||||
// Compute the full install destination. Note that converting
|
// Compute the full install destination. Note that converting
|
||||||
// to unix slashes also removes any trailing slash.
|
// to unix slashes also removes any trailing slash.
|
||||||
std::string destination = "${CMAKE_INSTALL_PREFIX}";
|
// We also skip over the leading slash given by the user.
|
||||||
destination += l->second.GetInstallPath();
|
std::string destination = l->second.GetInstallPath().substr(1);
|
||||||
cmSystemTools::ConvertToUnixSlashes(destination);
|
cmSystemTools::ConvertToUnixSlashes(destination);
|
||||||
|
|
||||||
// Generate the proper install generator for this target type.
|
// Generate the proper install generator for this target type.
|
||||||
@ -2372,8 +2372,8 @@ cmLocalGenerator
|
|||||||
// destination.
|
// destination.
|
||||||
cmInstallTargetGenerator g1(l->second, destination.c_str(), true);
|
cmInstallTargetGenerator g1(l->second, destination.c_str(), true);
|
||||||
g1.Generate(os, config, configurationTypes);
|
g1.Generate(os, config, configurationTypes);
|
||||||
destination = "${CMAKE_INSTALL_PREFIX}";
|
// We also skip over the leading slash given by the user.
|
||||||
destination += l->second.GetRuntimeInstallPath();
|
destination = l->second.GetRuntimeInstallPath().substr(1);
|
||||||
cmSystemTools::ConvertToUnixSlashes(destination);
|
cmSystemTools::ConvertToUnixSlashes(destination);
|
||||||
cmInstallTargetGenerator g2(l->second, destination.c_str(), false);
|
cmInstallTargetGenerator g2(l->second, destination.c_str(), false);
|
||||||
g2.Generate(os, config, configurationTypes);
|
g2.Generate(os, config, configurationTypes);
|
||||||
|
@ -1061,8 +1061,7 @@ void cmLocalVisualStudio6Generator
|
|||||||
// Compute the proper name to use to link this library.
|
// Compute the proper name to use to link this library.
|
||||||
std::string lib;
|
std::string lib;
|
||||||
std::string libDebug;
|
std::string libDebug;
|
||||||
cmTarget* tgt = this->GlobalGenerator->FindTarget(0, j->first.c_str(),
|
cmTarget* tgt = this->GlobalGenerator->FindTarget(0, j->first.c_str());
|
||||||
false);
|
|
||||||
if(tgt)
|
if(tgt)
|
||||||
{
|
{
|
||||||
lib = cmSystemTools::GetFilenameWithoutExtension
|
lib = cmSystemTools::GetFilenameWithoutExtension
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
#include <cmsys/RegularExpression.hxx>
|
#include <cmsys/RegularExpression.hxx>
|
||||||
|
|
||||||
|
#include <cmsys/auto_ptr.hxx>
|
||||||
|
|
||||||
#include <ctype.h> // for isspace
|
#include <ctype.h> // for isspace
|
||||||
|
|
||||||
// default is not to be building executables
|
// default is not to be building executables
|
||||||
@ -176,6 +178,12 @@ cmMakefile::~cmMakefile()
|
|||||||
{
|
{
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
for(std::vector<cmTarget*>::iterator
|
||||||
|
i = this->ImportedTargetsOwned.begin();
|
||||||
|
i != this->ImportedTargetsOwned.end(); ++i)
|
||||||
|
{
|
||||||
|
delete *i;
|
||||||
|
}
|
||||||
for(unsigned int i=0; i < this->UsedCommands.size(); i++)
|
for(unsigned int i=0; i < this->UsedCommands.size(); i++)
|
||||||
{
|
{
|
||||||
delete this->UsedCommands[i];
|
delete this->UsedCommands[i];
|
||||||
@ -824,7 +832,7 @@ void cmMakefile::AddUtilityCommand(const char* utilityName,
|
|||||||
bool escapeOldStyle, const char* comment)
|
bool escapeOldStyle, const char* comment)
|
||||||
{
|
{
|
||||||
// Create a target instance for this utility.
|
// Create a target instance for this utility.
|
||||||
cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName, false);
|
cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
|
||||||
if (excludeFromAll)
|
if (excludeFromAll)
|
||||||
{
|
{
|
||||||
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
|
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
|
||||||
@ -1005,7 +1013,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
|
|||||||
if ( i != this->Targets.end())
|
if ( i != this->Targets.end())
|
||||||
{
|
{
|
||||||
cmTarget* tgt =
|
cmTarget* tgt =
|
||||||
this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib,false);
|
this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib);
|
||||||
if(tgt)
|
if(tgt)
|
||||||
{
|
{
|
||||||
bool allowModules = true;
|
bool allowModules = true;
|
||||||
@ -1018,8 +1026,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
|
|||||||
// if it is not a static or shared library then you can not link to it
|
// if it is not a static or shared library then you can not link to it
|
||||||
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
|
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||||
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
|
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||||
(tgt->GetType() == cmTarget::EXECUTABLE &&
|
tgt->IsExecutableWithExports()))
|
||||||
tgt->GetPropertyAsBool("ENABLE_EXPORTS"))))
|
|
||||||
{
|
{
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "Attempt to add link target " << lib << " of type: "
|
e << "Attempt to add link target " << lib << " of type: "
|
||||||
@ -1162,6 +1169,9 @@ void cmMakefile::InitializeFromParent()
|
|||||||
// Copy include regular expressions.
|
// Copy include regular expressions.
|
||||||
this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
|
this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
|
||||||
this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
|
this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
|
||||||
|
|
||||||
|
// Imported targets.
|
||||||
|
this->ImportedTargets = parent->ImportedTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
|
void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
|
||||||
@ -1467,7 +1477,7 @@ void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
|
|||||||
type = cmTarget::STATIC_LIBRARY;
|
type = cmTarget::STATIC_LIBRARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTarget* target = this->AddNewTarget(type, lname, false);
|
cmTarget* target = this->AddNewTarget(type, lname);
|
||||||
// Clear its dependencies. Otherwise, dependencies might persist
|
// Clear its dependencies. Otherwise, dependencies might persist
|
||||||
// over changes in CMakeLists.txt, making the information stale and
|
// over changes in CMakeLists.txt, making the information stale and
|
||||||
// hence useless.
|
// hence useless.
|
||||||
@ -1484,7 +1494,7 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
|
|||||||
const std::vector<std::string> &srcs,
|
const std::vector<std::string> &srcs,
|
||||||
bool excludeFromAll)
|
bool excludeFromAll)
|
||||||
{
|
{
|
||||||
cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName, false);
|
cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
|
||||||
if(excludeFromAll)
|
if(excludeFromAll)
|
||||||
{
|
{
|
||||||
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
|
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
|
||||||
@ -1494,26 +1504,16 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
cmTarget* cmMakefile::AddNewTarget(cmTarget::TargetType type,
|
cmTarget*
|
||||||
const char* name,
|
cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
|
||||||
bool isImported)
|
|
||||||
{
|
{
|
||||||
cmTargets::iterator it;
|
cmTargets::iterator it;
|
||||||
cmTarget target;
|
cmTarget target;
|
||||||
target.SetType(type, name);
|
target.SetType(type, name);
|
||||||
target.SetMakefile(this);
|
target.SetMakefile(this);
|
||||||
if (isImported)
|
|
||||||
{
|
|
||||||
target.MarkAsImported();
|
|
||||||
it=this->ImportedTargets.insert(
|
|
||||||
cmTargets::value_type(target.GetName(), target)).first;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
it=this->Targets.insert(
|
it=this->Targets.insert(
|
||||||
cmTargets::value_type(target.GetName(), target)).first;
|
cmTargets::value_type(target.GetName(), target)).first;
|
||||||
}
|
|
||||||
this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
|
this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
@ -2869,7 +2869,7 @@ bool cmMakefile::GetPropertyAsBool(const char* prop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmTarget* cmMakefile::FindTarget(const char* name, bool useImportedTargets)
|
cmTarget* cmMakefile::FindTarget(const char* name)
|
||||||
{
|
{
|
||||||
cmTargets& tgts = this->GetTargets();
|
cmTargets& tgts = this->GetTargets();
|
||||||
|
|
||||||
@ -2879,15 +2879,6 @@ cmTarget* cmMakefile::FindTarget(const char* name, bool useImportedTargets)
|
|||||||
return &i->second;
|
return &i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useImportedTargets)
|
|
||||||
{
|
|
||||||
cmTargets::iterator impTarget = this->ImportedTargets.find(name);
|
|
||||||
if (impTarget != this->ImportedTargets.end())
|
|
||||||
{
|
|
||||||
return &impTarget->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3091,3 +3082,37 @@ void cmMakefile::DefineProperties(cmake *cm)
|
|||||||
"The same concept applies to the default build of other generators.",
|
"The same concept applies to the default build of other generators.",
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget*
|
||||||
|
cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
|
||||||
|
{
|
||||||
|
// Create the target.
|
||||||
|
cmsys::auto_ptr<cmTarget> target(new cmTarget);
|
||||||
|
target->SetType(type, name);
|
||||||
|
target->SetMakefile(this);
|
||||||
|
target->MarkAsImported();
|
||||||
|
|
||||||
|
// Add to the set of available imported targets.
|
||||||
|
this->ImportedTargets[name] = target.get();
|
||||||
|
|
||||||
|
// Transfer ownership to this cmMakefile object.
|
||||||
|
this->ImportedTargetsOwned.push_back(target.get());
|
||||||
|
return target.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget* cmMakefile::FindTargetToUse(const char* name)
|
||||||
|
{
|
||||||
|
// Look for an imported target. These take priority because they
|
||||||
|
// are more local in scope and do not have to be globally unique.
|
||||||
|
std::map<cmStdString, cmTarget*>::const_iterator
|
||||||
|
imported = this->ImportedTargets.find(name);
|
||||||
|
if(imported != this->ImportedTargets.end())
|
||||||
|
{
|
||||||
|
return imported->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a target built in this project.
|
||||||
|
return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
|
||||||
|
}
|
||||||
|
@ -172,9 +172,10 @@ public:
|
|||||||
void AddDefineFlag(const char* definition);
|
void AddDefineFlag(const char* definition);
|
||||||
void RemoveDefineFlag(const char* definition);
|
void RemoveDefineFlag(const char* definition);
|
||||||
|
|
||||||
cmTarget* AddNewTarget(cmTarget::TargetType type,
|
/** Create a new imported target with the name and type given. */
|
||||||
const char* name,
|
cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type);
|
||||||
bool isImported);
|
|
||||||
|
cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an executable to the build.
|
* Add an executable to the build.
|
||||||
@ -436,10 +437,12 @@ public:
|
|||||||
* Get the list of targets, const version
|
* Get the list of targets, const version
|
||||||
*/
|
*/
|
||||||
const cmTargets &GetTargets() const { return this->Targets; }
|
const cmTargets &GetTargets() const { return this->Targets; }
|
||||||
const cmTargets &GetImportedTargets() const { return this->ImportedTargets; }
|
|
||||||
|
|
||||||
cmTarget* FindTarget(const char* name, bool useImportedTargets);
|
cmTarget* FindTarget(const char* name);
|
||||||
|
|
||||||
|
/** Find a target to use in place of the given name. The target
|
||||||
|
returned may be imported or built within the project. */
|
||||||
|
cmTarget* FindTargetToUse(const char* name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of include directories in the build.
|
* Get a list of include directories in the build.
|
||||||
@ -766,7 +769,6 @@ protected:
|
|||||||
|
|
||||||
// libraries, classes, and executables
|
// libraries, classes, and executables
|
||||||
cmTargets Targets;
|
cmTargets Targets;
|
||||||
cmTargets ImportedTargets;
|
|
||||||
std::vector<cmSourceFile*> SourceFiles;
|
std::vector<cmSourceFile*> SourceFiles;
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
@ -842,6 +844,10 @@ private:
|
|||||||
|
|
||||||
// stack of list files being read
|
// stack of list files being read
|
||||||
std::deque<cmStdString> ListFileStack;
|
std::deque<cmStdString> ListFileStack;
|
||||||
|
|
||||||
|
cmTarget* FindBasicTarget(const char* name);
|
||||||
|
std::vector<cmTarget*> ImportedTargetsOwned;
|
||||||
|
std::map<cmStdString, cmTarget*> ImportedTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add symbol export flags if necessary.
|
// Add symbol export flags if necessary.
|
||||||
if(this->Target->GetPropertyAsBool("ENABLE_EXPORTS"))
|
if(this->Target->IsExecutableWithExports())
|
||||||
{
|
{
|
||||||
std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
|
std::string export_flag_var = "CMAKE_EXE_EXPORTS_";
|
||||||
export_flag_var += linkLanguage;
|
export_flag_var += linkLanguage;
|
||||||
@ -351,7 +351,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
|||||||
this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
|
this->Makefile->GetRequiredDefinition(linkRuleVar.c_str());
|
||||||
std::vector<std::string> commands1;
|
std::vector<std::string> commands1;
|
||||||
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
|
||||||
if(this->Target->GetPropertyAsBool("ENABLE_EXPORTS"))
|
if(this->Target->IsExecutableWithExports())
|
||||||
{
|
{
|
||||||
// If a separate rule for creating an import library is specified
|
// If a separate rule for creating an import library is specified
|
||||||
// add it now.
|
// add it now.
|
||||||
|
@ -869,7 +869,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
|
|||||||
for(cmTarget::LinkLibraryVectorType::const_iterator j = libs.begin();
|
for(cmTarget::LinkLibraryVectorType::const_iterator j = libs.begin();
|
||||||
j != libs.end(); ++j)
|
j != libs.end(); ++j)
|
||||||
{
|
{
|
||||||
if(cmTarget const* linkee = gg->FindTarget(0, j->first.c_str(), false))
|
if(cmTarget const* linkee = gg->FindTarget(0, j->first.c_str()))
|
||||||
{
|
{
|
||||||
if(emitted.insert(linkee).second)
|
if(emitted.insert(linkee).second)
|
||||||
{
|
{
|
||||||
@ -1371,7 +1371,7 @@ void cmMakefileTargetGenerator
|
|||||||
{
|
{
|
||||||
// Depend on other CMake targets.
|
// Depend on other CMake targets.
|
||||||
if(cmTarget* tgt =
|
if(cmTarget* tgt =
|
||||||
this->GlobalGenerator->FindTarget(0, lib->first.c_str(), false))
|
this->GlobalGenerator->FindTarget(0, lib->first.c_str()))
|
||||||
{
|
{
|
||||||
if(const char* location =
|
if(const char* location =
|
||||||
tgt->GetLocation(this->LocalGenerator->ConfigurationName.c_str()))
|
tgt->GetLocation(this->LocalGenerator->ConfigurationName.c_str()))
|
||||||
|
@ -220,9 +220,7 @@ bool cmSetPropertyCommand::HandleTargetMode()
|
|||||||
for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
|
for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
|
||||||
ni != this->Names.end(); ++ni)
|
ni != this->Names.end(); ++ni)
|
||||||
{
|
{
|
||||||
if(cmTarget* target =
|
if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
|
||||||
->FindTarget(0, ni->c_str(), true))
|
|
||||||
{
|
{
|
||||||
// Handle the current target.
|
// Handle the current target.
|
||||||
if(!this->HandleTarget(target))
|
if(!this->HandleTarget(target))
|
||||||
|
@ -95,9 +95,7 @@ bool cmSetTargetPropertiesCommand
|
|||||||
std::vector<std::string> &propertyPairs,
|
std::vector<std::string> &propertyPairs,
|
||||||
cmMakefile *mf)
|
cmMakefile *mf)
|
||||||
{
|
{
|
||||||
cmTarget* target =
|
if(cmTarget* target = mf->FindTargetToUse(tname))
|
||||||
mf->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, tname, true);
|
|
||||||
if ( target)
|
|
||||||
{
|
{
|
||||||
// now loop through all the props and set them
|
// now loop through all the props and set them
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
|
@ -153,6 +153,96 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||||||
"A target property that can be set to override the suffix "
|
"A target property that can be set to override the suffix "
|
||||||
"(such as \".lib\") on an import library name.");
|
"(such as \".lib\") on an import library name.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED", cmProperty::TARGET,
|
||||||
|
"Read-only indication of whether a target is IMPORTED.",
|
||||||
|
"The boolean value of this property is true for targets created with "
|
||||||
|
"the IMPORTED option to add_executable or add_library. "
|
||||||
|
"It is false for targets built within the project.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_CONFIGURATIONS", cmProperty::TARGET,
|
||||||
|
"Configurations provided for an IMPORTED target.",
|
||||||
|
"Lists configuration names available for an IMPORTED target. "
|
||||||
|
"The names correspond to configurations defined in the project from "
|
||||||
|
"which the target is imported. "
|
||||||
|
"If the importing project uses a different set of configurations "
|
||||||
|
"the names may be mapped using the MAP_IMPORTED_CONFIG_<CONFIG> "
|
||||||
|
"property. "
|
||||||
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_ENABLE_EXPORTS", cmProperty::TARGET,
|
||||||
|
"Enable linking to an IMPORTED executable target.",
|
||||||
|
"Indicates that an IMPORTED executable target exports symbols for "
|
||||||
|
"use by plugin modules. "
|
||||||
|
"This is the imported target equivalent of the ENABLE_EXPORTS "
|
||||||
|
"property.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_IMPLIB", cmProperty::TARGET,
|
||||||
|
"Full path to the import library for an IMPORTED target.",
|
||||||
|
"Specifies the location of the \".lib\" part of a windows DLL. "
|
||||||
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_IMPLIB_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Per-configuration version of IMPORTED_IMPLIB property.",
|
||||||
|
"This property is used when loading settings for the <CONFIG> "
|
||||||
|
"configuration of an imported target. "
|
||||||
|
"Configuration names correspond to those provided by the project "
|
||||||
|
"from which the target is imported.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_LINK_LIBRARIES", cmProperty::TARGET,
|
||||||
|
"Transitive link dependencies of an IMPORTED target.",
|
||||||
|
"Lists dependencies that must be linked when an IMPORTED library "
|
||||||
|
"target is linked to another target. "
|
||||||
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_LINK_LIBRARIES_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Per-configuration version of IMPORTED_LINK_LIBRARIES property.",
|
||||||
|
"This property is used when loading settings for the <CONFIG> "
|
||||||
|
"configuration of an imported target. "
|
||||||
|
"Configuration names correspond to those provided by the project "
|
||||||
|
"from which the target is imported.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_LOCATION", cmProperty::TARGET,
|
||||||
|
"Full path to the main file on disk for an IMPORTED target.",
|
||||||
|
"Specifies the location of an IMPORTED target file on disk. "
|
||||||
|
"For executables this is the location of the executable file. "
|
||||||
|
"For static libraries and modules this is the location of the "
|
||||||
|
"library or module. "
|
||||||
|
"For shared libraries on non-DLL platforms this is the location of "
|
||||||
|
"the shared library. "
|
||||||
|
"For DLLs this is the location of the \".dll\" part of the library. "
|
||||||
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_LOCATION_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Per-configuration version of IMPORTED_LOCATION property.",
|
||||||
|
"This property is used when loading settings for the <CONFIG> "
|
||||||
|
"configuration of an imported target. "
|
||||||
|
"Configuration names correspond to those provided by the project "
|
||||||
|
"from which the target is imported.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_SONAME", cmProperty::TARGET,
|
||||||
|
"The \"soname\" of an IMPORTED target of shared library type.",
|
||||||
|
"Specifies the \"soname\" embedded in an imported shared library. "
|
||||||
|
"This is meaningful only on platforms supporting the feature. "
|
||||||
|
"Ignored for non-imported targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("IMPORTED_SONAME_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Per-configuration version of IMPORTED_SONAME property.",
|
||||||
|
"This property is used when loading settings for the <CONFIG> "
|
||||||
|
"configuration of an imported target. "
|
||||||
|
"Configuration names correspond to those provided by the project "
|
||||||
|
"from which the target is imported.");
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("EXCLUDE_FROM_ALL", cmProperty::TARGET,
|
("EXCLUDE_FROM_ALL", cmProperty::TARGET,
|
||||||
"Exclude the target from the all target.",
|
"Exclude the target from the all target.",
|
||||||
@ -206,11 +296,37 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("LOCATION", cmProperty::TARGET,
|
("LOCATION", cmProperty::TARGET,
|
||||||
"Where a target will be written on disk.",
|
"Deprecated. Use LOCATION_<CONFIG> or avoid altogether.",
|
||||||
"A read only property on a target that indicates where that target "
|
"This property is provided for compatibility with CMake 2.4 and below. "
|
||||||
"will be written. For libraries and executables this will be where "
|
"It was meant to get the location of an executable target's output file "
|
||||||
"the file is written on disk. This property is computed based on a "
|
"for use in add_custom_command. "
|
||||||
"number of other settings.");
|
"In CMake 2.6 and above add_custom_command automatically recognizes a "
|
||||||
|
"target name in its COMMAND and DEPENDS options and computes the "
|
||||||
|
"target location. Therefore this property need not be used. "
|
||||||
|
"This property is not defined for IMPORTED targets because they "
|
||||||
|
"were not available in CMake 2.4 or below anyway.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("LOCATION_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Read-only property providing a target location on disk.",
|
||||||
|
"A read-only property that indicates where a target's main file is "
|
||||||
|
"located on disk for the configuration <CONFIG>. "
|
||||||
|
"The property is defined only for library and executable targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Map from project configuration to IMPORTED target's configuration.",
|
||||||
|
"List configurations of an imported target that may be used for "
|
||||||
|
"the current project's <CONFIG> configuration. "
|
||||||
|
"Targets imported from another project may not provide the same set "
|
||||||
|
"of configuration names available in the current project. "
|
||||||
|
"Setting this property tells CMake what imported configurations are "
|
||||||
|
"suitable for use when building the <CONFIG> configuration. "
|
||||||
|
"The first configuration in the list found to be provided by the "
|
||||||
|
"imported target is selected. If no matching configurations are "
|
||||||
|
"available the imported target is considered to be not found. "
|
||||||
|
"This property is ignored for non-imported targets.",
|
||||||
|
false /* TODO: make this chained */ );
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("OUTPUT_NAME", cmProperty::TARGET,
|
("OUTPUT_NAME", cmProperty::TARGET,
|
||||||
@ -480,6 +596,25 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::IsExecutableWithExports()
|
||||||
|
{
|
||||||
|
if(this->GetType() == cmTarget::EXECUTABLE)
|
||||||
|
{
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
// The "IMPORTED_" namespace is used for properties exported
|
||||||
|
// from the project providing imported targets.
|
||||||
|
return this->GetPropertyAsBool("IMPORTED_ENABLE_EXPORTS");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this->GetPropertyAsBool("ENABLE_EXPORTS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class cmTargetTraceDependencies
|
class cmTargetTraceDependencies
|
||||||
{
|
{
|
||||||
@ -603,8 +738,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for a non-imported target with this name.
|
// Check for a non-imported target with this name.
|
||||||
if(cmTarget* t =
|
if(cmTarget* t = this->GlobalGenerator->FindTarget(0, util.c_str()))
|
||||||
this->GlobalGenerator->FindTarget(0, util.c_str(), false))
|
|
||||||
{
|
{
|
||||||
// If we find the target and the dep was given as a full path,
|
// If we find the target and the dep was given as a full path,
|
||||||
// then make sure it was not a full path to something else, and
|
// then make sure it was not a full path to something else, and
|
||||||
@ -671,8 +805,7 @@ cmTargetTraceDependencies
|
|||||||
{
|
{
|
||||||
std::string const& command = *cit->begin();
|
std::string const& command = *cit->begin();
|
||||||
// Look for a non-imported target with this name.
|
// Look for a non-imported target with this name.
|
||||||
if(cmTarget* t =
|
if(cmTarget* t = this->GlobalGenerator->FindTarget(0, command.c_str()))
|
||||||
this->GlobalGenerator->FindTarget(0, command.c_str(), false))
|
|
||||||
{
|
{
|
||||||
if(t->GetType() == cmTarget::EXECUTABLE)
|
if(t->GetType() == cmTarget::EXECUTABLE)
|
||||||
{
|
{
|
||||||
@ -1287,6 +1420,13 @@ void cmTarget::SetProperty(const char* prop, const char* value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->Properties.SetProperty(prop, value, cmProperty::TARGET);
|
this->Properties.SetProperty(prop, value, cmProperty::TARGET);
|
||||||
|
|
||||||
|
// If imported information is being set, wipe out cached
|
||||||
|
// information.
|
||||||
|
if(this->IsImported() && strncmp(prop, "IMPORTED", 8) == 0)
|
||||||
|
{
|
||||||
|
this->ImportInfoMap.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1297,6 +1437,13 @@ void cmTarget::AppendProperty(const char* prop, const char* value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->Properties.AppendProperty(prop, value, cmProperty::TARGET);
|
this->Properties.AppendProperty(prop, value, cmProperty::TARGET);
|
||||||
|
|
||||||
|
// If imported information is being set, wipe out cached
|
||||||
|
// information.
|
||||||
|
if(this->IsImported() && strncmp(prop, "IMPORTED", 8) == 0)
|
||||||
|
{
|
||||||
|
this->ImportInfoMap.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1319,10 +1466,11 @@ const char* cmTarget::GetDirectory(const char* config, bool implib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char* cmTarget::ImportedGetDirectory(const char* config, bool)
|
const char* cmTarget::ImportedGetDirectory(const char* config, bool implib)
|
||||||
{
|
{
|
||||||
const char* location=this->GetLocation(config);
|
this->Directory =
|
||||||
this->Directory = cmSystemTools::GetFilenamePath(location);
|
cmSystemTools::GetFilenamePath(
|
||||||
|
this->ImportedGetFullPath(config, implib));
|
||||||
return this->Directory.c_str();
|
return this->Directory.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,18 +1508,8 @@ const char* cmTarget::GetLocation(const char* config)
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char* cmTarget::ImportedGetLocation(const char* config)
|
const char* cmTarget::ImportedGetLocation(const char* config)
|
||||||
{
|
{
|
||||||
if ((config) && (strlen(config)))
|
this->Location = this->ImportedGetFullPath(config, false);
|
||||||
{
|
return this->Location.c_str();
|
||||||
std::string propertyName=cmSystemTools::UpperCase(config);
|
|
||||||
propertyName+="_LOCATION";
|
|
||||||
const char* configLocation=this->GetProperty(propertyName.c_str());
|
|
||||||
if ((configLocation) && (strlen(configLocation)))
|
|
||||||
{
|
|
||||||
return configLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->GetProperty("LOCATION");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1484,38 +1622,41 @@ const char *cmTarget::GetProperty(const char* prop,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use GetLocation() for imported targets, because there this
|
// Watch for special "computed" properties that are dependent on
|
||||||
// calls GetProperty() to get the location...
|
// other properties or variables. Always recompute them.
|
||||||
if (!this->IsImported())
|
if(this->GetType() == cmTarget::EXECUTABLE ||
|
||||||
|
this->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||||
|
this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
this->GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
{
|
{
|
||||||
// watch for special "computed" properties that are dependent on other
|
if(!this->IsImported() && strcmp(prop,"LOCATION") == 0)
|
||||||
// properties or variables, always recompute them
|
|
||||||
if (!strcmp(prop,"LOCATION"))
|
|
||||||
{
|
{
|
||||||
// Set the LOCATION property of the target. Note that this
|
// Set the LOCATION property of the target. Note that this
|
||||||
// cannot take into account the per-configuration name of the
|
// cannot take into account the per-configuration name of the
|
||||||
// target because the configuration type may not be known at
|
// target because the configuration type may not be known at
|
||||||
// CMake time. We should deprecate this feature and instead
|
// CMake time. It is now deprecated as described in the
|
||||||
// support transforming an executable target name given as the
|
// documentation.
|
||||||
// command part of custom commands into the proper path at
|
|
||||||
// build time. Alternatively we could put environment
|
|
||||||
// variable settings in all custom commands that hold the name
|
|
||||||
// of the target for each configuration and then give a
|
|
||||||
// reference to the variable in the location.
|
|
||||||
this->SetProperty("LOCATION", this->GetLocation(0));
|
this->SetProperty("LOCATION", this->GetLocation(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-configuration location can be computed.
|
// Support "LOCATION_<CONFIG>".
|
||||||
|
if(strncmp(prop, "LOCATION_", 9) == 0)
|
||||||
|
{
|
||||||
|
std::string configName = prop+9;
|
||||||
|
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Support "<CONFIG>_LOCATION" for compatiblity.
|
||||||
int len = static_cast<int>(strlen(prop));
|
int len = static_cast<int>(strlen(prop));
|
||||||
if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0)
|
if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0)
|
||||||
{
|
{
|
||||||
std::string configName(prop, len-9);
|
std::string configName(prop, len-9);
|
||||||
|
if(configName != "IMPORTED")
|
||||||
|
{
|
||||||
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(strcmp(prop, "OBJECT_FILES") == 0)
|
|
||||||
{
|
|
||||||
this->ComputeObjectFiles();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1750,13 +1891,55 @@ std::string cmTarget::GetPDBName(const char* config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetFullName(const char* config, bool implib)
|
std::string cmTarget::GetSOName(const char* config)
|
||||||
{
|
{
|
||||||
return this->GetFullNameInternal(this->GetType(), config, implib);
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
// Lookup the imported soname.
|
||||||
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
||||||
|
{
|
||||||
|
return info->SOName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Compute the soname that will be built.
|
||||||
|
std::string name;
|
||||||
|
std::string soName;
|
||||||
|
std::string realName;
|
||||||
|
std::string impName;
|
||||||
|
std::string pdbName;
|
||||||
|
this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
|
||||||
|
return soName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::GetFullName(std::string& prefix, std::string& base,
|
std::string cmTarget::GetFullName(const char* config, bool implib)
|
||||||
|
{
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
return this->GetFullNameImported(config, implib);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this->GetFullNameInternal(this->GetType(), config, implib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmTarget::GetFullNameImported(const char* config, bool implib)
|
||||||
|
{
|
||||||
|
return cmSystemTools::GetFilenameName(
|
||||||
|
this->ImportedGetFullPath(config, implib));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GetFullNameComponents(std::string& prefix, std::string& base,
|
||||||
std::string& suffix, const char* config,
|
std::string& suffix, const char* config,
|
||||||
bool implib)
|
bool implib)
|
||||||
{
|
{
|
||||||
@ -1766,6 +1949,19 @@ void cmTarget::GetFullName(std::string& prefix, std::string& base,
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetFullPath(const char* config, bool implib)
|
std::string cmTarget::GetFullPath(const char* config, bool implib)
|
||||||
|
{
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
return this->ImportedGetFullPath(config, implib);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this->NormalGetFullPath(config, implib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmTarget::NormalGetFullPath(const char* config, bool implib)
|
||||||
{
|
{
|
||||||
// Start with the output directory for the target.
|
// Start with the output directory for the target.
|
||||||
std::string fpath = this->GetDirectory(config, implib);
|
std::string fpath = this->GetDirectory(config, implib);
|
||||||
@ -1777,7 +1973,30 @@ std::string cmTarget::GetFullPath(const char* config, bool implib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmTarget::GetFullNameInternal(TargetType type, const char* config,
|
std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
|
||||||
|
{
|
||||||
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
||||||
|
{
|
||||||
|
if(implib)
|
||||||
|
{
|
||||||
|
return info->ImportLibrary;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return info->Location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string result = this->GetName();
|
||||||
|
result += "-NOTFOUND";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string
|
||||||
|
cmTarget::GetFullNameInternal(TargetType type, const char* config,
|
||||||
bool implib)
|
bool implib)
|
||||||
{
|
{
|
||||||
std::string prefix;
|
std::string prefix;
|
||||||
@ -1794,43 +2013,6 @@ void cmTarget::GetFullNameInternal(TargetType type,
|
|||||||
std::string& outPrefix,
|
std::string& outPrefix,
|
||||||
std::string& outBase,
|
std::string& outBase,
|
||||||
std::string& outSuffix)
|
std::string& outSuffix)
|
||||||
{
|
|
||||||
if (this->IsImported())
|
|
||||||
{
|
|
||||||
this->ImportedGetFullNameInternal(type, config, implib,
|
|
||||||
outPrefix, outBase, outSuffix);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->NormalGetFullNameInternal(type, config, implib,
|
|
||||||
outPrefix, outBase, outSuffix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmTarget::ImportedGetFullNameInternal(TargetType ,
|
|
||||||
const char* config,
|
|
||||||
bool ,
|
|
||||||
std::string& outPrefix,
|
|
||||||
std::string& outBase,
|
|
||||||
std::string& outSuffix)
|
|
||||||
{
|
|
||||||
// find the basename, suffix and prefix from getLocation()
|
|
||||||
// implib ?
|
|
||||||
std::string location=this->GetLocation(config);
|
|
||||||
outBase=cmSystemTools::GetFilenameWithoutExtension(location);
|
|
||||||
outSuffix = cmSystemTools::GetFilenameExtension(location);
|
|
||||||
outPrefix = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmTarget::NormalGetFullNameInternal(TargetType type,
|
|
||||||
const char* config,
|
|
||||||
bool implib,
|
|
||||||
std::string& outPrefix,
|
|
||||||
std::string& outBase,
|
|
||||||
std::string& outSuffix)
|
|
||||||
{
|
{
|
||||||
// Use just the target name for non-main target types.
|
// Use just the target name for non-main target types.
|
||||||
if(type != cmTarget::STATIC_LIBRARY &&
|
if(type != cmTarget::STATIC_LIBRARY &&
|
||||||
@ -2019,6 +2201,14 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
|
|||||||
TargetType type,
|
TargetType type,
|
||||||
const char* config)
|
const char* config)
|
||||||
{
|
{
|
||||||
|
// This should not be called for imported targets.
|
||||||
|
// TODO: Split cmTarget into a class hierarchy to get compile-time
|
||||||
|
// enforcement of the limited imported target API.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the name of the soname flag variable for this language.
|
// Construct the name of the soname flag variable for this language.
|
||||||
const char* ll =
|
const char* ll =
|
||||||
this->GetLinkerLanguage(
|
this->GetLinkerLanguage(
|
||||||
@ -2140,6 +2330,14 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
|
|||||||
TargetType type,
|
TargetType type,
|
||||||
const char* config)
|
const char* config)
|
||||||
{
|
{
|
||||||
|
// This should not be called for imported targets.
|
||||||
|
// TODO: Split cmTarget into a class hierarchy to get compile-time
|
||||||
|
// enforcement of the limited imported target API.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
// This versioning is supported only for executables and then only
|
// This versioning is supported only for executables and then only
|
||||||
// when the platform supports symbolic links.
|
// when the platform supports symbolic links.
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
@ -2554,8 +2752,7 @@ const char* cmTarget::GetExportMacro()
|
|||||||
// Define the symbol for targets that export symbols.
|
// Define the symbol for targets that export symbols.
|
||||||
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
|
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
this->GetType() == cmTarget::MODULE_LIBRARY ||
|
this->GetType() == cmTarget::MODULE_LIBRARY ||
|
||||||
this->GetType() == cmTarget::EXECUTABLE &&
|
this->IsExecutableWithExports())
|
||||||
this->GetPropertyAsBool("ENABLE_EXPORTS"))
|
|
||||||
{
|
{
|
||||||
if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
|
if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
|
||||||
{
|
{
|
||||||
@ -2618,3 +2815,208 @@ bool cmTarget::IsChrpathAvailable()
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget::ImportInfo const*
|
||||||
|
cmTarget::GetImportInfo(const char* config)
|
||||||
|
{
|
||||||
|
// There is no imported information for non-imported targets.
|
||||||
|
if(!this->IsImported())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup/compute/cache the import information for this
|
||||||
|
// configuration.
|
||||||
|
std::string config_upper;
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
config_upper = cmSystemTools::UpperCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config_upper = "NOCONFIG";
|
||||||
|
}
|
||||||
|
ImportInfoMapType::const_iterator i =
|
||||||
|
this->ImportInfoMap.find(config_upper);
|
||||||
|
if(i == this->ImportInfoMap.end())
|
||||||
|
{
|
||||||
|
ImportInfo info;
|
||||||
|
this->ComputeImportInfo(config_upper, info);
|
||||||
|
ImportInfoMapType::value_type entry(config_upper, info);
|
||||||
|
i = this->ImportInfoMap.insert(entry).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the location is empty then the target is not available for
|
||||||
|
// this configuration.
|
||||||
|
if(i->second.Location.empty())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the import information.
|
||||||
|
return &i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
||||||
|
ImportInfo& info)
|
||||||
|
{
|
||||||
|
// This method finds information about an imported target from its
|
||||||
|
// properties. The "IMPORTED_" namespace is reserved for properties
|
||||||
|
// defined by the project exporting the target.
|
||||||
|
|
||||||
|
// Track the configuration-specific property suffix.
|
||||||
|
std::string suffix = "_";
|
||||||
|
suffix += desired_config;
|
||||||
|
|
||||||
|
// Look for a mapping from the current project's configuration to
|
||||||
|
// the imported project's configuration.
|
||||||
|
std::vector<std::string> mappedConfigs;
|
||||||
|
{
|
||||||
|
std::string mapProp = "MAP_IMPORTED_CONFIG_";
|
||||||
|
mapProp += desired_config;
|
||||||
|
if(const char* mapValue = this->GetProperty(mapProp.c_str()))
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(mapValue, mappedConfigs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a mapping was found, check its configurations.
|
||||||
|
const char* loc = 0;
|
||||||
|
for(std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
|
||||||
|
!loc && mci != mappedConfigs.end(); ++mci)
|
||||||
|
{
|
||||||
|
// Look for this configuration.
|
||||||
|
std::string mcUpper = cmSystemTools::UpperCase(mci->c_str());
|
||||||
|
std::string locProp = "IMPORTED_LOCATION_";
|
||||||
|
locProp += mcUpper;
|
||||||
|
loc = this->GetProperty(locProp.c_str());
|
||||||
|
|
||||||
|
// If it was found, use it for all properties below.
|
||||||
|
if(loc)
|
||||||
|
{
|
||||||
|
suffix = "_";
|
||||||
|
suffix += mcUpper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we needed to find one of the mapped configurations but did not
|
||||||
|
// then the target is not found. The project does not want any
|
||||||
|
// other configuration.
|
||||||
|
if(!mappedConfigs.empty() && !loc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have not yet found it then there are no mapped
|
||||||
|
// configurations. Look for an exact-match.
|
||||||
|
if(!loc)
|
||||||
|
{
|
||||||
|
std::string locProp = "IMPORTED_LOCATION";
|
||||||
|
locProp += suffix;
|
||||||
|
loc = this->GetProperty(locProp.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have not yet found it then there are no mapped
|
||||||
|
// configurations and no exact match.
|
||||||
|
if(!loc)
|
||||||
|
{
|
||||||
|
// The suffix computed above is not useful.
|
||||||
|
suffix = "";
|
||||||
|
|
||||||
|
// Look for a configuration-less location. This may be set by
|
||||||
|
// manually-written code.
|
||||||
|
loc = this->GetProperty("IMPORTED_LOCATION");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have not yet found it then the project is willing to try
|
||||||
|
// any available configuration.
|
||||||
|
if(!loc)
|
||||||
|
{
|
||||||
|
std::vector<std::string> availableConfigs;
|
||||||
|
if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS"))
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(iconfigs, availableConfigs);
|
||||||
|
}
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
aci = availableConfigs.begin();
|
||||||
|
!loc && aci != availableConfigs.end(); ++aci)
|
||||||
|
{
|
||||||
|
suffix = "_";
|
||||||
|
suffix += cmSystemTools::UpperCase(availableConfigs[0]);
|
||||||
|
std::string locProp = "IMPORTED_LOCATION";
|
||||||
|
locProp += suffix;
|
||||||
|
loc = this->GetProperty(locProp.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have not yet found it then the target is not available.
|
||||||
|
if(!loc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A provided configuration has been chosen. Load the
|
||||||
|
// configuration's properties.
|
||||||
|
info.Location = loc;
|
||||||
|
|
||||||
|
// Get the soname.
|
||||||
|
if(this->GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
|
{
|
||||||
|
std::string soProp = "IMPORTED_SONAME";
|
||||||
|
soProp += suffix;
|
||||||
|
if(const char* config_soname = this->GetProperty(soProp.c_str()))
|
||||||
|
{
|
||||||
|
info.SOName = config_soname;
|
||||||
|
}
|
||||||
|
else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
|
||||||
|
{
|
||||||
|
info.SOName = soname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the import library.
|
||||||
|
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
this->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
std::string impProp = "IMPORTED_IMPLIB";
|
||||||
|
impProp += suffix;
|
||||||
|
if(const char* config_implib = this->GetProperty(impProp.c_str()))
|
||||||
|
{
|
||||||
|
info.ImportLibrary = config_implib;
|
||||||
|
}
|
||||||
|
else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
|
||||||
|
{
|
||||||
|
info.ImportLibrary = implib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the link dependencies.
|
||||||
|
{
|
||||||
|
std::string linkProp = "IMPORTED_LINK_LIBRARIES";
|
||||||
|
linkProp += suffix;
|
||||||
|
if(const char* config_libs = this->GetProperty(linkProp.c_str()))
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(config_libs, info.LinkLibraries);
|
||||||
|
}
|
||||||
|
else if(const char* libs = this->GetProperty("IMPORTED_LINK_LIBRARIES"))
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(libs, info.LinkLibraries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::vector<std::string> const*
|
||||||
|
cmTarget::GetImportedLinkLibraries(const char* config)
|
||||||
|
{
|
||||||
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
||||||
|
{
|
||||||
|
return &info->LinkLibraries;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -194,6 +194,11 @@ public:
|
|||||||
|
|
||||||
bool IsImported() const {return this->IsImportedTarget;}
|
bool IsImported() const {return this->IsImportedTarget;}
|
||||||
|
|
||||||
|
/** Get link libraries for the given configuration of an imported
|
||||||
|
target. */
|
||||||
|
std::vector<std::string> const*
|
||||||
|
GetImportedLinkLibraries(const char* config);
|
||||||
|
|
||||||
/** Get the directory in which this target will be built. If the
|
/** Get the directory in which this target will be built. If the
|
||||||
configuration name is given then the generator will add its
|
configuration name is given then the generator will add its
|
||||||
subdirectory for that configuration. Otherwise just the canonical
|
subdirectory for that configuration. Otherwise just the canonical
|
||||||
@ -226,13 +231,16 @@ public:
|
|||||||
/** Get the full name of the target according to the settings in its
|
/** Get the full name of the target according to the settings in its
|
||||||
makefile. */
|
makefile. */
|
||||||
std::string GetFullName(const char* config=0, bool implib = false);
|
std::string GetFullName(const char* config=0, bool implib = false);
|
||||||
void GetFullName(std::string& prefix,
|
void GetFullNameComponents(std::string& prefix,
|
||||||
std::string& base, std::string& suffix,
|
std::string& base, std::string& suffix,
|
||||||
const char* config=0, bool implib = false);
|
const char* config=0, bool implib = false);
|
||||||
|
|
||||||
/** Get the name of the pdb file for the target. */
|
/** Get the name of the pdb file for the target. */
|
||||||
std::string GetPDBName(const char* config=0);
|
std::string GetPDBName(const char* config=0);
|
||||||
|
|
||||||
|
/** Get the soname of the target. Allowed only for a shared library. */
|
||||||
|
std::string GetSOName(const char* config);
|
||||||
|
|
||||||
/** Get the full path to the target according to the settings in its
|
/** Get the full path to the target according to the settings in its
|
||||||
makefile and the configuration type. */
|
makefile and the configuration type. */
|
||||||
std::string GetFullPath(const char* config=0, bool implib = false);
|
std::string GetFullPath(const char* config=0, bool implib = false);
|
||||||
@ -308,6 +316,10 @@ public:
|
|||||||
// until we have per-target object file properties.
|
// until we have per-target object file properties.
|
||||||
void GetLanguages(std::set<cmStdString>& languages) const;
|
void GetLanguages(std::set<cmStdString>& languages) const;
|
||||||
|
|
||||||
|
/** Return whether this target is an executable with symbol exports
|
||||||
|
enabled. */
|
||||||
|
bool IsExecutableWithExports();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
@ -393,20 +405,14 @@ private:
|
|||||||
const char* ImportedGetLocation(const char* config);
|
const char* ImportedGetLocation(const char* config);
|
||||||
const char* NormalGetLocation(const char* config);
|
const char* NormalGetLocation(const char* config);
|
||||||
|
|
||||||
void NormalGetFullNameInternal(TargetType type, const char* config,
|
std::string GetFullNameImported(const char* config, bool implib);
|
||||||
bool implib,
|
|
||||||
std::string& outPrefix,
|
|
||||||
std::string& outBase,
|
|
||||||
std::string& outSuffix);
|
|
||||||
void ImportedGetFullNameInternal(TargetType type, const char* config,
|
|
||||||
bool implib,
|
|
||||||
std::string& outPrefix,
|
|
||||||
std::string& outBase,
|
|
||||||
std::string& outSuffix);
|
|
||||||
|
|
||||||
const char* ImportedGetDirectory(const char* config, bool implib);
|
const char* ImportedGetDirectory(const char* config, bool implib);
|
||||||
const char* NormalGetDirectory(const char* config, bool implib);
|
const char* NormalGetDirectory(const char* config, bool implib);
|
||||||
|
|
||||||
|
std::string ImportedGetFullPath(const char* config, bool implib);
|
||||||
|
std::string NormalGetFullPath(const char* config, bool implib);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::vector<cmCustomCommand> PreBuildCommands;
|
std::vector<cmCustomCommand> PreBuildCommands;
|
||||||
@ -436,6 +442,19 @@ private:
|
|||||||
bool DLLPlatform;
|
bool DLLPlatform;
|
||||||
bool IsImportedTarget;
|
bool IsImportedTarget;
|
||||||
|
|
||||||
|
// Cache import information from properties for each configuration.
|
||||||
|
struct ImportInfo
|
||||||
|
{
|
||||||
|
std::string Location;
|
||||||
|
std::string SOName;
|
||||||
|
std::string ImportLibrary;
|
||||||
|
std::vector<std::string> LinkLibraries;
|
||||||
|
};
|
||||||
|
typedef std::map<cmStdString, ImportInfo> ImportInfoMapType;
|
||||||
|
ImportInfoMapType ImportInfoMap;
|
||||||
|
ImportInfo const* GetImportInfo(const char* config);
|
||||||
|
void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
|
||||||
|
|
||||||
// The cmMakefile instance that owns this target. This should
|
// The cmMakefile instance that owns this target. This should
|
||||||
// always be set.
|
// always be set.
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user