ENH: Merging changes from branch CMake-SourceFile2-b between tags

CMake-SourceFile2-bp and CMake-SourceFile2-b-mp1 to trunk.  This
commit is surrounded by tags CMake-SourceFile2-b-mp1-pre and
CMake-SourceFile2-b-mp1-post on the trunk.

The changes re-implement cmSourceFile and the use of it to allow
instances to be created much earlier.  The use of cmSourceFileLocation
allows locating a source file referenced by a user to be much simpler
and more robust.  The two SetName methods are no longer needed so some
duplicate code has been removed.  The strange "SourceName" stuff is
gone.  Code that created cmSourceFile instances on the stack and then
sent them to cmMakefile::AddSource has been simplified and converted
to getting cmSourceFile instances from cmMakefile.  The CPluginAPI has
preserved the old API through a compatibility interface.

Source lists are gone.  Targets now get real instances of cmSourceFile
right away instead of storing a list of strings until the final pass.

TraceVSDependencies has been re-written to avoid the use of
SourceName.  It is now called TraceDependencies since it is not just
for VS.  It is now implemented with a helper object which makes the
code simpler.
This commit is contained in:
Brad King 2007-06-18 11:59:23 -04:00
parent ef81ac50e5
commit 35936433e1
33 changed files with 1397 additions and 1224 deletions

View File

@ -148,6 +148,8 @@ SET(SRCS
cmPropertyMap.h cmPropertyMap.h
cmSourceFile.cxx cmSourceFile.cxx
cmSourceFile.h cmSourceFile.h
cmSourceFileLocation.cxx
cmSourceFileLocation.h
cmSourceGroup.cxx cmSourceGroup.cxx
cmSourceGroup.h cmSourceGroup.h
cmSystemTools.cxx cmSystemTools.cxx

View File

@ -56,9 +56,9 @@ bool cmAuxSourceDirectoryCommand::InitialPass
if( dotpos != std::string::npos ) if( dotpos != std::string::npos )
{ {
std::string ext = file.substr(dotpos+1); std::string ext = file.substr(dotpos+1);
file = file.substr(0, dotpos); std::string base = file.substr(0, dotpos);
// Process only source files // Process only source files
if( file.size() != 0 if( base.size() != 0
&& std::find( this->Makefile->GetSourceExtensions().begin(), && std::find( this->Makefile->GetSourceExtensions().begin(),
this->Makefile->GetSourceExtensions().end(), ext ) this->Makefile->GetSourceExtensions().end(), ext )
!= this->Makefile->GetSourceExtensions().end() ) != this->Makefile->GetSourceExtensions().end() )
@ -68,21 +68,14 @@ bool cmAuxSourceDirectoryCommand::InitialPass
fullname += file; fullname += file;
// add the file as a class file so // add the file as a class file so
// depends can be done // depends can be done
cmSourceFile cmfile; cmSourceFile* sf =
cmfile.SetMakefile(this->Makefile); this->Makefile->GetOrCreateSource(fullname.c_str());
cmfile.SetName(fullname.c_str(), sf->SetProperty("ABSTRACT","0");
this->Makefile->GetCurrentDirectory(), if(!sourceListValue.empty())
this->Makefile->GetSourceExtensions(),
this->Makefile->GetHeaderExtensions());
cmfile.SetProperty("ABSTRACT","0");
this->Makefile->AddSource(cmfile);
if (sourceListValue.size() > 0)
{ {
sourceListValue += ";"; sourceListValue += ";";
} }
sourceListValue += cmfile.GetSourceName(); sourceListValue += fullname;
sourceListValue += ".";
sourceListValue += cmfile.GetSourceExtension();
} }
} }
} }

View File

@ -488,104 +488,341 @@ int CCONV cmGetTotalArgumentSize(int argc, char **argv)
return result; return result;
} }
// Source file proxy object to support the old cmSourceFile/cmMakefile
// API for source files.
struct cmCPluginAPISourceFile
{
cmCPluginAPISourceFile(): RealSourceFile(0) {}
cmSourceFile* RealSourceFile;
std::string SourceName;
std::string SourceExtension;
std::string FullPath;
std::vector<std::string> Depends;
cmPropertyMap Properties;
};
// Keep a map from real cmSourceFile instances stored in a makefile to
// the CPluginAPI proxy source file.
class cmCPluginAPISourceFileMap:
public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
{
public:
typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived;
typedef derived::iterator iterator;
typedef derived::value_type value_type;
~cmCPluginAPISourceFileMap()
{
for(iterator i=this->begin(); i != this->end(); ++i)
{
delete i->second;
}
}
};
static cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
void * CCONV cmCreateSourceFile()
{
return (void*)new cmCPluginAPISourceFile;
}
void * CCONV cmCreateNewSourceFile(void *arg)
{
(void)arg; // no longer needed
return (void*)new cmCPluginAPISourceFile;
}
void CCONV cmDestroySourceFile(void *arg)
{
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
// Only delete if it was created by cmCreateSourceFile or
// cmCreateNewSourceFile and is therefore not in the map.
if(!sf->RealSourceFile)
{
delete sf;
}
}
void CCONV *cmGetSource(void *arg, const char *name) void CCONV *cmGetSource(void *arg, const char *name)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); cmMakefile *mf = static_cast<cmMakefile *>(arg);
return (void *)mf->GetSource(name); if(cmSourceFile* rsf = mf->GetSource(name))
{
// Lookup the proxy source file object for this source.
cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf);
if(i == cmCPluginAPISourceFiles.end())
{
// Create a proxy source file object for this source.
cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
sf->RealSourceFile = rsf;
sf->FullPath = rsf->GetFullPath();
sf->SourceName =
cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath.c_str());
sf->SourceExtension =
cmSystemTools::GetFilenameLastExtension(sf->FullPath.c_str());
// Store the proxy in the map so it can be re-used and deleted later.
cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
i = cmCPluginAPISourceFiles.insert(entry).first;
}
return (void *)i->second;
}
else
{
return 0;
}
} }
void * CCONV cmAddSource(void *arg, void *arg2) void * CCONV cmAddSource(void *arg, void *arg2)
{ {
cmMakefile *mf = static_cast<cmMakefile *>(arg); cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmSourceFile *sf = static_cast<cmSourceFile *>(arg2); cmCPluginAPISourceFile* osf = static_cast<cmCPluginAPISourceFile*>(arg2);
return (void *)mf->AddSource(*sf); if(osf->FullPath.empty())
} {
return 0;
}
// Create the real cmSourceFile instance and copy over saved information.
cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath.c_str());
rsf->GetProperties() = osf->Properties;
for(std::vector<std::string>::iterator i = osf->Depends.begin();
i != osf->Depends.end(); ++i)
{
rsf->AddDepend(i->c_str());
}
void * CCONV cmCreateSourceFile() // Create the proxy for the real source file.
{ cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
return (void *)(new cmSourceFile); sf->RealSourceFile = rsf;
} sf->FullPath = osf->FullPath;
sf->SourceName = osf->SourceName;
sf->SourceExtension = osf->SourceExtension;
void * CCONV cmCreateNewSourceFile(void *arg) // Store the proxy in the map so it can be re-used and deleted later.
{ cmCPluginAPISourceFiles[rsf] = sf;
cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmSourceFile *sf = new cmSourceFile;
sf->SetMakefile(mf);
return (void *)sf; return (void *)sf;
} }
void CCONV cmDestroySourceFile(void *arg)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
delete sf;
}
const char * CCONV cmSourceFileGetSourceName(void *arg) const char * CCONV cmSourceFileGetSourceName(void *arg)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return sf->GetSourceName().c_str(); return sf->SourceName.c_str();
} }
const char * CCONV cmSourceFileGetFullPath(void *arg) const char * CCONV cmSourceFileGetFullPath(void *arg)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return sf->GetFullPath().c_str(); return sf->FullPath.c_str();
} }
const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop) const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return sf->GetProperty(prop); if(cmSourceFile* rsf = sf->RealSourceFile)
{
return rsf->GetProperty(prop);
}
else
{
if(!strcmp(prop,"LOCATION"))
{
return sf->FullPath.c_str();
}
bool chain = false;
// Ignore chain because old code will not expect it and it is a
// pain to implement here anyway.
return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
chain);
}
} }
int CCONV cmSourceFileGetPropertyAsBool(void *arg,const char *prop) int CCONV cmSourceFileGetPropertyAsBool(void *arg,const char *prop)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return (sf->GetPropertyAsBool(prop) ? 1: 0); if(cmSourceFile* rsf = sf->RealSourceFile)
{
return rsf->GetPropertyAsBool(prop) ? 1:0;
}
else
{
return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop))? 1:0;
}
} }
void CCONV cmSourceFileSetProperty(void *arg,const char *prop, void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
const char *val) const char *value)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
sf->SetProperty(prop,val); if(cmSourceFile* rsf = sf->RealSourceFile)
{
rsf->SetProperty(prop, value);
}
else if(prop)
{
if(!value) { value = "NOTFOUND"; }
sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
}
} }
void CCONV cmSourceFileAddDepend(void *arg, const char *depend) void CCONV cmSourceFileAddDepend(void *arg, const char *depend)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
sf->AddDepend(depend); if(cmSourceFile* rsf = sf->RealSourceFile)
{
rsf->AddDepend(depend);
}
else
{
sf->Depends.push_back(depend);
}
} }
void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir, void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir,
int numSourceExtensions, int numSourceExtensions,
const char **sourceExtensions, const char **sourceExtensions,
int numHeaderExtensions, int numHeaderExtensions,
const char **headerExtensions) const char **headerExtensions)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
std::vector<std::string> srcs; if(sf->RealSourceFile)
std::vector<std::string> hdrs; {
// SetName is allowed only on temporary source files created by
// the command for building and passing to AddSource.
return;
}
std::vector<std::string> sourceExts;
std::vector<std::string> headerExts;
int i; int i;
for (i = 0; i < numSourceExtensions; ++i) for (i = 0; i < numSourceExtensions; ++i)
{ {
srcs.push_back(sourceExtensions[i]); sourceExts.push_back(sourceExtensions[i]);
} }
for (i = 0; i < numHeaderExtensions; ++i) for (i = 0; i < numHeaderExtensions; ++i)
{ {
hdrs.push_back(headerExtensions[i]); headerExts.push_back(headerExtensions[i]);
} }
sf->SetName(name,dir, srcs, hdrs);
// Implement the old SetName method code here.
sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
cmProperty::SOURCE_FILE);
// Save the original name given.
sf->SourceName = name;
// Convert the name to a full path in case the given name is a
// relative path.
std::string pathname = cmSystemTools::CollapseFullPath(name, dir);
// First try and see whether the listed file can be found
// as is without extensions added on.
std::string hname = pathname;
if(cmSystemTools::FileExists(hname.c_str()))
{
sf->SourceName = cmSystemTools::GetFilenamePath(name);
if ( sf->SourceName.size() > 0 )
{
sf->SourceName += "/";
}
sf->SourceName += cmSystemTools::GetFilenameWithoutLastExtension(name);
std::string::size_type pos = hname.rfind('.');
if(pos != std::string::npos)
{
sf->SourceExtension = hname.substr(pos+1, hname.size()-pos);
if ( cmSystemTools::FileIsFullPath(name) )
{
std::string::size_type pos2 = hname.rfind('/');
if(pos2 != std::string::npos)
{
sf->SourceName = hname.substr(pos2+1, pos - pos2-1);
}
}
}
// See if the file is a header file
if(std::find( headerExts.begin(), headerExts.end(),
sf->SourceExtension ) == headerExts.end())
{
sf->Properties.SetProperty("HEADER_FILE_ONLY", "0",
cmProperty::SOURCE_FILE);
}
sf->FullPath = hname;
return;
}
// Next, try the various source extensions
for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
ext != sourceExts.end(); ++ext )
{
hname = pathname;
hname += ".";
hname += *ext;
if(cmSystemTools::FileExists(hname.c_str()))
{
sf->SourceExtension = *ext;
sf->Properties.SetProperty("HEADER_FILE_ONLY", "0",
cmProperty::SOURCE_FILE);
sf->FullPath = hname;
return;
}
}
// Finally, try the various header extensions
for( std::vector<std::string>::const_iterator ext = headerExts.begin();
ext != headerExts.end(); ++ext )
{
hname = pathname;
hname += ".";
hname += *ext;
if(cmSystemTools::FileExists(hname.c_str()))
{
sf->SourceExtension = *ext;
sf->FullPath = hname;
return;
}
}
cmOStringStream e;
e << "Cannot find source file \"" << pathname << "\"";
e << "\n\nTried extensions";
for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
ext != sourceExts.end(); ++ext )
{
e << " ." << *ext;
}
for( std::vector<std::string>::const_iterator ext = headerExts.begin();
ext != headerExts.end(); ++ext )
{
e << " ." << *ext;
}
cmSystemTools::Error(e.str().c_str());
return;
} }
void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir, void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
const char *ext, int headerFileOnly) const char *ext, int headerFileOnly)
{ {
cmSourceFile *sf = static_cast<cmSourceFile *>(arg); cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
sf->SetName(name,dir,ext,(headerFileOnly ? true : false)); if(sf->RealSourceFile)
} {
// SetName is allowed only on temporary source files created by
// the command for building and passing to AddSource.
return;
}
// Implement the old SetName method code here.
sf->Properties.SetProperty("HEADER_FILE_ONLY",
headerFileOnly? "1" : "0",
cmProperty::SOURCE_FILE);
sf->SourceName = name;
std::string fname = sf->SourceName;
if(ext && strlen(ext))
{
fname += ".";
fname += ext;
}
sf->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir);
cmSystemTools::ConvertToUnixSlashes(sf->FullPath);
sf->SourceExtension = ext;
}
char * CCONV cmGetFilenameWithoutExtension(const char *name) char * CCONV cmGetFilenameWithoutExtension(const char *name)
{ {

View File

@ -170,29 +170,17 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args)
res = false; res = false;
} }
// Create the source list // Construct the source list.
cmSourceFile cfile;
cfile.SetMakefile(this->Makefile);
std::string sourceListValue; std::string sourceListValue;
{
cfile.SetProperty("ABSTRACT","0"); cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver.c_str());
cfile.SetName(cmSystemTools::GetFilenameWithoutExtension(args[1]).c_str(), sf->SetProperty("ABSTRACT","0");
this->Makefile->GetCurrentOutputDirectory(),
cmSystemTools::GetFilenameExtension(args[1]).c_str()+1,
false);
this->Makefile->AddSource(cfile);
sourceListValue = args[1]; sourceListValue = args[1];
}
for(i = testsBegin; i != tests.end(); ++i) for(i = testsBegin; i != tests.end(); ++i)
{ {
cmSourceFile icfile; cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str());
icfile.SetMakefile(this->Makefile); sf->SetProperty("ABSTRACT","0");
icfile.SetProperty("ABSTRACT","0");
icfile.SetName(i->c_str(),
this->Makefile->GetCurrentDirectory(),
this->Makefile->GetSourceExtensions(),
this->Makefile->GetHeaderExtensions());
this->Makefile->AddSource(icfile);
sourceListValue += ";"; sourceListValue += ";";
sourceListValue += *i; sourceListValue += *i;
} }

View File

@ -53,20 +53,17 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args)
// to generate .cxx and .h files // to generate .cxx and .h files
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{ {
cmSourceFile header_file; std::string outName = outputDirectory;
header_file.SetMakefile(this->Makefile); outName += "/";
std::string srcName = cmSystemTools::GetFilenameWithoutExtension(*i); outName += cmSystemTools::GetFilenameWithoutExtension(*i);
const bool headerFileOnly = true; std::string hname = outName;
header_file.SetName(srcName.c_str(), hname += ".h";
outputDirectory.c_str(), "h",headerFileOnly);
std::string origname = cdir + "/" + *i; std::string origname = cdir + "/" + *i;
std::string hname = header_file.GetFullPath();
// add starting depends // add starting depends
std::vector<std::string> depends; std::vector<std::string> depends;
depends.push_back(origname); depends.push_back(origname);
depends.push_back(fluid_exe); depends.push_back(fluid_exe);
std::string cxxres = outputDirectory.c_str(); std::string cxxres = outName;
cxxres += "/" + srcName;
cxxres += ".cxx"; cxxres += ".cxx";
cmCustomCommandLine commandLine; cmCustomCommandLine commandLine;
@ -123,12 +120,12 @@ void cmFLTKWrapUICommand::FinalPass()
// people should add the srcs to the target themselves, but the old command // people should add the srcs to the target themselves, but the old command
// didn't support that, so check and see if they added the files in and if // didn't support that, so check and see if they added the files in and if
// they didn;t then print a warning and add then anyhow // they didn;t then print a warning and add then anyhow
std::vector<std::string> const& srcs = std::vector<cmSourceFile*> const& srcs =
this->Makefile->GetTargets()[this->Target].GetSourceLists(); this->Makefile->GetTargets()[this->Target].GetSourceFiles();
bool found = false; bool found = false;
for (unsigned int i = 0; i < srcs.size(); ++i) for (unsigned int i = 0; i < srcs.size(); ++i)
{ {
if (srcs[i] == if (srcs[i]->GetFullPath() ==
this->GeneratedSourcesClasses[0]->GetFullPath()) this->GeneratedSourcesClasses[0]->GetFullPath())
{ {
found = true; found = true;

View File

@ -38,6 +38,11 @@ bool cmGetSourceFilePropertyCommand::InitialPass(
} }
if(sf) if(sf)
{ {
if(args[2] == "LOCATION")
{
// Make sure the location is known.
sf->GetFullPath();
}
const char *prop = sf->GetProperty(args[2].c_str()); const char *prop = sf->GetProperty(args[2].c_str());
if (prop) if (prop)
{ {

View File

@ -19,6 +19,7 @@
#include "cmExternalMakefileProjectGenerator.h" #include "cmExternalMakefileProjectGenerator.h"
#include "cmake.h" #include "cmake.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmVersion.h" #include "cmVersion.h"
#include <stdlib.h> // required for atof #include <stdlib.h> // required for atof
@ -483,39 +484,32 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
} }
} }
const char* cmGlobalGenerator //----------------------------------------------------------------------------
::GetLanguageOutputExtensionForLanguage(const char* lang) const char*
cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
{ {
if(!lang) if(const char* lang = source.GetLanguage())
{ {
return ""; if(this->LanguageToOutputExtension.count(lang) > 0)
{
return this->LanguageToOutputExtension[lang].c_str();
}
} }
if(this->LanguageToOutputExtension.count(lang) > 0) else
{
return this->LanguageToOutputExtension[lang].c_str();
}
return "";
}
const char* cmGlobalGenerator
::GetLanguageOutputExtensionFromExtension(const char* ext)
{
if(!ext)
{
return "";
}
const char* lang = this->GetLanguageFromExtension(ext);
if(!lang || *lang == 0)
{ {
// if no language is found then check to see if it is already an // if no language is found then check to see if it is already an
// ouput extension for some language. In that case it should be ignored // ouput extension for some language. In that case it should be ignored
// and in this map, so it will not be compiled but will just be used. // and in this map, so it will not be compiled but will just be used.
if(this->OutputExtensions.count(ext)) std::string const& ext = source.GetExtension();
if(!ext.empty())
{ {
return ext; if(this->OutputExtensions.count(ext))
{
return ext.c_str();
}
} }
} }
return this->GetLanguageOutputExtensionForLanguage(lang); return "";
} }

View File

@ -143,10 +143,8 @@ public:
bool IgnoreFile(const char* ext); bool IgnoreFile(const char* ext);
///! What is the preference for linkers and this language (None or Prefered) ///! What is the preference for linkers and this language (None or Prefered)
const char* GetLinkerPreference(const char* lang); const char* GetLinkerPreference(const char* lang);
///! What is the output extension for a given language. ///! What is the object file extension for a given source file?
const char* GetLanguageOutputExtensionForLanguage(const char* lang); const char* GetLanguageOutputExtension(cmSourceFile const&);
///! What is the output extension for a given source file extension.
const char* GetLanguageOutputExtensionFromExtension(const char* lang);
///! What is the configurations directory variable called? ///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGInitDirectory() { return "."; } virtual const char* GetCMakeCFGInitDirectory() { return "."; }

View File

@ -440,9 +440,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
cmXCodeObject* children = group->GetObject("children"); cmXCodeObject* children = group->GetObject("children");
children->AddObject(fileRef); children->AddObject(fileRef);
cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
std::string fname = sf->GetSourceName(); std::string fname = sf->GetFullPath();
fname += ".";
fname += sf->GetSourceExtension();
std::string comment = fname; std::string comment = fname;
comment += " in "; comment += " in ";
std::string gname = group->GetObject("name")->GetString(); std::string gname = group->GetObject("name")->GetString();
@ -458,7 +456,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
const char* lang = const char* lang =
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf); this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
std::string sourcecode = "sourcecode"; std::string sourcecode = "sourcecode";
std::string ext = sf->GetSourceExtension(); std::string ext = sf->GetExtension();
ext = cmSystemTools::LowerCase(ext); ext = cmSystemTools::LowerCase(ext);
if(ext == "o") if(ext == "o")
{ {
@ -2046,12 +2044,12 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
// MACOSX_BUNDLE file // MACOSX_BUNDLE file
if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")) if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
{ {
cmSourceFile file; std::string plistFile =
file.SetName("Info", this->CurrentMakefile->GetCurrentOutputDirectory();
this->CurrentMakefile->GetCurrentOutputDirectory(), plistFile += "/Info.plist";
"plist", false); cmSourceFile* sf =
cmtarget.AddSourceFile this->CurrentMakefile->GetOrCreateSource(plistFile.c_str(), true);
(this->CurrentMakefile->AddSource(file)); cmtarget.AddSourceFile(sf);
} }
std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles(); std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
// add framework copy headers // add framework copy headers

View File

@ -147,12 +147,12 @@ void cmLocalGenerator::TraceDependencies()
// so don't build a projectfile for it // so don't build a projectfile for it
if (strncmp(t->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0) if (strncmp(t->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0)
{ {
std::string projectFilename; const char* projectFilename = 0;
if (this->IsMakefileGenerator == false) // only use of this variable if (this->IsMakefileGenerator == false) // only use of this variable
{ {
projectFilename=t->second.GetName(); projectFilename = t->second.GetName();
} }
t->second.TraceVSDependencies(projectFilename, this->Makefile); t->second.TraceDependencies(projectFilename);
} }
} }
} }
@ -625,18 +625,21 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
std::vector<cmSourceFile*> const& classes = target.GetSourceFiles(); std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); ++i) i != classes.end(); ++i)
{ {
if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") && cmSourceFile* sf = *i;
!(*i)->GetCustomCommand()) if(!sf->GetCustomCommand() &&
!sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
!sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
{ {
std::string outExt = std::string::size_type dir_len = 0;
this->GlobalGenerator->GetLanguageOutputExtensionFromExtension( dir_len += strlen(this->Makefile->GetCurrentOutputDirectory());
(*i)->GetSourceExtension().c_str()); dir_len += 1;
if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") ) std::string obj = this->GetObjectFileNameWithoutTarget(*sf, dir_len);
if(!obj.empty())
{ {
std::string ofname = this->Makefile->GetCurrentOutputDirectory(); std::string ofname = this->Makefile->GetCurrentOutputDirectory();
ofname += "/"; ofname += "/";
ofname += (*i)->GetSourceName() + outExt; ofname += obj;
objVector.push_back(ofname); objVector.push_back(ofname);
this->AddCustomCommandToCreateObject(ofname.c_str(), this->AddCustomCommandToCreateObject(ofname.c_str(),
llang, *(*i), target); llang, *(*i), target);
@ -1358,11 +1361,12 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin(); for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i) i != sources.end(); ++i)
{ {
if((*i)->GetSourceExtension() == "def") cmSourceFile* sf = *i;
if(sf->GetExtension() == "def")
{ {
linkFlags += linkFlags +=
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
linkFlags += this->Convert((*i)->GetFullPath().c_str(), linkFlags += this->Convert(sf->GetFullPath().c_str(),
START_OUTPUT, SHELL); START_OUTPUT, SHELL);
linkFlags += " "; linkFlags += " ";
} }
@ -2672,23 +2676,18 @@ cmLocalGenerator
// Replace the original source file extension with the object file // Replace the original source file extension with the object file
// extension. // extension.
std::string::size_type dot_pos = objectName.rfind("."); if(!source.GetPropertyAsBool("KEEP_EXTENSION"))
if(dot_pos != std::string::npos)
{ {
objectName = objectName.substr(0, dot_pos); // Remove the original extension.
} std::string::size_type dot_pos = objectName.rfind(".");
if ( source.GetPropertyAsBool("KEEP_EXTENSION") ) if(dot_pos != std::string::npos)
{
if ( !source.GetSourceExtension().empty() )
{ {
objectName += "." + source.GetSourceExtension(); objectName = objectName.substr(0, dot_pos);
} }
}
else // Store the new extension.
{
objectName += objectName +=
this->GlobalGenerator->GetLanguageOutputExtensionFromExtension( this->GlobalGenerator->GetLanguageOutputExtension(source);
source.GetSourceExtension().c_str());
} }
// Convert to a safe name. // Convert to a safe name.
@ -2700,15 +2699,7 @@ const char*
cmLocalGenerator cmLocalGenerator
::GetSourceFileLanguage(const cmSourceFile& source) ::GetSourceFileLanguage(const cmSourceFile& source)
{ {
// Check for an explicitly assigned language. return source.GetLanguage();
if(const char* lang = source.GetProperty("LANGUAGE"))
{
return lang;
}
// Infer the language from the source file extension.
return (this->GlobalGenerator
->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -2784,8 +2775,3 @@ cmLocalGenerator::GetTargetObjectFileDirectories(cmTarget* ,
cmSystemTools::Error("GetTargetObjectFileDirectories" cmSystemTools::Error("GetTargetObjectFileDirectories"
" called on cmLocalGenerator"); " called on cmLocalGenerator");
} }
std::string cmLocalGenerator::GetSourceObjectName(cmSourceFile& sf)
{
return sf.GetSourceName();
}

View File

@ -225,8 +225,6 @@ public:
GetTargetObjectFileDirectories(cmTarget* target, GetTargetObjectFileDirectories(cmTarget* target,
std::vector<std::string>& std::vector<std::string>&
dirs); dirs);
// return the source name for the object file
virtual std::string GetSourceObjectName(cmSourceFile& );
/** /**
* Convert the given remote path to a relative path with respect to * Convert the given remote path to a relative path with respect to

View File

@ -323,7 +323,7 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
sourceGroup.AssignSource(*i); sourceGroup.AssignSource(*i);
// while we are at it, if it is a .rule file then for visual studio 6 we // while we are at it, if it is a .rule file then for visual studio 6 we
// must generate it // must generate it
if ((*i)->GetSourceExtension() == "rule") if ((*i)->GetExtension() == "rule")
{ {
if(!cmSystemTools::FileExists(source.c_str())) if(!cmSystemTools::FileExists(source.c_str()))
{ {

View File

@ -883,10 +883,11 @@ void cmLocalVisualStudio7Generator
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++) i != classes.end(); i++)
{ {
if(cmSystemTools::UpperCase((*i)->GetSourceExtension()) == "DEF") cmSourceFile* sf = *i;
if(cmSystemTools::UpperCase(sf->GetExtension()) == "DEF")
{ {
fout << "\t\t\t\tModuleDefinitionFile=\"" fout << "\t\t\t\tModuleDefinitionFile=\""
<< this->ConvertToXMLOutputPath((*i)->GetFullPath().c_str()) << this->ConvertToXMLOutputPath(sf->GetFullPath().c_str())
<< "\"\n"; << "\"\n";
return; return;
} }
@ -969,7 +970,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
{ {
// Add the file to the list of sources. // Add the file to the list of sources.
std::string source = (*i)->GetFullPath(); std::string source = (*i)->GetFullPath();
if(cmSystemTools::UpperCase((*i)->GetSourceExtension()) == "DEF") if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
{ {
this->ModuleDefinitionFile = (*i)->GetFullPath(); this->ModuleDefinitionFile = (*i)->GetFullPath();
} }
@ -1070,8 +1071,9 @@ void cmLocalVisualStudio7Generator
compileFlags += " "; compileFlags += " ";
compileFlags += cflags; compileFlags += cflags;
} }
const char* lang = this->GlobalGenerator->GetLanguageFromExtension const char* lang =
((*sf)->GetSourceExtension().c_str()); this->GlobalGenerator->GetLanguageFromExtension
((*sf)->GetExtension().c_str());
const char* sourceLang = this->GetSourceFileLanguage(*(*sf)); const char* sourceLang = this->GetSourceFileLanguage(*(*sf));
const char* linkLanguage = target.GetLinkerLanguage const char* linkLanguage = target.GetLinkerLanguage
(this->GetGlobalGenerator()); (this->GetGlobalGenerator());
@ -1138,7 +1140,7 @@ void cmLocalVisualStudio7Generator
|| objectName.size() || excludedFromBuild) || objectName.size() || excludedFromBuild)
{ {
const char* aCompilerTool = "VCCLCompilerTool"; const char* aCompilerTool = "VCCLCompilerTool";
std::string ext = (*sf)->GetSourceExtension(); std::string ext = (*sf)->GetExtension();
ext = cmSystemTools::LowerCase(ext); ext = cmSystemTools::LowerCase(ext);
if(ext == "idl") if(ext == "idl")
{ {
@ -1902,18 +1904,3 @@ GetTargetObjectFileDirectories(cmTarget* target,
std::cerr << dir << "\n"; std::cerr << dir << "\n";
dirs.push_back(dir); dirs.push_back(dir);
} }
// return the source name for the object file
std::string
cmLocalVisualStudio7Generator::GetSourceObjectName(cmSourceFile& sf )
{
std::string ret = sf.GetSourceName();
std::string::size_type pos = ret.find("/");
if(pos == ret.npos)
{
return ret;
}
return ret.substr(pos+1);
}

View File

@ -62,8 +62,6 @@ public:
void GetTargetObjectFileDirectories(cmTarget* target, void GetTargetObjectFileDirectories(cmTarget* target,
std::vector<std::string>& std::vector<std::string>&
dirs); dirs);
// return the source name for the object file
virtual std::string GetSourceObjectName(cmSourceFile& );
void SetExtraFlagTable(cmVS7FlagTable const* table) void SetExtraFlagTable(cmVS7FlagTable const* table)
{ this->ExtraFlagTable = table; } { this->ExtraFlagTable = table; }

View File

@ -73,7 +73,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
std::string objectName = std::string objectName =
cmSystemTools::LowerCase( cmSystemTools::LowerCase(
cmSystemTools::GetFilenameWithoutLastExtension( cmSystemTools::GetFilenameWithoutLastExtension(
sf->GetFullPath().c_str())); sf->GetFullPath()));
objectName += ".obj"; objectName += ".obj";
objectNameCounts[objectName] += 1; objectNameCounts[objectName] += 1;
} }
@ -95,7 +95,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
std::string objectName = std::string objectName =
cmSystemTools::LowerCase( cmSystemTools::LowerCase(
cmSystemTools::GetFilenameWithoutLastExtension( cmSystemTools::GetFilenameWithoutLastExtension(
sf->GetFullPath().c_str())); sf->GetFullPath()));
objectName += ".obj"; objectName += ".obj";
if(objectNameCounts[objectName] > 1) if(objectNameCounts[objectName] > 1)
{ {

View File

@ -24,16 +24,3 @@ GetTargetObjectFileDirectories(cmTarget* target,
g->GetTargetObjectFileDirectories(target, g->GetTargetObjectFileDirectories(target,
dirs); dirs);
} }
// return the source name for the object file
std::string cmLocalXCodeGenerator::GetSourceObjectName(cmSourceFile& sf )
{
std::string ret = sf.GetSourceName();
std::string::size_type pos = ret.find("/");
if(pos == ret.npos)
{
return ret;
}
return ret.substr(pos+1);
}

View File

@ -35,8 +35,6 @@ public:
void GetTargetObjectFileDirectories(cmTarget* target, void GetTargetObjectFileDirectories(cmTarget* target,
std::vector<std::string>& std::vector<std::string>&
dirs); dirs);
// return the source name for the object file
virtual std::string GetSourceObjectName(cmSourceFile& );
private: private:
}; };

View File

@ -18,6 +18,7 @@
#include "cmVersion.h" #include "cmVersion.h"
#include "cmCommand.h" #include "cmCommand.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
@ -557,7 +558,6 @@ void cmMakefile::ConfigureFinalPass()
for (cmTargets::iterator l = this->Targets.begin(); for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); l++) l != this->Targets.end(); l++)
{ {
l->second.GenerateSourceFilesFromSourceLists(*this);
l->second.AnalyzeLibDependencies(*this); l->second.AnalyzeLibDependencies(*this);
} }
} }
@ -772,7 +772,7 @@ cmMakefile::AddCustomCommandOldStyle(const char* target,
{ {
if (this->Targets.find(target) != this->Targets.end()) if (this->Targets.find(target) != this->Targets.end())
{ {
this->Targets[target].AddSourceListEntry(source); this->Targets[target].AddSource(source);
} }
else else
{ {
@ -854,10 +854,10 @@ void cmMakefile::AddUtilityCommand(const char* utilityName,
commandLines, comment, commandLines, comment,
workingDirectory, no_replace, workingDirectory, no_replace,
escapeOldStyle); escapeOldStyle);
target->AddSourceListEntry(force.c_str()); cmSourceFile* sf = target->AddSource(force.c_str());
// The output is not actually created so mark it symbolic. // The output is not actually created so mark it symbolic.
if(cmSourceFile* sf = this->GetSource(force.c_str())) if(sf)
{ {
sf->SetProperty("SYMBOLIC", "1"); sf->SetProperty("SYMBOLIC", "1");
} }
@ -1364,7 +1364,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
{ {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
} }
target->SetSourceList(srcs); target->AddSources(srcs);
this->AddGlobalLinkInformation(lname, *target); this->AddGlobalLinkInformation(lname, *target);
} }
@ -1377,7 +1377,7 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
{ {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
} }
target->SetSourceList(srcs); target->AddSources(srcs);
this->AddGlobalLinkInformation(exeName, *target); this->AddGlobalLinkInformation(exeName, *target);
return target; return target;
} }
@ -2116,219 +2116,43 @@ cmData* cmMakefile::LookupData(const char* name) const
} }
} }
cmSourceFile* cmMakefile::GetSource(const char* sourceName) const //----------------------------------------------------------------------------
cmSourceFile* cmMakefile::GetSource(const char* sourceName)
{ {
// if the source is provided with a full path use it, otherwise cmSourceFileLocation sfl(this, sourceName);
// by default it is in the current source dir for(std::vector<cmSourceFile*>::const_iterator
std::string path; sfi = this->SourceFiles.begin();
if (cmSystemTools::FileIsFullPath(sourceName)) sfi != this->SourceFiles.end(); ++sfi)
{ {
path = cmSystemTools::GetFilenamePath(sourceName); cmSourceFile* sf = *sfi;
} if(sf->Matches(sfl))
else
{
path = this->GetCurrentDirectory();
// even though it is not a full path, it may still be relative
std::string subpath = cmSystemTools::GetFilenamePath(sourceName);
if (!subpath.empty())
{ {
path += "/"; return sf;
path += cmSystemTools::GetFilenamePath(sourceName);
} }
} }
path = cmSystemTools::CollapseFullPath(path.c_str());
std::string sname =
cmSystemTools::GetFilenameWithoutLastExtension(sourceName);
// compute the extension
std::string ext
= cmSystemTools::GetFilenameLastExtension(sourceName);
if ( ext.length() && ext[0] == '.' )
{
ext = ext.substr(1);
}
for(std::vector<cmSourceFile*>::const_iterator i =
this->SourceFiles.begin();
i != this->SourceFiles.end(); ++i)
{
if ((*i)->GetSourceNameWithoutLastExtension() == sname &&
cmSystemTools::GetFilenamePath((*i)->GetFullPath()) == path &&
(ext.size() == 0 || (ext == (*i)->GetSourceExtension())))
{
return *i;
}
}
// geeze, if it wasn't found maybe it is listed under the output dir
if (!cmSystemTools::GetFilenamePath(sourceName).empty())
{
return 0;
}
path = this->GetCurrentOutputDirectory();
for(std::vector<cmSourceFile*>::const_iterator i =
this->SourceFiles.begin();
i != this->SourceFiles.end(); ++i)
{
if ((*i)->GetSourceName() == sname &&
cmSystemTools::GetFilenamePath((*i)->GetFullPath()) == path &&
(ext.size() == 0 || (ext == (*i)->GetSourceExtension())))
{
return *i;
}
}
return 0; return 0;
} }
//----------------------------------------------------------------------------
cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName, cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
bool generated) bool generated)
{ {
// make it a full path first if(cmSourceFile* esf = this->GetSource(sourceName))
std::string src = sourceName;
bool relative = !cmSystemTools::FileIsFullPath(sourceName);
std::string srcTreeFile = this->GetCurrentDirectory();
srcTreeFile += "/";
srcTreeFile += sourceName;
if(relative)
{ {
src = srcTreeFile; return esf;
}
// check to see if it exists
cmSourceFile* ret = this->GetSource(src.c_str());
if (ret)
{
return ret;
}
// OK a source file object doesn't exist for the source
// maybe we made a bad call on assuming it was in the src tree
std::string buildTreeFile = this->GetCurrentOutputDirectory();
buildTreeFile += "/";
buildTreeFile += sourceName;
if (relative)
{
src = buildTreeFile;
ret = this->GetSource(src.c_str());
if (ret)
{
return ret;
}
// if it has not been marked generated check to see if it exists in the
// src tree
if(!generated)
{
// see if the file is in the source tree, otherwise assume it
// is in the binary tree
if (cmSystemTools::FileExists(srcTreeFile.c_str()) &&
!cmSystemTools::FileIsDirectory(srcTreeFile.c_str()))
{
src = srcTreeFile;
}
else
{
if ( cmSystemTools::GetFilenameLastExtension
(srcTreeFile.c_str()).size() == 0)
{
if (cmSystemTools::DoesFileExistWithExtensions(
srcTreeFile.c_str(), this->GetSourceExtensions()))
{
src = srcTreeFile;
}
else if (cmSystemTools::DoesFileExistWithExtensions(
srcTreeFile.c_str(), this->GetHeaderExtensions()))
{
src = srcTreeFile;
}
}
}
}
}
// a cmSourceFile instance does not exist yet so we must create one
// go back to looking in the source directory for it
// we must create one
cmSourceFile file;
file.SetMakefile(this);
std::string path = cmSystemTools::GetFilenamePath(src);
if(generated)
{
std::string ext = cmSystemTools::GetFilenameLastExtension(src);
std::string name_no_ext = cmSystemTools::GetFilenameName(src.c_str());
name_no_ext = name_no_ext.substr(0, name_no_ext.length()-ext.length());
if ( ext.length() && ext[0] == '.' )
{
ext = ext.substr(1);
}
bool headerFile =
!(std::find( this->HeaderFileExtensions.begin(),
this->HeaderFileExtensions.end(), ext ) ==
this->HeaderFileExtensions.end());
file.SetName(name_no_ext.c_str(), path.c_str(), ext.c_str(), headerFile);
} }
else else
{ {
std::string relPath = cmSystemTools::GetFilenamePath(sourceName); cmSourceFile* sf = new cmSourceFile(this, sourceName);
if (relative && relPath.size()) if(generated)
{ {
// we need to keep the relative part of the filename sf->SetProperty("GENERATED", "1");
std::string fullPathLessRel = path;
std::string::size_type pos = fullPathLessRel.rfind(relPath);
if (pos == std::string::npos)
{
cmSystemTools::Error(
"CMake failed to properly look up relative cmSourceFile: ",
sourceName);
}
fullPathLessRel.erase(pos-1);
file.SetName(sourceName, fullPathLessRel.c_str(),
this->GetSourceExtensions(),
this->GetHeaderExtensions());
}
else
{
file.SetName(cmSystemTools::GetFilenameName(src.c_str()).c_str(),
path.c_str(),
this->GetSourceExtensions(),
this->GetHeaderExtensions());
} }
this->SourceFiles.push_back(sf);
return sf;
} }
// add the source file to the makefile
this->AddSource(file);
src = file.GetFullPath();
ret = this->GetSource(src.c_str());
if (!ret)
{
cmSystemTools::Error(
"CMake failed to properly look up cmSourceFile: ", sourceName);
}
else
{
ret->SetMakefile(this);
}
return ret;
} }
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
{
// check to see if it exists
cmSourceFile* ret = this->GetSource(sf.GetFullPath().c_str());
if(ret)
{
return ret;
}
ret = new cmSourceFile(sf);
this->SourceFiles.push_back(ret);
return ret;
}
void cmMakefile::EnableLanguage(std::vector<std::string> const & lang) void cmMakefile::EnableLanguage(std::vector<std::string> const & lang)
{ {
this->AddDefinition("CMAKE_CFG_INTDIR", this->AddDefinition("CMAKE_CFG_INTDIR",

View File

@ -463,19 +463,16 @@ public:
/** Get a cmSourceFile pointer for a given source name, if the name is /** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then a null pointer is returned. * not found, then a null pointer is returned.
*/ */
cmSourceFile* GetSource(const char* sourceName) const; cmSourceFile* GetSource(const char* sourceName);
///! Add a new cmSourceFile to the list of sources for this makefile.
cmSourceFile* AddSource(cmSourceFile const&);
/** Get a cmSourceFile pointer for a given source name, if the name is /** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then create the source file and return it. generated * not found, then create the source file and return it. generated
* indicates if it is a generated file, this is used in determining * indicates if it is a generated file, this is used in determining
* how to create the source file instance e.g. name * how to create the source file instance e.g. name
*/ */
cmSourceFile* GetOrCreateSource(const char* sourceName, cmSourceFile* GetOrCreateSource(const char* sourceName,
bool generated = false); bool generated = false);
/** /**
* Obtain a list of auxiliary source directories. * Obtain a list of auxiliary source directories.
*/ */

View File

@ -147,13 +147,14 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin(); for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i) i != sources.end(); ++i)
{ {
if((*i)->GetSourceExtension() == "def") cmSourceFile* sf = *i;
if(sf->GetExtension() == "def")
{ {
extraFlags += " "; extraFlags += " ";
extraFlags += extraFlags +=
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
extraFlags += extraFlags +=
this->Convert((*i)->GetFullPath().c_str(), this->Convert(sf->GetFullPath().c_str(),
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
} }
@ -290,13 +291,7 @@ void cmMakefileLibraryTargetGenerator::CopyFrameworkPublicHeaders(
cmCustomCommandLine line; cmCustomCommandLine line;
cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str()); cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str());
std::string dest = outpath + "Headers/"; std::string dest = outpath + "Headers/";
dest += sf->GetSourceName(); dest += cmSystemTools::GetFilenameName(sf->GetFullPath());
std::string ext = sf->GetSourceExtension();
if(ext.size())
{
dest += ".";
dest += sf->GetSourceExtension();
}
line.push_back("$(CMAKE_COMMAND)"); line.push_back("$(CMAKE_COMMAND)");
line.push_back("-E"); line.push_back("-E");
line.push_back("copy_if_different"); line.push_back("copy_if_different");
@ -347,13 +342,7 @@ void cmMakefileLibraryTargetGenerator::CopyFrameworkResources(
continue; continue;
} }
std::string dest = outpath + "Resources/"; std::string dest = outpath + "Resources/";
dest += sf->GetSourceName(); dest += cmSystemTools::GetFilenameName(sf->GetFullPath());
std::string ext = sf->GetSourceExtension();
if(ext.size())
{
dest += ".";
dest += sf->GetSourceExtension();
}
line.push_back("$(CMAKE_COMMAND)"); line.push_back("$(CMAKE_COMMAND)");
line.push_back("-E"); line.push_back("-E");
line.push_back("copy_if_different"); line.push_back("copy_if_different");

View File

@ -152,7 +152,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY")) else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
{ {
if(!this->GlobalGenerator->IgnoreFile if(!this->GlobalGenerator->IgnoreFile
((*source)->GetSourceExtension().c_str())) ((*source)->GetExtension().c_str()))
{ {
// Generate this object file's rule file. // Generate this object file's rule file.
this->WriteObjectRuleFiles(*(*source)); this->WriteObjectRuleFiles(*(*source));
@ -307,8 +307,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
{ {
cmOStringStream err; cmOStringStream err;
err << "Warning: Source file \"" err << "Warning: Source file \""
<< source.GetSourceName().c_str() << "." << source.GetFullPath()
<< source.GetSourceExtension().c_str()
<< "\" is listed multiple times for target \"" << "\" is listed multiple times for target \""
<< this->Target->GetName() << this->Target->GetName()
<< "\"."; << "\".";

View File

@ -223,13 +223,6 @@ ListDependencies(cmDependInformation const *info,
void cmOutputRequiredFilesCommand::FinalPass() void cmOutputRequiredFilesCommand::FinalPass()
{ {
cmTargets &tgts = this->Makefile->GetTargets();
for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{
l->second.GenerateSourceFilesFromSourceLists(*this->Makefile);
}
// compute the list of files // compute the list of files
cmLBDepend md; cmLBDepend md;
md.SetMakefile(this->Makefile); md.SetMakefile(this->Makefile);

View File

@ -24,120 +24,96 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn)
this->SetError("called with incorrect number of arguments"); this->SetError("called with incorrect number of arguments");
return false; return false;
} }
// This command supports source list inputs for compatibility.
std::vector<std::string> args; std::vector<std::string> args;
this->Makefile->ExpandSourceListArguments(argsIn, args, 2); this->Makefile->ExpandSourceListArguments(argsIn, args, 2);
// what is the current source dir // Get the moc executable to run in the custom command.
std::string cdir = this->Makefile->GetCurrentDirectory(); const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// keep the library name // Get the variable holding the list of sources.
this->LibraryName = args[0]; std::string const& sourceList = args[1];
this->SourceList = args[1]; std::string sourceListValue =
this->Makefile->GetSafeDefinition(sourceList.c_str());
std::string sourceListValue;
// was the list already populated // Create a rule for all sources listed.
const char *def = this->Makefile->GetDefinition(this->SourceList.c_str());
if (def)
{
sourceListValue = def;
}
// get the list of classes for this library
for(std::vector<std::string>::iterator j = (args.begin() + 2); for(std::vector<std::string>::iterator j = (args.begin() + 2);
j != args.end(); ++j) j != args.end(); ++j)
{ {
cmSourceFile *curr = this->Makefile->GetSource(j->c_str()); cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
// if we should wrap the class // if we should wrap the class
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) if(!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE")))
{ {
cmSourceFile file; // Compute the name of the file to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j);
std::string newName = this->Makefile->GetCurrentOutputDirectory();
newName += "/moc_";
newName += srcName;
newName += ".cxx";
cmSourceFile* sf =
this->Makefile->GetOrCreateSource(newName.c_str(), true);
if (curr) if (curr)
{ {
file.SetProperty("ABSTRACT",curr->GetProperty("ABSTRACT")); sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
} }
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j); // Compute the name of the header from which to generate the file.
std::string newName = "moc_" + srcName;
file.SetName(newName.c_str(),
this->Makefile->GetCurrentOutputDirectory(),
"cxx",false);
std::string hname; std::string hname;
if ( (*j)[0] == '/' || (*j)[1] == ':' ) if(cmSystemTools::FileIsFullPath(j->c_str()))
{ {
hname = *j; hname = *j;
} }
else else
{ {
if ( curr && curr->GetPropertyAsBool("GENERATED") ) if(curr && curr->GetPropertyAsBool("GENERATED"))
{ {
hname = std::string(this->Makefile->GetCurrentOutputDirectory()) hname = this->Makefile->GetCurrentOutputDirectory();
+ "/" + *j;
} }
else else
{ {
hname = cdir + "/" + *j; hname = this->Makefile->GetCurrentDirectory();
} }
hname += "/";
hname += *j;
} }
this->WrapHeaders.push_back(hname);
// add starting depends // Append the generated source file to the list.
file.AddDepend(hname.c_str()); if(!sourceListValue.empty())
this->WrapClasses.push_back(file);
if (sourceListValue.size() > 0)
{ {
sourceListValue += ";"; sourceListValue += ";";
} }
sourceListValue += newName + ".cxx"; sourceListValue += newName;
// Create the custom command to generate the file.
cmCustomCommandLine commandLine;
commandLine.push_back(moc_exe);
commandLine.push_back("-o");
commandLine.push_back(newName);
commandLine.push_back(hname);
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
std::vector<std::string> depends;
depends.push_back(moc_exe);
depends.push_back(hname);
const char* no_main_dependency = 0;
const char* no_working_dir = 0;
this->Makefile->AddCustomCommandToOutput(newName.c_str(),
depends,
no_main_dependency,
commandLines,
"QT Wrapped File",
no_working_dir);
} }
} }
this->Makefile->AddDefinition(this->SourceList.c_str(), // Store the final list of source files.
this->Makefile->AddDefinition(sourceList.c_str(),
sourceListValue.c_str()); sourceListValue.c_str());
return true; return true;
} }
void cmQTWrapCPPCommand::FinalPass()
{
// first we add the rules for all the .h to Moc files
size_t lastClass = this->WrapClasses.size();
std::vector<std::string> depends;
const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// wrap all the .h files
depends.push_back(moc_exe);
for(size_t classNum = 0; classNum < lastClass; classNum++)
{
// Add output to build list
this->Makefile->AddSource(this->WrapClasses[classNum]);
// set up moc command
std::string res = this->Makefile->GetCurrentOutputDirectory();
res += "/";
res += this->WrapClasses[classNum].GetSourceName() + ".cxx";
cmCustomCommandLine commandLine;
commandLine.push_back(moc_exe);
commandLine.push_back("-o");
commandLine.push_back(res);
commandLine.push_back(this->WrapHeaders[classNum]);
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
std::vector<std::string> realdepends = depends;
realdepends.push_back(this->WrapHeaders[classNum]);
const char* no_main_dependency = 0;
const char* no_working_dir = 0;
this->Makefile->AddCustomCommandToOutput(res.c_str(),
realdepends,
no_main_dependency,
commandLines,
"QT Wrapped File",
no_working_dir);
}
}

View File

@ -45,14 +45,6 @@ public:
* the CMakeLists.txt file. * the CMakeLists.txt file.
*/ */
virtual bool InitialPass(std::vector<std::string> const& args); virtual bool InitialPass(std::vector<std::string> const& args);
/**
* This is called at the end after all the information
* specified by the command is accumulated. Most commands do
* not implement this method. At this point, reading and
* writing to the cache can be done.
*/
virtual void FinalPass();
/** /**
* The name of the command as specified in CMakeList.txt. * The name of the command as specified in CMakeList.txt.
@ -79,18 +71,6 @@ public:
"The moc files will be added to the library using the DestName " "The moc files will be added to the library using the DestName "
"source list."; "source list.";
} }
private:
/**
* List of produced files.
*/
std::vector<cmSourceFile> WrapClasses;
/**
* List of header files that pprovide the source for WrapClasses.
*/
std::vector<std::string> WrapHeaders;
std::string LibraryName;
std::string SourceList;
}; };

View File

@ -24,191 +24,147 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn)
this->SetError("called with incorrect number of arguments"); this->SetError("called with incorrect number of arguments");
return false; return false;
} }
// This command supports source list inputs for compatibility.
std::vector<std::string> args; std::vector<std::string> args;
this->Makefile->ExpandSourceListArguments(argsIn, args, 3); this->Makefile->ExpandSourceListArguments(argsIn, args, 3);
// what is the current source dir // Get the uic and moc executables to run in the custom commands.
std::string cdir = this->Makefile->GetCurrentDirectory();
// keep the library name
this->LibraryName = args[0];
this->HeaderList = args[1];
this->SourceList = args[2];
std::string sourceListValue;
std::string headerListValue;
const char *def = this->Makefile->GetDefinition(this->SourceList.c_str());
if (def)
{
sourceListValue = def;
}
// get the list of classes for this library
for(std::vector<std::string>::iterator j = (args.begin() + 3);
j != args.end(); ++j)
{
cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
// if we should wrap the class
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{
cmSourceFile header_file;
cmSourceFile source_file;
cmSourceFile moc_file;
std::string srcName = cmSystemTools::GetFilenameWithoutExtension(*j);
header_file.SetName(srcName.c_str(),
this->Makefile->GetCurrentOutputDirectory(),
"h",false);
source_file.SetName(srcName.c_str(),
this->Makefile->GetCurrentOutputDirectory(),
"cxx",false);
std::string moc_source_name("moc_");
moc_source_name = moc_source_name + srcName;
moc_file.SetName(moc_source_name.c_str(),
this->Makefile->GetCurrentOutputDirectory(),
"cxx",false);
std::string origname;
if ( (*j)[0] == '/' || (*j)[1] == ':' )
{
origname = *j;
}
else
{
if ( curr && curr->GetPropertyAsBool("GENERATED") )
{
origname = std::string(this->Makefile->GetCurrentOutputDirectory())
+ "/" + *j;
}
else
{
origname = cdir + "/" + *j;
}
}
std::string hname = header_file.GetFullPath();
this->WrapUserInterface.push_back(origname);
// add starting depends
moc_file.AddDepend(hname.c_str());
source_file.AddDepend(hname.c_str());
source_file.AddDepend(origname.c_str());
header_file.AddDepend(origname.c_str());
this->WrapHeadersClasses.push_back(header_file);
this->WrapSourcesClasses.push_back(source_file);
this->WrapMocClasses.push_back(moc_file);
this->Makefile->AddSource(header_file);
this->Makefile->AddSource(source_file);
this->Makefile->AddSource(moc_file);
// create the list of headers
if (headerListValue.size() > 0)
{
headerListValue += ";";
}
headerListValue += header_file.GetFullPath();
// create the list of sources
if (sourceListValue.size() > 0)
{
sourceListValue += ";";
}
sourceListValue += source_file.GetFullPath();
sourceListValue += ";";
sourceListValue += moc_file.GetFullPath();
}
}
this->Makefile->AddDefinition(this->SourceList.c_str(),
sourceListValue.c_str());
this->Makefile->AddDefinition(this->HeaderList.c_str(),
headerListValue.c_str());
return true;
}
void cmQTWrapUICommand::FinalPass()
{
// first we add the rules for all the .ui to .h and .cxx files
size_t lastHeadersClass = this->WrapHeadersClasses.size();
std::vector<std::string> depends;
const char* uic_exe = const char* uic_exe =
this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE"); this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE");
const char* moc_exe = const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE"); this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// wrap all the .h files // Get the variable holding the list of sources.
depends.push_back(uic_exe); std::string const& headerList = args[1];
std::string const& sourceList = args[2];
std::string headerListValue =
this->Makefile->GetSafeDefinition(headerList.c_str());
std::string sourceListValue =
this->Makefile->GetSafeDefinition(sourceList.c_str());
for(size_t classNum = 0; classNum < lastHeadersClass; classNum++) // Create rules for all sources listed.
for(std::vector<std::string>::iterator j = (args.begin() + 3);
j != args.end(); ++j)
{ {
// set up .ui to .h and .cxx command cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
std::string hres = this->Makefile->GetCurrentOutputDirectory(); // if we should wrap the class
hres += "/"; if(!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE")))
hres += this->WrapHeadersClasses[classNum].GetSourceName() + "." + {
this->WrapHeadersClasses[classNum].GetSourceExtension(); // Compute the name of the files to generate.
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j);
std::string hName = this->Makefile->GetCurrentOutputDirectory();
hName += "/";
hName += srcName;
hName += ".h";
std::string cxxName = this->Makefile->GetCurrentOutputDirectory();
cxxName += "/";
cxxName += srcName;
cxxName += ".cxx";
std::string mocName = this->Makefile->GetCurrentOutputDirectory();
mocName += "/moc_";
mocName += srcName;
mocName += ".cxx";
std::string cxxres = this->Makefile->GetCurrentOutputDirectory(); // Compute the name of the ui file from which to generate others.
cxxres += "/"; std::string uiName;
cxxres += this->WrapSourcesClasses[classNum].GetSourceName() + "." + if(cmSystemTools::FileIsFullPath(j->c_str()))
this->WrapSourcesClasses[classNum].GetSourceExtension(); {
uiName = *j;
}
else
{
if(curr && curr->GetPropertyAsBool("GENERATED"))
{
uiName = this->Makefile->GetCurrentOutputDirectory();
}
else
{
uiName = this->Makefile->GetCurrentDirectory();
}
uiName += "/";
uiName += *j;
}
std::string mocres = this->Makefile->GetCurrentOutputDirectory(); // create the list of headers
mocres += "/"; if(!headerListValue.empty())
mocres += this->WrapMocClasses[classNum].GetSourceName() + "." + {
this->WrapMocClasses[classNum].GetSourceExtension(); headerListValue += ";";
}
headerListValue += hName;
cmCustomCommandLine hCommand; // create the list of sources
hCommand.push_back(uic_exe); if(!sourceListValue.empty())
hCommand.push_back("-o"); {
hCommand.push_back(hres); sourceListValue += ";";
hCommand.push_back(this->WrapUserInterface[classNum]); }
cmCustomCommandLines hCommandLines; sourceListValue += cxxName;
hCommandLines.push_back(hCommand); sourceListValue += ";";
sourceListValue += mocName;
cmCustomCommandLine cxxCommand; // set up .ui to .h and .cxx command
cxxCommand.push_back(uic_exe); cmCustomCommandLine hCommand;
cxxCommand.push_back("-impl"); hCommand.push_back(uic_exe);
cxxCommand.push_back(hres); hCommand.push_back("-o");
cxxCommand.push_back("-o"); hCommand.push_back(hName);
cxxCommand.push_back(cxxres); hCommand.push_back(uiName);
cxxCommand.push_back(this->WrapUserInterface[classNum]); cmCustomCommandLines hCommandLines;
cmCustomCommandLines cxxCommandLines; hCommandLines.push_back(hCommand);
cxxCommandLines.push_back(cxxCommand);
cmCustomCommandLine mocCommand; cmCustomCommandLine cxxCommand;
mocCommand.push_back(moc_exe); cxxCommand.push_back(uic_exe);
mocCommand.push_back("-o"); cxxCommand.push_back("-impl");
mocCommand.push_back(mocres); cxxCommand.push_back(hName);
mocCommand.push_back(hres); cxxCommand.push_back("-o");
cmCustomCommandLines mocCommandLines; cxxCommand.push_back(cxxName);
mocCommandLines.push_back(mocCommand); cxxCommand.push_back(uiName);
cmCustomCommandLines cxxCommandLines;
cxxCommandLines.push_back(cxxCommand);
depends.clear(); cmCustomCommandLine mocCommand;
depends.push_back(this->WrapUserInterface[classNum]); mocCommand.push_back(moc_exe);
const char* no_main_dependency = 0; mocCommand.push_back("-o");
const char* no_comment = 0; mocCommand.push_back(mocName);
const char* no_working_dir = 0; mocCommand.push_back(hName);
this->Makefile->AddCustomCommandToOutput(hres.c_str(), cmCustomCommandLines mocCommandLines;
depends, mocCommandLines.push_back(mocCommand);
no_main_dependency,
hCommandLines,
no_comment,
no_working_dir);
depends.push_back(hres); std::vector<std::string> depends;
depends.push_back(uiName);
const char* no_main_dependency = 0;
const char* no_comment = 0;
const char* no_working_dir = 0;
this->Makefile->AddCustomCommandToOutput(hName.c_str(),
depends,
no_main_dependency,
hCommandLines,
no_comment,
no_working_dir);
this->Makefile->AddCustomCommandToOutput(cxxres.c_str(), depends.push_back(hName);
depends, this->Makefile->AddCustomCommandToOutput(cxxName.c_str(),
no_main_dependency, depends,
cxxCommandLines, no_main_dependency,
no_comment, cxxCommandLines,
no_working_dir); no_comment,
no_working_dir);
depends.clear(); depends.clear();
depends.push_back(hres); depends.push_back(hName);
this->Makefile->AddCustomCommandToOutput(mocName.c_str(),
this->Makefile->AddCustomCommandToOutput(mocres.c_str(), depends,
depends, no_main_dependency,
no_main_dependency, mocCommandLines,
mocCommandLines, no_comment,
no_comment, no_working_dir);
no_working_dir); }
} }
// Store the final list of source files and headers.
this->Makefile->AddDefinition(sourceList.c_str(),
sourceListValue.c_str());
this->Makefile->AddDefinition(headerList.c_str(),
headerListValue.c_str());
return true;
} }

View File

@ -43,14 +43,6 @@ public:
* the CMakeLists.txt file. * the CMakeLists.txt file.
*/ */
virtual bool InitialPass(std::vector<std::string> const& args); virtual bool InitialPass(std::vector<std::string> const& args);
/**
* This is called at the end after all the information
* specified by the command is accumulated. Most commands do
* not implement this method. At this point, reading and
* writing to the cache can be done.
*/
virtual void FinalPass();
/** /**
* The name of the command as specified in CMakeList.txt. * The name of the command as specified in CMakeList.txt.
@ -80,21 +72,6 @@ public:
"The .cxx files will be added to the library using the SourcesDestName" "The .cxx files will be added to the library using the SourcesDestName"
"source list."; "source list.";
} }
private:
/**
* List of produced files.
*/
std::vector<cmSourceFile> WrapSourcesClasses;
std::vector<cmSourceFile> WrapHeadersClasses;
std::vector<cmSourceFile> WrapMocClasses;
/**
* List of header files that pprovide the source for WrapClasses.
*/
std::vector<std::string> WrapUserInterface;
std::string LibraryName;
std::string HeaderList;
std::string SourceList;
}; };

View File

@ -15,161 +15,235 @@
=========================================================================*/ =========================================================================*/
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmake.h" #include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmake.h"
// Set the name of the class and the full path to the file. //----------------------------------------------------------------------------
// The class must be found in dir and end in name.cxx, name.txx, cmSourceFile::cmSourceFile(cmMakefile* mf, const char* name):
// name.c or it will be considered a header file only class Location(mf, name)
// and not included in the build process
bool cmSourceFile::SetName(const char* name, const char* dir,
const std::vector<std::string>& sourceExts,
const std::vector<std::string>& headerExts,
const char* target)
{ {
this->CustomCommand = 0;
this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
this->FindFullPathFailed = false;
}
this->SetProperty("HEADER_FILE_ONLY","1"); //----------------------------------------------------------------------------
this->SourceNameWithoutLastExtension = ""; cmSourceFile::~cmSourceFile()
{
this->SetCustomCommand(0);
}
// Save the original name given. //----------------------------------------------------------------------------
this->SourceName = name; std::string const& cmSourceFile::GetExtension() const
{
return this->Extension;
}
// Convert the name to a full path in case the given name is a //----------------------------------------------------------------------------
// relative path. const char* cmSourceFile::GetLanguage()
std::string pathname = cmSystemTools::CollapseFullPath(name, dir); {
// Compute the final location of the file if necessary.
// First try and see whether the listed file can be found if(this->FullPath.empty())
// as is without extensions added on.
std::string hname = pathname;
if(cmSystemTools::FileExists(hname.c_str()))
{ {
this->SourceName = cmSystemTools::GetFilenamePath(name); this->GetFullPath();
if ( this->SourceName.size() > 0 ) }
{
this->SourceName += "/";
}
this->SourceName += cmSystemTools::GetFilenameWithoutLastExtension(name);
std::string::size_type pos = hname.rfind('.');
if(pos != std::string::npos)
{
this->SourceExtension = hname.substr(pos+1, hname.size()-pos);
if ( cmSystemTools::FileIsFullPath(name) )
{
std::string::size_type pos2 = hname.rfind('/');
if(pos2 != std::string::npos)
{
this->SourceName = hname.substr(pos2+1, pos - pos2-1);
}
}
}
// See if the file is a header file // Now try to determine the language.
if(std::find( headerExts.begin(), headerExts.end(), return static_cast<cmSourceFile const*>(this)->GetLanguage();
this->SourceExtension ) == headerExts.end()) }
{
this->SetProperty("HEADER_FILE_ONLY","0");
}
this->FullPath = hname;
// Mark this as an external object file if it has the proper //----------------------------------------------------------------------------
// extension. THIS CODE IS DUPLICATED IN THE OTHER SetName METHOD. const char* cmSourceFile::GetLanguage() const
// THESE METHODS SHOULD BE MERGED. {
if ( this->SourceExtension == "obj" || this->SourceExtension == "o" || // If the language was set explicitly by the user then use it.
this->SourceExtension == "lo" ) if(const char* lang = this->GetProperty("LANGUAGE"))
{
return lang;
}
// If the language was determined from the source file extension use it.
if(!this->Language.empty())
{
return this->Language.c_str();
}
// The language is not known.
return 0;
}
//----------------------------------------------------------------------------
std::string const& cmSourceFile::GetFullPath()
{
if(this->FullPath.empty())
{
if(this->FindFullPath())
{ {
this->SetProperty("EXTERNAL_OBJECT", "1"); this->CheckExtension();
} }
}
return this->FullPath;
}
//----------------------------------------------------------------------------
std::string const& cmSourceFile::GetFullPath() const
{
return this->FullPath;
}
//----------------------------------------------------------------------------
bool cmSourceFile::FindFullPath()
{
// If thie method has already failed once do not try again.
if(this->FindFullPathFailed)
{
return false;
}
// If the file is generated compute the location without checking on
// disk.
if(this->GetPropertyAsBool("GENERATED"))
{
// The file is either already a full path or is relative to the
// build directory for the target.
this->Location.DirectoryUseBinary();
this->FullPath = this->Location.GetDirectory();
this->FullPath += "/";
this->FullPath += this->Location.GetName();
return true; return true;
} }
// Next, try the various source extensions // The file is not generated. It must exist on disk.
for( std::vector<std::string>::const_iterator ext = sourceExts.begin(); cmMakefile* mf = this->Location.GetMakefile();
ext != sourceExts.end(); ++ext ) const char* tryDirs[3] = {0, 0, 0};
if(this->Location.DirectoryIsAmbiguous())
{ {
hname = pathname; tryDirs[0] = mf->GetCurrentDirectory();
hname += "."; tryDirs[1] = mf->GetCurrentOutputDirectory();
hname += *ext; }
if(cmSystemTools::FileExists(hname.c_str())) else
{
tryDirs[0] = "";
}
const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
for(const char* const* di = tryDirs; *di; ++di)
{
std::string tryPath = this->Location.GetDirectory();
if(!tryPath.empty())
{
tryPath += "/";
}
tryPath += this->Location.GetName();
tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str(), *di);
if(this->TryFullPath(tryPath.c_str(), 0))
{ {
this->SourceExtension = *ext;
this->SetProperty("HEADER_FILE_ONLY","0");
this->FullPath = hname;
return true; return true;
} }
} for(std::vector<std::string>::const_iterator ei = srcExts.begin();
ei != srcExts.end(); ++ei)
// Finally, try the various header extensions
for( std::vector<std::string>::const_iterator ext = headerExts.begin();
ext != headerExts.end(); ++ext )
{
hname = pathname;
hname += ".";
hname += *ext;
if(cmSystemTools::FileExists(hname.c_str()))
{ {
this->SourceExtension = *ext; if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
this->FullPath = hname; {
return true; return true;
}
}
for(std::vector<std::string>::const_iterator ei = hdrExts.begin();
ei != hdrExts.end(); ++ei)
{
if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
{
return true;
}
} }
} }
cmOStringStream e; cmOStringStream e;
e << "Cannot find source file \"" << pathname << "\""; e << "Cannot find source file \"" << this->Location.GetName() << "\"";
if(target)
{
e << " for target \"" << target << "\"";
}
e << "\n\nTried extensions"; e << "\n\nTried extensions";
for( std::vector<std::string>::const_iterator ext = sourceExts.begin(); for(std::vector<std::string>::const_iterator ext = srcExts.begin();
ext != sourceExts.end(); ++ext ) ext != srcExts.end(); ++ext)
{ {
e << " ." << *ext; e << " ." << *ext;
} }
for( std::vector<std::string>::const_iterator ext = headerExts.begin(); for(std::vector<std::string>::const_iterator ext = hdrExts.begin();
ext != headerExts.end(); ++ext ) ext != hdrExts.end(); ++ext)
{ {
e << " ." << *ext; e << " ." << *ext;
} }
cmSystemTools::Error(e.str().c_str()); cmSystemTools::Error(e.str().c_str());
this->FindFullPathFailed = true;
return false; return false;
} }
void cmSourceFile::SetName(const char* name, const char* dir, const char *ext, //----------------------------------------------------------------------------
bool hfo) bool cmSourceFile::TryFullPath(const char* tp, const char* ext)
{ {
this->SetProperty("HEADER_FILE_ONLY",(hfo ? "1" : "0")); std::string tryPath = tp;
this->SourceNameWithoutLastExtension = ""; if(ext && *ext)
this->SourceName = name;
std::string fname = this->SourceName;
if(ext && strlen(ext))
{ {
fname += "."; tryPath += ".";
fname += ext; tryPath += ext;
} }
this->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir); if(cmSystemTools::FileExists(tryPath.c_str()))
cmSystemTools::ConvertToUnixSlashes(this->FullPath); {
this->SourceExtension = ext; this->FullPath = tryPath;
return true;
}
return false;
}
// Mark this as an external object file if it has the proper //----------------------------------------------------------------------------
// extension. THIS CODE IS DUPLICATED IN THE OTHER SetName METHOD. void cmSourceFile::CheckExtension()
// THESE METHODS SHOULD BE MERGED. {
if ( this->SourceExtension == "obj" || this->SourceExtension == "o" || // Compute the extension.
this->SourceExtension == "lo" ) std::string realExt =
cmSystemTools::GetFilenameLastExtension(this->FullPath);
if(!realExt.empty())
{
// Store the extension without the leading '.'.
this->Extension = realExt.substr(1);
}
// Look for object files.
if(this->Extension == "obj" ||
this->Extension == "o" ||
this->Extension == "lo")
{ {
this->SetProperty("EXTERNAL_OBJECT", "1"); this->SetProperty("EXTERNAL_OBJECT", "1");
} }
return;
// Look for header files.
cmMakefile* mf = this->Location.GetMakefile();
const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
if(std::find(hdrExts.begin(), hdrExts.end(), this->Extension) ==
hdrExts.end())
{
this->SetProperty("HEADER_FILE_ONLY", "0");
}
else
{
this->SetProperty("HEADER_FILE_ONLY", "1");
}
// Try to identify the source file language from the extension.
cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
if(const char* l = gg->GetLanguageFromExtension(this->Extension.c_str()))
{
this->Language = l;
}
} }
void cmSourceFile::Print() const //----------------------------------------------------------------------------
bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
{ {
std::cerr << "this->FullPath: " << this->FullPath << "\n"; return this->Location.Matches(loc);
std::cerr << "this->SourceName: " << this->SourceName << std::endl;
std::cerr << "this->SourceExtension: " << this->SourceExtension << "\n";
} }
//----------------------------------------------------------------------------
void cmSourceFile::SetProperty(const char* prop, const char* value) void cmSourceFile::SetProperty(const char* prop, const char* value)
{ {
if (!prop) if (!prop)
@ -184,13 +258,20 @@ void cmSourceFile::SetProperty(const char* prop, const char* value)
this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
} }
const char *cmSourceFile::GetProperty(const char* prop) const //----------------------------------------------------------------------------
const char* cmSourceFile::GetProperty(const char* prop) const
{ {
// watch for special "computed" properties that are dependent on other // Check for computed properties.
// properties or variables, always recompute them if(strcmp(prop, "LOCATION") == 0)
if (!strcmp(prop,"LOCATION"))
{ {
return this->FullPath.c_str(); if(this->FullPath.empty())
{
return 0;
}
else
{
return this->FullPath.c_str();
}
} }
bool chain = false; bool chain = false;
@ -198,53 +279,40 @@ const char *cmSourceFile::GetProperty(const char* prop) const
this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain); this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain);
if (chain) if (chain)
{ {
return this->Makefile->GetProperty(prop,cmProperty::SOURCE_FILE); cmMakefile* mf = this->Location.GetMakefile();
return mf->GetProperty(prop,cmProperty::SOURCE_FILE);
} }
return retVal; return retVal;
} }
//----------------------------------------------------------------------------
bool cmSourceFile::GetPropertyAsBool(const char* prop) const bool cmSourceFile::GetPropertyAsBool(const char* prop) const
{ {
return cmSystemTools::IsOn(this->GetProperty(prop)); return cmSystemTools::IsOn(this->GetProperty(prop));
} }
void cmSourceFile::SetCustomCommand(cmCustomCommand* cc) //----------------------------------------------------------------------------
cmCustomCommand* cmSourceFile::GetCustomCommand()
{ {
if(this->CustomCommand) return this->CustomCommand;
{
delete this->CustomCommand;
}
this->CustomCommand = cc;
}
const std::string& cmSourceFile::GetSourceNameWithoutLastExtension()
{
if ( this->SourceNameWithoutLastExtension.empty() )
{
this->SourceNameWithoutLastExtension =
cmSystemTools::GetFilenameWithoutLastExtension(this->FullPath);
}
return this->SourceNameWithoutLastExtension;
}
cmSourceFile::cmSourceFile()
{
this->Makefile = 0;
this->CustomCommand = 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmSourceFile::SetMakefile(cmMakefile* mf) cmCustomCommand const* cmSourceFile::GetCustomCommand() const
{ {
// Set our makefile. return this->CustomCommand;
this->Makefile = mf;
// set the cmake instance of the properties
this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
} }
// define properties //----------------------------------------------------------------------------
void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
{
cmCustomCommand* old = this->CustomCommand;
this->CustomCommand = cc;
delete old;
}
//----------------------------------------------------------------------------
void cmSourceFile::DefineProperties(cmake *cm) void cmSourceFile::DefineProperties(cmake *cm)
{ {
// define properties // define properties

View File

@ -17,11 +17,11 @@
#ifndef cmSourceFile_h #ifndef cmSourceFile_h
#define cmSourceFile_h #define cmSourceFile_h
#include "cmSourceFileLocation.h"
#include "cmCustomCommand.h" #include "cmCustomCommand.h"
#include "cmPropertyMap.h" #include "cmPropertyMap.h"
class cmake; class cmake;
class cmMakefile;
/** \class cmSourceFile /** \class cmSourceFile
* \brief Represent a class loaded from a makefile. * \brief Represent a class loaded from a makefile.
@ -33,67 +33,41 @@ class cmSourceFile
{ {
public: public:
/** /**
* Construct instance as a concrete class with both a * Construct with the makefile storing the source and the initial
* .h and .cxx file. * name referencing it.
*/ */
cmSourceFile(); cmSourceFile(cmMakefile* mf, const char* name);
~cmSourceFile()
{ ~cmSourceFile();
this->SetCustomCommand(0);
}
/**
* Set the name of the file, given the directory the file should be
* in. The various extensions provided are tried on the name
* (e.g., cxx, cpp) in the directory to find the actual file.
*/
bool SetName(const char* name, const char* dir,
const std::vector<std::string>& sourceExts,
const std::vector<std::string>& headerExts,
const char* target = 0);
/** /**
* Get the list of the custom commands for this source file * Get the list of the custom commands for this source file
*/ */
const cmCustomCommand *GetCustomCommand() const cmCustomCommand* GetCustomCommand();
{return this->CustomCommand;} cmCustomCommand const* GetCustomCommand() const;
cmCustomCommand *GetCustomCommand() {return this->CustomCommand;}
void SetCustomCommand(cmCustomCommand *cc); void SetCustomCommand(cmCustomCommand *cc);
/**
* Set the name of the file, given the directory the file should be in. IN
* this version the extension is provided in the call. This is useful for
* generated files that do not exist prior to the build.
*/
void SetName(const char* name, const char* dir, const char *ext,
bool headerFileOnly);
/**
* Print the structure to std::cout.
*/
void Print() const;
///! Set/Get a property of this source file ///! Set/Get a property of this source file
void SetProperty(const char *prop, const char *value); void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop) const; const char *GetProperty(const char *prop) const;
bool GetPropertyAsBool(const char *prop) const; bool GetPropertyAsBool(const char *prop) const;
/** /**
* The full path to the file. * The full path to the file.
*/ */
const std::string &GetFullPath() const {return this->FullPath;} std::string const& GetFullPath();
std::string const& GetFullPath() const;
/** /**
* The file name associated with stripped off directory and extension. * Get the file extension of this source file.
* (In most cases this is the name of the class.)
*/ */
const std::string &GetSourceName() const {return this->SourceName;} std::string const& GetExtension() const;
/** /**
* The file extension associated with source file * Get the language of the compiler to use for this source file.
*/ */
const std::string &GetSourceExtension() const { const char* GetLanguage();
return this->SourceExtension;} const char* GetLanguage() const;
/** /**
* Return the vector that holds the list of dependencies * Return the vector that holds the list of dependencies
@ -101,33 +75,32 @@ public:
const std::vector<std::string> &GetDepends() const {return this->Depends;} const std::vector<std::string> &GetDepends() const {return this->Depends;}
void AddDepend(const char* d) { this->Depends.push_back(d); } void AddDepend(const char* d) { this->Depends.push_back(d); }
/**
* Get the source name without last extension
*/
const std::string& GetSourceNameWithoutLastExtension();
// Get the properties // Get the properties
cmPropertyMap &GetProperties() { return this->Properties; }; cmPropertyMap &GetProperties() { return this->Properties; };
// Define the properties // Define the properties
static void DefineProperties(cmake *cm); static void DefineProperties(cmake *cm);
///! Set the cmMakefile that owns this target /**
void SetMakefile(cmMakefile *mf); * Check whether the given source file location could refer to this
cmMakefile *GetMakefile() { return this->Makefile;}; * source.
*/
bool Matches(cmSourceFileLocation const&);
private: private:
cmSourceFileLocation Location;
cmPropertyMap Properties; cmPropertyMap Properties;
cmCustomCommand *CustomCommand; cmCustomCommand* CustomCommand;
std::string Extension;
std::string Language;
std::string FullPath; std::string FullPath;
std::string SourceName; bool FindFullPathFailed;
std::string SourceExtension;
std::vector<std::string> Depends;
std::string SourceNameWithoutLastExtension;
// The cmMakefile instance that owns this source file. This should bool FindFullPath();
// always be set. bool TryFullPath(const char* tryPath, const char* ext);
cmMakefile* Makefile; void CheckExtension();
std::vector<std::string> Depends;
}; };
#endif #endif

View File

@ -0,0 +1,212 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmSourceFileLocation.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
//----------------------------------------------------------------------------
cmSourceFileLocation
::cmSourceFileLocation(cmMakefile* mf, const char* name): Makefile(mf)
{
this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name);
this->AmbiguousExtension = true;
this->Directory = cmSystemTools::GetFilenamePath(name);
this->Name = cmSystemTools::GetFilenameName(name);
this->UpdateExtension(name);
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::Update(const char* name)
{
if(this->AmbiguousDirectory)
{
this->UpdateDirectory(name);
}
if(this->AmbiguousExtension)
{
this->UpdateExtension(name);
}
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
{
if(this->AmbiguousDirectory && !loc.AmbiguousDirectory)
{
this->Directory = loc.Directory;
this->AmbiguousDirectory = false;
}
if(this->AmbiguousExtension && !loc.AmbiguousExtension)
{
this->Name = loc.Name;
this->AmbiguousExtension = false;
}
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseSource()
{
if(this->AmbiguousDirectory)
{
this->Directory =
cmSystemTools::CollapseFullPath(
this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
this->AmbiguousDirectory = false;
}
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseBinary()
{
if(this->AmbiguousDirectory)
{
this->Directory =
cmSystemTools::CollapseFullPath(
this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
this->AmbiguousDirectory = false;
}
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::UpdateExtension(const char* name)
{
// Check the extension.
std::string ext = cmSystemTools::GetFilenameLastExtension(name);
if(!ext.empty()) { ext = ext.substr(1); }
// TODO: Let enable-language specify extensions for each language.
cmMakefile const* mf = this->Makefile;
const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
if(std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end() ||
std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
{
// This is a known extension. Use the given filename with extension.
this->Name = cmSystemTools::GetFilenameName(name);
this->AmbiguousExtension = false;
}
}
//----------------------------------------------------------------------------
void cmSourceFileLocation::UpdateDirectory(const char* name)
{
// If a full path was given we know the directory.
if(cmSystemTools::FileIsFullPath(name))
{
this->Directory = cmSystemTools::GetFilenamePath(name);
this->AmbiguousDirectory = false;
}
}
//----------------------------------------------------------------------------
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
{
if(this->AmbiguousExtension || loc.AmbiguousExtension)
{
// Need to compare without the file extension.
std::string thisName;
if(this->AmbiguousExtension)
{
thisName = this->Name;
}
else
{
thisName = cmSystemTools::GetFilenameWithoutLastExtension(this->Name);
}
std::string locName;
if(loc.AmbiguousExtension)
{
locName = loc.Name;
}
else
{
locName = cmSystemTools::GetFilenameWithoutLastExtension(loc.Name);
}
if(thisName != locName)
{
return false;
}
}
else
{
// Compare with extension.
if(this->Name != loc.Name)
{
return false;
}
}
if(!this->AmbiguousDirectory && !loc.AmbiguousDirectory)
{
// Both sides have absolute directories.
if(this->Directory != loc.Directory)
{
return false;
}
}
else if(this->AmbiguousDirectory && loc.AmbiguousDirectory &&
this->Makefile == loc.Makefile)
{
// Both sides have directories relative to the same location.
if(this->Directory != loc.Directory)
{
return false;
}
}
else if(this->AmbiguousDirectory && loc.AmbiguousDirectory)
{
// Each side has a directory relative to a different location.
// This can occur when referencing a source file from a different
// directory. This is not yet allowed.
abort();
}
else if(this->AmbiguousDirectory)
{
// Compare possible directory combinations.
std::string srcDir =
cmSystemTools::CollapseFullPath(
this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
std::string binDir =
cmSystemTools::CollapseFullPath(
this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
if(srcDir != loc.Directory &&
binDir != loc.Directory)
{
return false;
}
}
else if(loc.AmbiguousDirectory)
{
// Compare possible directory combinations.
std::string srcDir =
cmSystemTools::CollapseFullPath(
loc.Directory.c_str(), loc.Makefile->GetCurrentDirectory());
std::string binDir =
cmSystemTools::CollapseFullPath(
loc.Directory.c_str(), loc.Makefile->GetCurrentOutputDirectory());
if(srcDir != this->Directory &&
binDir != this->Directory)
{
return false;
}
}
// File locations match.
this->Update(loc);
return true;
}

View File

@ -0,0 +1,104 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmSourceFileLocation_h
#define cmSourceFileLocation_h
#include "cmStandardIncludes.h"
class cmMakefile;
/** \class cmSourceFileLocation
* \brief cmSourceFileLocation tracks knowledge about a source file location
*
* Source files can be referenced by a variety of names. The
* directory and/or extension may be omitted leading to a certain
* level of ambiguity about the source file location. This class is
* used by cmSourceFile to keep track of what is known about the
* source file location. Each reference may add some information
* about the directory or extension of the file.
*/
class cmSourceFileLocation
{
public:
/**
* Construct for a source file created in a given cmMakefile
* instance with an initial name.
*/
cmSourceFileLocation(cmMakefile* mf, const char* name);
/**
* Return whether the givne source file location could refers to the
* same source file as this location given the level of ambiguity in
* each location.
*/
bool Matches(cmSourceFileLocation const& loc);
/**
* Explicity state that the source file is located in the source tree.
*/
void DirectoryUseSource();
/**
* Explicity state that the source file is located in the build tree.
*/
void DirectoryUseBinary();
/**
* Return whether the directory containing the source is ambiguous.
*/
bool DirectoryIsAmbiguous() const { return this->AmbiguousDirectory; }
/**
* Return whether the extension of the source name is ambiguous.
*/
bool ExtensionIsAmbiguous() const { return this->AmbiguousExtension; }
/**
* Get the directory containing the file as best is currently known.
* If DirectoryIsAmbiguous() returns false this will be a full path.
* Otherwise it will be a relative path (possibly empty) that is
* either with respect to the source or build tree.
*/
const char* GetDirectory() const { return this->Directory.c_str(); }
/**
* Get the file name as best is currently known. If
* ExtensionIsAmbiguous() returns true this name may not be the
* final name (but could be). Otherwise the returned name is the
* final name.
*/
const char* GetName() const { return this->Name.c_str(); }
/**
* Get the cmMakefile instance for which the source file was created.
*/
cmMakefile* GetMakefile() const { return this->Makefile; }
private:
cmMakefile* Makefile;
bool AmbiguousDirectory;
bool AmbiguousExtension;
std::string Directory;
std::string Name;
// Update the location with additional knowledge.
void Update(cmSourceFileLocation const& loc);
void Update(const char* name);
void UpdateExtension(const char* name);
void UpdateDirectory(const char* name);
};
#endif

View File

@ -281,6 +281,7 @@ void cmTarget::DefineProperties(cmake *cm)
"An internal property used by some generators to record the name of " "An internal property used by some generators to record the name of "
"project or dsp file associated with this target."); "project or dsp file associated with this target.");
#if 0
cm->DefineProperty cm->DefineProperty
("OBJECT_FILES", cmProperty::TARGET, ("OBJECT_FILES", cmProperty::TARGET,
"Used to get the resulting list of object files that make up a " "Used to get the resulting list of object files that make up a "
@ -289,6 +290,7 @@ void cmTarget::DefineProperties(cmake *cm)
"into another library. It is a read only property. It " "into another library. It is a read only property. It "
"converts the source list for the target into a list of full " "converts the source list for the target into a list of full "
"paths to object names that will be produced by the target."); "paths to object names that will be produced by the target.");
#endif
#define CM_TARGET_FILE_TYPES_DOC \ #define CM_TARGET_FILE_TYPES_DOC \
"There are three kinds of target files that may be built: " \ "There are three kinds of target files that may be built: " \
@ -414,16 +416,199 @@ void cmTarget::SetMakefile(cmMakefile* mf)
} }
} }
//----------------------------------------------------------------------------
void cmTarget::CheckForTargetsAsCommand(const cmCustomCommand& cc) class cmTargetTraceDependencies
{ {
public:
cmTargetTraceDependencies(cmTarget* target, const char* vsProjectFile);
void Trace();
private:
cmTarget* Target;
cmMakefile* Makefile;
cmGlobalGenerator* GlobalGenerator;
std::queue<cmStdString> DependencyQueue;
std::set<cmStdString> DependenciesQueued;
std::set<cmSourceFile*> TargetSources;
void QueueOnce(std::string const& name);
void QueueOnce(std::vector<std::string> const& names);
void QueueDependencies(cmSourceFile* sf);
bool IsUtility(std::string const& dep);
void CheckCustomCommand(cmCustomCommand const& cc);
void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
};
//----------------------------------------------------------------------------
cmTargetTraceDependencies
::cmTargetTraceDependencies(cmTarget* target, const char* vsProjectFile):
Target(target)
{
// Convenience.
this->Makefile = this->Target->GetMakefile();
this->GlobalGenerator =
this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
// Queue all the source files already specified for the target.
std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
si != sources.end(); ++si)
{
// Queue the source file itself in case it is generated.
this->QueueOnce((*si)->GetFullPath());
// Queue the dependencies of the source file in case they are
// generated.
this->QueueDependencies(*si);
// Track the sources already known to the target.
this->TargetSources.insert(*si);
}
// Queue the VS project file to check dependencies on the rule to
// generate it.
if(vsProjectFile)
{
this->QueueOnce(vsProjectFile);
}
// Queue pre-build, pre-link, and post-build rule dependencies.
this->CheckCustomCommands(this->Target->GetPreBuildCommands());
this->CheckCustomCommands(this->Target->GetPreLinkCommands());
this->CheckCustomCommands(this->Target->GetPostBuildCommands());
}
//----------------------------------------------------------------------------
void cmTargetTraceDependencies::Trace()
{
// Process one dependency at a time until the queue is empty.
while(!this->DependencyQueue.empty())
{
// Get the next dependency in from queue.
std::string dep = this->DependencyQueue.front();
this->DependencyQueue.pop();
// Check if we know how to generate this dependency.
if(cmSourceFile* sf =
this->Makefile->GetSourceFileWithOutput(dep.c_str()))
{
// Queue dependencies needed to generate this file.
this->QueueDependencies(sf);
// Make sure this file is in the target.
if(this->TargetSources.insert(sf).second)
{
this->Target->AddSourceFile(sf);
}
}
}
}
//----------------------------------------------------------------------------
void cmTargetTraceDependencies::QueueOnce(std::string const& name)
{
if(this->DependenciesQueued.insert(name).second)
{
this->DependencyQueue.push(name);
}
}
//----------------------------------------------------------------------------
void
cmTargetTraceDependencies::QueueOnce(std::vector<std::string> const& names)
{
for(std::vector<std::string>::const_iterator i = names.begin();
i != names.end(); ++i)
{
this->QueueOnce(*i);
}
}
//----------------------------------------------------------------------------
bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
{
// Dependencies on targets (utilities) are supposed to be named by
// just the target name. However for compatibility we support
// naming the output file generated by the target (assuming there is
// no output-name property which old code would not have set). In
// that case the target name will be the file basename of the
// dependency.
std::string util = cmSystemTools::GetFilenameName(dep);
if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
{
util = cmSystemTools::GetFilenameWithoutLastExtension(util);
}
// Check for a non-imported target with this name.
if(cmTarget* t =
this->GlobalGenerator->FindTarget(0, util.c_str(), false))
{
// If we find the target and the dep was given as a full path,
// then make sure it was not a full path to something else, and
// the fact that the name matched a target was just a coincidence.
if(cmSystemTools::FileIsFullPath(dep.c_str()))
{
// This is really only for compatibility so we do not need to
// worry about configuration names and output names.
std::string tLocation = t->GetLocation(0);
tLocation = cmSystemTools::GetFilenamePath(tLocation);
std::string depLocation = cmSystemTools::GetFilenamePath(dep);
depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
if(depLocation == tLocation)
{
this->Target->AddUtility(util.c_str());
return true;
}
}
else
{
// The original name of the dependency was not a full path. It
// must name a target, so add the target-level dependency.
this->Target->AddUtility(util.c_str());
return true;
}
}
// The dependency does not name a target built in this project.
return false;
}
//----------------------------------------------------------------------------
void cmTargetTraceDependencies::QueueDependencies(cmSourceFile* sf)
{
// Queue dependency added explicitly by the user.
if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
{
std::vector<std::string> objDeps;
cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
this->QueueOnce(objDeps);
}
// Queue dependencies added programatically by commands.
this->QueueOnce(sf->GetDepends());
// Queue custom command dependencies.
if(cmCustomCommand const* cc = sf->GetCustomCommand())
{
this->CheckCustomCommand(*cc);
}
}
//----------------------------------------------------------------------------
void
cmTargetTraceDependencies
::CheckCustomCommand(cmCustomCommand const& cc)
{
// Transform command names that reference targets built in this
// project to corresponding target-level dependencies.
for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin(); for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
cit != cc.GetCommandLines().end(); ++cit ) cit != cc.GetCommandLines().end(); ++cit)
{ {
std::string const& command = *cit->begin(); std::string const& command = *cit->begin();
// Look for a non-imported target with this name. // Look for a non-imported target with this name.
if(cmTarget* t = this->Makefile->GetLocalGenerator()-> if(cmTarget* t =
GetGlobalGenerator()->FindTarget(0, command.c_str(), false)) this->GlobalGenerator->FindTarget(0, command.c_str(), false))
{ {
if(t->GetType() == cmTarget::EXECUTABLE) if(t->GetType() == cmTarget::EXECUTABLE)
{ {
@ -431,269 +616,67 @@ void cmTarget::CheckForTargetsAsCommand(const cmCustomCommand& cc)
// this project. Add the target-level dependency to make // this project. Add the target-level dependency to make
// sure the executable is up to date before this custom // sure the executable is up to date before this custom
// command possibly runs. // command possibly runs.
this->AddUtility(command.c_str()); this->Target->AddUtility(command.c_str());
} }
} }
} }
// Queue the custom command dependencies.
std::vector<std::string> const& depends = cc.GetDepends();
for(std::vector<std::string>::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
std::string const& dep = *di;
if(!this->IsUtility(dep))
{
// The dependency does not name a target and may be a file we
// know how to generate. Queue it.
this->QueueOnce(dep);
}
}
} }
//----------------------------------------------------------------------------
void void
cmTarget cmTargetTraceDependencies
::CheckForTargetsAsCommand(const std::vector<cmCustomCommand>& commands) ::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
{ {
for ( std::vector<cmCustomCommand>::const_iterator cli = commands.begin(); for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
cli != commands.end(); cli != commands.end(); ++cli)
++cli )
{ {
this->CheckForTargetsAsCommand(*cli); this->CheckCustomCommand(*cli);
} }
} }
//----------------------------------------------------------------------------
void cmTarget::TraceDependencies(const char* vsProjectFile)
{
// Use a helper object to trace the dependencies.
cmTargetTraceDependencies tracer(this, vsProjectFile);
tracer.Trace();
}
void cmTarget::TraceVSDependencies(std::string projFile, //----------------------------------------------------------------------------
cmMakefile *makefile) void cmTarget::AddSources(std::vector<std::string> const& srcs)
{ {
// get the classes from the source lists then add them to the groups for(std::vector<std::string>::const_iterator i = srcs.begin();
std::vector<cmSourceFile*> & classes = this->SourceFiles; i != srcs.end(); ++i)
// use a deck to keep track of processed source files
std::queue<std::string> srcFilesToProcess;
std::set<cmStdString> srcFilesQueued;
std::string name;
std::vector<cmSourceFile*> newClasses;
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); ++i)
{ {
name = (*i)->GetSourceName(); this->AddSource(i->c_str());
if ((*i)->GetSourceExtension() != "rule")
{
name += ".";
name += (*i)->GetSourceExtension();
}
srcFilesToProcess.push(name);
srcFilesQueued.insert(name);
// does this sourcefile have object depends on it?
// If so then add them as well
const char* additionalDeps = (*i)->GetProperty("OBJECT_DEPENDS");
std::vector<std::string> depends = (*i)->GetDepends();
if (additionalDeps || depends.size())
{
if(additionalDeps)
{
cmSystemTools::ExpandListArgument(additionalDeps, depends);
}
for(std::vector<std::string>::iterator id = depends.begin();
id != depends.end(); ++id)
{
// if there is a custom rule to generate that dependency
// then add it to the list
cmSourceFile* outsf =
makefile->GetSourceFileWithOutput(id->c_str());
// if a source file was found then add it
if (outsf &&
(std::find(classes.begin(),classes.end(),outsf) == classes.end())
&&
(std::find(newClasses.begin(),newClasses.end(),outsf)
== newClasses.end()))
{
// then add the source to this target and add it to the queue
newClasses.push_back(outsf);
name = outsf->GetSourceName();
if (outsf->GetSourceExtension() != "rule")
{
name += ".";
name += outsf->GetSourceExtension();
}
std::string temp =
cmSystemTools::GetFilenamePath(outsf->GetFullPath());
temp += "/";
temp += name;
// if it hasn't been processed
if (srcFilesQueued.find(temp) == srcFilesQueued.end())
{
srcFilesToProcess.push(temp);
srcFilesQueued.insert(temp);
}
}
}
}
}
for(std::vector<cmSourceFile*>::const_iterator i = newClasses.begin();
i != newClasses.end(); ++i)
{
classes.push_back(*i);
}
// add in the project file itself
if (projFile.size())
{
srcFilesToProcess.push(projFile);
srcFilesQueued.insert(projFile);
}
// add in the library depends for custom targets
if (this->GetType() == cmTarget::UTILITY ||
this->GetType() == cmTarget::GLOBAL_TARGET)
{
for (std::vector<cmCustomCommand>::iterator ic =
this->GetPostBuildCommands().begin();
ic != this->GetPostBuildCommands().end(); ++ic)
{
cmCustomCommand &c = *ic;
for (std::vector<std::string>::const_iterator i
= c.GetDepends().begin(); i != c.GetDepends().end(); ++i)
{
srcFilesToProcess.push(*i);
srcFilesQueued.insert(*i);
}
}
}
this->CheckForTargetsAsCommand(this->GetPreBuildCommands());
this->CheckForTargetsAsCommand(this->GetPreLinkCommands());
this->CheckForTargetsAsCommand(this->GetPostBuildCommands());
while (!srcFilesToProcess.empty())
{
// is this source the output of a custom command
cmSourceFile* outsf =
makefile->GetSourceFileWithOutput(srcFilesToProcess.front().c_str());
if (outsf)
{
// is it not already in the target?
if (std::find(classes.begin(),classes.end(),outsf) == classes.end())
{
// then add the source to this target and add it to the queue
classes.push_back(outsf);
name = outsf->GetSourceName();
if (outsf->GetSourceExtension() != "rule")
{
name += ".";
name += outsf->GetSourceExtension();
}
std::string temp =
cmSystemTools::GetFilenamePath(outsf->GetFullPath());
temp += "/";
temp += name;
// if it hasn't been processed
if (srcFilesQueued.find(temp) == srcFilesQueued.end())
{
srcFilesToProcess.push(temp);
srcFilesQueued.insert(temp);
}
}
// Add target-level dependencies for the commands.
this->CheckForTargetsAsCommand(*outsf->GetCustomCommand());
// add its dependencies to the list to check
for (unsigned int i = 0;
i < outsf->GetCustomCommand()->GetDepends().size();
++i)
{
const std::string& fullName
= outsf->GetCustomCommand()->GetDepends()[i];
std::string dep = cmSystemTools::GetFilenameName(fullName);
if (cmSystemTools::GetFilenameLastExtension(dep) == ".exe")
{
dep = cmSystemTools::GetFilenameWithoutLastExtension(dep);
}
bool isUtility = false;
// Check for a non-imported target with this name.
if(cmTarget* t = this->Makefile->GetLocalGenerator()->
GetGlobalGenerator()->FindTarget(0, dep.c_str(), false))
{
// if we find the target and the dep was given as a full
// path, then make sure it was not a full path to something
// else, and the fact that the name matched a target was
// just a coincident
if(cmSystemTools::FileIsFullPath(fullName.c_str()))
{
std::string tLocation = t->GetLocation(0);
tLocation = cmSystemTools::GetFilenamePath(tLocation);
std::string depLocation = cmSystemTools::GetFilenamePath(
std::string(fullName));
depLocation =
cmSystemTools::CollapseFullPath(depLocation.c_str());
tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
if(depLocation == tLocation)
{
isUtility = true;
}
}
// if it was not a full path then it must be a target
else
{
isUtility = true;
}
}
if(isUtility)
{
// The dependency refers to a target built in this project.
// Add the target-level dependency to make sure the target
// is up to date before this custom command possibly runs.
this->AddUtility(dep.c_str());
}
else
{
if (srcFilesQueued.find(outsf->GetCustomCommand()->GetDepends()[i])
== srcFilesQueued.end())
{
srcFilesToProcess.push
(outsf->GetCustomCommand()->GetDepends()[i]);
srcFilesQueued.insert(outsf->GetCustomCommand()->GetDepends()[i]);
}
}
}
}
// finished with this SF move to the next
srcFilesToProcess.pop();
} }
} }
void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf) cmSourceFile* cmTarget::AddSource(const char* s)
{ {
// only allow this to be called once std::string src = s;
// there is a lazy evaluation of this in ComputeObjectFiles,
// that could break backwards compatibility with projects that
// use old style source lists.
if(this->SourceFiles.size() != 0)
{
return;
}
// for each src lists add the classes
for (std::vector<std::string>::const_iterator s = this->SourceLists.begin();
s != this->SourceLists.end(); ++s)
{
int done = 0;
// replace any variables
std::string temps = *s;
mf.ExpandVariablesInString(temps);
// Next if one wasn't found then assume it is a single class // For backwards compatibility replace varibles in source names.
// check to see if it is an existing source file // This should eventually be removed.
if (!done) this->Makefile->ExpandVariablesInString(src);
{
cmSourceFile* sourceFile = mf.GetSource(temps.c_str()); cmSourceFile* sf = this->Makefile->GetOrCreateSource(src.c_str());
if ( sourceFile ) this->AddSourceFile(sf);
{ return sf;
this->SourceFiles.push_back(sourceFile);
done = 1;
}
}
// if we still are not done, try to create the SourceFile structure
if (!done)
{
cmSourceFile file;
file.GetProperties().
SetCMakeInstance(this->Makefile->GetCMakeInstance());
file.SetProperty("ABSTRACT","0");
file.SetName(temps.c_str(), mf.GetCurrentDirectory(),
mf.GetSourceExtensions(),
mf.GetHeaderExtensions(), this->Name.c_str());
this->SourceFiles.push_back(mf.AddSource(file));
}
}
} }
void cmTarget::MergeLinkLibraries( cmMakefile& mf, void cmTarget::MergeLinkLibraries( cmMakefile& mf,
@ -1328,9 +1311,7 @@ void cmTarget::ComputeObjectFiles()
{ {
return; return;
} }
#if 0
// Force the SourceFiles vector to be populated
this->GenerateSourceFilesFromSourceLists(*this->Makefile);
std::vector<std::string> dirs; std::vector<std::string> dirs;
this->Makefile->GetLocalGenerator()-> this->Makefile->GetLocalGenerator()->
GetTargetObjectFileDirectories(this, GetTargetObjectFileDirectories(this,
@ -1346,10 +1327,7 @@ void cmTarget::ComputeObjectFiles()
s != this->SourceFiles.end(); ++s) s != this->SourceFiles.end(); ++s)
{ {
cmSourceFile* sf = *s; cmSourceFile* sf = *s;
const char* lang = this->Makefile->GetLocalGenerator()-> if(const char* lang = sf->GetLanguage())
GetGlobalGenerator()->
GetLanguageFromExtension(sf->GetSourceExtension().c_str());
if (lang)
{ {
std::string lookupObj = objExtensionLookup1 + lang; std::string lookupObj = objExtensionLookup1 + lang;
lookupObj += objExtensionLookup2; lookupObj += objExtensionLookup2;
@ -1371,6 +1349,7 @@ void cmTarget::ComputeObjectFiles()
} }
} }
this->SetProperty("OBJECT_FILES", objectFiles.c_str()); this->SetProperty("OBJECT_FILES", objectFiles.c_str());
#endif
} }
@ -1487,9 +1466,7 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg)
= this->SourceFiles.begin(); = this->SourceFiles.begin();
i != this->SourceFiles.end(); ++i) i != this->SourceFiles.end(); ++i)
{ {
const char* lang = if(const char* lang = (*i)->GetLanguage())
gg->GetLanguageFromExtension((*i)->GetSourceExtension().c_str());
if(lang)
{ {
languages.insert(lang); languages.insert(lang);
} }

View File

@ -73,16 +73,6 @@ public:
std::vector<cmCustomCommand> &GetPostBuildCommands() std::vector<cmCustomCommand> &GetPostBuildCommands()
{return this->PostBuildCommands;} {return this->PostBuildCommands;}
/**
* Get the list of the source lists used by this target
*/
std::vector<std::string> const& GetSourceLists() {return this->SourceLists;}
void AddSourceListEntry(const char* src)
{ this->SourceLists.push_back(src); }
void SetSourceList(std::vector<std::string> const& srcs)
{ this->SourceLists = srcs; }
///! Return the list of frameworks being linked to this target ///! Return the list of frameworks being linked to this target
std::vector<std::string> &GetFrameworks() {return this->Frameworks;} std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
@ -93,6 +83,12 @@ public:
{return this->SourceFiles;} {return this->SourceFiles;}
void AddSourceFile(cmSourceFile* sf) { this->SourceFiles.push_back(sf); } void AddSourceFile(cmSourceFile* sf) { this->SourceFiles.push_back(sf); }
/**
* Add sources to the target.
*/
void AddSources(std::vector<std::string> const& srcs);
cmSourceFile* AddSource(const char* src);
/** /**
* Get the list of the source files used by this target * Get the list of the source files used by this target
*/ */
@ -149,12 +145,6 @@ 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; }
/**
* Generate the SourceFilesList from the SourceLists. This should only be
* done once to be safe.
*/
void GenerateSourceFilesFromSourceLists(cmMakefile &mf);
/** 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.
@ -193,7 +183,7 @@ public:
* Trace through the source files in this target and add al source files * Trace through the source files in this target and add al source files
* that they depend on, used by all generators * that they depend on, used by all generators
*/ */
void TraceVSDependencies(std::string projName, cmMakefile *mf); void TraceDependencies(const char* vsProjectFile);
///! Return the prefered linker language for this target ///! Return the prefered linker language for this target
const char* GetLinkerLanguage(cmGlobalGenerator*); const char* GetLinkerLanguage(cmGlobalGenerator*);
@ -302,14 +292,6 @@ private:
const LibraryID& lib, const LibraryID& lib,
const LibraryID& dep); const LibraryID& dep);
/*
* Check custom commands for known targets and add a target-level
* dependency.
*/
void CheckForTargetsAsCommand(const cmCustomCommand& cc);
void CheckForTargetsAsCommand(const std::vector<cmCustomCommand>& commands);
/** /**
* Emits the library \a lib and all its dependencies into link_line. * Emits the library \a lib and all its dependencies into link_line.
* \a emitted keeps track of the libraries that have been emitted to * \a emitted keeps track of the libraries that have been emitted to
@ -379,7 +361,6 @@ private:
std::vector<cmCustomCommand> PreBuildCommands; std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands; std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands; std::vector<cmCustomCommand> PostBuildCommands;
std::vector<std::string> SourceLists;
TargetType TargetTypeValue; TargetType TargetTypeValue;
std::vector<cmSourceFile*> SourceFiles; std::vector<cmSourceFile*> SourceFiles;
LinkLibraryVectorType LinkLibraries; LinkLibraryVectorType LinkLibraries;

View File

@ -137,6 +137,7 @@ CMAKE_CXX_SOURCES="\
cmInstallScriptGenerator \ cmInstallScriptGenerator \
cmInstallTargetGenerator \ cmInstallTargetGenerator \
cmSourceFile \ cmSourceFile \
cmSourceFileLocation \
cmSystemTools \ cmSystemTools \
cmVersion \ cmVersion \
cmFileTimeComparison \ cmFileTimeComparison \