Commit 9e64d5b2 authored by Brad King's avatar Brad King
Browse files

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
parent afad1243
......@@ -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;
// Construct the property name.
std::string prop = "IMPORTED_IMPLIB";
prop += suffix;
// Append the installed file name.
value += itgen->GetInstallFilename(target, config,
cmInstallTargetGenerator::NameImplib);
// Store the property.
properties[prop] = value;
}
else if(itgen->GetTarget()->IsAppBundleOnApple())
else
{
value += ".app/Contents/MacOS/";
value += fname;
}
// Construct the property name.
std::string prop = "IMPORTED_LOCATION";
prop += suffix;
// Store the property.
properties[prop] = value;
}
// 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment