ENH: add cmExternalMakefileProjectGenerator, which should make it easier to

write generators for IDE projects, which use already existing makefiles
(current the kdevelop generator)
-first stept of the export interface, iniitial export() command
-more replacements for the FIND_XXX docs

Alex
This commit is contained in:
Alexander Neundorf 2007-06-08 11:57:16 -04:00
parent 79077f8373
commit 0ddc9f62e5
16 changed files with 950 additions and 359 deletions

View File

@ -37,6 +37,7 @@
#include "cmEndForEachCommand.cxx" #include "cmEndForEachCommand.cxx"
#include "cmEndIfCommand.cxx" #include "cmEndIfCommand.cxx"
#include "cmExecProgramCommand.cxx" #include "cmExecProgramCommand.cxx"
#include "cmExternalMakefileProjectGenerator.cxx"
#include "cmFindBase.cxx" #include "cmFindBase.cxx"
#include "cmFileCommand.cxx" #include "cmFileCommand.cxx"
#include "cmFindFileCommand.cxx" #include "cmFindFileCommand.cxx"

View File

@ -24,6 +24,7 @@
#include "cmEndMacroCommand.cxx" #include "cmEndMacroCommand.cxx"
#include "cmEndWhileCommand.cxx" #include "cmEndWhileCommand.cxx"
#include "cmExecuteProcessCommand.cxx" #include "cmExecuteProcessCommand.cxx"
#include "cmExportCommand.cxx"
#include "cmExportLibraryDependencies.cxx" #include "cmExportLibraryDependencies.cxx"
#include "cmFLTKWrapUICommand.cxx" #include "cmFLTKWrapUICommand.cxx"
#include "cmGetDirectoryPropertyCommand.cxx" #include "cmGetDirectoryPropertyCommand.cxx"
@ -76,6 +77,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
commands.push_back(new cmEndMacroCommand); commands.push_back(new cmEndMacroCommand);
commands.push_back(new cmEndWhileCommand); commands.push_back(new cmEndWhileCommand);
commands.push_back(new cmExecuteProcessCommand); commands.push_back(new cmExecuteProcessCommand);
commands.push_back(new cmExportCommand);
commands.push_back(new cmExportLibraryDependenciesCommand); commands.push_back(new cmExportLibraryDependenciesCommand);
commands.push_back(new cmFLTKWrapUICommand); commands.push_back(new cmFLTKWrapUICommand);
commands.push_back(new cmGetDirectoryPropertyCommand); commands.push_back(new cmGetDirectoryPropertyCommand);

233
Source/cmExportCommand.cxx Normal file
View File

@ -0,0 +1,233 @@
/*=========================================================================
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 "cmExportCommand.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include <cmsys/auto_ptr.hxx>
// cmExportCommand
bool cmExportCommand
::InitialPass(std::vector<std::string> const& args)
{
if(args.size() < 2 )
{
this->SetError("called with too few arguments");
return false;
}
std::string filename;
std::string prefix;
std::string exportName;
std::vector<std::string> targets;
bool append = false;
if (!this->ParseArgs(args, filename, prefix, exportName, targets, append))
{
return false;
}
if ( !this->Makefile->CanIWriteThisFile(filename.c_str()) )
{
std::string e = "attempted to write a file: " + filename
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
if ((targets.empty()) || (filename.empty()))
{
return true;
}
// Use copy-if-different if not appending.
cmsys::auto_ptr<std::ofstream> foutPtr;
if(append)
{
cmsys::auto_ptr<std::ofstream> ap(
new std::ofstream(filename.c_str(), std::ios::app));
foutPtr = ap;
}
else
{
cmsys::auto_ptr<cmGeneratedFileStream> ap(
new cmGeneratedFileStream(filename.c_str(), true));
ap->SetCopyIfDifferent(true);
foutPtr = ap;
}
std::ostream& fout = *foutPtr.get();
if (!fout)
{
cmSystemTools::Error("Error Writing ", filename.c_str());
cmSystemTools::ReportLastSystemError("");
return true;
}
// the following code may move into an "export generator"
// Compute the set of configurations.
std::vector<std::string> configurationTypes;
if(const char* types =
this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
cmSystemTools::ExpandListArgument(types, configurationTypes);
}
if(configurationTypes.empty())
{
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
if (config!=0)
{
configurationTypes.push_back(config);
}
}
for(std::vector<std::string>::const_iterator currentTarget = targets.begin();
currentTarget != targets.end();
++currentTarget)
{
// Look for a CMake target with the given name, which is an executable
// and which can be run
cmTarget* target = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, currentTarget->c_str(), true);
if ((target != 0)
&& ((target->GetType() == cmTarget::EXECUTABLE)
|| (target->GetType() == cmTarget::STATIC_LIBRARY)
|| (target->GetType() == cmTarget::SHARED_LIBRARY)
|| (target->GetType() == cmTarget::MODULE_LIBRARY)))
{
switch (target->GetType())
{
case cmTarget::EXECUTABLE:
fout << "ADD_EXECUTABLE(" << prefix.c_str() << currentTarget->c_str() << " IMPORT )\n";
break;
case cmTarget::STATIC_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " STATIC IMPORT )\n";
break;
case cmTarget::SHARED_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " SHARED IMPORT )\n";
break;
case cmTarget::MODULE_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " MODULE IMPORT )\n";
break;
default: // should never happen
break;
}
fout << "SET_TARGET_PROPERTIES(" << prefix.c_str() << currentTarget->c_str() << " PROPERTIES \n";
fout << " LOCATION " << target->GetLocation(0) << "\n";
for(std::vector<std::string>::const_iterator currentConfig = configurationTypes.begin();
currentConfig != configurationTypes.end();
++currentConfig)
{
if (!currentConfig->empty())
{
const char* loc = target->GetLocation(currentConfig->c_str());
if (loc && *loc)
{
fout << " " << currentConfig->c_str()<< "_LOCATION " << loc << "\n";
}
}
}
fout << " )\n\n";
}
else
{
}
}
return true;
}
bool cmExportCommand::ParseArgs(const std::vector<std::string>& args,
std::string& filename,
std::string& prefix,
std::string& exportName,
std::vector<std::string>& targets,
bool& append) const
{
bool doingFile = false;
bool doingPrefix = false;
bool doingTargets = false;
bool doingName = true;
for(std::vector<std::string>::const_iterator it = args.begin();
it != args.end();
++it)
{
if (*it == "FILE")
{
doingFile = true;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (*it == "PREFIX")
{
doingFile = false;
doingPrefix = true;
doingName = false;
doingTargets = false;
}
else if (*it == "TARGETS")
{
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = true;
}
else if (*it == "APPEND")
{
append = true;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingFile)
{
filename = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingPrefix)
{
prefix = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingTargets)
{
targets.push_back(*it);
}
else if (doingName)
{
exportName = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else
{
}
}
return true;
}

85
Source/cmExportCommand.h Normal file
View File

@ -0,0 +1,85 @@
/*=========================================================================
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 cmExportCommand_h
#define cmExportCommand_h
#include "cmCommand.h"
/** \class cmExportLibraryDependenciesCommand
* \brief Add a test to the lists of tests to run.
*
* cmExportLibraryDependenciesCommand adds a test to the list of tests to run
*
*/
class cmExportCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmExportCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "EXPORT";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return
"Write out the dependency information for all targets of a project.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" EXPORT(TARGETS tgt1 tgt2 ... [PREFIX <prefix>] FILE <filename> [APPEND])\n"
"Create a file that can be included into a CMake listfile with the "
"INCLUDE command. The file will contain a number of SET commands "
"that will set all the variables needed for library dependency "
"information. This should be the last command in the top level "
"CMakeLists.txt file of the project. If the APPEND option is "
"specified, the SET commands will be appended to the given file "
"instead of replacing it.";
}
cmTypeMacro(cmExportCommand, cmCommand);
private:
bool ParseArgs(const std::vector<std::string>& args, std::string& filename,
std::string& prefix, std::string& exportName,
std::vector<std::string>& targets, bool& append ) const;
};
#endif

View File

@ -0,0 +1,70 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2007 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 <assert.h>
#include "cmExternalMakefileProjectGenerator.h"
std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
const char* globalGenerator,
const char* extraGenerator)
{
std::string fullName;
if (globalGenerator)
{
fullName = globalGenerator;
if (extraGenerator && *extraGenerator)
{
fullName += " - ";
fullName += extraGenerator;
}
}
return fullName;
}
const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
const char* fullName)
{
// at least one global generator must be supported
assert(!this->SupportedGlobalGenerators.empty());
if (fullName==0)
{
return 0;
}
std::string currentName = fullName;
// if we get only the short name, take the first global generator as default
if (currentName == this->GetName())
{
return this->SupportedGlobalGenerators[0].c_str();
}
// otherwise search for the matching global generator
for (std::vector<std::string>::const_iterator
it = this->SupportedGlobalGenerators.begin();
it != this->SupportedGlobalGenerators.end();
++it)
{
if (this->CreateFullGeneratorName(it->c_str(), this->GetName())
== currentName)
{
return it->c_str();
}
}
return 0;
}

View File

@ -0,0 +1,73 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2007 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 cmExternalMakefileProjectGenerator_h
#define cmExternalMakefileProjectGenerator_h
#include <vector>
#include <string>
#include "cmDocumentation.h"
class cmGlobalGenerator;
/** \class cmExternalMakefileProjectGenerator
* \brief Base class for generators for "External Makefile based IDE projects".
*
* cmExternalMakefileProjectGenerator is a base class for generators
* for "external makefile based projects", i.e. IDE projects which work
* an already existing makefiles.
* See cmGlobalKdevelopGenerator as an example.
* After the makefiles have been generated by one of the Makefile
* generators, the Generate() method is called and this generator
* can iterate over the local generators and/or projects to produce the
* project files for the IDE.
*/
class cmExternalMakefileProjectGenerator
{
public:
///! Get the name for this generator.
virtual const char* GetName() const = 0;
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
const char* fullName) const = 0;
///! set the global generator which will generate the makefiles
virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
{this->GlobalGenerator = generator;}
///! Return the list of global generators supported by this extra generator
const std::vector<std::string>& GetSupportedGlobalGenerators() const
{return this->SupportedGlobalGenerators;}
///! Get the name of the global generator for the given full name
const char* GetGlobalGeneratorName(const char* fullName);
/** Create a full name from the given global generator name and the
* extra generator name
*/
static std::string CreateFullGeneratorName(const char* globalGenerator,
const char* extraGenerator);
///! Generate the project files, the Makefiles have already been generated
virtual void Generate() = 0;
protected:
///! Contains the names of the global generators support by this generator.
std::vector<std::string> SupportedGlobalGenerators;
///! the global generator which creates the makefiles
const cmGlobalGenerator* GlobalGenerator;
};
#endif

View File

@ -32,6 +32,10 @@ cmFindLibraryCommand::cmFindLibraryCommand()
"SEARCH_XXX_DESC", "library"); "SEARCH_XXX_DESC", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "library"); "SEARCH_XXX", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
this->GenericDocumentation += this->GenericDocumentation +=
"\n" "\n"
"If the library found is a framework, then VAR will be set to " "If the library found is a framework, then VAR will be set to "

View File

@ -36,6 +36,10 @@ cmFindPathCommand::cmFindPathCommand()
"directory containing the named file"); "directory containing the named file");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "file in a directory"); "SEARCH_XXX", "file in a directory");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
this->ExtraDocAdded = false; this->ExtraDocAdded = false;
} }

View File

@ -37,6 +37,9 @@ cmFindProgramCommand::cmFindProgramCommand()
"SEARCH_XXX_DESC", "program"); "SEARCH_XXX_DESC", "program");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "program"); "SEARCH_XXX", "program");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
} }
// cmFindProgramCommand // cmFindProgramCommand

View File

@ -9,20 +9,21 @@
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information. PURPOSE. See the above copyright notices for more information.
=========================================================================*/ =========================================================================*/
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmake.h" #include "cmake.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmVersion.h" #include "cmVersion.h"
#include <stdlib.h> // required for atof #include <stdlib.h> // required for atof
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h> #include <windows.h>
#endif #endif
@ -47,10 +48,12 @@ cmGlobalGenerator::cmGlobalGenerator()
// how long to let try compiles run // how long to let try compiles run
this->TryCompileTimeout = 0; this->TryCompileTimeout = 0;
this->ExtraGenerator = 0;
} }
cmGlobalGenerator::~cmGlobalGenerator() cmGlobalGenerator::~cmGlobalGenerator()
{ {
// Delete any existing cmLocalGenerators // Delete any existing cmLocalGenerators
unsigned int i; unsigned int i;
for (i = 0; i < this->LocalGenerators.size(); ++i) for (i = 0; i < this->LocalGenerators.size(); ++i)
@ -58,6 +61,11 @@ cmGlobalGenerator::~cmGlobalGenerator()
delete this->LocalGenerators[i]; delete this->LocalGenerators[i];
} }
this->LocalGenerators.clear(); this->LocalGenerators.clear();
if (this->ExtraGenerator)
{
delete this->ExtraGenerator;
}
} }
// Find the make program for the generator, required for try compiles // Find the make program for the generator, required for try compiles
@ -72,13 +80,13 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM") if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
|| cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
{ {
std::string setMakeProgram = std::string setMakeProgram =
mf->GetModulesFile(this->FindMakeProgramFile.c_str()); mf->GetModulesFile(this->FindMakeProgramFile.c_str());
if(setMakeProgram.size()) if(setMakeProgram.size())
{ {
mf->ReadListFile(0, setMakeProgram.c_str()); mf->ReadListFile(0, setMakeProgram.c_str());
} }
} }
if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM") if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
|| cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
{ {
@ -120,12 +128,12 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
// it will stop forwarding output, and let the build finish. // it will stop forwarding output, and let the build finish.
// Then it will retry the build. It will continue this // Then it will retry the build. It will continue this
// untill no text file busy errors occur. // untill no text file busy errors occur.
std::string cmakexbuild = std::string cmakexbuild =
this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND"); this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5); cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
cmakexbuild += "cmakexbuild"; cmakexbuild += "cmakexbuild";
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM",
cmakexbuild.c_str(), cmakexbuild.c_str(),
"make program", "make program",
cmCacheManager::FILEPATH); cmCacheManager::FILEPATH);
@ -135,49 +143,49 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
// enable the given language // enable the given language
// //
// The following files are loaded in this order: // The following files are loaded in this order:
// //
// First figure out what OS we are running on: // First figure out what OS we are running on:
// //
// CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake // CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
// CMakeDetermineSystem.cmake - figure out os info and create // CMakeDetermineSystem.cmake - figure out os info and create
// CMakeSystem.cmake IFF CMAKE_SYSTEM_NAME // CMakeSystem.cmake IFF CMAKE_SYSTEM_NAME
// not set // not set
// CMakeSystem.cmake - configured file created by // CMakeSystem.cmake - configured file created by
// CMakeDetermineSystem.cmake IFF CMAKE_SYSTEM_LOADED // CMakeDetermineSystem.cmake IFF CMAKE_SYSTEM_LOADED
// Next try and enable all languages found in the languages vector // Next try and enable all languages found in the languages vector
//
// FOREACH LANG in languages
// CMake(LANG)Compiler.cmake - configured file create by
// CMakeDetermine(LANG)Compiler.cmake
// CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
// creates CMake(LANG)Compiler.cmake
// CMake(LANG)Compiler.cmake - configured file created by
// CMakeDetermine(LANG)Compiler.cmake
// //
// CMakeSystemSpecificInformation.cmake // FOREACH LANG in languages
// CMake(LANG)Compiler.cmake - configured file create by
// CMakeDetermine(LANG)Compiler.cmake
// CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
// creates CMake(LANG)Compiler.cmake
// CMake(LANG)Compiler.cmake - configured file created by
// CMakeDetermine(LANG)Compiler.cmake
//
// CMakeSystemSpecificInformation.cmake
// - includes Platform/${CMAKE_SYSTEM_NAME}.cmake // - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
// may use compiler stuff // may use compiler stuff
// FOREACH LANG in languages // FOREACH LANG in languages
// CMake(LANG)Information.cmake // CMake(LANG)Information.cmake
// - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake // - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
// CMakeTest(LANG)Compiler.cmake // CMakeTest(LANG)Compiler.cmake
// - Make sure the compiler works with a try compile if // - Make sure the compiler works with a try compile if
// CMakeDetermine(LANG) was loaded // CMakeDetermine(LANG) was loaded
// //
// Now load a few files that can override values set in any of the above // Now load a few files that can override values set in any of the above
// CMake(PROJECTNAME)Compatibility.cmake // CMake(PROJECTNAME)Compatibility.cmake
// - load any backwards compatibility stuff for current project // - load any backwards compatibility stuff for current project
// ${CMAKE_USER_MAKE_RULES_OVERRIDE} // ${CMAKE_USER_MAKE_RULES_OVERRIDE}
// - allow users a chance to override system variables // - allow users a chance to override system variables
// //
// //
void void
cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *mf) cmMakefile *mf)
{ {
if(languages.size() == 0) if(languages.size() == 0)
{ {
cmSystemTools::Error("EnableLanguage must have a lang specified!"); cmSystemTools::Error("EnableLanguage must have a lang specified!");
@ -187,7 +195,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
mf->AddDefinition("RUN_CONFIGURE", true); mf->AddDefinition("RUN_CONFIGURE", true);
std::string rootBin = mf->GetHomeOutputDirectory(); std::string rootBin = mf->GetHomeOutputDirectory();
rootBin += cmake::GetCMakeFilesDirectory(); rootBin += cmake::GetCMakeFilesDirectory();
// If the configuration files path has been set, // If the configuration files path has been set,
// then we are in a try compile and need to copy the enable language // then we are in a try compile and need to copy the enable language
// files from the parent cmake bin dir, into the try compile bin dir // files from the parent cmake bin dir, into the try compile bin dir
@ -206,8 +214,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
} }
// set the dir for parent files so they can be used by modules // set the dir for parent files so they can be used by modules
mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str()); mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str());
// find and make sure CMAKE_MAKE_PROGRAM is defined // find and make sure CMAKE_MAKE_PROGRAM is defined
this->FindMakeProgram(mf); this->FindMakeProgram(mf);
@ -225,7 +233,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// what platform we are running on // what platform we are running on
if (!mf->GetDefinition("CMAKE_SYSTEM_NAME")) if (!mf->GetDefinition("CMAKE_SYSTEM_NAME"))
{ {
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
/* Windows version number data. */ /* Windows version number data. */
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(osvi)); ZeroMemory(&osvi, sizeof(osvi));
@ -247,9 +255,9 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
mf->ReadListFile(0,fpath.c_str()); mf->ReadListFile(0,fpath.c_str());
} }
std::map<cmStdString, bool> needTestLanguage; std::map<cmStdString, bool> needTestLanguage;
// foreach language // foreach language
// load the CMakeDetermine(LANG)Compiler.cmake file to find // load the CMakeDetermine(LANG)Compiler.cmake file to find
// the compiler // the compiler
for(std::vector<std::string>::const_iterator l = languages.begin(); for(std::vector<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l) l != languages.end(); ++l)
@ -283,19 +291,19 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
{ {
if(!mf->ReadListFile(0,fpath.c_str())) if(!mf->ReadListFile(0,fpath.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
fpath.c_str()); fpath.c_str());
} }
// if this file was found then the language was already determined // if this file was found then the language was already determined
// to be working // to be working
needTestLanguage[lang] = false; needTestLanguage[lang] = false;
this->SetLanguageEnabled(lang, mf); this->SetLanguageEnabled(lang, mf);
// this can only be called after loading CMake(LANG)Compiler.cmake // this can only be called after loading CMake(LANG)Compiler.cmake
} }
} }
if(!this->GetLanguageEnabled(lang) ) if(!this->GetLanguageEnabled(lang) )
{ {
if (this->CMakeInstance->GetIsInTryCompile()) if (this->CMakeInstance->GetIsInTryCompile())
{ {
cmSystemTools::Error("This should not have happen. " cmSystemTools::Error("This should not have happen. "
@ -303,18 +311,18 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
"using a broken CMakeLists.txt file or a " "using a broken CMakeLists.txt file or a "
"problematic release of CMake"); "problematic release of CMake");
} }
// if the CMake(LANG)Compiler.cmake file was not found then // if the CMake(LANG)Compiler.cmake file was not found then
// load CMakeDetermine(LANG)Compiler.cmake // load CMakeDetermine(LANG)Compiler.cmake
std::string determineCompiler = "CMakeDetermine"; std::string determineCompiler = "CMakeDetermine";
determineCompiler += lang; determineCompiler += lang;
determineCompiler += "Compiler.cmake"; determineCompiler += "Compiler.cmake";
std::string determineFile = std::string determineFile =
mf->GetModulesFile(determineCompiler.c_str()); mf->GetModulesFile(determineCompiler.c_str());
if(!mf->ReadListFile(0,determineFile.c_str())) if(!mf->ReadListFile(0,determineFile.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
determineFile.c_str()); determineFile.c_str());
} }
needTestLanguage[lang] = true; needTestLanguage[lang] = true;
determineLanguageCalled = true; determineLanguageCalled = true;
// Some generators like visual studio should not use the env variables // Some generators like visual studio should not use the env variables
@ -331,15 +339,15 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
compilerEnv += lang; compilerEnv += lang;
compilerEnv += "_COMPILER_ENV_VAR"; compilerEnv += "_COMPILER_ENV_VAR";
std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str()); std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
std::string envVarValue = std::string envVarValue =
mf->GetRequiredDefinition(compilerName.c_str()); mf->GetRequiredDefinition(compilerName.c_str());
std::string env = envVar; std::string env = envVar;
env += "="; env += "=";
env += envVarValue; env += envVarValue;
cmSystemTools::PutEnv(env.c_str()); cmSystemTools::PutEnv(env.c_str());
} }
} // end if(!this->GetLanguageEnabled(lang) ) } // end if(!this->GetLanguageEnabled(lang) )
// if determineLanguage was called then load the file it // if determineLanguage was called then load the file it
// configures CMake(LANG)Compiler.cmake // configures CMake(LANG)Compiler.cmake
if(determineLanguageCalled) if(determineLanguageCalled)
{ {
@ -349,10 +357,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
fpath += "Compiler.cmake"; fpath += "Compiler.cmake";
if(!mf->ReadListFile(0,fpath.c_str())) if(!mf->ReadListFile(0,fpath.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
fpath.c_str()); fpath.c_str());
} }
this->SetLanguageEnabled(lang, mf); this->SetLanguageEnabled(lang, mf);
// this can only be called after loading CMake(LANG)Compiler.cmake // this can only be called after loading CMake(LANG)Compiler.cmake
// the language must be enabled for try compile to work, but we do // the language must be enabled for try compile to work, but we do
// not know if it is a working compiler yet so set the test language // not know if it is a working compiler yet so set the test language
@ -360,14 +368,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
needTestLanguage[lang] = true; needTestLanguage[lang] = true;
} }
} // end loop over languages } // end loop over languages
// **** Load the system specific information if not yet loaded // **** Load the system specific information if not yet loaded
if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED")) if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
{ {
fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake"); fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
if(!mf->ReadListFile(0,fpath.c_str())) if(!mf->ReadListFile(0,fpath.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
fpath.c_str()); fpath.c_str());
} }
} }
@ -386,14 +394,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
langLoadedVar += lang; langLoadedVar += lang;
langLoadedVar += "_INFORMATION_LOADED"; langLoadedVar += "_INFORMATION_LOADED";
if (!mf->GetDefinition(langLoadedVar.c_str())) if (!mf->GetDefinition(langLoadedVar.c_str()))
{ {
fpath = "CMake"; fpath = "CMake";
fpath += lang; fpath += lang;
fpath += "Information.cmake"; fpath += "Information.cmake";
fpath = mf->GetModulesFile(fpath.c_str()); fpath = mf->GetModulesFile(fpath.c_str());
if(!mf->ReadListFile(0,fpath.c_str())) if(!mf->ReadListFile(0,fpath.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
fpath.c_str()); fpath.c_str());
} }
} }
@ -411,7 +419,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
std::string ifpath = mf->GetModulesFile(testLang.c_str()); std::string ifpath = mf->GetModulesFile(testLang.c_str());
if(!mf->ReadListFile(0,ifpath.c_str())) if(!mf->ReadListFile(0,ifpath.c_str()))
{ {
cmSystemTools::Error("Could not find cmake module file:", cmSystemTools::Error("Could not find cmake module file:",
ifpath.c_str()); ifpath.c_str());
} }
std::string compilerWorks = "CMAKE_"; std::string compilerWorks = "CMAKE_";
@ -421,7 +429,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// CMake(LANG)Compiler.cmake file so that it will get tested the // CMake(LANG)Compiler.cmake file so that it will get tested the
// next time cmake is run // next time cmake is run
if(!mf->IsOn(compilerWorks.c_str())) if(!mf->IsOn(compilerWorks.c_str()))
{ {
fpath = rootBin; fpath = rootBin;
fpath += "/CMake"; fpath += "/CMake";
fpath += lang; fpath += lang;
@ -441,22 +449,22 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
{ {
if(strcmp(lang, "C") == 0) if(strcmp(lang, "C") == 0)
{ {
ifpath = ifpath =
mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake"); mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake");
mf->ReadListFile(0,ifpath.c_str()); mf->ReadListFile(0,ifpath.c_str());
} }
if(strcmp(lang, "CXX") == 0) if(strcmp(lang, "CXX") == 0)
{ {
ifpath = ifpath =
mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake"); mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake");
mf->ReadListFile(0,ifpath.c_str()); mf->ReadListFile(0,ifpath.c_str());
} }
} }
} }
} // end if in try compile } // end if in try compile
} // end need test language } // end need test language
} // end for each language } // end for each language
// Now load files that can override any settings on the platform or for // Now load files that can override any settings on the platform or for
// the project First load the project compatibility file if it is in // the project First load the project compatibility file if it is in
// cmake // cmake
@ -466,14 +474,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
projectCompatibility += "Compatibility.cmake"; projectCompatibility += "Compatibility.cmake";
if(cmSystemTools::FileExists(projectCompatibility.c_str())) if(cmSystemTools::FileExists(projectCompatibility.c_str()))
{ {
mf->ReadListFile(0,projectCompatibility.c_str()); mf->ReadListFile(0,projectCompatibility.c_str());
} }
} }
const char* cmGlobalGenerator const char* cmGlobalGenerator
::GetLanguageOutputExtensionForLanguage(const char* lang) ::GetLanguageOutputExtensionForLanguage(const char* lang)
{ {
if(!lang) if(!lang)
{ {
return ""; return "";
} }
@ -527,7 +535,7 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
{ {
return; return;
} }
std::string outputExtensionVar = std::string("CMAKE_") + std::string outputExtensionVar = std::string("CMAKE_") +
std::string(l) + std::string("_OUTPUT_EXTENSION"); std::string(l) + std::string("_OUTPUT_EXTENSION");
const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str()); const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
if(outputExtension) if(outputExtension)
@ -539,8 +547,8 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
this->OutputExtensions[outputExtension+1] = outputExtension+1; this->OutputExtensions[outputExtension+1] = outputExtension+1;
} }
} }
std::string linkerPrefVar = std::string("CMAKE_") + std::string linkerPrefVar = std::string("CMAKE_") +
std::string(l) + std::string("_LINKER_PREFERENCE"); std::string(l) + std::string("_LINKER_PREFERENCE");
const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str()); const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
if(!linkerPref) if(!linkerPref)
@ -548,10 +556,10 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf)
linkerPref = "None"; linkerPref = "None";
} }
this->LanguageToLinkerPreference[l] = linkerPref; this->LanguageToLinkerPreference[l] = linkerPref;
std::string extensionsVar = std::string("CMAKE_") + std::string extensionsVar = std::string("CMAKE_") +
std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS"); std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS");
std::string ignoreExtensionsVar = std::string("CMAKE_") + std::string ignoreExtensionsVar = std::string("CMAKE_") +
std::string(l) + std::string("_IGNORE_EXTENSIONS"); std::string(l) + std::string("_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str()); std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
std::string exts = mf->GetSafeDefinition(extensionsVar.c_str()); std::string exts = mf->GetSafeDefinition(extensionsVar.c_str());
@ -598,12 +606,12 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
// loop over local gens and get the targets for each one // loop over local gens and get the targets for each one
for(unsigned int i = 0; i < gens->size(); ++i) for(unsigned int i = 0; i < gens->size(); ++i)
{ {
cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets(); cmTargets& targets = (*gens)[i]->GetMakefile()->GetTargets();
for (cmTargets::iterator l = targets.begin(); for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++) l != targets.end(); l++)
{ {
cmTarget& target = l->second; cmTarget& target = l->second;
std::set<cmStdString>::const_iterator pos = std::set<cmStdString>::const_iterator pos =
target.GetUtilities().find(targetIn->GetName()); target.GetUtilities().find(targetIn->GetName());
if(pos != target.GetUtilities().end()) if(pos != target.GetUtilities().end())
{ {
@ -611,7 +619,7 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
} }
} }
} }
return false; return false;
} }
void cmGlobalGenerator::Configure() void cmGlobalGenerator::Configure()
@ -639,10 +647,10 @@ void cmGlobalGenerator::Configure()
lg->GetMakefile()->SetStartOutputDirectory lg->GetMakefile()->SetStartOutputDirectory
(this->CMakeInstance->GetStartOutputDirectory()); (this->CMakeInstance->GetStartOutputDirectory());
lg->GetMakefile()->MakeStartDirectoriesCurrent(); lg->GetMakefile()->MakeStartDirectoriesCurrent();
// now do it // now do it
lg->Configure(); lg->Configure();
// update the cache entry for the number of local generators, this is used // update the cache entry for the number of local generators, this is used
// for progress // for progress
char num[100]; char num[100];
@ -650,7 +658,7 @@ void cmGlobalGenerator::Configure()
this->GetCMakeInstance()->AddCacheEntry this->GetCMakeInstance()->AddCacheEntry
("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num, ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
"number of local generators", cmCacheManager::INTERNAL); "number of local generators", cmCacheManager::INTERNAL);
std::set<cmStdString> notFoundMap; std::set<cmStdString> notFoundMap;
// after it is all done do a ConfigureFinalPass // after it is all done do a ConfigureFinalPass
cmCacheManager* manager = 0; cmCacheManager* manager = 0;
@ -658,8 +666,8 @@ void cmGlobalGenerator::Configure()
{ {
manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
this->LocalGenerators[i]->ConfigureFinalPass(); this->LocalGenerators[i]->ConfigureFinalPass();
cmTargets & targets = cmTargets & targets =
this->LocalGenerators[i]->GetMakefile()->GetTargets(); this->LocalGenerators[i]->GetMakefile()->GetTargets();
for (cmTargets::iterator l = targets.begin(); for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++) l != targets.end(); l++)
{ {
@ -667,23 +675,23 @@ void cmGlobalGenerator::Configure()
for(cmTarget::LinkLibraryVectorType::iterator lib = libs.begin(); for(cmTarget::LinkLibraryVectorType::iterator lib = libs.begin();
lib != libs.end(); ++lib) lib != libs.end(); ++lib)
{ {
if(lib->first.size() > 9 && if(lib->first.size() > 9 &&
cmSystemTools::IsNOTFOUND(lib->first.c_str())) cmSystemTools::IsNOTFOUND(lib->first.c_str()))
{ {
std::string varName = lib->first.substr(0, lib->first.size()-9); std::string varName = lib->first.substr(0, lib->first.size()-9);
notFoundMap.insert(varName); notFoundMap.insert(varName);
} }
} }
std::vector<std::string>& incs = std::vector<std::string>& incs =
this->LocalGenerators[i]->GetMakefile()->GetIncludeDirectories(); this->LocalGenerators[i]->GetMakefile()->GetIncludeDirectories();
for( std::vector<std::string>::iterator lib = incs.begin(); for( std::vector<std::string>::iterator lib = incs.begin();
lib != incs.end(); ++lib) lib != incs.end(); ++lib)
{ {
if(lib->size() > 9 && if(lib->size() > 9 &&
cmSystemTools::IsNOTFOUND(lib->c_str())) cmSystemTools::IsNOTFOUND(lib->c_str()))
{ {
std::string varName = lib->substr(0, lib->size()-9); std::string varName = lib->substr(0, lib->size()-9);
notFoundMap.insert(varName); notFoundMap.insert(varName);
} }
} }
@ -698,11 +706,11 @@ void cmGlobalGenerator::Configure()
std::string notFoundVars; std::string notFoundVars;
for(std::set<cmStdString>::iterator ii = notFoundMap.begin(); for(std::set<cmStdString>::iterator ii = notFoundMap.begin();
ii != notFoundMap.end(); ++ii) ii != notFoundMap.end(); ++ii)
{ {
notFoundVars += *ii; notFoundVars += *ii;
if(manager) if(manager)
{ {
cmCacheManager::CacheIterator it = cmCacheManager::CacheIterator it =
manager->GetCacheIterator(ii->c_str()); manager->GetCacheIterator(ii->c_str());
if(it.GetPropertyAsBool("ADVANCED")) if(it.GetPropertyAsBool("ADVANCED"))
{ {
@ -719,8 +727,8 @@ void cmGlobalGenerator::Configure()
// at this point this->LocalGenerators has been filled, // at this point this->LocalGenerators has been filled,
// so create the map from project name to vector of local generators // so create the map from project name to vector of local generators
this->FillProjectMap(); this->FillProjectMap();
// now create project to target map // now create project to target map
// This will make sure that targets have all the // This will make sure that targets have all the
// targets they depend on as part of the build. // targets they depend on as part of the build.
this->FillProjectToTargetMap(); this->FillProjectToTargetMap();
@ -740,7 +748,7 @@ void cmGlobalGenerator::Generate()
this->CreateDefaultGlobalTargets(&globalTargets); this->CreateDefaultGlobalTargets(&globalTargets);
for (i = 0; i < this->LocalGenerators.size(); ++i) for (i = 0; i < this->LocalGenerators.size(); ++i)
{ {
cmTargets* targets = cmTargets* targets =
&(this->LocalGenerators[i]->GetMakefile()->GetTargets()); &(this->LocalGenerators[i]->GetMakefile()->GetTargets());
cmTargets::iterator tarIt; cmTargets::iterator tarIt;
for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt ) for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt )
@ -762,7 +770,7 @@ void cmGlobalGenerator::Generate()
(*targets)[tit->first].SetMakefile(mf); (*targets)[tit->first].SetMakefile(mf);
} }
} }
// Add generator specific helper commands // Add generator specific helper commands
for (i = 0; i < this->LocalGenerators.size(); ++i) for (i = 0; i < this->LocalGenerators.size(); ++i)
{ {
@ -788,14 +796,20 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->Generate(); this->LocalGenerators[i]->Generate();
this->LocalGenerators[i]->GenerateInstallRules(); this->LocalGenerators[i]->GenerateInstallRules();
this->LocalGenerators[i]->GenerateTestFiles(); this->LocalGenerators[i]->GenerateTestFiles();
this->CMakeInstance->UpdateProgress("Generating", this->CMakeInstance->UpdateProgress("Generating",
(i+1.0f)/this->LocalGenerators.size()); (i+1.0f)/this->LocalGenerators.size());
} }
if (this->ExtraGenerator != 0)
{
this->ExtraGenerator->Generate();
}
this->CMakeInstance->UpdateProgress("Generating done", -1); this->CMakeInstance->UpdateProgress("Generating done", -1);
} }
int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
const char *projectName, const char *projectName,
const char *target, const char *target,
std::string *output, cmMakefile *mf) std::string *output, cmMakefile *mf)
{ {
@ -815,7 +829,7 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
#if 0 #if 0
#if defined(_WIN32) || defined(__CYGWIN__) #if defined(_WIN32) || defined(__CYGWIN__)
std::string tmp = target; std::string tmp = target;
// if the target does not already end in . something // if the target does not already end in . something
// then assume .exe // then assume .exe
if(tmp.size() < 4 || tmp[tmp.size()-4] != '.') if(tmp.size() < 4 || tmp[tmp.size()-4] != '.')
{ {
@ -827,12 +841,12 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
return this->Build(srcdir,bindir,projectName, return this->Build(srcdir,bindir,projectName,
newTarget.c_str(), newTarget.c_str(),
output,makeCommand.c_str(),config,false,true, output,makeCommand.c_str(),config,false,true,
this->TryCompileTimeout); this->TryCompileTimeout);
} }
std::string cmGlobalGenerator std::string cmGlobalGenerator
::GenerateBuildCommand(const char* makeProgram, const char *projectName, ::GenerateBuildCommand(const char* makeProgram, const char *projectName,
const char* additionalOptions, const char *targetName, const char* additionalOptions, const char *targetName,
const char* config, bool ignoreErrors, bool) const char* config, bool ignoreErrors, bool)
{ {
@ -840,7 +854,7 @@ std::string cmGlobalGenerator
(void)projectName; (void)projectName;
(void)config; (void)config;
std::string makeCommand = std::string makeCommand =
cmSystemTools::ConvertToUnixOutputPath(makeProgram); cmSystemTools::ConvertToUnixOutputPath(makeProgram);
// Since we have full control over the invocation of nmake, let us // Since we have full control over the invocation of nmake, let us
@ -865,18 +879,18 @@ std::string cmGlobalGenerator
} }
return makeCommand; return makeCommand;
} }
int cmGlobalGenerator::Build( int cmGlobalGenerator::Build(
const char *, const char *bindir, const char *, const char *bindir,
const char *projectName, const char *target, const char *projectName, const char *target,
std::string *output, std::string *output,
const char *makeCommandCSTR, const char *makeCommandCSTR,
const char *config, const char *config,
bool clean, bool fast, bool clean, bool fast,
double timeout) double timeout)
{ {
*output += "\nTesting TryCompileWithoutMakefile\n"; *output += "\nTesting TryCompileWithoutMakefile\n";
/** /**
* Run an executable command and put the stdout in output. * Run an executable command and put the stdout in output.
*/ */
@ -890,10 +904,10 @@ int cmGlobalGenerator::Build(
// should we do a clean first? // should we do a clean first?
if (clean) if (clean)
{ {
std::string cleanCommand = std::string cleanCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, this->GenerateBuildCommand(makeCommandCSTR, projectName,
0, "clean", config, false, fast); 0, "clean", config, false, fast);
if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), output, if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), output,
&retVal, 0, false, timeout)) &retVal, 0, false, timeout))
{ {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
@ -902,19 +916,19 @@ int cmGlobalGenerator::Build(
{ {
*output += "\nGenerator: execution of make clean failed.\n"; *output += "\nGenerator: execution of make clean failed.\n";
} }
// return to the original directory // return to the original directory
cmSystemTools::ChangeDirectory(cwd.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str());
return 1; return 1;
} }
} }
// now build // now build
std::string makeCommand = std::string makeCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, this->GenerateBuildCommand(makeCommandCSTR, projectName,
0, target, config, false, fast); 0, target, config, false, fast);
if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output, if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output,
&retVal, 0, false, timeout)) &retVal, 0, false, timeout))
{ {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
@ -923,17 +937,17 @@ int cmGlobalGenerator::Build(
makeCommand.c_str()); makeCommand.c_str());
if (output) if (output)
{ {
*output += "\nGenerator: execution of make failed. Make command was: " *output += "\nGenerator: execution of make failed. Make command was: "
+ makeCommand + "\n"; + makeCommand + "\n";
} }
// return to the original directory // return to the original directory
cmSystemTools::ChangeDirectory(cwd.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str());
return 1; return 1;
} }
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
// The SGI MipsPro 7.3 compiler does not return an error code when // The SGI MipsPro 7.3 compiler does not return an error code when
// the source has a #error in it! This is a work-around for such // the source has a #error in it! This is a work-around for such
// compilers. // compilers.
@ -941,26 +955,26 @@ int cmGlobalGenerator::Build(
{ {
retVal = 1; retVal = 1;
} }
cmSystemTools::ChangeDirectory(cwd.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str());
return retVal; return retVal;
} }
void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg) void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
{ {
this->LocalGenerators.push_back(lg); this->LocalGenerators.push_back(lg);
// update progress // update progress
// estimate how many lg there will be // estimate how many lg there will be
const char *numGenC = const char *numGenC =
this->CMakeInstance->GetCacheManager()->GetCacheValue this->CMakeInstance->GetCacheManager()->GetCacheValue
("CMAKE_NUMBER_OF_LOCAL_GENERATORS"); ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
if (!numGenC) if (!numGenC)
{ {
return; return;
} }
int numGen = atoi(numGenC); int numGen = atoi(numGenC);
float prog = 0.9f*this->LocalGenerators.size()/numGen; float prog = 0.9f*this->LocalGenerators.size()/numGen;
if (prog > 0.9f) if (prog > 0.9f)
@ -1017,7 +1031,7 @@ void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
entry.full = ""; entry.full = "";
} }
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
cmLocalGenerator* gen) cmLocalGenerator* gen)
{ {
if(gen == root) if(gen == root)
@ -1039,7 +1053,7 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
{ {
for(std::map<cmStdString, bool>::iterator i = for(std::map<cmStdString, bool>::iterator i =
this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i) this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i)
{ {
lang.push_back(i->first); lang.push_back(i->first);
@ -1056,15 +1070,15 @@ const char* cmGlobalGenerator::GetLinkerPreference(const char* lang)
} }
void cmGlobalGenerator::FillProjectMap() void cmGlobalGenerator::FillProjectMap()
{ {
this->ProjectMap.clear(); // make sure we start with a clean map this->ProjectMap.clear(); // make sure we start with a clean map
unsigned int i; unsigned int i;
for(i = 0; i < this->LocalGenerators.size(); ++i) for(i = 0; i < this->LocalGenerators.size(); ++i)
{ {
// for each local generator add all projects // for each local generator add all projects
cmLocalGenerator *lg = this->LocalGenerators[i]; cmLocalGenerator *lg = this->LocalGenerators[i];
std::string name; std::string name;
do do
{ {
if (name != lg->GetMakefile()->GetProjectName()) if (name != lg->GetMakefile()->GetProjectName())
{ {
@ -1082,8 +1096,8 @@ void cmGlobalGenerator::FillProjectMap()
void cmGlobalGenerator::FillProjectToTargetMap() void cmGlobalGenerator::FillProjectToTargetMap()
{ {
// loop over each project in the build // loop over each project in the build
for(std::map<cmStdString, for(std::map<cmStdString,
std::vector<cmLocalGenerator*> >::iterator m = std::vector<cmLocalGenerator*> >::iterator m =
this->ProjectMap.begin(); this->ProjectMap.begin();
m != this->ProjectMap.end(); ++m) m != this->ProjectMap.end(); ++m)
{ {
@ -1098,9 +1112,9 @@ void cmGlobalGenerator::FillProjectToTargetMap()
const char* exclude = 0; const char* exclude = 0;
std::string excludeSave; std::string excludeSave;
bool chain = false; bool chain = false;
exclude = exclude =
projectMakefile->GetProperties(). projectMakefile->GetProperties().
GetPropertyValue("EXCLUDE_FROM_ALL", GetPropertyValue("EXCLUDE_FROM_ALL",
cmProperty::DIRECTORY, chain); cmProperty::DIRECTORY, chain);
if(exclude) if(exclude)
{ {
@ -1112,7 +1126,7 @@ void cmGlobalGenerator::FillProjectToTargetMap()
// now loop over all cmLocalGenerators in this project and pull // now loop over all cmLocalGenerators in this project and pull
// out all the targets that depend on each other, even if those // out all the targets that depend on each other, even if those
// targets come from a target that is excluded. // targets come from a target that is excluded.
for(std::vector<cmLocalGenerator*>::iterator lg = for(std::vector<cmLocalGenerator*>::iterator lg =
lgs.begin(); lg != lgs.end(); ++lg) lgs.begin(); lg != lgs.end(); ++lg)
{ {
cmMakefile* mf = (*lg)->GetMakefile(); cmMakefile* mf = (*lg)->GetMakefile();
@ -1121,7 +1135,7 @@ void cmGlobalGenerator::FillProjectToTargetMap()
t != targets.end(); ++t) t != targets.end(); ++t)
{ {
cmTarget& target = t->second; cmTarget& target = t->second;
// if the target is in all then add it to the project // if the target is in all then add it to the project
if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{ {
// add this target to the project // add this target to the project
@ -1131,9 +1145,9 @@ void cmGlobalGenerator::FillProjectToTargetMap()
this->ProjectToTargetMap[projectName].insert(tgtdeps.begin(), this->ProjectToTargetMap[projectName].insert(tgtdeps.begin(),
tgtdeps.end()); tgtdeps.end());
} }
} }
} }
// Now restore the EXCLUDE_FROM_ALL property on the project top // Now restore the EXCLUDE_FROM_ALL property on the project top
// makefile // makefile
if(exclude) if(exclude)
{ {
@ -1141,13 +1155,13 @@ void cmGlobalGenerator::FillProjectToTargetMap()
} }
projectMakefile->SetProperty("EXCLUDE_FROM_ALL", exclude); projectMakefile->SetProperty("EXCLUDE_FROM_ALL", exclude);
} }
// dump the map for debug purposes // dump the map for debug purposes
// right now this map is not being used, but it was // right now this map is not being used, but it was
// checked in to avoid constant conflicts. // checked in to avoid constant conflicts.
// It is also the first step to creating sub projects // It is also the first step to creating sub projects
// that contain all of the targets they need. // that contain all of the targets they need.
#if 0 #if 0
std::map<cmStdString, std::set<cmTarget*> >::iterator i = std::map<cmStdString, std::set<cmTarget*> >::iterator i =
this->ProjectToTargetMap.begin(); this->ProjectToTargetMap.begin();
for(; i != this->ProjectToTargetMap.end(); ++i) for(; i != this->ProjectToTargetMap.end(); ++i)
{ {
@ -1179,7 +1193,7 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
} }
cmTarget* cmGlobalGenerator::FindTarget(const char* project, cmTarget* cmGlobalGenerator::FindTarget(const char* project,
const char* name, const char* name,
bool useImportedTargets) bool useImportedTargets)
{ {
@ -1189,7 +1203,7 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project]; std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
for(unsigned int i = 0; i < gens->size(); ++i) for(unsigned int i = 0; i < gens->size(); ++i)
{ {
cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name, cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
useImportedTargets); useImportedTargets);
if(ret) if(ret)
{ {
@ -1206,7 +1220,7 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
{ {
return i->second; return i->second;
} }
if ( useImportedTargets ) if ( useImportedTargets )
{ {
std::map<cmStdString,cmTarget *>::iterator importedTarget = std::map<cmStdString,cmTarget *>::iterator importedTarget =
@ -1271,7 +1285,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
const char* packageSourceTargetName = this->GetPackageSourceTargetName(); const char* packageSourceTargetName = this->GetPackageSourceTargetName();
if ( packageSourceTargetName ) if ( packageSourceTargetName )
{ {
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end()); cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end()); singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end()); depends.erase(depends.begin(), depends.end());
@ -1293,7 +1307,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
// Test // Test
if(mf->IsOn("CMAKE_TESTING_ENABLED")) if(mf->IsOn("CMAKE_TESTING_ENABLED"))
{ {
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end()); cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end()); singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end()); depends.erase(depends.begin(), depends.end());
@ -1318,7 +1332,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
const char* editCacheTargetName = this->GetEditCacheTargetName(); const char* editCacheTargetName = this->GetEditCacheTargetName();
if ( editCacheTargetName ) if ( editCacheTargetName )
{ {
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end()); cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end()); singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end()); depends.erase(depends.begin(), depends.end());
@ -1344,7 +1358,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.push_back(singleLine); cpackCommandLines.push_back(singleLine);
(*targets)[editCacheTargetName] = (*targets)[editCacheTargetName] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
editCacheTargetName, editCacheTargetName,
"Running interactive CMake command-line interface...", "Running interactive CMake command-line interface...",
&cpackCommandLines, depends); &cpackCommandLines, depends);
} }
@ -1354,7 +1368,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName(); const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
if ( rebuildCacheTargetName ) if ( rebuildCacheTargetName )
{ {
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end()); cpackCommandLines.end());
singleLine.erase(singleLine.begin(), singleLine.end()); singleLine.erase(singleLine.begin(), singleLine.end());
depends.erase(depends.begin(), depends.end()); depends.erase(depends.begin(), depends.end());
@ -1374,7 +1388,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.') if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.')
{ {
std::set<cmStdString>* componentsSet = &this->InstallComponents; std::set<cmStdString>* componentsSet = &this->InstallComponents;
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
cpackCommandLines.end()); cpackCommandLines.end());
depends.erase(depends.begin(), depends.end()); depends.erase(depends.begin(), depends.end());
cmOStringStream ostr; cmOStringStream ostr;
@ -1535,21 +1549,21 @@ std::vector<cmTarget *>& cmGlobalGenerator
::GetTargetDepends(cmTarget& target) ::GetTargetDepends(cmTarget& target)
{ {
// if the depends are already in the map then return // if the depends are already in the map then return
std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI = std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI =
this->TargetDependencies.find(target.GetName()); this->TargetDependencies.find(target.GetName());
if (tgtI != this->TargetDependencies.end()) if (tgtI != this->TargetDependencies.end())
{ {
return tgtI->second; return tgtI->second;
} }
// A target should not depend on itself. // A target should not depend on itself.
std::set<cmStdString> emitted; std::set<cmStdString> emitted;
emitted.insert(target.GetName()); emitted.insert(target.GetName());
// the vector of results // the vector of results
std::vector<cmTarget *>& result = std::vector<cmTarget *>& result =
this->TargetDependencies[target.GetName()]; this->TargetDependencies[target.GetName()];
// Loop over all library dependencies but not for static libs // Loop over all library dependencies but not for static libs
if (target.GetType() != cmTarget::STATIC_LIBRARY) if (target.GetType() != cmTarget::STATIC_LIBRARY)
{ {
@ -1560,7 +1574,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
// Don't emit the same library twice for this target. // Don't emit the same library twice for this target.
if(emitted.insert(lib->first).second) if(emitted.insert(lib->first).second)
{ {
cmTarget *target2 = cmTarget *target2 =
target.GetMakefile()->FindTarget(lib->first.c_str(), false); target.GetMakefile()->FindTarget(lib->first.c_str(), false);
// search each local generator until a match is found // search each local generator until a match is found
@ -1568,7 +1582,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
{ {
target2 = this->FindTarget(0,lib->first.c_str(), false); target2 = this->FindTarget(0,lib->first.c_str(), false);
} }
// if a match was found then ... // if a match was found then ...
if (target2) if (target2)
{ {
@ -1578,7 +1592,7 @@ std::vector<cmTarget *>& cmGlobalGenerator
} }
} }
} }
// Loop over all utility dependencies. // Loop over all utility dependencies.
const std::set<cmStdString>& tutils = target.GetUtilities(); const std::set<cmStdString>& tutils = target.GetUtilities();
for(std::set<cmStdString>::const_iterator util = tutils.begin(); for(std::set<cmStdString>::const_iterator util = tutils.begin();
@ -1588,13 +1602,13 @@ std::vector<cmTarget *>& cmGlobalGenerator
if(emitted.insert(*util).second) if(emitted.insert(*util).second)
{ {
cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str(), false); cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str(), false);
// search each local generator until a match is found // search each local generator until a match is found
if (!target2) if (!target2)
{ {
target2 = this->FindTarget(0,util->c_str(), false); target2 = this->FindTarget(0,util->c_str(), false);
} }
// if a match was found then ... // if a match was found then ...
if (target2) if (target2)
{ {
@ -1617,3 +1631,14 @@ void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
this->TotalTargets[v.first] = &v.second; this->TotalTargets[v.first] = &v.second;
} }
} }
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator *extraGenerator)
{
this->ExtraGenerator = extraGenerator;
if (this->ExtraGenerator!=0)
{
this->ExtraGenerator->SetGlobalGenerator(this);
}
}

View File

@ -19,6 +19,7 @@
#define cmGlobalGenerator_h #define cmGlobalGenerator_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmTarget.h" // For cmTargets #include "cmTarget.h" // For cmTargets
@ -123,6 +124,13 @@ public:
void AddLocalGenerator(cmLocalGenerator *lg); void AddLocalGenerator(cmLocalGenerator *lg);
///! Set an generator for an "external makefile based project"
void SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator *extraGenerator);
const char* GetExtraGeneratorName() const
{return this->ExtraGenerator!=0 ? this->ExtraGenerator->GetName():0;}
void AddInstallComponent(const char* component); void AddInstallComponent(const char* component);
void EnableInstallTarget(); void EnableInstallTarget();
@ -130,6 +138,8 @@ public:
bool GetForceUnixPaths() {return this->ForceUnixPaths;} bool GetForceUnixPaths() {return this->ForceUnixPaths;}
bool GetToolSupportsColor() { return this->ToolSupportsColor; } bool GetToolSupportsColor() { return this->ToolSupportsColor; }
bool SetToolSupportsColor(bool enable) { this->ToolSupportsColor = enable; }
///! return the language for the given extension ///! return the language for the given extension
const char* GetLanguageFromExtension(const char* ext); const char* GetLanguageFromExtension(const char* ext);
///! is an extension to be ignored ///! is an extension to be ignored
@ -196,6 +206,7 @@ public:
// what targets does the specified target depend on // what targets does the specified target depend on
std::vector<cmTarget *>& GetTargetDepends(cmTarget& target); std::vector<cmTarget *>& GetTargetDepends(cmTarget& target);
const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap() const {return this->ProjectMap;}
protected: protected:
// Fill the ProjectMap, this must be called after LocalGenerators // Fill the ProjectMap, this must be called after LocalGenerators
// has been populated. // has been populated.
@ -242,6 +253,8 @@ private:
std::map<cmStdString,cmTarget *> ImportedTotalTargets; std::map<cmStdString,cmTarget *> ImportedTotalTargets;
std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies; std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies;
cmExternalMakefileProjectGenerator* ExtraGenerator;
}; };
#endif #endif

View File

@ -17,6 +17,7 @@
=========================================================================*/ =========================================================================*/
#include "cmGlobalKdevelopGenerator.h" #include "cmGlobalKdevelopGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmake.h" #include "cmake.h"
@ -25,18 +26,9 @@
#include <cmsys/SystemTools.hxx> #include <cmsys/SystemTools.hxx>
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
{
// This type of makefile always requires unix style paths
this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
this->ToolSupportsColor = false;
this->SetForceVerboseMakefiles(true);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalKdevelopGenerator void cmGlobalKdevelopGenerator
::GetDocumentation(cmDocumentationEntry& entry) const ::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{ {
entry.name = this->GetName(); entry.name = this->GetName();
entry.brief = "Generates KDevelop 3 project files."; entry.brief = "Generates KDevelop 3 project files.";
@ -52,13 +44,31 @@ void cmGlobalKdevelopGenerator
"default make target. A \"make install\" target is also provided."; "default make target. A \"make install\" target is also provided.";
} }
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
:cmExternalMakefileProjectGenerator()
{
this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}
void cmGlobalKdevelopGenerator::SetGlobalGenerator(
cmGlobalGenerator* generator)
{
cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
generator;
mf->SetToolSupportsColor(false);
mf->SetForceVerboseMakefiles(true);
}
void cmGlobalKdevelopGenerator::Generate() void cmGlobalKdevelopGenerator::Generate()
{ {
this->cmGlobalUnixMakefileGenerator3::Generate();
// for each sub project in the project create // for each sub project in the project create
// a kdevelop project // a kdevelop project
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it) it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
{ {
cmMakefile* mf = it->second[0]->GetMakefile(); cmMakefile* mf = it->second[0]->GetMakefile();
std::string outputDir=mf->GetStartOutputDirectory(); std::string outputDir=mf->GetStartOutputDirectory();
@ -66,10 +76,9 @@ void cmGlobalKdevelopGenerator::Generate()
std::string projectName=mf->GetProjectName(); std::string projectName=mf->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;"); std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
std::string fileToOpen; std::string fileToOpen;
std::vector<cmLocalGenerator*>& lgs= it->second; const std::vector<cmLocalGenerator*>& lgs= it->second;
// create the project.kdevelop.filelist file // create the project.kdevelop.filelist file
if(!this->CreateFilelistFile(it->second[0], lgs, if(!this->CreateFilelistFile(lgs, outputDir, projectDir,
outputDir, projectDir,
projectName, cmakeFilePattern, fileToOpen)) projectName, cmakeFilePattern, fileToOpen))
{ {
cmSystemTools::Error("Can not create filelist file"); cmSystemTools::Error("Can not create filelist file");
@ -104,8 +113,7 @@ void cmGlobalKdevelopGenerator::Generate()
} }
bool cmGlobalKdevelopGenerator bool cmGlobalKdevelopGenerator
::CreateFilelistFile(cmLocalGenerator* , ::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir, const std::string& outputDir,
const std::string& projectDirIn, const std::string& projectDirIn,
const std::string& projectname, const std::string& projectname,
@ -252,7 +260,7 @@ bool cmGlobalKdevelopGenerator
} }
} }
return true; return true;
} }
/* create the project file, if it already exists, merge it with the /* create the project file, if it already exists, merge it with the

View File

@ -18,7 +18,9 @@
#ifndef cmGlobalKdevelopGenerator_h #ifndef cmGlobalKdevelopGenerator_h
#define cmGlobalKdevelopGenerator_h #define cmGlobalKdevelopGenerator_h
#include "cmGlobalUnixMakefileGenerator3.h" #include "cmExternalMakefileProjectGenerator.h"
class cmLocalGenerator;
/** \class cmGlobalKdevelopGenerator /** \class cmGlobalKdevelopGenerator
* \brief Write Unix Makefiles accompanied by KDevelop3 project files. * \brief Write Unix Makefiles accompanied by KDevelop3 project files.
@ -31,32 +33,27 @@
* file, which lists the source files relative to the kdevelop project * file, which lists the source files relative to the kdevelop project
* directory. The kdevelop project directory is the base source directory. * directory. The kdevelop project directory is the base source directory.
*/ */
class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator3 class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
{ {
public: public:
cmGlobalKdevelopGenerator(); cmGlobalKdevelopGenerator();
static cmGlobalGenerator* New() { return new cmGlobalKdevelopGenerator; } virtual void SetGlobalGenerator(cmGlobalGenerator* generator);
///! Get the name for the generator.
virtual const char* GetName() const {
return cmGlobalKdevelopGenerator::GetActualName();}
static const char* GetActualName() {return "KDevelop3";}
virtual const char* GetName() const
{ return cmGlobalKdevelopGenerator::GetActualName();}
static const char* GetActualName() { return "KDevelop3";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmGlobalKdevelopGenerator; }
/** Get the documentation entry for this generator. */ /** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry) const; virtual void GetDocumentation(cmDocumentationEntry& entry,
const char* fullName) const;
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
* requests that they Generate.
*/
virtual void Generate();
virtual void Generate();
private:
/*** Create the foo.kdevelop.filelist file, return false if it doesn't /*** Create the foo.kdevelop.filelist file, return false if it doesn't
succeed. If the file already exists the contents will be merged. succeed. If the file already exists the contents will be merged.
*/ */
bool CreateFilelistFile(cmLocalGenerator* lg, bool CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir, const std::string& outputDir,
const std::string& projectDirIn, const std::string& projectDirIn,
const std::string& projectname, const std::string& projectname,
@ -95,6 +92,7 @@ public:
const std::string& fileToOpen, const std::string& fileToOpen,
const std::string& sessionFilename); const std::string& sessionFilename);
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -169,6 +169,7 @@ cmake::cmake()
#endif #endif
this->AddDefaultGenerators(); this->AddDefaultGenerators();
this->AddDefaultExtraGenerators();
this->AddDefaultCommands(); this->AddDefaultCommands();
// Make sure we can capture the build tool output. // Make sure we can capture the build tool output.
@ -1405,6 +1406,40 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
return 1; return 1;
} }
void cmake::AddExtraGenerator(const char* name,
CreateExtraGeneratorFunctionType newFunction)
{
this->ExtraGenerators[name] = newFunction;
cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
const std::vector<std::string>& supportedGlobalGenerators =
extraGenerator->GetSupportedGlobalGenerators();
for(std::vector<std::string>::const_iterator
it = supportedGlobalGenerators.begin();
it != supportedGlobalGenerators.end();
++it )
{
std::string fullName = cmExternalMakefileProjectGenerator::
CreateFullGeneratorName(it->c_str(), name);
this->ExtraGenerators[fullName.c_str()] = newFunction;
}
delete extraGenerator;
}
void cmake::AddDefaultExtraGenerators()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
// e.g. codeblocks, kdevelop4 ?
# endif
#endif
// e.g. eclipse ?
#ifdef CMAKE_USE_KDEVELOP
this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), &cmGlobalKdevelopGenerator::New);
#endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmake::GetRegisteredGenerators(std::vector<std::string>& names) void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
{ {
@ -1417,17 +1452,30 @@ void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name) cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
{ {
RegisteredGeneratorsMap::const_iterator i = this->Generators.find(name); cmGlobalGenerator* generator = 0;
if(i != this->Generators.end()) cmExternalMakefileProjectGenerator* extraGenerator = 0;
RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name);
if(genIt == this->Generators.end())
{ {
cmGlobalGenerator* generator = (i->second)(); RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
generator->SetCMakeInstance(this); this->ExtraGenerators.find(name);
return generator; if (extraGenIt == this->ExtraGenerators.end())
} {
else return 0;
{ }
return 0; extraGenerator = (extraGenIt->second)();
} genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name));
if(genIt == this->Generators.end())
{
delete extraGenerator;
return 0;
}
}
generator = (genIt->second)();
generator->SetCMakeInstance(this);
generator->SetExternalMakefileProjectGenerator(extraGenerator);
return generator;
} }
void cmake::SetHomeDirectory(const char* dir) void cmake::SetHomeDirectory(const char* dir)
@ -1599,9 +1647,13 @@ int cmake::Configure()
{ {
const char* genName = const char* genName =
this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
const char* extraGenName =
this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
if(genName) if(genName)
{ {
this->GlobalGenerator = this->CreateGlobalGenerator(genName); std::string fullName = cmExternalMakefileProjectGenerator::
CreateFullGeneratorName(genName, extraGenName);
this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str());
} }
if(this->GlobalGenerator) if(this->GlobalGenerator)
{ {
@ -1688,6 +1740,10 @@ int cmake::Configure()
this->GlobalGenerator->GetName(), this->GlobalGenerator->GetName(),
"Name of generator.", "Name of generator.",
cmCacheManager::INTERNAL); cmCacheManager::INTERNAL);
this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
this->GlobalGenerator->GetExtraGeneratorName(),
"Name of external makefile project generator.",
cmCacheManager::INTERNAL);
} }
// reset any system configuration information, except for when we are // reset any system configuration information, except for when we are
@ -1750,6 +1806,7 @@ int cmake::Configure()
// We must have a bad generator selection. Wipe the cache entry so the // We must have a bad generator selection. Wipe the cache entry so the
// user can select another. // user can select another.
this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR"); this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
this->CacheManager->RemoveCacheEntry("CMAKE_EMP_GENERATOR");
} }
// only save the cache if there were no fatal errors // only save the cache if there were no fatal errors
if ( !this->ScriptMode ) if ( !this->ScriptMode )
@ -2001,10 +2058,6 @@ void cmake::AddDefaultGenerators()
this->Generators[cmGlobalXCodeGenerator::GetActualName()] = this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
&cmGlobalXCodeGenerator::New; &cmGlobalXCodeGenerator::New;
#endif #endif
#ifdef CMAKE_USE_KDEVELOP
this->Generators[cmGlobalKdevelopGenerator::GetActualName()] =
&cmGlobalKdevelopGenerator::New;
#endif
} }
int cmake::LoadCache() int cmake::LoadCache()
@ -2121,6 +2174,16 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
delete generator; delete generator;
v.push_back(e); v.push_back(e);
} }
for(RegisteredExtraGeneratorsMap::const_iterator
i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
{
cmDocumentationEntry e;
cmExternalMakefileProjectGenerator* generator = (i->second)();
generator->GetDocumentation(e, i->first.c_str());
e.name = i->first.c_str();
delete generator;
v.push_back(e);
}
cmDocumentationEntry empty = {0,0,0}; cmDocumentationEntry empty = {0,0,0};
v.push_back(empty); v.push_back(empty);
} }

View File

@ -51,6 +51,7 @@ class cmMakefile;
class cmCommand; class cmCommand;
class cmVariableWatch; class cmVariableWatch;
class cmFileTimeComparison; class cmFileTimeComparison;
class cmExternalMakefileProjectGenerator;
class cmake class cmake
{ {
@ -305,14 +306,22 @@ protected:
cmPropertyDefinitionMap DirectoryProperties; cmPropertyDefinitionMap DirectoryProperties;
cmPropertyDefinitionMap TestProperties; cmPropertyDefinitionMap TestProperties;
cmPropertyDefinitionMap GlobalProperties; cmPropertyDefinitionMap GlobalProperties;
typedef
cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
typedef std::map<cmStdString,
CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)(); typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
typedef std::map<cmStdString, typedef std::map<cmStdString,
CreateGeneratorFunctionType> RegisteredGeneratorsMap; CreateGeneratorFunctionType> RegisteredGeneratorsMap;
RegisteredCommandsMap Commands; RegisteredCommandsMap Commands;
RegisteredGeneratorsMap Generators; RegisteredGeneratorsMap Generators;
RegisteredExtraGeneratorsMap ExtraGenerators;
void AddDefaultCommands(); void AddDefaultCommands();
void AddDefaultGenerators(); void AddDefaultGenerators();
void AddDefaultExtraGenerators();
void AddExtraGenerator(const char* name, CreateExtraGeneratorFunctionType newFunction);
cmGlobalGenerator *GlobalGenerator; cmGlobalGenerator *GlobalGenerator;
cmCacheManager *CacheManager; cmCacheManager *CacheManager;