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