Merge topic 'ImprovedDotSupport2'

78c86f4 Exclude targets from the graphviz file based on a regex
5ea1e4c Collect targets and libs on demand instead of in the ctor
2a5790a Use std::cout instead of fprintf
7ba2d36 Enable/disable generating graphs depending on the target type
84ce612 Move the code for generating dot-files into separate class cmGraphVizWriter
a60b099 Generate separate dot files for each target, and a big one with everything.
487bd57 Properly insert all targets, also those which don't link to anything.
de2b2bf Move the code for collecting targets and libraries into separate functions
f7d56df Remove trailing whitespace and minor formatting changes for the dot-code
This commit is contained in:
David Cole 2010-11-23 16:11:26 -05:00 committed by CMake Topic Stage
commit 651120b7af
5 changed files with 642 additions and 344 deletions

View File

@ -183,6 +183,8 @@ SET(SRCS
cmGlobalUnixMakefileGenerator3.cxx cmGlobalUnixMakefileGenerator3.cxx
cmGlobalUnixMakefileGenerator3.h cmGlobalUnixMakefileGenerator3.h
cmGraphAdjacencyList.h cmGraphAdjacencyList.h
cmGraphVizWriter.cxx
cmGraphVizWriter.h
cmInstallGenerator.h cmInstallGenerator.h
cmInstallGenerator.cxx cmInstallGenerator.cxx
cmInstallExportGenerator.cxx cmInstallExportGenerator.cxx
@ -332,7 +334,7 @@ ENDIF (WIN32)
# create a library used by the command line and the GUI # create a library used by the command line and the GUI
ADD_LIBRARY(CMakeLib ${SRCS}) ADD_LIBRARY(CMakeLib ${SRCS})
TARGET_LINK_LIBRARIES(CMakeLib cmsys TARGET_LINK_LIBRARIES(CMakeLib cmsys
${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES} ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES} ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES}
${CMAKE_CURL_LIBRARIES} ) ${CMAKE_CURL_LIBRARIES} )
@ -432,7 +434,7 @@ IF(CYGWIN)
CPack/cmCPackCygwinSourceGenerator.cxx CPack/cmCPackCygwinSourceGenerator.cxx
) )
ENDIF(CYGWIN) ENDIF(CYGWIN)
IF(UNIX) IF(UNIX)
SET(CPACK_SRCS ${CPACK_SRCS} SET(CPACK_SRCS ${CPACK_SRCS}
CPack/cmCPackDebGenerator.cxx CPack/cmCPackDebGenerator.cxx

435
Source/cmGraphVizWriter.cxx Normal file
View File

@ -0,0 +1,435 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmGraphVizWriter.h"
#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmGeneratedFileStream.h"
#include <memory>
static const char* getShapeForTarget(const cmTarget* target)
{
if (!target)
{
return "ellipse";
}
switch ( target->GetType() )
{
case cmTarget::EXECUTABLE:
return "house";
case cmTarget::STATIC_LIBRARY:
return "diamond";
case cmTarget::SHARED_LIBRARY:
return "polygon";
case cmTarget::MODULE_LIBRARY:
return "octagon";
default:
break;
}
return "box";
}
cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
localGenerators)
:GraphType("digraph")
,GraphName("GG")
,GraphHeader("node [\n fontsize = \"12\"\n];")
,GraphNodePrefix("node")
,GenerateForExecutables(true)
,GenerateForStaticLibs(true)
,GenerateForSharedLibs(true)
,GenerateForModuleLibs(true)
,LocalGenerators(localGenerators)
,HaveTargetsAndLibs(false)
{
}
void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
const char* fallbackSettingsFileName)
{
cmake cm;
cmGlobalGenerator ggi;
ggi.SetCMakeInstance(&cm);
std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
cmMakefile *mf = lg->GetMakefile();
const char* inFileName = settingsFileName;
if ( !cmSystemTools::FileExists(inFileName) )
{
inFileName = fallbackSettingsFileName;
if ( !cmSystemTools::FileExists(inFileName) )
{
return;
}
}
if ( !mf->ReadListFile(0, inFileName) )
{
cmSystemTools::Error("Problem opening GraphViz options file: ",
inFileName);
return;
}
std::cout << "Reading GraphViz options file: " << inFileName << std::endl;
#define __set_if_set(var, cmakeDefinition) \
{ \
const char* value = mf->GetDefinition(cmakeDefinition); \
if ( value ) \
{ \
var = value; \
} \
}
__set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
__set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
__set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
__set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");
#define __set_bool_if_set(var, cmakeDefinition) \
{ \
const char* value = mf->GetDefinition(cmakeDefinition); \
if ( value ) \
{ \
var = mf->IsOn(cmakeDefinition); \
} \
}
__set_bool_if_set(this->GenerateForExecutables, "GRAPHVIZ_EXECUTABLES");
__set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS");
__set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS");
__set_bool_if_set(this->GenerateForModuleLibs , "GRAPHVIZ_MODULE_LIBS");
cmStdString tmpRegexString;
__set_if_set(tmpRegexString, "GRAPHVIZ_TARGET_IGNORE_REGEX");
if (tmpRegexString.size() > 0)
{
if (!this->TargetIgnoreRegex.compile(tmpRegexString.c_str()))
{
std::cerr << "Could not compile bad regex \"" << tmpRegexString << "\""
<< std::endl;
}
}
this->TargetsToIgnore.clear();
const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
if ( ignoreTargets )
{
std::vector<std::string> ignoreTargetsVector;
cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
for(std::vector<std::string>::iterator itvIt = ignoreTargetsVector.begin();
itvIt != ignoreTargetsVector.end();
++ itvIt )
{
this->TargetsToIgnore.insert(itvIt->c_str());
}
}
}
void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
{
this->CollectTargetsAndLibs();
for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
this->TargetPtrs.begin();
ptrIt != this->TargetPtrs.end();
++ptrIt)
{
if (ptrIt->second == NULL)
{
continue;
}
if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
{
continue;
}
std::set<std::string> insertedConnections;
std::set<std::string> insertedNodes;
std::string currentFilename = fileName;
currentFilename += ".";
currentFilename += ptrIt->first;
cmGeneratedFileStream str(currentFilename.c_str());
if ( !str )
{
return;
}
std::cout << "Writing " << currentFilename << "..." << std::endl;
this->WriteHeader(str);
this->WriteConnections(ptrIt->first.c_str(),
insertedNodes, insertedConnections, str);
this->WriteFooter(str);
}
}
void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
{
this->CollectTargetsAndLibs();
cmGeneratedFileStream str(fileName);
if ( !str )
{
return;
}
this->WriteHeader(str);
std::cout << "Writing " << fileName << "..." << std::endl;
std::set<std::string> insertedConnections;
std::set<std::string> insertedNodes;
for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
this->TargetPtrs.begin();
ptrIt != this->TargetPtrs.end();
++ptrIt)
{
if (ptrIt->second == NULL)
{
continue;
}
if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
{
continue;
}
this->WriteConnections(ptrIt->first.c_str(),
insertedNodes, insertedConnections, str);
}
this->WriteFooter(str);
}
void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
{
str << this->GraphType << " " << this->GraphName << " {" << std::endl;
str << this->GraphHeader << std::endl;
}
void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
{
str << "}" << std::endl;
}
void cmGraphVizWriter::WriteConnections(const char* targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const
{
std::map<cmStdString, const cmTarget* >::const_iterator targetPtrIt =
this->TargetPtrs.find(targetName);
if (targetPtrIt == this->TargetPtrs.end()) // not found at all
{
return;
}
this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
if (targetPtrIt->second == NULL) // it's an external library
{
return;
}
std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
const cmTarget::LinkLibraryVectorType* ll =
&(targetPtrIt->second->GetOriginalLinkLibraries());
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
llit != ll->end();
++ llit )
{
const char* libName = llit->first.c_str();
std::map<cmStdString, cmStdString>::const_iterator libNameIt =
this->TargetNamesNodes.find(libName);
std::string connectionName = myNodeName;
connectionName += "-";
connectionName += libNameIt->second;
if (insertedConnections.find(connectionName) == insertedConnections.end())
{
insertedConnections.insert(connectionName);
this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
insertedNodes, str);
str << " \"" << myNodeName.c_str() << "\" -> \""
<< libNameIt->second.c_str() << "\"";
str << " // " << targetName << " -> " << libName << std::endl;
this->WriteConnections(libName, insertedNodes, insertedConnections, str);
}
}
}
void cmGraphVizWriter::WriteNode(const char* targetName,
const cmTarget* target,
std::set<std::string>& insertedNodes,
cmGeneratedFileStream& str) const
{
if (insertedNodes.find(targetName) == insertedNodes.end())
{
insertedNodes.insert(targetName);
std::map<cmStdString, cmStdString>::const_iterator nameIt =
this->TargetNamesNodes.find(targetName);
str << " \"" << nameIt->second.c_str() << "\" [ label=\""
<< targetName << "\" shape=\"" << getShapeForTarget(target)
<< "\"];" << std::endl;
}
}
void cmGraphVizWriter::CollectTargetsAndLibs()
{
if (this->HaveTargetsAndLibs == false)
{
this->HaveTargetsAndLibs = true;
int cnt = this->CollectAllTargets();
this->CollectAllExternalLibs(cnt);
}
}
int cmGraphVizWriter::CollectAllTargets()
{
int cnt = 0;
// First pass get the list of all cmake targets
for (std::vector<cmLocalGenerator*>::const_iterator lit =
this->LocalGenerators.begin();
lit != this->LocalGenerators.end();
++ lit )
{
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
for ( cmTargets::const_iterator tit = targets->begin();
tit != targets->end();
++ tit )
{
const char* realTargetName = tit->first.c_str();
if(this->IgnoreThisTarget(realTargetName))
{
// Skip ignored targets
continue;
}
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
cmOStringStream ostr;
ostr << this->GraphNodePrefix << cnt++;
this->TargetNamesNodes[realTargetName] = ostr.str();
this->TargetPtrs[realTargetName] = &tit->second;
}
}
return cnt;
}
int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
{
// Ok, now find all the stuff we link to that is not in cmake
for (std::vector<cmLocalGenerator*>::const_iterator lit =
this->LocalGenerators.begin();
lit != this->LocalGenerators.end();
++ lit )
{
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
for ( cmTargets::const_iterator tit = targets->begin();
tit != targets->end();
++ tit )
{
const char* realTargetName = tit->first.c_str();
if (this->IgnoreThisTarget(realTargetName))
{
// Skip ignored targets
continue;
}
const cmTarget::LinkLibraryVectorType* ll =
&(tit->second.GetOriginalLinkLibraries());
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
llit != ll->end();
++ llit )
{
const char* libName = llit->first.c_str();
if (this->IgnoreThisTarget(libName))
{
// Skip ignored targets
continue;
}
std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
this->TargetPtrs.find(libName);
if ( tarIt == this->TargetPtrs.end() )
{
cmOStringStream ostr;
ostr << this->GraphNodePrefix << cnt++;
this->TargetNamesNodes[libName] = ostr.str();
this->TargetPtrs[libName] = NULL;
//str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
//<< "\" shape=\"ellipse\"];" << std::endl;
}
}
}
}
return cnt;
}
bool cmGraphVizWriter::IgnoreThisTarget(const char* name)
{
if (this->TargetIgnoreRegex.is_valid())
{
if (this->TargetIgnoreRegex.find(name))
{
return true;
}
}
return (this->TargetsToIgnore.find(name) != this->TargetsToIgnore.end());
}
bool cmGraphVizWriter::GenerateForTargetType(cmTarget::TargetType targetType)
const
{
switch (targetType)
{
case cmTarget::EXECUTABLE:
return this->GenerateForExecutables;
case cmTarget::STATIC_LIBRARY:
return this->GenerateForStaticLibs;
case cmTarget::SHARED_LIBRARY:
return this->GenerateForSharedLibs;
case cmTarget::MODULE_LIBRARY:
return this->GenerateForModuleLibs;
default:
break;
}
return false;
}

84
Source/cmGraphVizWriter.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef CMGRAPHVIZWRITER_H
#define CMGRAPHVIZWRITER_H
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmStandardIncludes.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"
#include <cmsys/RegularExpression.hxx>
/** This class implements writing files for graphviz (dot) for graphs
* representing the dependencies between the targets in the project. */
class cmGraphVizWriter
{
public:
cmGraphVizWriter(const std::vector<cmLocalGenerator*>& localGenerators);
void ReadSettings(const char* settingsFileName,
const char* fallbackSettingsFileName);
void WritePerTargetFiles(const char* fileName);
void WriteGlobalFile(const char* fileName);
protected:
void CollectTargetsAndLibs();
int CollectAllTargets();
int CollectAllExternalLibs(int cnt);
void WriteHeader(cmGeneratedFileStream& str) const;
void WriteConnections(const char* targetName,
std::set<std::string>& insertedNodes,
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const;
void WriteNode(const char* targetName, const cmTarget* target,
std::set<std::string>& insertedNodes,
cmGeneratedFileStream& str) const;
void WriteFooter(cmGeneratedFileStream& str) const;
bool IgnoreThisTarget(const char* name);
bool GenerateForTargetType(cmTarget::TargetType targetType) const;
cmStdString GraphType;
cmStdString GraphName;
cmStdString GraphHeader;
cmStdString GraphNodePrefix;
bool GenerateForExecutables;
bool GenerateForStaticLibs;
bool GenerateForSharedLibs;
bool GenerateForModuleLibs;
cmsys::RegularExpression TargetIgnoreRegex;
std::set<cmStdString> TargetsToIgnore;
const std::vector<cmLocalGenerator*>& LocalGenerators;
std::map<cmStdString, const cmTarget*> TargetPtrs;
// maps from the actual target names to node names in dot:
std::map<cmStdString, cmStdString> TargetNamesNodes;
bool HaveTargetsAndLibs;
};
#endif

View File

@ -26,6 +26,7 @@
#include "cmDocumentationFormatterText.h" #include "cmDocumentationFormatterText.h"
#if defined(CMAKE_BUILD_WITH_CMAKE) #if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmGraphVizWriter.h"
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmVariableWatch.h" # include "cmVariableWatch.h"
# include <cmsys/Terminal.h> # include <cmsys/Terminal.h>
@ -169,7 +170,7 @@ cmake::cmake()
this->ProgressCallback = 0; this->ProgressCallback = 0;
this->ProgressCallbackClientData = 0; this->ProgressCallbackClientData = 0;
this->ScriptMode = false; this->ScriptMode = false;
#ifdef CMAKE_BUILD_WITH_CMAKE #ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch = new cmVariableWatch; this->VariableWatch = new cmVariableWatch;
this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN", this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN",
@ -382,7 +383,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
this->DoSuppressDevWarnings = true; this->DoSuppressDevWarnings = true;
} }
else if(arg.find("-Wdev",0) == 0) else if(arg.find("-Wdev",0) == 0)
{ {
this->SuppressDevWarnings = false; this->SuppressDevWarnings = false;
this->DoSuppressDevWarnings = true; this->DoSuppressDevWarnings = true;
} }
@ -406,7 +407,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
cmsys::Glob::PatternToRegex(entryPattern.c_str(), true, true).c_str()); cmsys::Glob::PatternToRegex(entryPattern.c_str(), true, true).c_str());
//go through all cache entries and collect the vars which will be removed //go through all cache entries and collect the vars which will be removed
std::vector<std::string> entriesToDelete; std::vector<std::string> entriesToDelete;
cmCacheManager::CacheIterator it = cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(); this->CacheManager->GetCacheIterator();
for ( it.Begin(); !it.IsAtEnd(); it.Next() ) for ( it.Begin(); !it.IsAtEnd(); it.Next() )
{ {
@ -422,8 +423,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
} }
// now remove them from the cache // now remove them from the cache
for(std::vector<std::string>::const_iterator currentEntry = for(std::vector<std::string>::const_iterator currentEntry =
entriesToDelete.begin(); entriesToDelete.begin();
currentEntry != entriesToDelete.end(); currentEntry != entriesToDelete.end();
++currentEntry) ++currentEntry)
{ {
@ -791,7 +792,7 @@ int cmake::AddCMakePaths()
cMakeSelf += "/cmake"; cMakeSelf += "/cmake";
std::cerr << cMakeSelf.c_str() << "\n"; std::cerr << cMakeSelf.c_str() << "\n";
} }
#endif #endif
if(!cmSystemTools::FileExists(cMakeSelf.c_str())) if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
{ {
cmSystemTools::Error("CMake executable cannot be found at ", cmSystemTools::Error("CMake executable cannot be found at ",
@ -802,12 +803,12 @@ int cmake::AddCMakePaths()
this->CacheManager->AddCacheEntry this->CacheManager->AddCacheEntry
("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.", ("CMAKE_COMMAND",cMakeSelf.c_str(), "Path to CMake executable.",
cmCacheManager::INTERNAL); cmCacheManager::INTERNAL);
// if the edit command is not yet in the cache, // if the edit command is not yet in the cache,
// or if CMakeEditCommand has been set on this object, // or if CMakeEditCommand has been set on this object,
// then set the CMAKE_EDIT_COMMAND in the cache // then set the CMAKE_EDIT_COMMAND in the cache
// This will mean that the last gui to edit the cache // This will mean that the last gui to edit the cache
// will be the one that make edit_cache uses. // will be the one that make edit_cache uses.
if(!this->GetCacheDefinition("CMAKE_EDIT_COMMAND") if(!this->GetCacheDefinition("CMAKE_EDIT_COMMAND")
|| !this->CMakeEditCommand.empty()) || !this->CMakeEditCommand.empty())
{ {
// Find and save the command to edit the cache // Find and save the command to edit the cache
@ -815,8 +816,8 @@ int cmake::AddCMakePaths()
if(!this->CMakeEditCommand.empty()) if(!this->CMakeEditCommand.empty())
{ {
editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf) editCacheCommand = cmSystemTools::GetFilenamePath(cMakeSelf)
+ std::string("/") + std::string("/")
+ this->CMakeEditCommand + this->CMakeEditCommand
+ cmSystemTools::GetFilenameExtension(cMakeSelf); + cmSystemTools::GetFilenameExtension(cMakeSelf);
} }
if( !cmSystemTools::FileExists(editCacheCommand.c_str())) if( !cmSystemTools::FileExists(editCacheCommand.c_str()))
@ -936,7 +937,7 @@ void CMakeCommandUsage(const char* program)
errorStream errorStream
<< "cmake bootstrap\n"; << "cmake bootstrap\n";
#endif #endif
// If you add new commands, change here, // If you add new commands, change here,
// and in cmakemain.cxx in the options table // and in cmakemain.cxx in the options table
errorStream errorStream
<< "Usage: " << program << " -E [command] [arguments ...]\n" << "Usage: " << program << " -E [command] [arguments ...]\n"
@ -1091,7 +1092,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0; return 0;
} }
#endif #endif
else if (args[1] == "make_directory" && args.size() == 3) else if (args[1] == "make_directory" && args.size() == 3)
{ {
if(!cmSystemTools::MakeDirectory(args[2].c_str())) if(!cmSystemTools::MakeDirectory(args[2].c_str()))
@ -1342,7 +1343,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
} }
return 0; return 0;
} }
// Command to create a symbolic link. Fails on platforms not // Command to create a symbolic link. Fails on platforms not
// supporting them. // supporting them.
else if (args[1] == "create_symlink" && args.size() == 4) else if (args[1] == "create_symlink" && args.size() == 4)
@ -1410,7 +1411,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
// Use the make system's VERBOSE environment variable to enable // Use the make system's VERBOSE environment variable to enable
// verbose output. This can be skipped by also setting CMAKE_NO_VERBOSE // verbose output. This can be skipped by also setting CMAKE_NO_VERBOSE
// (which is set by the Eclipse and KDevelop generators). // (which is set by the Eclipse and KDevelop generators).
bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0) bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0)
&& (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0)); && (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0));
// Create a cmake object instance to process dependencies. // Create a cmake object instance to process dependencies.
@ -1635,14 +1636,14 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
return 1; return 1;
} }
void cmake::AddExtraGenerator(const char* name, void cmake::AddExtraGenerator(const char* name,
CreateExtraGeneratorFunctionType newFunction) CreateExtraGeneratorFunctionType newFunction)
{ {
cmExternalMakefileProjectGenerator* extraGenerator = newFunction(); cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
const std::vector<std::string>& supportedGlobalGenerators = const std::vector<std::string>& supportedGlobalGenerators =
extraGenerator->GetSupportedGlobalGenerators(); extraGenerator->GetSupportedGlobalGenerators();
for(std::vector<std::string>::const_iterator for(std::vector<std::string>::const_iterator
it = supportedGlobalGenerators.begin(); it = supportedGlobalGenerators.begin();
it != supportedGlobalGenerators.end(); it != supportedGlobalGenerators.end();
++it ) ++it )
@ -1670,11 +1671,11 @@ void cmake::AddDefaultExtraGenerators()
#endif #endif
#ifdef CMAKE_USE_KDEVELOP #ifdef CMAKE_USE_KDEVELOP
this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(),
&cmGlobalKdevelopGenerator::New); &cmGlobalKdevelopGenerator::New);
// for kdevelop also add the generator with just the name of the // for kdevelop also add the generator with just the name of the
// extra generator, since it was this way since cmake 2.2 // extra generator, since it was this way since cmake 2.2
this->ExtraGenerators[cmGlobalKdevelopGenerator::GetActualName()] this->ExtraGenerators[cmGlobalKdevelopGenerator::GetActualName()]
= &cmGlobalKdevelopGenerator::New; = &cmGlobalKdevelopGenerator::New;
#endif #endif
@ -1690,7 +1691,7 @@ void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
{ {
names.push_back(i->first); names.push_back(i->first);
} }
for(RegisteredExtraGeneratorsMap::const_iterator for(RegisteredExtraGeneratorsMap::const_iterator
i = this->ExtraGenerators.begin(); i = this->ExtraGenerators.begin();
i != this->ExtraGenerators.end(); ++i) i != this->ExtraGenerators.end(); ++i)
{ {
@ -1828,7 +1829,7 @@ int cmake::DoPreConfigureChecks()
// do a sanity check on some values // do a sanity check on some values
if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY")) if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
{ {
std::string cacheStart = std::string cacheStart =
this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"); this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
cacheStart += "/CMakeLists.txt"; cacheStart += "/CMakeLists.txt";
std::string currentStart = this->GetHomeDirectory(); std::string currentStart = this->GetHomeDirectory();
@ -1872,13 +1873,13 @@ int cmake::HandleDeleteCacheVariables(const char* var)
cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator(); cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator();
std::vector<SaveCacheEntry> saved; std::vector<SaveCacheEntry> saved;
cmOStringStream warning; cmOStringStream warning;
warning warning
<< "You have changed variables that require your cache to be deleted.\n" << "You have changed variables that require your cache to be deleted.\n"
<< "Configure will be re-run and you may have to reset some variables.\n" << "Configure will be re-run and you may have to reset some variables.\n"
<< "The following variables have changed:\n"; << "The following variables have changed:\n";
for(std::vector<std::string>::iterator i = argsSplit.begin(); for(std::vector<std::string>::iterator i = argsSplit.begin();
i != argsSplit.end(); ++i) i != argsSplit.end(); ++i)
{ {
SaveCacheEntry save; SaveCacheEntry save;
save.key = *i; save.key = *i;
warning << *i << "= "; warning << *i << "= ";
@ -1892,7 +1893,7 @@ int cmake::HandleDeleteCacheVariables(const char* var)
} }
saved.push_back(save); saved.push_back(save);
} }
// remove the cache // remove the cache
this->CacheManager->DeleteCache(this->GetStartOutputDirectory()); this->CacheManager->DeleteCache(this->GetStartOutputDirectory());
// load the empty cache // load the empty cache
@ -1964,7 +1965,7 @@ int cmake::ActualConfigure()
if ( !res ) if ( !res )
{ {
this->CacheManager->AddCacheEntry this->CacheManager->AddCacheEntry
("CMAKE_HOME_DIRECTORY", ("CMAKE_HOME_DIRECTORY",
this->GetHomeDirectory(), this->GetHomeDirectory(),
"Start directory with the top level CMakeLists.txt file for this " "Start directory with the top level CMakeLists.txt file for this "
"project", "project",
@ -1974,9 +1975,9 @@ int cmake::ActualConfigure()
// no generator specified on the command line // no generator specified on the command line
if(!this->GlobalGenerator) if(!this->GlobalGenerator)
{ {
const char* genName = const char* genName =
this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
const char* extraGenName = const char* extraGenName =
this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR"); this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
if(genName) if(genName)
{ {
@ -1998,7 +1999,7 @@ int cmake::ActualConfigure()
this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator); this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW) #elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
std::string installedCompiler; std::string installedCompiler;
// Try to find the newest VS installed on the computer and // Try to find the newest VS installed on the computer and
// use that as a default if -G is not specified // use that as a default if -G is not specified
std::string vsregBase = std::string vsregBase =
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\"; "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\";
@ -2062,11 +2063,11 @@ int cmake::ActualConfigure()
} }
if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR")) if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR"))
{ {
this->CacheManager->AddCacheEntry("CMAKE_GENERATOR", this->CacheManager->AddCacheEntry("CMAKE_GENERATOR",
this->GlobalGenerator->GetName(), this->GlobalGenerator->GetName(),
"Name of generator.", "Name of generator.",
cmCacheManager::INTERNAL); cmCacheManager::INTERNAL);
this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR", this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
this->GlobalGenerator->GetExtraGeneratorName(), this->GlobalGenerator->GetExtraGeneratorName(),
"Name of external makefile project generator.", "Name of external makefile project generator.",
cmCacheManager::INTERNAL); cmCacheManager::INTERNAL);
@ -2205,7 +2206,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
// set the cmake command // set the cmake command
this->CMakeCommand = args[0]; this->CMakeCommand = args[0];
if ( !this->ScriptMode ) if ( !this->ScriptMode )
{ {
// load the cache // load the cache
@ -2330,7 +2331,7 @@ void cmake::AddCacheEntry(const char* key, const char* value,
const char* helpString, const char* helpString,
int type) int type)
{ {
this->CacheManager->AddCacheEntry(key, value, this->CacheManager->AddCacheEntry(key, value,
helpString, helpString,
cmCacheManager::CacheEntryType(type)); cmCacheManager::CacheEntryType(type));
} }
@ -2445,8 +2446,8 @@ void cmake::UpdateProgress(const char *msg, float prog)
} }
} }
void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v, void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v,
bool withCurrentCommands, bool withCurrentCommands,
bool withCompatCommands) const bool withCompatCommands) const
{ {
for(RegisteredCommandsMap::const_iterator j = this->Commands.begin(); for(RegisteredCommandsMap::const_iterator j = this->Commands.begin();
@ -2457,7 +2458,7 @@ void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v,
{ {
continue; continue;
} }
cmDocumentationEntry e((*j).second->GetName(), cmDocumentationEntry e((*j).second->GetName(),
(*j).second->GetTerseDocumentation(), (*j).second->GetTerseDocumentation(),
(*j).second->GetFullDocumentation()); (*j).second->GetFullDocumentation());
@ -2493,7 +2494,7 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
delete generator; delete generator;
v.push_back(e); v.push_back(e);
} }
for(RegisteredExtraGeneratorsMap::const_iterator for(RegisteredExtraGeneratorsMap::const_iterator
i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i) i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
{ {
cmDocumentationEntry e; cmDocumentationEntry e;
@ -2508,7 +2509,7 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
void cmake::UpdateConversionPathTable() void cmake::UpdateConversionPathTable()
{ {
// Update the path conversion table with any specified file: // Update the path conversion table with any specified file:
const char* tablepath = const char* tablepath =
this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE"); this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE");
if(tablepath) if(tablepath)
@ -2540,7 +2541,7 @@ int cmake::CheckBuildSystem()
// the make system's VERBOSE environment variable to enable verbose // the make system's VERBOSE environment variable to enable verbose
// output. This can be skipped by setting CMAKE_NO_VERBOSE (which is set // output. This can be skipped by setting CMAKE_NO_VERBOSE (which is set
// by the Eclipse and KDevelop generators). // by the Eclipse and KDevelop generators).
bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0) bool verbose = ((cmSystemTools::GetEnv("VERBOSE") != 0)
&& (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0)); && (cmSystemTools::GetEnv("CMAKE_NO_VERBOSE") == 0));
// This method will check the integrity of the build system if the // This method will check the integrity of the build system if the
@ -2549,7 +2550,7 @@ int cmake::CheckBuildSystem()
// If no file is provided for the check, we have to rerun. // If no file is provided for the check, we have to rerun.
if(this->CheckBuildSystemArgument.size() == 0) if(this->CheckBuildSystemArgument.size() == 0)
{ {
if(verbose) if(verbose)
{ {
cmOStringStream msg; cmOStringStream msg;
@ -2565,7 +2566,7 @@ int cmake::CheckBuildSystem()
if(verbose) if(verbose)
{ {
cmOStringStream msg; cmOStringStream msg;
msg << "Re-run cmake missing file: " msg << "Re-run cmake missing file: "
<< this->CheckBuildSystemArgument.c_str() << "\n"; << this->CheckBuildSystemArgument.c_str() << "\n";
cmSystemTools::Stdout(msg.str().c_str()); cmSystemTools::Stdout(msg.str().c_str());
} }
@ -2585,7 +2586,7 @@ int cmake::CheckBuildSystem()
if(verbose) if(verbose)
{ {
cmOStringStream msg; cmOStringStream msg;
msg << "Re-run cmake error reading : " msg << "Re-run cmake error reading : "
<< this->CheckBuildSystemArgument.c_str() << "\n"; << this->CheckBuildSystemArgument.c_str() << "\n";
cmSystemTools::Stdout(msg.str().c_str()); cmSystemTools::Stdout(msg.str().c_str());
} }
@ -2835,253 +2836,27 @@ const char* cmake::GetCPackCommand()
return this->CPackCommand.c_str(); return this->CPackCommand.c_str();
} }
void cmake::GenerateGraphViz(const char* fileName) const void cmake::GenerateGraphViz(const char* fileName) const
{ {
cmGeneratedFileStream str(fileName); #ifdef CMAKE_BUILD_WITH_CMAKE
if ( !str ) std::auto_ptr<cmGraphVizWriter> gvWriter(
{ new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators()));
return;
}
cmake cm;
cmGlobalGenerator ggi;
ggi.SetCMakeInstance(&cm);
std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
cmMakefile *mf = lg->GetMakefile();
std::string infile = this->GetHomeOutputDirectory(); std::string settingsFile = this->GetHomeOutputDirectory();
infile += "/CMakeGraphVizOptions.cmake"; settingsFile += "/CMakeGraphVizOptions.cmake";
if ( !cmSystemTools::FileExists(infile.c_str()) ) std::string fallbackSettingsFile = this->GetHomeDirectory();
{ fallbackSettingsFile += "/CMakeGraphVizOptions.cmake";
infile = this->GetHomeDirectory();
infile += "/CMakeGraphVizOptions.cmake";
if ( !cmSystemTools::FileExists(infile.c_str()) )
{
infile = "";
}
}
if ( !infile.empty() ) gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str());
{
if ( !mf->ReadListFile(0, infile.c_str()) )
{
cmSystemTools::Error("Problem opening GraphViz options file: ",
infile.c_str());
return;
}
std::cout << "Read GraphViz options file: " << infile.c_str()
<< std::endl;
}
#define __set_if_not_set(var, value, cmakeDefinition) \ gvWriter->WritePerTargetFiles(fileName);
const char* var = mf->GetDefinition(cmakeDefinition); \ gvWriter->WriteGlobalFile(fileName);
if ( !var ) \
{ \
var = value; \
}
__set_if_not_set(graphType, "digraph", "GRAPHVIZ_GRAPH_TYPE");
__set_if_not_set(graphName, "GG", "GRAPHVIZ_GRAPH_NAME");
__set_if_not_set(graphHeader, "node [\n fontsize = \"12\"\n];",
"GRAPHVIZ_GRAPH_HEADER");
__set_if_not_set(graphNodePrefix, "node", "GRAPHVIZ_NODE_PREFIX");
const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
std::set<cmStdString> ignoreTargetsSet;
if ( ignoreTargets )
{
std::vector<std::string> ignoreTargetsVector;
cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
std::vector<std::string>::iterator itvIt;
for ( itvIt = ignoreTargetsVector.begin();
itvIt != ignoreTargetsVector.end();
++ itvIt )
{
ignoreTargetsSet.insert(itvIt->c_str());
}
}
str << graphType << " " << graphName << " {" << std::endl; #endif
str << graphHeader << std::endl;
const cmGlobalGenerator* gg = this->GetGlobalGenerator();
const std::vector<cmLocalGenerator*>& localGenerators =
gg->GetLocalGenerators();
std::vector<cmLocalGenerator*>::const_iterator lit;
// for target deps
// 1 - cmake target
// 2 - external target
// 0 - no deps
std::map<cmStdString, int> targetDeps;
std::map<cmStdString, const cmTarget*> targetPtrs;
std::map<cmStdString, cmStdString> targetNamesNodes;
int cnt = 0;
// First pass get the list of all cmake targets
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
{
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
cmTargets::const_iterator tit;
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
{
const char* realTargetName = tit->first.c_str();
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
{
// Skip ignored targets
continue;
}
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
cmOStringStream ostr;
ostr << graphNodePrefix << cnt++;
targetNamesNodes[realTargetName] = ostr.str();
targetPtrs[realTargetName] = &tit->second;
}
}
// Ok, now find all the stuff we link to that is not in cmake
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
{
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
cmTargets::const_iterator tit;
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
{
const cmTarget::LinkLibraryVectorType* ll
= &(tit->second.GetOriginalLinkLibraries());
cmTarget::LinkLibraryVectorType::const_iterator llit;
const char* realTargetName = tit->first.c_str();
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
{
// Skip ignored targets
continue;
}
if ( ll->size() > 0 )
{
targetDeps[realTargetName] = 1;
}
for ( llit = ll->begin(); llit != ll->end(); ++ llit )
{
const char* libName = llit->first.c_str();
std::map<cmStdString, cmStdString>::const_iterator tarIt
= targetNamesNodes.find(libName);
if ( ignoreTargetsSet.find(libName) != ignoreTargetsSet.end() )
{
// Skip ignored targets
continue;
}
if ( tarIt == targetNamesNodes.end() )
{
cmOStringStream ostr;
ostr << graphNodePrefix << cnt++;
targetDeps[libName] = 2;
targetNamesNodes[libName] = ostr.str();
//str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
//<< "\" shape=\"ellipse\"];" << std::endl;
}
else
{
std::map<cmStdString, int>::const_iterator depIt
= targetDeps.find(libName);
if ( depIt == targetDeps.end() )
{
targetDeps[libName] = 1;
}
}
}
}
}
// Write out nodes
std::map<cmStdString, int>::const_iterator depIt;
for ( depIt = targetDeps.begin(); depIt != targetDeps.end(); ++ depIt )
{
const char* newTargetName = depIt->first.c_str();
std::map<cmStdString, cmStdString>::const_iterator tarIt
= targetNamesNodes.find(newTargetName);
if ( tarIt == targetNamesNodes.end() )
{
// We should not be here.
std::cout << __LINE__ << " Cannot find library: " << newTargetName
<< " even though it was added in the previous pass" << std::endl;
abort();
}
str << " \"" << tarIt->second.c_str() << "\" [ label=\""
<< newTargetName << "\" shape=\"";
if ( depIt->second == 1 )
{
std::map<cmStdString, const cmTarget*>::const_iterator tarTypeIt =
targetPtrs.find(newTargetName);
if ( tarTypeIt == targetPtrs.end() )
{
// We should not be here.
std::cout << __LINE__ << " Cannot find library: " << newTargetName
<< " even though it was added in the previous pass" << std::endl;
abort();
}
const cmTarget* tg = tarTypeIt->second;
switch ( tg->GetType() )
{
case cmTarget::EXECUTABLE:
str << "house";
break;
case cmTarget::STATIC_LIBRARY:
str << "diamond";
break;
case cmTarget::SHARED_LIBRARY:
str << "polygon";
break;
case cmTarget::MODULE_LIBRARY:
str << "octagon";
break;
default:
str << "box";
}
}
else
{
str << "ellipse";
}
str << "\"];" << std::endl;
}
// Now generate the connectivity
for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit )
{
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
cmTargets::const_iterator tit;
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
{
std::map<cmStdString, int>::iterator dependIt
= targetDeps.find(tit->first.c_str());
if ( dependIt == targetDeps.end() )
{
continue;
}
std::map<cmStdString, cmStdString>::iterator cmakeTarIt
= targetNamesNodes.find(tit->first.c_str());
const cmTarget::LinkLibraryVectorType* ll
= &(tit->second.GetOriginalLinkLibraries());
cmTarget::LinkLibraryVectorType::const_iterator llit;
for ( llit = ll->begin(); llit != ll->end(); ++ llit )
{
const char* libName = llit->first.c_str();
std::map<cmStdString, cmStdString>::const_iterator tarIt
= targetNamesNodes.find(libName);
if ( tarIt == targetNamesNodes.end() )
{
// We should not be here.
std::cout << __LINE__ << " Cannot find library: " << libName
<< " even though it was added in the previous pass" << std::endl;
abort();
}
str << " \"" << cmakeTarIt->second.c_str() << "\" -> \""
<< tarIt->second.c_str() << "\"" << std::endl;
}
}
}
// TODO: Use dotted or something for external libraries
//str << " \"node0\":f4 -> \"node12\"[color=\"#0000ff\" style=dotted]"
//<< std::endl;
//
str << "}" << std::endl;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int cmake::SymlinkLibrary(std::vector<std::string>& args) int cmake::SymlinkLibrary(std::vector<std::string>& args)
{ {
@ -3336,7 +3111,7 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
void cmake::DefineProperties(cmake *cm) void cmake::DefineProperties(cmake *cm)
{ {
cm->DefineProperty cm->DefineProperty
("REPORT_UNDEFINED_PROPERTIES", cmProperty::GLOBAL, ("REPORT_UNDEFINED_PROPERTIES", cmProperty::GLOBAL,
"If set, report any undefined properties to this file.", "If set, report any undefined properties to this file.",
"If this property is set to a filename then when CMake runs " "If this property is set to a filename then when CMake runs "
"it will report any properties or variables that were accessed " "it will report any properties or variables that were accessed "
@ -3344,7 +3119,7 @@ void cmake::DefineProperties(cmake *cm)
); );
cm->DefineProperty cm->DefineProperty
("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL, ("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL,
"Does the target platform support shared libraries.", "Does the target platform support shared libraries.",
"TARGET_SUPPORTS_SHARED_LIBS is a boolean specifying whether the target " "TARGET_SUPPORTS_SHARED_LIBS is a boolean specifying whether the target "
"platform supports shared libraries. Basically all current general " "platform supports shared libraries. Basically all current general "
@ -3381,7 +3156,7 @@ void cmake::DefineProperties(cmake *cm)
"this list.This property is used by the macros in FeatureSummary.cmake."); "this list.This property is used by the macros in FeatureSummary.cmake.");
cm->DefineProperty cm->DefineProperty
("DISABLED_FEATURES", cmProperty::GLOBAL, ("DISABLED_FEATURES", cmProperty::GLOBAL,
"List of features which are disabled during the CMake run.", "List of features which are disabled during the CMake run.",
"List of features which are disabled during the CMake run. Be default " "List of features which are disabled during the CMake run. Be default "
"it contains the names of all packages which were not found. This is " "it contains the names of all packages which were not found. This is "
"determined using the <NAME>_FOUND variables. Packages which are " "determined using the <NAME>_FOUND variables. Packages which are "
@ -3531,13 +3306,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
bool chained, const char *docSection) bool chained, const char *docSection)
{ {
this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription, this->PropertyDefinitions[scope].DefineProperty(name,scope,ShortDescription,
FullDescription, FullDescription,
docSection, docSection,
chained); chained);
} }
cmPropertyDefinition *cmake cmPropertyDefinition *cmake
::GetPropertyDefinition(const char *name, ::GetPropertyDefinition(const char *name,
cmProperty::ScopeType scope) cmProperty::ScopeType scope)
{ {
if (this->IsPropertyDefined(name,scope)) if (this->IsPropertyDefined(name,scope))
@ -3547,7 +3322,7 @@ cmPropertyDefinition *cmake
return 0; return 0;
} }
void cmake::RecordPropertyAccess(const char *name, void cmake::RecordPropertyAccess(const char *name,
cmProperty::ScopeType scope) cmProperty::ScopeType scope)
{ {
this->AccessedProperties.insert this->AccessedProperties.insert
@ -3619,13 +3394,13 @@ void cmake::ReportUndefinedPropertyAccesses(const char *filename)
{ {
if (!this->IsPropertyDefined(ap->first.c_str(),ap->second) && if (!this->IsPropertyDefined(ap->first.c_str(),ap->second) &&
aliasedProperties.find(std::pair<cmStdString,cmProperty::ScopeType> aliasedProperties.find(std::pair<cmStdString,cmProperty::ScopeType>
(ap->first,ap->second)) == (ap->first,ap->second)) ==
aliasedProperties.end()) aliasedProperties.end())
{ {
const char *scopeStr = ""; const char *scopeStr = "";
switch (ap->second) switch (ap->second)
{ {
case cmProperty::TARGET: case cmProperty::TARGET:
scopeStr = "TARGET"; scopeStr = "TARGET";
break; break;
case cmProperty::SOURCE_FILE: case cmProperty::SOURCE_FILE:
@ -3727,7 +3502,7 @@ const char *cmake::GetProperty(const char* prop, cmProperty::ScopeType scope)
} }
else if ( propname == "COMMANDS" ) else if ( propname == "COMMANDS" )
{ {
cmake::RegisteredCommandsMap::iterator cmds cmake::RegisteredCommandsMap::iterator cmds
= this->GetCommands()->begin(); = this->GetCommands()->begin();
for (unsigned int cc=0 ; cmds != this->GetCommands()->end(); ++ cmds ) for (unsigned int cc=0 ; cmds != this->GetCommands()->end(); ++ cmds )
{ {
@ -3835,14 +3610,14 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// we have to find the module directory, so we can copy the files // we have to find the module directory, so we can copy the files
this->AddCMakePaths(); this->AddCMakePaths();
std::string modulesPath = std::string modulesPath =
this->CacheManager->GetCacheValue("CMAKE_ROOT"); this->CacheManager->GetCacheValue("CMAKE_ROOT");
modulesPath += "/Modules"; modulesPath += "/Modules";
std::string inFile = modulesPath; std::string inFile = modulesPath;
inFile += "/SystemInformation.cmake"; inFile += "/SystemInformation.cmake";
std::string outFile = destPath; std::string outFile = destPath;
outFile += "/CMakeLists.txt"; outFile += "/CMakeLists.txt";
// Copy file // Copy file
if(!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str())) if(!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str()))
{ {
@ -3850,7 +3625,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
<< "\" to \"" << outFile.c_str() << "\".\n"; << "\" to \"" << outFile.c_str() << "\".\n";
return 1; return 1;
} }
// do we write to a file or to stdout? // do we write to a file or to stdout?
if (resultFile.size() == 0) if (resultFile.size() == 0)
{ {
@ -3876,7 +3651,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
// change back to the original directory // change back to the original directory
cmSystemTools::ChangeDirectory(cwd.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str());
// echo results to stdout if needed // echo results to stdout if needed
if (writeToStdout) if (writeToStdout)
{ {
@ -3897,7 +3672,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
fclose(fin); fclose(fin);
} }
} }
// clean up the directory // clean up the directory
cmSystemTools::RemoveADirectory(destPath.c_str()); cmSystemTools::RemoveADirectory(destPath.c_str());
return 0; return 0;
@ -4016,7 +3791,7 @@ int cmake::VisualStudioLink(std::vector<std::string>& args, int type)
for(std::vector<std::string>::iterator i = args.begin(); for(std::vector<std::string>::iterator i = args.begin();
i != args.end(); ++i) i != args.end(); ++i)
{ {
// check for nmake temporary files // check for nmake temporary files
if((*i)[0] == '@' && i->find("@CMakeFiles") != 0 ) if((*i)[0] == '@' && i->find("@CMakeFiles") != 0 )
{ {
std::ifstream fin(i->substr(1).c_str()); std::ifstream fin(i->substr(1).c_str());
@ -4069,7 +3844,7 @@ int cmake::VisualStudioLink(std::vector<std::string>& args, int type)
type, hasManifest, verbose); type, hasManifest, verbose);
} }
int cmake::ParseVisualStudioLinkCommand(std::vector<std::string>& args, int cmake::ParseVisualStudioLinkCommand(std::vector<std::string>& args,
std::vector<cmStdString>& command, std::vector<cmStdString>& command,
std::string& targetName) std::string& targetName)
{ {
@ -4120,7 +3895,7 @@ bool cmake::RunCommand(const char* comment,
&retCode, 0, false); &retCode, 0, false);
// always print the output of the command, unless // always print the output of the command, unless
// it is the dumb rc command banner, but if the command // it is the dumb rc command banner, but if the command
// returned an error code then print the output anyway as // returned an error code then print the output anyway as
// the banner may be mixed with some other important information. // the banner may be mixed with some other important information.
if(output.find("Resource Compiler Version") == output.npos if(output.find("Resource Compiler Version") == output.npos
|| retCode !=0) || retCode !=0)
@ -4141,12 +3916,12 @@ bool cmake::RunCommand(const char* comment,
return retCode == 0; return retCode == 0;
} }
int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args, int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
int type, bool verbose) int type, bool verbose)
{ {
// This follows the steps listed here: // This follows the steps listed here:
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx // http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
// 1. Compiler compiles the application and generates the *.obj files. // 1. Compiler compiles the application and generates the *.obj files.
// 2. An empty manifest file is generated if this is a clean build and if // 2. An empty manifest file is generated if this is a clean build and if
// not the previous one is reused. // not the previous one is reused.
@ -4158,10 +3933,10 @@ int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
// on. // on.
// 5. The manifest tool (mt.exe) is then used to generate the final // 5. The manifest tool (mt.exe) is then used to generate the final
// manifest. // manifest.
// If the final manifest is changed, then 6 and 7 are run, if not // If the final manifest is changed, then 6 and 7 are run, if not
// they are skipped, and it is done. // they are skipped, and it is done.
// 6. The resource compiler is invoked one more time. // 6. The resource compiler is invoked one more time.
// 7. Finally, the Linker does another incremental link, but since the // 7. Finally, the Linker does another incremental link, but since the
// only thing that has changed is the *.res file that contains the // only thing that has changed is the *.res file that contains the
@ -4220,7 +3995,7 @@ int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
outputOpt += resourceFile; outputOpt += resourceFile;
rcCommand.push_back(outputOpt); rcCommand.push_back(outputOpt);
rcCommand.push_back(resourceInputFile); rcCommand.push_back(resourceInputFile);
// Run rc command to create resource // Run rc command to create resource
if(!cmake::RunCommand("RC Pass 1", rcCommand, verbose)) if(!cmake::RunCommand("RC Pass 1", rcCommand, verbose))
{ {
return -1; return -1;
@ -4230,7 +4005,7 @@ int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
{ {
return -1; return -1;
} }
// create mt command // create mt command
std::string outArg("/out:"); std::string outArg("/out:");
outArg+= manifestFile; outArg+= manifestFile;
mtCommand.push_back("/nologo"); mtCommand.push_back("/nologo");
@ -4281,7 +4056,7 @@ int cmake::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
{ {
return -1; return -1;
} }
// Run the link command as given // Run the link command as given
linkCommand.push_back("/MANIFEST"); linkCommand.push_back("/MANIFEST");
if(!cmake::RunCommand("LINK", linkCommand, verbose)) if(!cmake::RunCommand("LINK", linkCommand, verbose))
{ {
@ -4472,7 +4247,7 @@ int cmake::Build(const std::string& dir,
makeProgram = it.GetValue(); makeProgram = it.GetValue();
return gen->Build(0, dir.c_str(), return gen->Build(0, dir.c_str(),
projName.c_str(), target.c_str(), projName.c_str(), target.c_str(),
&output, &output,
makeProgram.c_str(), makeProgram.c_str(),
config.c_str(), clean, false, 0, true, config.c_str(), clean, false, 0, true,
0, nativeOptions); 0, nativeOptions);

View File

@ -21,14 +21,14 @@
// command line arguments. // command line arguments.
// 3) Load the cache by calling LoadCache (duh) // 3) Load the cache by calling LoadCache (duh)
// 4) if you are using command line arguments with -D or -C flags then // 4) if you are using command line arguments with -D or -C flags then
// call SetCacheArgs (or if for some other reason you want to modify the // call SetCacheArgs (or if for some other reason you want to modify the
// cache, do it now. // cache, do it now.
// 5) Finally call Configure // 5) Finally call Configure
// 6) Let the user change values and go back to step 5 // 6) Let the user change values and go back to step 5
// 7) call Generate // 7) call Generate
// //
// If your GUI allows the user to change the start & home directories then // If your GUI allows the user to change the start & home directories then
// you must at a minimum redo steps 2 through 7. // you must at a minimum redo steps 2 through 7.
// //
@ -50,6 +50,8 @@ class cmExternalMakefileProjectGenerator;
class cmDocumentationSection; class cmDocumentationSection;
class cmPolicies; class cmPolicies;
class cmListFileBacktrace; class cmListFileBacktrace;
class cmTarget;
class cmGeneratedFileStream;
class cmake class cmake
{ {
@ -73,14 +75,14 @@ class cmake
static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";}; static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";};
static const char *GetCMakeFilesDirectoryPostSlash() { static const char *GetCMakeFilesDirectoryPostSlash() {
return "CMakeFiles/";}; return "CMakeFiles/";};
//@{ //@{
/** /**
* Set/Get the home directory (or output directory) in the project. The * Set/Get the home directory (or output directory) in the project. The
* home directory is the top directory of the project. It is where * home directory is the top directory of the project. It is where
* cmake was run. Remember that CMake processes * cmake was run. Remember that CMake processes
* CMakeLists files by recursing up the tree starting at the StartDirectory * CMakeLists files by recursing up the tree starting at the StartDirectory
* and going up until it reaches the HomeDirectory. * and going up until it reaches the HomeDirectory.
*/ */
void SetHomeDirectory(const char* dir); void SetHomeDirectory(const char* dir);
const char* GetHomeDirectory() const const char* GetHomeDirectory() const
@ -100,9 +102,9 @@ class cmake
* is the directory of the CMakeLists.txt file that started the current * is the directory of the CMakeLists.txt file that started the current
* round of processing. Remember that CMake processes CMakeLists files by * round of processing. Remember that CMake processes CMakeLists files by
* recursing up the tree starting at the StartDirectory and going up until * recursing up the tree starting at the StartDirectory and going up until
* it reaches the HomeDirectory. * it reaches the HomeDirectory.
*/ */
void SetStartDirectory(const char* dir) void SetStartDirectory(const char* dir)
{ {
this->cmStartDirectory = dir; this->cmStartDirectory = dir;
cmSystemTools::ConvertToUnixSlashes(this->cmStartDirectory); cmSystemTools::ConvertToUnixSlashes(this->cmStartDirectory);
@ -158,7 +160,7 @@ class cmake
///! Return the global generator assigned to this instance of cmake ///! Return the global generator assigned to this instance of cmake
cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; } cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
///! Return the global generator assigned to this instance of cmake, const ///! Return the global generator assigned to this instance of cmake, const
const cmGlobalGenerator* GetGlobalGenerator() const const cmGlobalGenerator* GetGlobalGenerator() const
{ return this->GlobalGenerator; } { return this->GlobalGenerator; }
///! Return the global generator assigned to this instance of cmake ///! Return the global generator assigned to this instance of cmake
@ -169,25 +171,25 @@ class cmake
///! get the cmCachemManager used by this invocation of cmake ///! get the cmCachemManager used by this invocation of cmake
cmCacheManager *GetCacheManager() { return this->CacheManager; } cmCacheManager *GetCacheManager() { return this->CacheManager; }
///! set the cmake command this instance of cmake should use ///! set the cmake command this instance of cmake should use
void SetCMakeCommand(const char* cmd) { this->CMakeCommand = cmd; } void SetCMakeCommand(const char* cmd) { this->CMakeCommand = cmd; }
/** /**
* Given a variable name, return its value (as a string). * Given a variable name, return its value (as a string).
*/ */
const char* GetCacheDefinition(const char*) const; const char* GetCacheDefinition(const char*) const;
///! Add an entry into the cache ///! Add an entry into the cache
void AddCacheEntry(const char* key, const char* value, void AddCacheEntry(const char* key, const char* value,
const char* helpString, const char* helpString,
int type); int type);
/** /**
* Execute commands during the build process. Supports options such * Execute commands during the build process. Supports options such
* as echo, remove file etc. * as echo, remove file etc.
*/ */
static int ExecuteCMakeCommand(std::vector<std::string>&); static int ExecuteCMakeCommand(std::vector<std::string>&);
/** /**
* Get the system information and write it to the file specified * Get the system information and write it to the file specified
*/ */
int GetSystemInformation(std::vector<std::string>&); int GetSystemInformation(std::vector<std::string>&);
@ -210,16 +212,16 @@ class cmake
/** Check if a command exists. */ /** Check if a command exists. */
bool CommandExists(const char* name) const; bool CommandExists(const char* name) const;
///! Parse command line arguments ///! Parse command line arguments
void SetArgs(const std::vector<std::string>&); void SetArgs(const std::vector<std::string>&);
///! Is this cmake running as a result of a TRY_COMPILE command ///! Is this cmake running as a result of a TRY_COMPILE command
bool GetIsInTryCompile() { return this->InTryCompile; } bool GetIsInTryCompile() { return this->InTryCompile; }
///! Is this cmake running as a result of a TRY_COMPILE command ///! Is this cmake running as a result of a TRY_COMPILE command
void SetIsInTryCompile(bool i) { this->InTryCompile = i; } void SetIsInTryCompile(bool i) { this->InTryCompile = i; }
///! Parse command line arguments that might set cache values ///! Parse command line arguments that might set cache values
bool SetCacheArgs(const std::vector<std::string>&); bool SetCacheArgs(const std::vector<std::string>&);
@ -227,9 +229,9 @@ class cmake
(const char*msg, float progress, void *); (const char*msg, float progress, void *);
/** /**
* Set the function used by GUI's to receive progress updates * Set the function used by GUI's to receive progress updates
* Function gets passed: message as a const char*, a progress * Function gets passed: message as a const char*, a progress
* amount ranging from 0 to 1.0 and client data. The progress * amount ranging from 0 to 1.0 and client data. The progress
* number provided may be negative in cases where a message is * number provided may be negative in cases where a message is
* to be displayed without any progress percentage. * to be displayed without any progress percentage.
*/ */
void SetProgressCallback(ProgressCallbackType f, void* clientData=0); void SetProgressCallback(ProgressCallbackType f, void* clientData=0);
@ -244,14 +246,14 @@ class cmake
cmVariableWatch* GetVariableWatch() { return this->VariableWatch; } cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
/** Get the documentation entries for the supported commands. /** Get the documentation entries for the supported commands.
* If withCurrentCommands is true, the documentation for the * If withCurrentCommands is true, the documentation for the
* recommended set of commands is included. * recommended set of commands is included.
* If withCompatCommands is true, the documentation for discouraged * If withCompatCommands is true, the documentation for discouraged
* (compatibility) commands is included. * (compatibility) commands is included.
* You probably don't want to set both to false. * You probably don't want to set both to false.
*/ */
void GetCommandDocumentation(std::vector<cmDocumentationEntry>& entries, void GetCommandDocumentation(std::vector<cmDocumentationEntry>& entries,
bool withCurrentCommands = true, bool withCurrentCommands = true,
bool withCompatCommands = true) const; bool withCompatCommands = true) const;
void GetPropertiesDocumentation(std::map<std::string, void GetPropertiesDocumentation(std::map<std::string,
cmDocumentationSection *>&); cmDocumentationSection *>&);
@ -278,7 +280,7 @@ class cmake
*/ */
void SetScriptMode(bool mode) { this->ScriptMode = mode; } void SetScriptMode(bool mode) { this->ScriptMode = mode; }
bool GetScriptMode() { return this->ScriptMode; } bool GetScriptMode() { return this->ScriptMode; }
///! Debug the try compile stuff by not delelting the files ///! Debug the try compile stuff by not delelting the files
bool GetDebugTryCompile(){return this->DebugTryCompile;} bool GetDebugTryCompile(){return this->DebugTryCompile;}
void DebugTryCompileOn(){this->DebugTryCompile = true;} void DebugTryCompileOn(){this->DebugTryCompile = true;}
@ -310,7 +312,7 @@ class cmake
void DefineProperty(const char *name, cmProperty::ScopeType scope, void DefineProperty(const char *name, cmProperty::ScopeType scope,
const char *ShortDescription, const char *ShortDescription,
const char *FullDescription, const char *FullDescription,
bool chain = false, bool chain = false,
const char *variableGroup = 0); const char *variableGroup = 0);
// get property definition // get property definition
@ -338,7 +340,7 @@ class cmake
} }
void SetSuppressDevWarnings(bool v) void SetSuppressDevWarnings(bool v)
{ {
this->SuppressDevWarnings = v; this->SuppressDevWarnings = v;
this->DoSuppressDevWarnings = true; this->DoSuppressDevWarnings = true;
} }
@ -357,10 +359,10 @@ protected:
cmPropertyMap Properties; cmPropertyMap Properties;
std::set<std::pair<cmStdString,cmProperty::ScopeType> > AccessedProperties; std::set<std::pair<cmStdString,cmProperty::ScopeType> > AccessedProperties;
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>
PropertyDefinitions; PropertyDefinitions;
typedef typedef
cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)(); cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
typedef std::map<cmStdString, typedef std::map<cmStdString,
CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap; CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
@ -374,15 +376,15 @@ protected:
void AddDefaultCommands(); void AddDefaultCommands();
void AddDefaultGenerators(); void AddDefaultGenerators();
void AddDefaultExtraGenerators(); void AddDefaultExtraGenerators();
void AddExtraGenerator(const char* name, void AddExtraGenerator(const char* name,
CreateExtraGeneratorFunctionType newFunction); CreateExtraGeneratorFunctionType newFunction);
cmPolicies *Policies; cmPolicies *Policies;
cmGlobalGenerator *GlobalGenerator; cmGlobalGenerator *GlobalGenerator;
cmCacheManager *CacheManager; cmCacheManager *CacheManager;
std::string cmHomeDirectory; std::string cmHomeDirectory;
std::string HomeOutputDirectory; std::string HomeOutputDirectory;
std::string cmStartDirectory; std::string cmStartDirectory;
std::string StartOutputDirectory; std::string StartOutputDirectory;
bool SuppressDevWarnings; bool SuppressDevWarnings;
bool DoSuppressDevWarnings; bool DoSuppressDevWarnings;
@ -393,7 +395,7 @@ protected:
///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file. ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
/// If it is set, truncate it to 50kb /// If it is set, truncate it to 50kb
void TruncateOutputLog(const char* fname); void TruncateOutputLog(const char* fname);
/** /**
* Method called to check build system integrity at build time. * Method called to check build system integrity at build time.
* Returns 1 if CMake should rerun and 0 otherwise. * Returns 1 if CMake should rerun and 0 otherwise.
@ -416,24 +418,24 @@ protected:
static int ExecuteLinkScript(std::vector<std::string>& args); static int ExecuteLinkScript(std::vector<std::string>& args);
static int VisualStudioLink(std::vector<std::string>& args, int type); static int VisualStudioLink(std::vector<std::string>& args, int type);
static int VisualStudioLinkIncremental(std::vector<std::string>& args, static int VisualStudioLinkIncremental(std::vector<std::string>& args,
int type, int type,
bool verbose); bool verbose);
static int VisualStudioLinkNonIncremental(std::vector<std::string>& args, static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
int type, int type,
bool hasManifest, bool hasManifest,
bool verbose); bool verbose);
static int ParseVisualStudioLinkCommand(std::vector<std::string>& args, static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
std::vector<cmStdString>& command, std::vector<cmStdString>& command,
std::string& targetName); std::string& targetName);
static bool RunCommand(const char* comment, static bool RunCommand(const char* comment,
std::vector<cmStdString>& command, std::vector<cmStdString>& command,
bool verbose, bool verbose,
int* retCodeOut = 0); int* retCodeOut = 0);
cmVariableWatch* VariableWatch; cmVariableWatch* VariableWatch;
///! Find the full path to one of the cmake programs like ctest, cpack, etc. ///! Find the full path to one of the cmake programs like ctest, cpack, etc.
std::string FindCMakeProgram(const char* name) const; std::string FindCMakeProgram(const char* name) const;
private: private:
cmake(const cmake&); // Not implemented. cmake(const cmake&); // Not implemented.
void operator=(const cmake&); // Not implemented. void operator=(const cmake&); // Not implemented.
ProgressCallbackType ProgressCallback; ProgressCallbackType ProgressCallback;
@ -458,7 +460,7 @@ private:
cmFileTimeComparison* FileComparison; cmFileTimeComparison* FileComparison;
std::string GraphVizFile; std::string GraphVizFile;
std::vector<std::string> DebugConfigs; std::vector<std::string> DebugConfigs;
void UpdateConversionPathTable(); void UpdateConversionPathTable();
}; };