ENH: Improve exporting/importing of targets
- Use real name instead of link for location of versioned targets - Error when a target is exported multiple times
This commit is contained in:
parent
afad124313
commit
9e64d5b272
|
@ -33,8 +33,20 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
tei != this->Exports->end(); ++tei)
|
||||
{
|
||||
cmTarget* te = *tei;
|
||||
this->ExportedTargets.insert(te);
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
if(this->ExportedTargets.insert(te).second)
|
||||
{
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty())
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "given target \"" << te->GetName() << "\" more than once.";
|
||||
this->ExportCommand->ErrorMessage = e.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate import file content for each configuration.
|
||||
|
@ -93,12 +105,21 @@ cmExportBuildFileGenerator
|
|||
{
|
||||
std::string prop = "IMPORTED_LOCATION";
|
||||
prop += suffix;
|
||||
std::string value = target->GetFullPath(config, false);
|
||||
if(target->IsAppBundleOnApple())
|
||||
std::string value;
|
||||
if(target->IsFrameworkOnApple())
|
||||
{
|
||||
value = target->GetFullPath(config, false);
|
||||
}
|
||||
else if(target->IsAppBundleOnApple())
|
||||
{
|
||||
value = target->GetFullPath(config, false);
|
||||
value += ".app/Contents/MacOS/";
|
||||
value += target->GetFullName(config, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = target->GetFullPath(config, false, true);
|
||||
}
|
||||
properties[prop] = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ bool cmExportCommand
|
|||
}
|
||||
|
||||
// Generate the import file.
|
||||
if(!ebfg.GenerateImportFile())
|
||||
if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty())
|
||||
{
|
||||
this->SetError("could not write export file.");
|
||||
return false;
|
||||
|
|
|
@ -36,8 +36,19 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
tei != this->ExportSet->end(); ++tei)
|
||||
{
|
||||
cmTargetExport* te = *tei;
|
||||
this->ExportedTargets.insert(te->Target);
|
||||
this->GenerateImportTargetCode(os, te->Target);
|
||||
if(this->ExportedTargets.insert(te->Target).second)
|
||||
{
|
||||
this->GenerateImportTargetCode(os, te->Target);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
|
||||
<< "includes target \"" << te->Target->GetName()
|
||||
<< "\" more than once in the export set.";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now load per-configuration properties for them.
|
||||
|
@ -204,11 +215,8 @@ cmExportInstallFileGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
// Construct the property name.
|
||||
std::string prop = (itgen->IsImportLibrary()?
|
||||
"IMPORTED_IMPLIB" : "IMPORTED_LOCATION");
|
||||
prop += suffix;
|
||||
// Get the target to be installed.
|
||||
cmTarget* target = itgen->GetTarget();
|
||||
|
||||
// Construct the installed location of the target.
|
||||
std::string dest = itgen->GetDestination();
|
||||
|
@ -225,25 +233,47 @@ cmExportInstallFileGenerator
|
|||
value += dest;
|
||||
value += "/";
|
||||
|
||||
// Append the installed file name.
|
||||
std::string fname = itgen->GetInstallFilename(config);
|
||||
value += fname;
|
||||
|
||||
// Fix name for frameworks and bundles.
|
||||
if(itgen->GetTarget()->IsFrameworkOnApple())
|
||||
if(itgen->IsImportLibrary())
|
||||
{
|
||||
value += ".framework/";
|
||||
value += fname;
|
||||
}
|
||||
else if(itgen->GetTarget()->IsAppBundleOnApple())
|
||||
{
|
||||
value += ".app/Contents/MacOS/";
|
||||
value += fname;
|
||||
}
|
||||
// Construct the property name.
|
||||
std::string prop = "IMPORTED_IMPLIB";
|
||||
prop += suffix;
|
||||
|
||||
// Store the property.
|
||||
properties[prop] = value;
|
||||
}
|
||||
// Append the installed file name.
|
||||
value += itgen->GetInstallFilename(target, config,
|
||||
cmInstallTargetGenerator::NameImplib);
|
||||
|
||||
// Store the property.
|
||||
properties[prop] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct the property name.
|
||||
std::string prop = "IMPORTED_LOCATION";
|
||||
prop += suffix;
|
||||
|
||||
// Append the installed file name.
|
||||
if(target->IsFrameworkOnApple())
|
||||
{
|
||||
value += itgen->GetInstallFilename(target, config);
|
||||
value += ".framework/";
|
||||
value += itgen->GetInstallFilename(target, config);
|
||||
}
|
||||
else if(target->IsAppBundleOnApple())
|
||||
{
|
||||
value += itgen->GetInstallFilename(target, config);
|
||||
value += ".app/Contents/MacOS/";
|
||||
value += itgen->GetInstallFilename(target, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
value += itgen->GetInstallFilename(target, config,
|
||||
cmInstallTargetGenerator::NameReal);
|
||||
}
|
||||
|
||||
// Store the property.
|
||||
properties[prop] = value;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -394,6 +394,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
cmInstallFilesGenerator* publicHeaderGenerator = 0;
|
||||
cmInstallFilesGenerator* resourceGenerator = 0;
|
||||
|
||||
// Track whether this is a namelink-only rule.
|
||||
bool namelinkOnly = false;
|
||||
|
||||
switch(target.GetType())
|
||||
{
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
|
@ -464,6 +467,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
libraryGenerator = CreateInstallTargetGenerator(target,
|
||||
libraryArgs, false);
|
||||
libraryGenerator->SetNamelinkMode(namelinkMode);
|
||||
namelinkOnly =
|
||||
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -503,6 +508,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
libraryGenerator = CreateInstallTargetGenerator(target, libraryArgs,
|
||||
false);
|
||||
libraryGenerator->SetNamelinkMode(namelinkMode);
|
||||
namelinkOnly =
|
||||
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -583,7 +590,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
createInstallGeneratorsForTargetFileSets = false;
|
||||
}
|
||||
|
||||
if(createInstallGeneratorsForTargetFileSets)
|
||||
if(createInstallGeneratorsForTargetFileSets && !namelinkOnly)
|
||||
{
|
||||
const char* files = target.GetProperty("PRIVATE_HEADER");
|
||||
if ((files) && (*files))
|
||||
|
@ -673,7 +680,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
this->Makefile->AddInstallGenerator(publicHeaderGenerator);
|
||||
this->Makefile->AddInstallGenerator(resourceGenerator);
|
||||
|
||||
if (!exports.GetString().empty())
|
||||
// Add this install rule to an export if one was specified and
|
||||
// this is not a namelink-only rule.
|
||||
if(!exports.GetString().empty() && !namelinkOnly)
|
||||
{
|
||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
||||
->AddTargetToExports(exports.GetCString(), &target,
|
||||
|
|
|
@ -144,10 +144,10 @@ cmInstallTargetGenerator
|
|||
Indent const& indent)
|
||||
{
|
||||
// Compute the full path to the main installed file for this target.
|
||||
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
|
||||
std::string toInstallPath = this->GetInstallDestination();
|
||||
toInstallPath += "/";
|
||||
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||
this->ImportLibrary, false);
|
||||
toInstallPath += this->GetInstallFilename(this->Target, config, nameType);
|
||||
|
||||
// Track whether post-install operations should be added to the
|
||||
// script.
|
||||
|
@ -194,8 +194,8 @@ cmInstallTargetGenerator
|
|||
// Need to apply install_name_tool and stripping to binary
|
||||
// inside bundle.
|
||||
toInstallPath += ".app/Contents/MacOS/";
|
||||
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||
this->ImportLibrary, false);
|
||||
toInstallPath +=
|
||||
this->GetInstallFilename(this->Target, config, nameType);
|
||||
literal_args += " USE_SOURCE_PERMISSIONS";
|
||||
}
|
||||
else
|
||||
|
@ -250,7 +250,7 @@ cmInstallTargetGenerator
|
|||
// inside framework.
|
||||
toInstallPath += ".framework/";
|
||||
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||
this->ImportLibrary, false);
|
||||
NameNormal);
|
||||
|
||||
literal_args += " USE_SOURCE_PERMISSIONS";
|
||||
}
|
||||
|
@ -369,16 +369,16 @@ cmInstallTargetGenerator
|
|||
std::string
|
||||
cmInstallTargetGenerator::GetInstallFilename(const char* config) const
|
||||
{
|
||||
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
|
||||
return
|
||||
cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
|
||||
this->ImportLibrary, false);
|
||||
nameType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
|
||||
const char* config,
|
||||
bool implib,
|
||||
bool useSOName)
|
||||
NameType nameType)
|
||||
{
|
||||
std::string fname;
|
||||
// Compute the name of the library.
|
||||
|
@ -391,11 +391,16 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
|
|||
target->GetExecutableNames(targetName, targetNameReal,
|
||||
targetNameImport, targetNamePDB,
|
||||
config);
|
||||
if(implib)
|
||||
if(nameType == NameImplib)
|
||||
{
|
||||
// Use the import library name.
|
||||
fname = targetNameImport;
|
||||
}
|
||||
else if(nameType == NameReal)
|
||||
{
|
||||
// Use the canonical name.
|
||||
fname = targetNameReal;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the canonical name.
|
||||
|
@ -411,16 +416,21 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
|
|||
std::string targetNamePDB;
|
||||
target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
|
||||
targetNameImport, targetNamePDB, config);
|
||||
if(implib)
|
||||
if(nameType == NameImplib)
|
||||
{
|
||||
// Use the import library name.
|
||||
fname = targetNameImport;
|
||||
}
|
||||
else if(useSOName)
|
||||
else if(nameType == NameSO)
|
||||
{
|
||||
// Use the soname.
|
||||
fname = targetNameSO;
|
||||
}
|
||||
else if(nameType == NameReal)
|
||||
{
|
||||
// Use the real name.
|
||||
fname = targetNameReal;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the canonical name.
|
||||
|
@ -474,7 +484,7 @@ cmInstallTargetGenerator
|
|||
// The directory portions differ. Append the filename to
|
||||
// create the mapping.
|
||||
std::string fname =
|
||||
this->GetInstallFilename(tgt, config, false, true);
|
||||
this->GetInstallFilename(tgt, config, NameSO);
|
||||
|
||||
// Map from the build-tree install_name.
|
||||
for_build += fname;
|
||||
|
@ -511,8 +521,7 @@ cmInstallTargetGenerator
|
|||
{
|
||||
// Prepare to refer to the install-tree install_name.
|
||||
new_id = for_install;
|
||||
new_id += this->GetInstallFilename(this->Target, config,
|
||||
this->ImportLibrary, true);
|
||||
new_id += this->GetInstallFilename(this->Target, config, NameSO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,20 @@ public:
|
|||
NamelinkModeSkip
|
||||
};
|
||||
void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; }
|
||||
NamelinkModeType GetNamelinkMode() const { return this->NamelinkMode; }
|
||||
|
||||
std::string GetInstallFilename(const char* config) const;
|
||||
static std::string GetInstallFilename(cmTarget*target, const char* config,
|
||||
bool implib, bool useSOName);
|
||||
|
||||
enum NameType
|
||||
{
|
||||
NameNormal,
|
||||
NameImplib,
|
||||
NameSO,
|
||||
NameReal
|
||||
};
|
||||
|
||||
static std::string GetInstallFilename(cmTarget*target, const char* config,
|
||||
NameType nameType = NameNormal);
|
||||
|
||||
cmTarget* GetTarget() const { return this->Target; }
|
||||
bool IsImportLibrary() const { return this->ImportLibrary; }
|
||||
|
|
|
@ -8,6 +8,7 @@ endif(CMAKE_ANSI_CFLAGS)
|
|||
add_library(testExe1lib STATIC testExe1lib.c) # not exported
|
||||
add_executable(testExe1 testExe1.c)
|
||||
target_link_libraries(testExe1 testExe1lib)
|
||||
set_property(TARGET testExe1 PROPERTY VERSION 4)
|
||||
|
||||
add_library(testExe2libImp SHARED testExe2libImp.c)
|
||||
set_property(TARGET testExe2libImp PROPERTY LIBRARY_OUTPUT_DIRECTORY impl)
|
||||
|
@ -27,6 +28,8 @@ set_property(TARGET testLib3Imp PROPERTY LIBRARY_OUTPUT_DIRECTORY impl)
|
|||
add_library(testLib3 SHARED testLib3.c)
|
||||
target_link_libraries(testLib3 testLib3Imp)
|
||||
set_property(TARGET testLib3 PROPERTY LINK_INTERFACE_LIBRARIES "")
|
||||
set_property(TARGET testLib3 PROPERTY VERSION 1.2)
|
||||
set_property(TARGET testLib3 PROPERTY SOVERSION 3)
|
||||
|
||||
add_library(testLib4 SHARED testLib4.c)
|
||||
set_property(TARGET testLib4 PROPERTY FRAMEWORK 1)
|
||||
|
@ -41,7 +44,7 @@ install(
|
|||
testExe2lib
|
||||
EXPORT exp
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
LIBRARY DESTINATION lib NAMELINK_SKIP
|
||||
ARCHIVE DESTINATION lib
|
||||
FRAMEWORK DESTINATION Frameworks
|
||||
BUNDLE DESTINATION Applications
|
||||
|
|
Loading…
Reference in New Issue