ENH: Add InstallNameFixupPath to support installing built frameworks on the Mac. Change Application to Applications in the BundleTest. Also correct small typo (tcl->Tcl) noted in bug 4572.
This commit is contained in:
parent
6d508a3094
commit
9a4e7ea742
|
@ -181,6 +181,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
||||||
targetList.Follows(0);
|
targetList.Follows(0);
|
||||||
genericArgs.ArgumentGroup.Follows(&targetList);
|
genericArgs.ArgumentGroup.Follows(&targetList);
|
||||||
genericArgs.Parse(&genericArgVector.GetVector(), &unknownArgs);
|
genericArgs.Parse(&genericArgVector.GetVector(), &unknownArgs);
|
||||||
|
bool success = genericArgs.Finalize();
|
||||||
|
|
||||||
cmInstallCommandArguments archiveArgs;
|
cmInstallCommandArguments archiveArgs;
|
||||||
cmInstallCommandArguments libraryArgs;
|
cmInstallCommandArguments libraryArgs;
|
||||||
|
@ -219,7 +220,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
||||||
publicHeaderArgs.SetGenericArguments(&genericArgs);
|
publicHeaderArgs.SetGenericArguments(&genericArgs);
|
||||||
privateHeaderArgs.SetGenericArguments(&genericArgs);
|
privateHeaderArgs.SetGenericArguments(&genericArgs);
|
||||||
|
|
||||||
bool success = archiveArgs.Finalize();
|
success = success && archiveArgs.Finalize();
|
||||||
success = success && libraryArgs.Finalize();
|
success = success && libraryArgs.Finalize();
|
||||||
success = success && runtimeArgs.Finalize();
|
success = success && runtimeArgs.Finalize();
|
||||||
success = success && frameworkArgs.Finalize();
|
success = success && frameworkArgs.Finalize();
|
||||||
|
|
|
@ -154,11 +154,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.
|
||||||
std::string toFullPath = "$ENV{DESTDIR}";
|
std::string toInstallPath = this->Destination;
|
||||||
toFullPath += this->Destination;
|
toInstallPath += "/";
|
||||||
toFullPath += "/";
|
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||||
toFullPath += this->GetInstallFilename(this->Target, config,
|
this->ImportLibrary, false);
|
||||||
this->ImportLibrary, false);
|
|
||||||
|
|
||||||
// Compute the list of files to install for this target.
|
// Compute the list of files to install for this target.
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
|
@ -198,9 +197,9 @@ cmInstallTargetGenerator
|
||||||
type = cmTarget::INSTALL_DIRECTORY;
|
type = cmTarget::INSTALL_DIRECTORY;
|
||||||
// Need to apply install_name_tool and stripping to binary
|
// Need to apply install_name_tool and stripping to binary
|
||||||
// inside bundle.
|
// inside bundle.
|
||||||
toFullPath += ".app/Contents/MacOS/";
|
toInstallPath += ".app/Contents/MacOS/";
|
||||||
toFullPath += this->GetInstallFilename(this->Target, config,
|
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||||
this->ImportLibrary, false);
|
this->ImportLibrary, false);
|
||||||
literal_args += " USE_SOURCE_PERMISSIONS";
|
literal_args += " USE_SOURCE_PERMISSIONS";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -234,6 +233,25 @@ cmInstallTargetGenerator
|
||||||
// An import library looks like a static library.
|
// An import library looks like a static library.
|
||||||
type = cmTarget::STATIC_LIBRARY;
|
type = cmTarget::STATIC_LIBRARY;
|
||||||
}
|
}
|
||||||
|
else if(this->Target->GetMakefile()->IsOn("APPLE") &&
|
||||||
|
this->Target->GetPropertyAsBool("FRAMEWORK"))
|
||||||
|
{
|
||||||
|
// Compute the build tree location of the framework directory
|
||||||
|
std::string from1 = fromDirConfig;
|
||||||
|
// Remove trailing slashes
|
||||||
|
cmSystemTools::ConvertToUnixSlashes(from1);
|
||||||
|
files.push_back(from1);
|
||||||
|
|
||||||
|
type = cmTarget::INSTALL_DIRECTORY;
|
||||||
|
|
||||||
|
// Need to apply install_name_tool and stripping to binary
|
||||||
|
// inside framework.
|
||||||
|
toInstallPath += ".framework/";
|
||||||
|
toInstallPath += this->GetInstallFilename(this->Target, config,
|
||||||
|
this->ImportLibrary, false);
|
||||||
|
|
||||||
|
literal_args += " USE_SOURCE_PERMISSIONS";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string from1 = fromDirConfig;
|
std::string from1 = fromDirConfig;
|
||||||
|
@ -266,11 +284,20 @@ cmInstallTargetGenerator
|
||||||
no_rename, literal_args.c_str(),
|
no_rename, literal_args.c_str(),
|
||||||
indent);
|
indent);
|
||||||
|
|
||||||
os << indent << "IF(EXISTS \"" << toFullPath << "\")\n";
|
std::string toDestDirPath = "$ENV{DESTDIR}";
|
||||||
this->AddInstallNamePatchRule(os, indent.Next(), config, toFullPath);
|
if(toInstallPath[0] != '/')
|
||||||
this->AddRanlibRule(os, indent.Next(), type, toFullPath);
|
{
|
||||||
this->AddStripRule(os, indent.Next(), type, toFullPath);
|
toDestDirPath += "/";
|
||||||
os << indent << "ENDIF(EXISTS \"" << toFullPath << "\")\n";
|
}
|
||||||
|
toDestDirPath += toInstallPath;
|
||||||
|
|
||||||
|
this->Target->SetInstallNameFixupPath(toInstallPath.c_str());
|
||||||
|
|
||||||
|
os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
|
||||||
|
this->AddInstallNamePatchRule(os, indent.Next(), config, toDestDirPath);
|
||||||
|
this->AddRanlibRule(os, indent.Next(), type, toDestDirPath);
|
||||||
|
this->AddStripRule(os, indent.Next(), type, toDestDirPath);
|
||||||
|
os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -343,7 +370,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
|
||||||
void
|
void
|
||||||
cmInstallTargetGenerator
|
cmInstallTargetGenerator
|
||||||
::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
|
::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
|
||||||
const char* config, std::string const& toFullPath)
|
const char* config, std::string const& toDestDirPath)
|
||||||
{
|
{
|
||||||
if(this->ImportLibrary ||
|
if(this->ImportLibrary ||
|
||||||
!(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
|
!(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
@ -354,9 +381,9 @@ cmInstallTargetGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix the install_name settings in installed binaries.
|
// Fix the install_name settings in installed binaries.
|
||||||
std::string installNameTool =
|
std::string installNameTool =
|
||||||
this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
|
this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
|
||||||
|
|
||||||
if(!installNameTool.size())
|
if(!installNameTool.size())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -393,16 +420,24 @@ cmInstallTargetGenerator
|
||||||
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
|
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
|
||||||
std::string for_install =
|
std::string for_install =
|
||||||
tgt->GetInstallNameDirForInstallTree(config);
|
tgt->GetInstallNameDirForInstallTree(config);
|
||||||
|
std::string fname =
|
||||||
|
this->GetInstallFilename(tgt, config, false, true);
|
||||||
|
|
||||||
|
// Map from the build-tree install_name.
|
||||||
|
for_build += fname;
|
||||||
|
|
||||||
|
// Map to the install-tree install_name.
|
||||||
|
if (!for_install.empty())
|
||||||
|
{
|
||||||
|
for_install += fname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for_install = tgt->GetInstallNameFixupPath();
|
||||||
|
}
|
||||||
|
|
||||||
if(for_build != for_install)
|
if(for_build != for_install)
|
||||||
{
|
{
|
||||||
std::string fname =
|
|
||||||
this->GetInstallFilename(tgt, config, false, true);
|
|
||||||
// Map from the build-tree install_name.
|
|
||||||
for_build += fname;
|
|
||||||
|
|
||||||
// Map to the install-tree install_name.
|
|
||||||
for_install += fname;
|
|
||||||
|
|
||||||
// Store the mapping entry.
|
// Store the mapping entry.
|
||||||
install_name_remap[for_build] = for_install;
|
install_name_remap[for_build] = for_install;
|
||||||
}
|
}
|
||||||
|
@ -419,12 +454,22 @@ cmInstallTargetGenerator
|
||||||
this->Target->GetInstallNameDirForBuildTree(config);
|
this->Target->GetInstallNameDirForBuildTree(config);
|
||||||
std::string for_install =
|
std::string for_install =
|
||||||
this->Target->GetInstallNameDirForInstallTree(config);
|
this->Target->GetInstallNameDirForInstallTree(config);
|
||||||
|
std::string fname =
|
||||||
|
this->GetInstallFilename(this->Target, config, this->ImportLibrary,
|
||||||
|
true);
|
||||||
|
for_build += fname;
|
||||||
|
if (!for_install.empty())
|
||||||
|
{
|
||||||
|
for_install += fname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for_install = this->Target->GetInstallNameFixupPath();
|
||||||
|
}
|
||||||
if(for_build != for_install)
|
if(for_build != for_install)
|
||||||
{
|
{
|
||||||
// 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,
|
|
||||||
this->ImportLibrary, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +490,7 @@ cmInstallTargetGenerator
|
||||||
os << "\n" << indent << " -change \""
|
os << "\n" << indent << " -change \""
|
||||||
<< i->first << "\" \"" << i->second << "\"";
|
<< i->first << "\" \"" << i->second << "\"";
|
||||||
}
|
}
|
||||||
os << "\n" << indent << " \"" << toFullPath << "\")\n";
|
os << "\n" << indent << " \"" << toDestDirPath << "\")\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +499,7 @@ void
|
||||||
cmInstallTargetGenerator::AddStripRule(std::ostream& os,
|
cmInstallTargetGenerator::AddStripRule(std::ostream& os,
|
||||||
Indent const& indent,
|
Indent const& indent,
|
||||||
cmTarget::TargetType type,
|
cmTarget::TargetType type,
|
||||||
const std::string& toFullPath)
|
const std::string& toDestDirPath)
|
||||||
{
|
{
|
||||||
|
|
||||||
// don't strip static libraries, because it removes the only symbol table
|
// don't strip static libraries, because it removes the only symbol table
|
||||||
|
@ -479,7 +524,7 @@ cmInstallTargetGenerator::AddStripRule(std::ostream& os,
|
||||||
os << indent << "IF(CMAKE_INSTALL_DO_STRIP)\n";
|
os << indent << "IF(CMAKE_INSTALL_DO_STRIP)\n";
|
||||||
os << indent << " EXECUTE_PROCESS(COMMAND \""
|
os << indent << " EXECUTE_PROCESS(COMMAND \""
|
||||||
<< this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
|
<< this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
|
||||||
<< "\" \"" << toFullPath << "\")\n";
|
<< "\" \"" << toDestDirPath << "\")\n";
|
||||||
os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
|
os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +533,7 @@ void
|
||||||
cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
|
cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
|
||||||
Indent const& indent,
|
Indent const& indent,
|
||||||
cmTarget::TargetType type,
|
cmTarget::TargetType type,
|
||||||
const std::string& toFullPath)
|
const std::string& toDestDirPath)
|
||||||
{
|
{
|
||||||
// Static libraries need ranlib on this platform.
|
// Static libraries need ranlib on this platform.
|
||||||
if(type != cmTarget::STATIC_LIBRARY)
|
if(type != cmTarget::STATIC_LIBRARY)
|
||||||
|
@ -511,5 +556,5 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
|
||||||
}
|
}
|
||||||
|
|
||||||
os << indent << "EXECUTE_PROCESS(COMMAND \""
|
os << indent << "EXECUTE_PROCESS(COMMAND \""
|
||||||
<< ranlib << "\" \"" << toFullPath << "\")\n";
|
<< ranlib << "\" \"" << toDestDirPath << "\")\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,13 +53,13 @@ protected:
|
||||||
Indent const& indent);
|
Indent const& indent);
|
||||||
void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
|
void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
|
||||||
const char* config,
|
const char* config,
|
||||||
const std::string& toFullPath);
|
const std::string& toDestDirPath);
|
||||||
void AddStripRule(std::ostream& os, Indent const& indent,
|
void AddStripRule(std::ostream& os, Indent const& indent,
|
||||||
cmTarget::TargetType type,
|
cmTarget::TargetType type,
|
||||||
const std::string& toFullPath);
|
const std::string& toDestDirPath);
|
||||||
void AddRanlibRule(std::ostream& os, Indent const& indent,
|
void AddRanlibRule(std::ostream& os, Indent const& indent,
|
||||||
cmTarget::TargetType type,
|
cmTarget::TargetType type,
|
||||||
const std::string& toFullPath);
|
const std::string& toDestDirPath);
|
||||||
|
|
||||||
cmTarget* Target;
|
cmTarget* Target;
|
||||||
bool ImportLibrary;
|
bool ImportLibrary;
|
||||||
|
|
|
@ -137,7 +137,7 @@ public:
|
||||||
*/
|
*/
|
||||||
std::string GetRuntimeInstallPath() {return this->RuntimeInstallPath;}
|
std::string GetRuntimeInstallPath() {return this->RuntimeInstallPath;}
|
||||||
void SetRuntimeInstallPath(const char *name) {
|
void SetRuntimeInstallPath(const char *name) {
|
||||||
this->RuntimeInstallPath = name;}
|
this->RuntimeInstallPath = name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get/Set whether there is an install rule for this target.
|
* Get/Set whether there is an install rule for this target.
|
||||||
|
@ -145,6 +145,18 @@ public:
|
||||||
bool GetHaveInstallRule() { return this->HaveInstallRule; }
|
bool GetHaveInstallRule() { return this->HaveInstallRule; }
|
||||||
void SetHaveInstallRule(bool h) { this->HaveInstallRule = h; }
|
void SetHaveInstallRule(bool h) { this->HaveInstallRule = h; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get/Set the path needed for calls to install_name_tool regarding this
|
||||||
|
* target. Used to support fixing up installed libraries and executables on
|
||||||
|
* the Mac (including bundles and frameworks). Only used if the target does
|
||||||
|
* not have an INSTALL_NAME_DIR property.
|
||||||
|
* See cmInstallTargetGenerator::AddInstallNamePatchRule and callers for
|
||||||
|
* more information.
|
||||||
|
*/
|
||||||
|
std::string GetInstallNameFixupPath() { return this->InstallNameFixupPath; }
|
||||||
|
void SetInstallNameFixupPath(const char *path) {
|
||||||
|
this->InstallNameFixupPath = path; }
|
||||||
|
|
||||||
/** Add a utility on which this project depends. A utility is an executable
|
/** Add a utility on which this project depends. A utility is an executable
|
||||||
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
|
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
|
||||||
* commands. It is not a full path nor does it have an extension.
|
* commands. It is not a full path nor does it have an extension.
|
||||||
|
@ -382,6 +394,7 @@ private:
|
||||||
std::vector<std::string> LinkDirectories;
|
std::vector<std::string> LinkDirectories;
|
||||||
std::vector<std::string> ExplicitLinkDirectories;
|
std::vector<std::string> ExplicitLinkDirectories;
|
||||||
bool HaveInstallRule;
|
bool HaveInstallRule;
|
||||||
|
std::string InstallNameFixupPath;
|
||||||
std::string InstallPath;
|
std::string InstallPath;
|
||||||
std::string RuntimeInstallPath;
|
std::string RuntimeInstallPath;
|
||||||
std::string OutputDir;
|
std::string OutputDir;
|
||||||
|
|
|
@ -27,7 +27,7 @@ ADD_EXECUTABLE(SecondBundle
|
||||||
TARGET_LINK_LIBRARIES(SecondBundle BundleTestLib)
|
TARGET_LINK_LIBRARIES(SecondBundle BundleTestLib)
|
||||||
|
|
||||||
# Test bundle installation.
|
# Test bundle installation.
|
||||||
INSTALL(TARGETS SecondBundle DESTINATION Application)
|
INSTALL(TARGETS SecondBundle DESTINATION Applications)
|
||||||
|
|
||||||
# Test whether bundles respect the output name. Since the library is
|
# Test whether bundles respect the output name. Since the library is
|
||||||
# installed into a location that uses this output name this will fail if the
|
# installed into a location that uses this output name this will fail if the
|
||||||
|
|
|
@ -36,9 +36,9 @@ ADD_EXECUTABLE(BundleTest
|
||||||
TARGET_LINK_LIBRARIES(BundleTest BundleTestLib)
|
TARGET_LINK_LIBRARIES(BundleTest BundleTestLib)
|
||||||
|
|
||||||
# Test bundle installation.
|
# Test bundle installation.
|
||||||
#INSTALL(TARGETS BundleTestLib DESTINATION Application/BundleTestExe.app/Contents/Plugins)
|
#INSTALL(TARGETS BundleTestLib DESTINATION Applications/BundleTestExe.app/Contents/Plugins)
|
||||||
INSTALL(TARGETS BundleTestLib DESTINATION Application/SecondBundleExe.app/Contents/Plugins)
|
INSTALL(TARGETS BundleTestLib DESTINATION Applications/SecondBundleExe.app/Contents/Plugins)
|
||||||
INSTALL(TARGETS BundleTest DESTINATION Application)
|
INSTALL(TARGETS BundleTest DESTINATION Applications)
|
||||||
|
|
||||||
# Test whether bundles respect the output name. Since the library is
|
# Test whether bundles respect the output name. Since the library is
|
||||||
# installed into a location that uses this output name this will fail if the
|
# installed into a location that uses this output name this will fail if the
|
||||||
|
@ -59,7 +59,7 @@ INCLUDE(CPack)
|
||||||
|
|
||||||
# test the framework find stuff
|
# test the framework find stuff
|
||||||
IF(EXISTS /usr/lib/libtcl.dylib
|
IF(EXISTS /usr/lib/libtcl.dylib
|
||||||
AND EXISTS /System/Library/Frameworks/tcl.framework)
|
AND EXISTS /System/Library/Frameworks/Tcl.framework)
|
||||||
SET(TCL NOTFOUND)
|
SET(TCL NOTFOUND)
|
||||||
FIND_LIBRARY(TCL tcl)
|
FIND_LIBRARY(TCL tcl)
|
||||||
MESSAGE("frame: ${TCL}")
|
MESSAGE("frame: ${TCL}")
|
||||||
|
@ -87,6 +87,6 @@ IF(EXISTS /usr/lib/libtcl.dylib
|
||||||
ENDIF(NOT "${TCL}" MATCHES .framework)
|
ENDIF(NOT "${TCL}" MATCHES .framework)
|
||||||
MESSAGE("frame: ${TCL}")
|
MESSAGE("frame: ${TCL}")
|
||||||
ENDIF(EXISTS /usr/lib/libtcl.dylib
|
ENDIF(EXISTS /usr/lib/libtcl.dylib
|
||||||
AND EXISTS /System/Library/Frameworks/tcl.framework)
|
AND EXISTS /System/Library/Frameworks/Tcl.framework)
|
||||||
|
|
||||||
SUBDIRS(BundleSubDir)
|
SUBDIRS(BundleSubDir)
|
||||||
|
|
|
@ -597,7 +597,7 @@ IF(BUILD_TESTING)
|
||||||
--build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
|
--build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
|
||||||
"-DCMake_SOURCE_DIR:PATH=${CMAKE_SOURCE_DIR}"
|
"-DCMake_SOURCE_DIR:PATH=${CMAKE_SOURCE_DIR}"
|
||||||
--test-command
|
--test-command
|
||||||
${BundleTestInstallDir}/Application/SecondBundleExe.app/Contents/MacOS/SecondBundleExe)
|
${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe)
|
||||||
|
|
||||||
ADD_TEST_MACRO(ObjC++ ObjC++)
|
ADD_TEST_MACRO(ObjC++ ObjC++)
|
||||||
ENDIF (APPLE AND CMAKE_COMPILER_IS_GNUCXX)
|
ENDIF (APPLE AND CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|
|
@ -27,7 +27,10 @@ set_source_files_properties(test.lua PROPERTIES
|
||||||
)
|
)
|
||||||
add_executable(bar bar.cxx)
|
add_executable(bar bar.cxx)
|
||||||
target_link_libraries(bar foo)
|
target_link_libraries(bar foo)
|
||||||
|
install(TARGETS foo bar
|
||||||
|
RUNTIME DESTINATION /Applications/CMakeTestsFramework/bin
|
||||||
|
FRAMEWORK DESTINATION /Library/Frameworks
|
||||||
|
)
|
||||||
|
|
||||||
# Make a static library and apply the framework properties to it to verify
|
# Make a static library and apply the framework properties to it to verify
|
||||||
# that everything still builds correctly, but it will not actually produce
|
# that everything still builds correctly, but it will not actually produce
|
||||||
|
|
Loading…
Reference in New Issue