ENH: add better support for framework linking

This commit is contained in:
Bill Hoffman 2005-12-26 13:14:19 -05:00
parent 102ab85a17
commit 452925649a
12 changed files with 137 additions and 20 deletions

View File

@ -1545,7 +1545,7 @@ void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
// if the library is not a full path then add it with a -l flag // if the library is not a full path then add it with a -l flag
// to the settings of the target // to the settings of the target
cmsys::RegularExpression reg("^([ \t]*\\-[lLWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)"); cmsys::RegularExpression reg("^([ \t]*\\-[lLWRBF])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
// if the library is not already in the form required by the compiler // if the library is not already in the form required by the compiler
// add a -l infront of the name // add a -l infront of the name
std::string link; std::string link;

View File

@ -1411,7 +1411,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
{ {
cmStdString& linkItem = *lib; cmStdString& linkItem = *lib;
// check to see if the link item has a -l already // check to see if the link item has a -l already
cmsys::RegularExpression reg("^([ \t]*\\-[lLWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)"); cmsys::RegularExpression reg("^([ \t]*\\-[lLWRBF])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
if(!reg.find(linkItem)) if(!reg.find(linkItem))
{ {
librariesLinked += libLinkFlag; librariesLinked += libLinkFlag;

View File

@ -445,6 +445,9 @@ cmLocalUnixMakefileGenerator3
// Add include directory flags. // Add include directory flags.
this->AppendFlags(flags, this->GetIncludeFlags(lang)); this->AppendFlags(flags, this->GetIncludeFlags(lang));
// Add include directory flags.
this->AppendFlags(flags, this->GetFrameworkFlags(target).c_str());
flagFileStream << lang << "_FLAGS = " << flags flagFileStream << lang << "_FLAGS = " << flags
<< "\n" << "\n"
<< "\n"; << "\n";
@ -498,6 +501,27 @@ cmLocalUnixMakefileGenerator3
this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles); this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles);
} }
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
::GetFrameworkFlags(cmTarget& target)
{
#ifndef __APPLE__
return std::string();
#else
std::string flags;
std::vector<std::string>& frameworks = target.GetFrameworks();
for(std::vector<std::string>::iterator i = frameworks.begin();
i != frameworks.end(); ++i)
{
flags += "-F";
flags += this->ConvertToOutputForExisting(i->c_str());
flags += " ";
}
return flags;
#endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
cmLocalUnixMakefileGenerator3 cmLocalUnixMakefileGenerator3

View File

@ -171,7 +171,9 @@ public:
void WriteLocalAllRules(std::ostream& ruleFileStream); void WriteLocalAllRules(std::ostream& ruleFileStream);
protected: protected:
// Return the a string with -F flags on apple
std::string GetFrameworkFlags(cmTarget&);
// write the depend info // write the depend info
void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt); void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);

View File

@ -2215,6 +2215,11 @@ std::string cmMakefile::FindLibrary(const char* name,
cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH"); cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH");
cmSystemTools::GetPath(path, "LIB"); cmSystemTools::GetPath(path, "LIB");
cmSystemTools::GetPath(path); cmSystemTools::GetPath(path);
bool supportFrameworks = false;
if(this->GetDefinition("APPLE"))
{
supportFrameworks = true;
}
// now add the path // now add the path
path.insert(path.end(), userPaths.begin(), userPaths.end()); path.insert(path.end(), userPaths.begin(), userPaths.end());
// Add some lib directories specific to compilers, depending on the // Add some lib directories specific to compilers, depending on the
@ -2270,6 +2275,13 @@ std::string cmMakefile::FindLibrary(const char* name,
path.push_back(lib_path); path.push_back(lib_path);
} }
} }
else if(supportFrameworks)
{
path.push_back("~/Library/Frameworks");
path.push_back("/Library/Frameworks");
path.push_back("/System/Library/Frameworks");
path.push_back("/Network/Library/Frameworks");
}
} }
if(m_LocalGenerator->GetGlobalGenerator()->GetLanguageEnabled("C")) if(m_LocalGenerator->GetGlobalGenerator()->GetLanguageEnabled("C"))
{ {

View File

@ -104,6 +104,7 @@ std::string cmOrderLinkDirectories::NoCaseExpression(const char* str)
//------------------------------------------------------------------- //-------------------------------------------------------------------
void cmOrderLinkDirectories::CreateRegularExpressions() void cmOrderLinkDirectories::CreateRegularExpressions()
{ {
m_SplitFramework.compile("(.*)/(.*)\\.framework$");
cmStdString libext = "("; cmStdString libext = "(";
bool first = true; bool first = true;
for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin(); for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin();
@ -278,29 +279,53 @@ bool cmOrderLinkDirectories::DetermineLibraryPathOrder()
cmStdString dir; cmStdString dir;
cmStdString file; cmStdString file;
std::vector<cmStdString> empty; std::vector<cmStdString> empty;
bool framework = false;
for(unsigned int i=0; i < m_RawLinkItems.size(); ++i) for(unsigned int i=0; i < m_RawLinkItems.size(); ++i)
{ {
if(cmSystemTools::FileIsFullPath(m_RawLinkItems[i].c_str())) if(cmSystemTools::FileIsFullPath(m_RawLinkItems[i].c_str()))
{ {
if(cmSystemTools::FileIsDirectory(m_RawLinkItems[i].c_str())) if(cmSystemTools::FileIsDirectory(m_RawLinkItems[i].c_str()))
{ {
std::string message = "Warning: Ignoring path found in link libraries for target: "; if(cmSystemTools::IsPathToFramework(m_RawLinkItems[i].c_str()))
message += m_TargetName; {
message += ", path is: "; m_SplitFramework.find(m_RawLinkItems[i]);
message += m_RawLinkItems[i]; cmStdString path = m_SplitFramework.match(1);
message += ". Expected a library name or a full path to a library name."; // Add the -F path if we have not yet done so
cmSystemTools::Message(message.c_str()); if(m_EmittedFrameworkPaths.insert(path).second)
continue; {
std::string fpath = "-F";
fpath += cmSystemTools::ConvertToOutputPath(path.c_str());
m_LinkItems.push_back(fpath);
}
// now add the -framework option
std::string frame = "-framework ";
frame += m_SplitFramework.match(2);
m_LinkItems.push_back(frame);
framework = true;
}
else
{
std::string message = "Warning: Ignoring path found in link libraries for target: ";
message += m_TargetName;
message += ", path is: ";
message += m_RawLinkItems[i];
message += ". Expected a library name or a full path to a library name.";
cmSystemTools::Message(message.c_str());
continue;
}
}
if(!framework)
{
cmSystemTools::SplitProgramPath(m_RawLinkItems[i].c_str(),
dir, file);
m_DirectoryToAfterList[dir] = empty;
m_LinkPathSet.insert(dir);
aLib.FullPath = m_RawLinkItems[i];
aLib.File = file;
aLib.Path = dir;
m_FullPathLibraries[aLib.FullPath] = aLib;
m_LinkItems.push_back(file);
} }
cmSystemTools::SplitProgramPath(m_RawLinkItems[i].c_str(),
dir, file);
m_DirectoryToAfterList[dir] = empty;
m_LinkPathSet.insert(dir);
aLib.FullPath = m_RawLinkItems[i];
aLib.File = file;
aLib.Path = dir;
m_FullPathLibraries[aLib.FullPath] = aLib;
m_LinkItems.push_back(file);
} }
else else
{ {

View File

@ -121,6 +121,8 @@ private:
std::vector<cmStdString> m_RawLinkItems; std::vector<cmStdString> m_RawLinkItems;
// This vector holds the sorted -L paths // This vector holds the sorted -L paths
std::vector<cmStdString> m_SortedSearchPaths; std::vector<cmStdString> m_SortedSearchPaths;
// This vector holds the -F paths
std::set<cmStdString> m_EmittedFrameworkPaths;
// This is the set of -L paths unsorted, but unique // This is the set of -L paths unsorted, but unique
std::set<cmStdString> m_LinkPathSet; std::set<cmStdString> m_LinkPathSet;
// the names of link extensions // the names of link extensions
@ -135,6 +137,7 @@ private:
cmsys::RegularExpression m_RemoveLibraryExtension; cmsys::RegularExpression m_RemoveLibraryExtension;
cmsys::RegularExpression m_ExtractBaseLibraryName; cmsys::RegularExpression m_ExtractBaseLibraryName;
cmsys::RegularExpression m_ExtractBaseLibraryNameNoPrefix; cmsys::RegularExpression m_ExtractBaseLibraryNameNoPrefix;
cmsys::RegularExpression m_SplitFramework;
bool m_Debug; bool m_Debug;
}; };

View File

@ -1345,3 +1345,16 @@ bool cmSystemTools::PutEnv(const char* value)
localEnvironment.push_back(envVar); localEnvironment.push_back(envVar);
return ret == 0; return ret == 0;
} }
bool cmSystemTools::IsPathToFramework(const char* path)
{
if(cmSystemTools::FileIsFullPath(path))
{
std::string libname = path;
if(libname.find(".framework") == libname.size()+1-sizeof(".framework"))
{
return true;
}
}
return false;
}

View File

@ -131,6 +131,8 @@ public:
///! Return true if value is NOTFOUND or ends in -NOTFOUND. ///! Return true if value is NOTFOUND or ends in -NOTFOUND.
static bool IsNOTFOUND(const char* value); static bool IsNOTFOUND(const char* value);
///! Return true if the path is a framework
static bool IsPathToFramework(const char* value);
static bool DoesFileExistWithExtensions( static bool DoesFileExistWithExtensions(
const char *name, const char *name,

View File

@ -301,9 +301,28 @@ void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
void cmTarget::AddLinkLibrary(const std::string& lib, void cmTarget::AddLinkLibrary(const std::string& lib,
LinkLibraryType llt) LinkLibraryType llt)
{ {
this->AddFramework(lib.c_str(), llt);
m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) ); m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
} }
bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType llt)
{
if(cmSystemTools::IsPathToFramework(libname.c_str()))
{
std::string frameworkDir = libname;
frameworkDir += "/../";
frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
std::vector<std::string>::iterator i =
std::find(m_Frameworks.begin(),
m_Frameworks.end(), frameworkDir);
if(i == m_Frameworks.end())
{
m_Frameworks.push_back(frameworkDir);
}
return true;
}
return false;
}
void cmTarget::AddLinkLibrary(cmMakefile& mf, void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib, const char *target, const char* lib,
LinkLibraryType llt) LinkLibraryType llt)
@ -313,7 +332,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
{ {
return; return;
} }
this->AddFramework(lib, llt);
m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) ); m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
if(llt != cmTarget::GENERAL) if(llt != cmTarget::GENERAL)

View File

@ -79,6 +79,9 @@ public:
* Get the list of the source lists used by this target * Get the list of the source lists used by this target
*/ */
std::vector<std::string> &GetSourceLists() {return m_SourceLists;} std::vector<std::string> &GetSourceLists() {return m_SourceLists;}
///! Return the list of frameworks being linked to this target
std::vector<std::string> &GetFrameworks() {return m_Frameworks;}
/** /**
* Get the list of the source files used by this target * Get the list of the source files used by this target
@ -97,6 +100,8 @@ public:
*/ */
void ClearDependencyInformation(cmMakefile& mf, const char* target); void ClearDependencyInformation(cmMakefile& mf, const char* target);
// Check to see if a library is a framework and treat it different on Mac
bool AddFramework(const std::string& lib, LinkLibraryType llt);
void AddLinkLibrary(cmMakefile& mf, void AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib, const char *target, const char* lib,
LinkLibraryType llt); LinkLibraryType llt);
@ -276,6 +281,7 @@ private:
std::vector<cmSourceFile*> m_SourceFiles; std::vector<cmSourceFile*> m_SourceFiles;
LinkLibraries m_LinkLibraries; LinkLibraries m_LinkLibraries;
LinkLibraries m_PrevLinkedLibraries; LinkLibraries m_PrevLinkedLibraries;
std::vector<std::string> m_Frameworks;
std::vector<std::string> m_LinkDirectories; std::vector<std::string> m_LinkDirectories;
std::string m_InstallPath; std::string m_InstallPath;
std::string m_RuntimeInstallPath; std::string m_RuntimeInstallPath;

View File

@ -1992,6 +1992,17 @@ kwsys_stl::string SystemTools
for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin(); for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
p != path.end(); ++p) p != path.end(); ++p)
{ {
#if defined(__APPLE__)
tryPath = *p;
tryPath += "/";
tryPath += name;
tryPath += ".framework";
if(SystemTools::FileExists(tryPath.c_str())
&& SystemTools::FileIsDirectory(tryPath.c_str()))
{
return SystemTools::CollapseFullPath(tryPath.c_str());
}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
tryPath = *p; tryPath = *p;
tryPath += "/"; tryPath += "/";