ENH: add better support for framework linking
This commit is contained in:
parent
102ab85a17
commit
452925649a
|
@ -1545,7 +1545,7 @@ void cmGlobalXCodeGenerator::AddLinkLibrary(cmXCodeObject* target,
|
|||
|
||||
// if the library is not a full path then add it with a -l flag
|
||||
// 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
|
||||
// add a -l infront of the name
|
||||
std::string link;
|
||||
|
|
|
@ -1411,7 +1411,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
|
|||
{
|
||||
cmStdString& linkItem = *lib;
|
||||
// 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))
|
||||
{
|
||||
librariesLinked += libLinkFlag;
|
||||
|
|
|
@ -445,6 +445,9 @@ cmLocalUnixMakefileGenerator3
|
|||
|
||||
// Add include directory flags.
|
||||
this->AppendFlags(flags, this->GetIncludeFlags(lang));
|
||||
// Add include directory flags.
|
||||
this->AppendFlags(flags, this->GetFrameworkFlags(target).c_str());
|
||||
|
||||
flagFileStream << lang << "_FLAGS = " << flags
|
||||
<< "\n"
|
||||
<< "\n";
|
||||
|
@ -498,6 +501,27 @@ cmLocalUnixMakefileGenerator3
|
|||
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
|
||||
cmLocalUnixMakefileGenerator3
|
||||
|
|
|
@ -171,7 +171,9 @@ public:
|
|||
void WriteLocalAllRules(std::ostream& ruleFileStream);
|
||||
|
||||
protected:
|
||||
|
||||
// Return the a string with -F flags on apple
|
||||
std::string GetFrameworkFlags(cmTarget&);
|
||||
|
||||
// write the depend info
|
||||
void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
|
||||
|
||||
|
|
|
@ -2215,6 +2215,11 @@ std::string cmMakefile::FindLibrary(const char* name,
|
|||
cmSystemTools::GetPath(path, "CMAKE_LIBRARY_PATH");
|
||||
cmSystemTools::GetPath(path, "LIB");
|
||||
cmSystemTools::GetPath(path);
|
||||
bool supportFrameworks = false;
|
||||
if(this->GetDefinition("APPLE"))
|
||||
{
|
||||
supportFrameworks = true;
|
||||
}
|
||||
// now add the path
|
||||
path.insert(path.end(), userPaths.begin(), userPaths.end());
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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"))
|
||||
{
|
||||
|
|
|
@ -104,6 +104,7 @@ std::string cmOrderLinkDirectories::NoCaseExpression(const char* str)
|
|||
//-------------------------------------------------------------------
|
||||
void cmOrderLinkDirectories::CreateRegularExpressions()
|
||||
{
|
||||
m_SplitFramework.compile("(.*)/(.*)\\.framework$");
|
||||
cmStdString libext = "(";
|
||||
bool first = true;
|
||||
for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin();
|
||||
|
@ -278,29 +279,53 @@ bool cmOrderLinkDirectories::DetermineLibraryPathOrder()
|
|||
cmStdString dir;
|
||||
cmStdString file;
|
||||
std::vector<cmStdString> empty;
|
||||
bool framework = false;
|
||||
for(unsigned int i=0; i < m_RawLinkItems.size(); ++i)
|
||||
{
|
||||
if(cmSystemTools::FileIsFullPath(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: ";
|
||||
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(cmSystemTools::IsPathToFramework(m_RawLinkItems[i].c_str()))
|
||||
{
|
||||
m_SplitFramework.find(m_RawLinkItems[i]);
|
||||
cmStdString path = m_SplitFramework.match(1);
|
||||
// Add the -F path if we have not yet done so
|
||||
if(m_EmittedFrameworkPaths.insert(path).second)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -121,6 +121,8 @@ private:
|
|||
std::vector<cmStdString> m_RawLinkItems;
|
||||
// This vector holds the sorted -L paths
|
||||
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
|
||||
std::set<cmStdString> m_LinkPathSet;
|
||||
// the names of link extensions
|
||||
|
@ -135,6 +137,7 @@ private:
|
|||
cmsys::RegularExpression m_RemoveLibraryExtension;
|
||||
cmsys::RegularExpression m_ExtractBaseLibraryName;
|
||||
cmsys::RegularExpression m_ExtractBaseLibraryNameNoPrefix;
|
||||
cmsys::RegularExpression m_SplitFramework;
|
||||
bool m_Debug;
|
||||
};
|
||||
|
||||
|
|
|
@ -1345,3 +1345,16 @@ bool cmSystemTools::PutEnv(const char* value)
|
|||
localEnvironment.push_back(envVar);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -131,6 +131,8 @@ public:
|
|||
|
||||
///! Return true if value is NOTFOUND or ends in -NOTFOUND.
|
||||
static bool IsNOTFOUND(const char* value);
|
||||
///! Return true if the path is a framework
|
||||
static bool IsPathToFramework(const char* value);
|
||||
|
||||
static bool DoesFileExistWithExtensions(
|
||||
const char *name,
|
||||
|
|
|
@ -301,9 +301,28 @@ void cmTarget::ClearDependencyInformation( cmMakefile& mf, const char* target )
|
|||
void cmTarget::AddLinkLibrary(const std::string& lib,
|
||||
LinkLibraryType llt)
|
||||
{
|
||||
this->AddFramework(lib.c_str(), 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,
|
||||
const char *target, const char* lib,
|
||||
LinkLibraryType llt)
|
||||
|
@ -313,7 +332,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->AddFramework(lib, llt);
|
||||
m_LinkLibraries.push_back( std::pair<std::string, cmTarget::LinkLibraryType>(lib,llt) );
|
||||
|
||||
if(llt != cmTarget::GENERAL)
|
||||
|
|
|
@ -79,6 +79,9 @@ public:
|
|||
* Get the list of the source lists used by this target
|
||||
*/
|
||||
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
|
||||
|
@ -97,6 +100,8 @@ public:
|
|||
*/
|
||||
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,
|
||||
const char *target, const char* lib,
|
||||
LinkLibraryType llt);
|
||||
|
@ -276,6 +281,7 @@ private:
|
|||
std::vector<cmSourceFile*> m_SourceFiles;
|
||||
LinkLibraries m_LinkLibraries;
|
||||
LinkLibraries m_PrevLinkedLibraries;
|
||||
std::vector<std::string> m_Frameworks;
|
||||
std::vector<std::string> m_LinkDirectories;
|
||||
std::string m_InstallPath;
|
||||
std::string m_RuntimeInstallPath;
|
||||
|
|
|
@ -1992,6 +1992,17 @@ kwsys_stl::string SystemTools
|
|||
for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
|
||||
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__)
|
||||
tryPath = *p;
|
||||
tryPath += "/";
|
||||
|
|
Loading…
Reference in New Issue