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
cmSourceFile.cxx
cmSourceFile.h
cmSourceFileLocation.cxx
cmSourceFileLocation.h
cmSourceGroup.cxx
cmSourceGroup.h
cmSystemTools.cxx

View File

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

View File

@ -488,104 +488,341 @@ int CCONV cmGetTotalArgumentSize(int argc, char **argv)
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)
{
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)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmSourceFile *sf = static_cast<cmSourceFile *>(arg2);
return (void *)mf->AddSource(*sf);
}
cmCPluginAPISourceFile* osf = static_cast<cmCPluginAPISourceFile*>(arg2);
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()
{
return (void *)(new cmSourceFile);
}
// Create the proxy for the real source file.
cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
sf->RealSourceFile = rsf;
sf->FullPath = osf->FullPath;
sf->SourceName = osf->SourceName;
sf->SourceExtension = osf->SourceExtension;
void * CCONV cmCreateNewSourceFile(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmSourceFile *sf = new cmSourceFile;
sf->SetMakefile(mf);
// Store the proxy in the map so it can be re-used and deleted later.
cmCPluginAPISourceFiles[rsf] = sf;
return (void *)sf;
}
void CCONV cmDestroySourceFile(void *arg)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
delete sf;
}
const char * CCONV cmSourceFileGetSourceName(void *arg)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
return sf->GetSourceName().c_str();
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return sf->SourceName.c_str();
}
const char * CCONV cmSourceFileGetFullPath(void *arg)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
return sf->GetFullPath().c_str();
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
return sf->FullPath.c_str();
}
const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
return sf->GetProperty(prop);
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
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)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
return (sf->GetPropertyAsBool(prop) ? 1: 0);
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
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,
const char *val)
const char *value)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
sf->SetProperty(prop,val);
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
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)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
sf->AddDepend(depend);
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
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,
int numSourceExtensions,
const char **sourceExtensions,
int numHeaderExtensions,
const char **headerExtensions)
int numSourceExtensions,
const char **sourceExtensions,
int numHeaderExtensions,
const char **headerExtensions)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
std::vector<std::string> srcs;
std::vector<std::string> hdrs;
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if(sf->RealSourceFile)
{
// 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;
for (i = 0; i < numSourceExtensions; ++i)
{
srcs.push_back(sourceExtensions[i]);
sourceExts.push_back(sourceExtensions[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,
const char *ext, int headerFileOnly)
const char *ext, int headerFileOnly)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
sf->SetName(name,dir,ext,(headerFileOnly ? true : false));
}
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
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)
{

View File

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

View File

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

View File

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

View File

@ -19,6 +19,7 @@
#include "cmExternalMakefileProjectGenerator.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmVersion.h"
#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)
{
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)
else
{
// 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
// 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);
///! What is the preference for linkers and this language (None or Prefered)
const char* GetLinkerPreference(const char* lang);
///! What is the output extension for a given language.
const char* GetLanguageOutputExtensionForLanguage(const char* lang);
///! What is the output extension for a given source file extension.
const char* GetLanguageOutputExtensionFromExtension(const char* lang);
///! What is the object file extension for a given source file?
const char* GetLanguageOutputExtension(cmSourceFile const&);
///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGInitDirectory() { return "."; }

View File

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

View File

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

View File

@ -225,8 +225,6 @@ public:
GetTargetObjectFileDirectories(cmTarget* target,
std::vector<std::string>&
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

View File

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

View File

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

View File

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

View File

@ -24,16 +24,3 @@ GetTargetObjectFileDirectories(cmTarget* target,
g->GetTargetObjectFileDirectories(target,
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,
std::vector<std::string>&
dirs);
// return the source name for the object file
virtual std::string GetSourceObjectName(cmSourceFile& );
private:
};

View File

@ -18,6 +18,7 @@
#include "cmVersion.h"
#include "cmCommand.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmSystemTools.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@ -557,7 +558,6 @@ void cmMakefile::ConfigureFinalPass()
for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); l++)
{
l->second.GenerateSourceFilesFromSourceLists(*this);
l->second.AnalyzeLibDependencies(*this);
}
}
@ -772,7 +772,7 @@ cmMakefile::AddCustomCommandOldStyle(const char* target,
{
if (this->Targets.find(target) != this->Targets.end())
{
this->Targets[target].AddSourceListEntry(source);
this->Targets[target].AddSource(source);
}
else
{
@ -854,10 +854,10 @@ void cmMakefile::AddUtilityCommand(const char* utilityName,
commandLines, comment,
workingDirectory, no_replace,
escapeOldStyle);
target->AddSourceListEntry(force.c_str());
cmSourceFile* sf = target->AddSource(force.c_str());
// The output is not actually created so mark it symbolic.
if(cmSourceFile* sf = this->GetSource(force.c_str()))
if(sf)
{
sf->SetProperty("SYMBOLIC", "1");
}
@ -1364,7 +1364,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
{
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->SetSourceList(srcs);
target->AddSources(srcs);
this->AddGlobalLinkInformation(lname, *target);
}
@ -1377,7 +1377,7 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
{
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->SetSourceList(srcs);
target->AddSources(srcs);
this->AddGlobalLinkInformation(exeName, *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
// by default it is in the current source dir
std::string path;
if (cmSystemTools::FileIsFullPath(sourceName))
cmSourceFileLocation sfl(this, sourceName);
for(std::vector<cmSourceFile*>::const_iterator
sfi = this->SourceFiles.begin();
sfi != this->SourceFiles.end(); ++sfi)
{
path = cmSystemTools::GetFilenamePath(sourceName);
}
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())
cmSourceFile* sf = *sfi;
if(sf->Matches(sfl))
{
path += "/";
path += cmSystemTools::GetFilenamePath(sourceName);
return sf;
}
}
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;
}
//----------------------------------------------------------------------------
cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
bool generated)
{
// make it a full path first
std::string src = sourceName;
bool relative = !cmSystemTools::FileIsFullPath(sourceName);
std::string srcTreeFile = this->GetCurrentDirectory();
srcTreeFile += "/";
srcTreeFile += sourceName;
if(relative)
if(cmSourceFile* esf = this->GetSource(sourceName))
{
src = srcTreeFile;
}
// 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);
return esf;
}
else
{
std::string relPath = cmSystemTools::GetFilenamePath(sourceName);
if (relative && relPath.size())
cmSourceFile* sf = new cmSourceFile(this, sourceName);
if(generated)
{
// we need to keep the relative part of the filename
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());
sf->SetProperty("GENERATED", "1");
}
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)
{
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
* not found, then a null pointer is returned.
*/
cmSourceFile* GetSource(const char* sourceName) const;
///! Add a new cmSourceFile to the list of sources for this makefile.
cmSourceFile* AddSource(cmSourceFile const&);
cmSourceFile* GetSource(const char* sourceName);
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then create the source file and return it. generated
* indicates if it is a generated file, this is used in determining
* how to create the source file instance e.g. name
*/
cmSourceFile* GetOrCreateSource(const char* sourceName,
cmSourceFile* GetOrCreateSource(const char* sourceName,
bool generated = false);
/**
* 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();
i != sources.end(); ++i)
{
if((*i)->GetSourceExtension() == "def")
cmSourceFile* sf = *i;
if(sf->GetExtension() == "def")
{
extraFlags += " ";
extraFlags +=
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
extraFlags +=
this->Convert((*i)->GetFullPath().c_str(),
this->Convert(sf->GetFullPath().c_str(),
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL);
}
@ -290,13 +291,7 @@ void cmMakefileLibraryTargetGenerator::CopyFrameworkPublicHeaders(
cmCustomCommandLine line;
cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str());
std::string dest = outpath + "Headers/";
dest += sf->GetSourceName();
std::string ext = sf->GetSourceExtension();
if(ext.size())
{
dest += ".";
dest += sf->GetSourceExtension();
}
dest += cmSystemTools::GetFilenameName(sf->GetFullPath());
line.push_back("$(CMAKE_COMMAND)");
line.push_back("-E");
line.push_back("copy_if_different");
@ -347,13 +342,7 @@ void cmMakefileLibraryTargetGenerator::CopyFrameworkResources(
continue;
}
std::string dest = outpath + "Resources/";
dest += sf->GetSourceName();
std::string ext = sf->GetSourceExtension();
if(ext.size())
{
dest += ".";
dest += sf->GetSourceExtension();
}
dest += cmSystemTools::GetFilenameName(sf->GetFullPath());
line.push_back("$(CMAKE_COMMAND)");
line.push_back("-E");
line.push_back("copy_if_different");

View File

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

View File

@ -223,13 +223,6 @@ ListDependencies(cmDependInformation const *info,
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
cmLBDepend md;
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");
return false;
}
// This command supports source list inputs for compatibility.
std::vector<std::string> args;
this->Makefile->ExpandSourceListArguments(argsIn, args, 2);
// what is the current source dir
std::string cdir = this->Makefile->GetCurrentDirectory();
// Get the moc executable to run in the custom command.
const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// keep the library name
this->LibraryName = args[0];
this->SourceList = args[1];
std::string sourceListValue;
// Get the variable holding the list of sources.
std::string const& sourceList = args[1];
std::string sourceListValue =
this->Makefile->GetSafeDefinition(sourceList.c_str());
// was the list already populated
const char *def = this->Makefile->GetDefinition(this->SourceList.c_str());
if (def)
{
sourceListValue = def;
}
// get the list of classes for this library
// Create a rule for all sources listed.
for(std::vector<std::string>::iterator j = (args.begin() + 2);
j != args.end(); ++j)
{
{
cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
// 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)
{
file.SetProperty("ABSTRACT",curr->GetProperty("ABSTRACT"));
sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
}
std::string srcName =
cmSystemTools::GetFilenameWithoutLastExtension(*j);
std::string newName = "moc_" + srcName;
file.SetName(newName.c_str(),
this->Makefile->GetCurrentOutputDirectory(),
"cxx",false);
// Compute the name of the header from which to generate the file.
std::string hname;
if ( (*j)[0] == '/' || (*j)[1] == ':' )
if(cmSystemTools::FileIsFullPath(j->c_str()))
{
hname = *j;
}
else
{
if ( curr && curr->GetPropertyAsBool("GENERATED") )
if(curr && curr->GetPropertyAsBool("GENERATED"))
{
hname = std::string(this->Makefile->GetCurrentOutputDirectory())
+ "/" + *j;
hname = this->Makefile->GetCurrentOutputDirectory();
}
else
{
hname = cdir + "/" + *j;
hname = this->Makefile->GetCurrentDirectory();
}
hname += "/";
hname += *j;
}
this->WrapHeaders.push_back(hname);
// add starting depends
file.AddDepend(hname.c_str());
this->WrapClasses.push_back(file);
if (sourceListValue.size() > 0)
// Append the generated source file to the list.
if(!sourceListValue.empty())
{
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());
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.
*/
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.
@ -79,18 +71,6 @@ public:
"The moc files will be added to the library using the DestName "
"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");
return false;
}
// This command supports source list inputs for compatibility.
std::vector<std::string> args;
this->Makefile->ExpandSourceListArguments(argsIn, args, 3);
// what is the current source dir
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;
// Get the uic and moc executables to run in the custom commands.
const char* uic_exe =
this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE");
const char* moc_exe =
this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
// wrap all the .h files
depends.push_back(uic_exe);
// Get the variable holding the list of sources.
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
std::string hres = this->Makefile->GetCurrentOutputDirectory();
hres += "/";
hres += this->WrapHeadersClasses[classNum].GetSourceName() + "." +
this->WrapHeadersClasses[classNum].GetSourceExtension();
cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
// if we should wrap the class
if(!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE")))
{
// 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();
cxxres += "/";
cxxres += this->WrapSourcesClasses[classNum].GetSourceName() + "." +
this->WrapSourcesClasses[classNum].GetSourceExtension();
// Compute the name of the ui file from which to generate others.
std::string uiName;
if(cmSystemTools::FileIsFullPath(j->c_str()))
{
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();
mocres += "/";
mocres += this->WrapMocClasses[classNum].GetSourceName() + "." +
this->WrapMocClasses[classNum].GetSourceExtension();
// create the list of headers
if(!headerListValue.empty())
{
headerListValue += ";";
}
headerListValue += hName;
cmCustomCommandLine hCommand;
hCommand.push_back(uic_exe);
hCommand.push_back("-o");
hCommand.push_back(hres);
hCommand.push_back(this->WrapUserInterface[classNum]);
cmCustomCommandLines hCommandLines;
hCommandLines.push_back(hCommand);
// create the list of sources
if(!sourceListValue.empty())
{
sourceListValue += ";";
}
sourceListValue += cxxName;
sourceListValue += ";";
sourceListValue += mocName;
cmCustomCommandLine cxxCommand;
cxxCommand.push_back(uic_exe);
cxxCommand.push_back("-impl");
cxxCommand.push_back(hres);
cxxCommand.push_back("-o");
cxxCommand.push_back(cxxres);
cxxCommand.push_back(this->WrapUserInterface[classNum]);
cmCustomCommandLines cxxCommandLines;
cxxCommandLines.push_back(cxxCommand);
// set up .ui to .h and .cxx command
cmCustomCommandLine hCommand;
hCommand.push_back(uic_exe);
hCommand.push_back("-o");
hCommand.push_back(hName);
hCommand.push_back(uiName);
cmCustomCommandLines hCommandLines;
hCommandLines.push_back(hCommand);
cmCustomCommandLine mocCommand;
mocCommand.push_back(moc_exe);
mocCommand.push_back("-o");
mocCommand.push_back(mocres);
mocCommand.push_back(hres);
cmCustomCommandLines mocCommandLines;
mocCommandLines.push_back(mocCommand);
cmCustomCommandLine cxxCommand;
cxxCommand.push_back(uic_exe);
cxxCommand.push_back("-impl");
cxxCommand.push_back(hName);
cxxCommand.push_back("-o");
cxxCommand.push_back(cxxName);
cxxCommand.push_back(uiName);
cmCustomCommandLines cxxCommandLines;
cxxCommandLines.push_back(cxxCommand);
depends.clear();
depends.push_back(this->WrapUserInterface[classNum]);
const char* no_main_dependency = 0;
const char* no_comment = 0;
const char* no_working_dir = 0;
this->Makefile->AddCustomCommandToOutput(hres.c_str(),
depends,
no_main_dependency,
hCommandLines,
no_comment,
no_working_dir);
cmCustomCommandLine mocCommand;
mocCommand.push_back(moc_exe);
mocCommand.push_back("-o");
mocCommand.push_back(mocName);
mocCommand.push_back(hName);
cmCustomCommandLines mocCommandLines;
mocCommandLines.push_back(mocCommand);
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,
no_main_dependency,
cxxCommandLines,
no_comment,
no_working_dir);
depends.push_back(hName);
this->Makefile->AddCustomCommandToOutput(cxxName.c_str(),
depends,
no_main_dependency,
cxxCommandLines,
no_comment,
no_working_dir);
depends.clear();
depends.push_back(hres);
this->Makefile->AddCustomCommandToOutput(mocres.c_str(),
depends,
no_main_dependency,
mocCommandLines,
no_comment,
no_working_dir);
depends.clear();
depends.push_back(hName);
this->Makefile->AddCustomCommandToOutput(mocName.c_str(),
depends,
no_main_dependency,
mocCommandLines,
no_comment,
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.
*/
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.
@ -80,21 +72,6 @@ public:
"The .cxx files will be added to the library using the SourcesDestName"
"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 "cmSystemTools.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.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,
// name.c or it will be considered a header file only class
// 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)
//----------------------------------------------------------------------------
cmSourceFile::cmSourceFile(cmMakefile* mf, const char* name):
Location(mf, name)
{
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.
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()))
//----------------------------------------------------------------------------
const char* cmSourceFile::GetLanguage()
{
// Compute the final location of the file if necessary.
if(this->FullPath.empty())
{
this->SourceName = cmSystemTools::GetFilenamePath(name);
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);
}
}
}
this->GetFullPath();
}
// See if the file is a header file
if(std::find( headerExts.begin(), headerExts.end(),
this->SourceExtension ) == headerExts.end())
{
this->SetProperty("HEADER_FILE_ONLY","0");
}
this->FullPath = hname;
// Now try to determine the language.
return static_cast<cmSourceFile const*>(this)->GetLanguage();
}
// Mark this as an external object file if it has the proper
// extension. THIS CODE IS DUPLICATED IN THE OTHER SetName METHOD.
// THESE METHODS SHOULD BE MERGED.
if ( this->SourceExtension == "obj" || this->SourceExtension == "o" ||
this->SourceExtension == "lo" )
//----------------------------------------------------------------------------
const char* cmSourceFile::GetLanguage() const
{
// If the language was set explicitly by the user then use it.
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;
}
// Next, try the various source extensions
for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
ext != sourceExts.end(); ++ext )
// The file is not generated. It must exist on disk.
cmMakefile* mf = this->Location.GetMakefile();
const char* tryDirs[3] = {0, 0, 0};
if(this->Location.DirectoryIsAmbiguous())
{
hname = pathname;
hname += ".";
hname += *ext;
if(cmSystemTools::FileExists(hname.c_str()))
tryDirs[0] = mf->GetCurrentDirectory();
tryDirs[1] = mf->GetCurrentOutputDirectory();
}
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;
}
}
// 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()))
for(std::vector<std::string>::const_iterator ei = srcExts.begin();
ei != srcExts.end(); ++ei)
{
this->SourceExtension = *ext;
this->FullPath = hname;
return true;
if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
{
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;
e << "Cannot find source file \"" << pathname << "\"";
if(target)
{
e << " for target \"" << target << "\"";
}
e << "Cannot find source file \"" << this->Location.GetName() << "\"";
e << "\n\nTried extensions";
for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
ext != sourceExts.end(); ++ext )
for(std::vector<std::string>::const_iterator ext = srcExts.begin();
ext != srcExts.end(); ++ext)
{
e << " ." << *ext;
}
for( std::vector<std::string>::const_iterator ext = headerExts.begin();
ext != headerExts.end(); ++ext )
for(std::vector<std::string>::const_iterator ext = hdrExts.begin();
ext != hdrExts.end(); ++ext)
{
e << " ." << *ext;
}
cmSystemTools::Error(e.str().c_str());
this->FindFullPathFailed = true;
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"));
this->SourceNameWithoutLastExtension = "";
this->SourceName = name;
std::string fname = this->SourceName;
if(ext && strlen(ext))
std::string tryPath = tp;
if(ext && *ext)
{
fname += ".";
fname += ext;
tryPath += ".";
tryPath += ext;
}
this->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir);
cmSystemTools::ConvertToUnixSlashes(this->FullPath);
this->SourceExtension = ext;
if(cmSystemTools::FileExists(tryPath.c_str()))
{
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.
// THESE METHODS SHOULD BE MERGED.
if ( this->SourceExtension == "obj" || this->SourceExtension == "o" ||
this->SourceExtension == "lo" )
//----------------------------------------------------------------------------
void cmSourceFile::CheckExtension()
{
// Compute the extension.
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");
}
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";
std::cerr << "this->SourceName: " << this->SourceName << std::endl;
std::cerr << "this->SourceExtension: " << this->SourceExtension << "\n";
return this->Location.Matches(loc);
}
//----------------------------------------------------------------------------
void cmSourceFile::SetProperty(const char* prop, const char* value)
{
if (!prop)
@ -184,13 +258,20 @@ void cmSourceFile::SetProperty(const char* prop, const char* value)
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
// properties or variables, always recompute them
if (!strcmp(prop,"LOCATION"))
// Check for computed properties.
if(strcmp(prop, "LOCATION") == 0)
{
return this->FullPath.c_str();
if(this->FullPath.empty())
{
return 0;
}
else
{
return this->FullPath.c_str();
}
}
bool chain = false;
@ -198,53 +279,40 @@ const char *cmSourceFile::GetProperty(const char* prop) const
this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, 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;
}
//----------------------------------------------------------------------------
bool cmSourceFile::GetPropertyAsBool(const char* prop) const
{
return cmSystemTools::IsOn(this->GetProperty(prop));
}
void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
//----------------------------------------------------------------------------
cmCustomCommand* cmSourceFile::GetCustomCommand()
{
if(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;
return this->CustomCommand;
}
//----------------------------------------------------------------------------
void cmSourceFile::SetMakefile(cmMakefile* mf)
cmCustomCommand const* cmSourceFile::GetCustomCommand() const
{
// Set our makefile.
this->Makefile = mf;
// set the cmake instance of the properties
this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
return this->CustomCommand;
}
// define properties
//----------------------------------------------------------------------------
void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
{
cmCustomCommand* old = this->CustomCommand;
this->CustomCommand = cc;
delete old;
}
//----------------------------------------------------------------------------
void cmSourceFile::DefineProperties(cmake *cm)
{
// define properties

View File

@ -17,11 +17,11 @@
#ifndef cmSourceFile_h
#define cmSourceFile_h
#include "cmSourceFileLocation.h"
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
class cmake;
class cmMakefile;
/** \class cmSourceFile
* \brief Represent a class loaded from a makefile.
@ -33,67 +33,41 @@ class cmSourceFile
{
public:
/**
* Construct instance as a concrete class with both a
* .h and .cxx file.
* Construct with the makefile storing the source and the initial
* name referencing it.
*/
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);
cmSourceFile(cmMakefile* mf, const char* name);
~cmSourceFile();
/**
* Get the list of the custom commands for this source file
*/
const cmCustomCommand *GetCustomCommand() const
{return this->CustomCommand;}
cmCustomCommand *GetCustomCommand() {return this->CustomCommand;}
cmCustomCommand* GetCustomCommand();
cmCustomCommand const* GetCustomCommand() const;
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
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop) const;
bool GetPropertyAsBool(const char *prop) const;
/**
* 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.
* (In most cases this is the name of the class.)
* Get the file extension of this source file.
*/
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 {
return this->SourceExtension;}
const char* GetLanguage();
const char* GetLanguage() const;
/**
* Return the vector that holds the list of dependencies
@ -101,33 +75,32 @@ public:
const std::vector<std::string> &GetDepends() const {return this->Depends;}
void AddDepend(const char* d) { this->Depends.push_back(d); }
/**
* Get the source name without last extension
*/
const std::string& GetSourceNameWithoutLastExtension();
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
// Define the properties
static void DefineProperties(cmake *cm);
///! Set the cmMakefile that owns this target
void SetMakefile(cmMakefile *mf);
cmMakefile *GetMakefile() { return this->Makefile;};
/**
* Check whether the given source file location could refer to this
* source.
*/
bool Matches(cmSourceFileLocation const&);
private:
cmSourceFileLocation Location;
cmPropertyMap Properties;
cmCustomCommand *CustomCommand;
cmCustomCommand* CustomCommand;
std::string Extension;
std::string Language;
std::string FullPath;
std::string SourceName;
std::string SourceExtension;
std::vector<std::string> Depends;
std::string SourceNameWithoutLastExtension;
bool FindFullPathFailed;
// The cmMakefile instance that owns this source file. This should
// always be set.
cmMakefile* Makefile;
bool FindFullPath();
bool TryFullPath(const char* tryPath, const char* ext);
void CheckExtension();
std::vector<std::string> Depends;
};
#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 "
"project or dsp file associated with this target.");
#if 0
cm->DefineProperty
("OBJECT_FILES", cmProperty::TARGET,
"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 "
"converts the source list for the target into a list of full "
"paths to object names that will be produced by the target.");
#endif
#define CM_TARGET_FILE_TYPES_DOC \
"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();
cit != cc.GetCommandLines().end(); ++cit )
cit != cc.GetCommandLines().end(); ++cit)
{
std::string const& command = *cit->begin();
// Look for a non-imported target with this name.
if(cmTarget* t = this->Makefile->GetLocalGenerator()->
GetGlobalGenerator()->FindTarget(0, command.c_str(), false))
if(cmTarget* t =
this->GlobalGenerator->FindTarget(0, command.c_str(), false))
{
if(t->GetType() == cmTarget::EXECUTABLE)
{
@ -431,269 +616,67 @@ void cmTarget::CheckForTargetsAsCommand(const cmCustomCommand& cc)
// this project. Add the target-level dependency to make
// sure the executable is up to date before this custom
// 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
cmTarget
::CheckForTargetsAsCommand(const std::vector<cmCustomCommand>& commands)
cmTargetTraceDependencies
::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
{
for ( std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
cli != commands.end();
++cli )
for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
cli != commands.end(); ++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)
{
// get the classes from the source lists then add them to the groups
std::vector<cmSourceFile*> & classes = this->SourceFiles;
// 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)
//----------------------------------------------------------------------------
void cmTarget::AddSources(std::vector<std::string> const& srcs)
{
for(std::vector<std::string>::const_iterator i = srcs.begin();
i != srcs.end(); ++i)
{
name = (*i)->GetSourceName();
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();
this->AddSource(i->c_str());
}
}
void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
cmSourceFile* cmTarget::AddSource(const char* s)
{
// only allow this to be called once
// 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);
std::string src = s;
// Next if one wasn't found then assume it is a single class
// check to see if it is an existing source file
if (!done)
{
cmSourceFile* sourceFile = mf.GetSource(temps.c_str());
if ( sourceFile )
{
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));
}
}
// For backwards compatibility replace varibles in source names.
// This should eventually be removed.
this->Makefile->ExpandVariablesInString(src);
cmSourceFile* sf = this->Makefile->GetOrCreateSource(src.c_str());
this->AddSourceFile(sf);
return sf;
}
void cmTarget::MergeLinkLibraries( cmMakefile& mf,
@ -1328,9 +1311,7 @@ void cmTarget::ComputeObjectFiles()
{
return;
}
// Force the SourceFiles vector to be populated
this->GenerateSourceFilesFromSourceLists(*this->Makefile);
#if 0
std::vector<std::string> dirs;
this->Makefile->GetLocalGenerator()->
GetTargetObjectFileDirectories(this,
@ -1346,10 +1327,7 @@ void cmTarget::ComputeObjectFiles()
s != this->SourceFiles.end(); ++s)
{
cmSourceFile* sf = *s;
const char* lang = this->Makefile->GetLocalGenerator()->
GetGlobalGenerator()->
GetLanguageFromExtension(sf->GetSourceExtension().c_str());
if (lang)
if(const char* lang = sf->GetLanguage())
{
std::string lookupObj = objExtensionLookup1 + lang;
lookupObj += objExtensionLookup2;
@ -1371,6 +1349,7 @@ void cmTarget::ComputeObjectFiles()
}
}
this->SetProperty("OBJECT_FILES", objectFiles.c_str());
#endif
}
@ -1487,9 +1466,7 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg)
= this->SourceFiles.begin();
i != this->SourceFiles.end(); ++i)
{
const char* lang =
gg->GetLanguageFromExtension((*i)->GetSourceExtension().c_str());
if(lang)
if(const char* lang = (*i)->GetLanguage())
{
languages.insert(lang);
}

View File

@ -73,16 +73,6 @@ public:
std::vector<cmCustomCommand> &GetPostBuildCommands()
{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
std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
@ -93,6 +83,12 @@ public:
{return this->SourceFiles;}
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
*/
@ -149,12 +145,6 @@ public:
bool GetHaveInstallRule() { return this->HaveInstallRule; }
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
* 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.
@ -193,7 +183,7 @@ public:
* Trace through the source files in this target and add al source files
* 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
const char* GetLinkerLanguage(cmGlobalGenerator*);
@ -302,14 +292,6 @@ private:
const LibraryID& lib,
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.
* \a emitted keeps track of the libraries that have been emitted to
@ -379,7 +361,6 @@ private:
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
std::vector<std::string> SourceLists;
TargetType TargetTypeValue;
std::vector<cmSourceFile*> SourceFiles;
LinkLibraryVectorType LinkLibraries;

View File

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