summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt4
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx52
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h2
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx7
-rw-r--r--Source/CPack/cmCPackBundleGenerator.h1
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx202
-rw-r--r--Source/CPack/cmCPackDebGenerator.h6
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx106
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h7
-rw-r--r--Source/CPack/cmCPackGenerator.cxx125
-rw-r--r--Source/CPack/cmCPackGenerator.h33
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx27
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx151
-rw-r--r--Source/CPack/cmCPackRPMGenerator.h6
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx14
-rw-r--r--Source/CTest/cmCTestRunTest.cxx42
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx2
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx49
-rw-r--r--Source/CTest/cmCTestTestHandler.h2
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx69
-rw-r--r--Source/CTest/cmCTestUploadCommand.h85
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx77
-rw-r--r--Source/CTest/cmCTestUploadHandler.h45
-rw-r--r--Source/cmAddCustomCommandCommand.cxx12
-rw-r--r--Source/cmAddCustomTargetCommand.cxx6
-rw-r--r--Source/cmArchiveWrite.cxx3
-rw-r--r--Source/cmCPluginAPI.cxx2
-rw-r--r--Source/cmCTest.cxx136
-rw-r--r--Source/cmCTest.h17
-rw-r--r--Source/cmDocumentVariables.cxx22
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx15
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h3
-rw-r--r--Source/cmFileCommand.cxx42
-rw-r--r--Source/cmFileCommand.h13
-rw-r--r--Source/cmFindBase.cxx12
-rw-r--r--Source/cmFindLibraryCommand.cxx4
-rw-r--r--Source/cmFindPackageCommand.cxx176
-rw-r--r--Source/cmFindPackageCommand.h11
-rw-r--r--Source/cmFindPathCommand.cxx2
-rw-r--r--Source/cmFindProgramCommand.cxx2
-rw-r--r--Source/cmGeneratorExpression.cxx2
-rw-r--r--Source/cmGlobalGenerator.cxx2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx205
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx223
-rw-r--r--Source/cmGlobalXCodeGenerator.h4
-rw-r--r--Source/cmGraphVizWriter.cxx190
-rw-r--r--Source/cmGraphVizWriter.h11
-rw-r--r--Source/cmIncludeDirectoryCommand.h2
-rw-r--r--Source/cmLocalGenerator.cxx1
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx12
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx4
-rw-r--r--Source/cmLocalVisualStudio10Generator.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx10
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx56
-rw-r--r--Source/cmLocalVisualStudioGenerator.h10
-rw-r--r--Source/cmMakefileTargetGenerator.cxx133
-rw-r--r--Source/cmMakefileTargetGenerator.h6
-rw-r--r--Source/cmOutputRequiredFilesCommand.h13
-rw-r--r--Source/cmScriptGenerator.cxx14
-rw-r--r--Source/cmScriptGenerator.h2
-rw-r--r--Source/cmSourceGroupCommand.cxx34
-rw-r--r--Source/cmStringCommand.cxx8
-rw-r--r--Source/cmStringCommand.h3
-rw-r--r--Source/cmSystemTools.cxx120
-rw-r--r--Source/cmSystemTools.h8
-rw-r--r--Source/cmTestGenerator.cxx16
-rw-r--r--Source/cmTestGenerator.h2
-rw-r--r--Source/cmTryCompileCommand.h16
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx58
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx7
-rw-r--r--Source/cmXCodeObject.cxx30
-rw-r--r--Source/cmXCodeObject.h15
-rw-r--r--Source/cmake.cxx48
-rw-r--r--Source/cmake.h4
-rw-r--r--Source/cmakemain.cxx3
-rw-r--r--Source/kwsys/CheckCXXSourceRuns.cmake62
-rw-r--r--Source/kwsys/EncodeExecutable.c1
-rw-r--r--Source/kwsys/Terminal.c2
-rw-r--r--Source/kwsys/kwsysDateStamp.cmake4
81 files changed, 2082 insertions, 863 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 278d4df..ca063d5 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -266,7 +266,7 @@ IF(UNIX)
SET(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx)
ENDIF(UNIX)
-# XCode only works on apple
+# Xcode only works on Apple
IF(APPLE)
SET(SRCS ${SRCS}
cmXCodeObject.cxx
@@ -394,6 +394,8 @@ SET(CTEST_SRCS cmCTest.cxx
CTest/cmCTestTestHandler.cxx
CTest/cmCTestUpdateCommand.cxx
CTest/cmCTestUpdateHandler.cxx
+ CTest/cmCTestUploadCommand.cxx
+ CTest/cmCTestUploadHandler.cxx
CTest/cmCTestVC.cxx
CTest/cmCTestVC.h
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index b629c63..0ce5b01 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -207,7 +207,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
}
//----------------------------------------------------------------------
-int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponent)
+int cmCPackArchiveGenerator::PackageComponentsAllInOne()
{
// reset the package file names
packageFileNames.clear();
@@ -221,38 +221,15 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponent)
<< std::endl);
DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive);
- // The ALL GROUP in ONE package case
- if (! allComponent) {
- // iterate over the component groups
- std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
- for (compGIt=this->ComponentGroups.begin();
- compGIt!=this->ComponentGroups.end(); ++compGIt)
- {
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
- << compGIt->first
- << std::endl);
- // now iterate over the component of this group
- std::vector<cmCPackComponent*>::iterator compIt;
- for (compIt=(compGIt->second).Components.begin();
- compIt!=(compGIt->second).Components.end();
- ++compIt)
- {
- // Add the files of this component to the archive
- addOneComponentToArchive(archive,*compIt);
- }
- }
- }
- // The ALL COMPONENT in ONE package case
- else
+ // The ALL COMPONENTS in ONE package case
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();compIt!=this->Components.end();
+ ++compIt )
{
- std::map<std::string, cmCPackComponent>::iterator compIt;
- for (compIt=this->Components.begin();compIt!=this->Components.end();
- ++compIt )
- {
- // Add the files of this component to the archive
- addOneComponentToArchive(archive,&(compIt->second));
- }
+ // Add the files of this component to the archive
+ addOneComponentToArchive(archive,&(compIt->second));
}
+
// archive goes out of scope so it will finalized and closed.
return 1;
}
@@ -265,21 +242,20 @@ int cmCPackArchiveGenerator::PackageFiles()
if (SupportsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
- // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
+ // If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (allComponentInOne ||
- (allGroupInOne && (!this->ComponentGroups.empty()))
- )
+ if (componentPackageMethod == ONE_PACKAGE)
{
- return PackageComponentsAllInOne(allComponentInOne);
+ return PackageComponentsAllInOne();
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup))
+ else
{
- return PackageComponents(ignoreComponentGroup);
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index dc17257..b1bbb83 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -65,7 +65,7 @@ protected:
* Special case of component install where all
* components will be put in a single installer.
*/
- int PackageComponentsAllInOne(bool allComponent);
+ int PackageComponentsAllInOne();
virtual const char* GetOutputExtension() = 0;
cmArchiveWrite::Compress Compress;
cmArchiveWrite::Type Archive;
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index 06a0509..af78e78 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -165,5 +165,10 @@ int cmCPackBundleGenerator::PackageFiles()
cmSystemTools::SetPermissions(command_target.str().c_str(), 0777);
}
- return this->CreateDMG();
+ return this->CreateDMG(toplevel, packageFileNames[0]);
+}
+
+bool cmCPackBundleGenerator::SupportsComponentInstallation() const
+{
+ return false;
}
diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h
index 82814b0..ed0187d 100644
--- a/Source/CPack/cmCPackBundleGenerator.h
+++ b/Source/CPack/cmCPackBundleGenerator.h
@@ -32,6 +32,7 @@ protected:
virtual int InitializeInternal();
virtual const char* GetPackagingInstallPrefix();
int PackageFiles();
+ bool SupportsComponentInstallation() const;
std::string InstallPrefix;
};
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index ca2185c..8c19bbd 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -51,6 +51,62 @@ int cmCPackDebGenerator::InitializeInternal()
}
//----------------------------------------------------------------------
+int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
+ std::string packageName)
+ {
+ int retval = 1;
+ // Begin the archive for this pack
+ std::string localToplevel(initialTopLevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+ +"-"+packageName + this->GetOutputExtension()
+ );
+
+ localToplevel += "/"+ packageName;
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackDeb.cmake the name of the component GROUP.
+ this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",packageName.c_str());
+ if (!this->ReadListFile("CPackDeb.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackDeb.cmake" << std::endl);
+ retval = 0;
+ return retval;
+ }
+
+ cmsys::Glob gl;
+ std::string findExpr(this->GetOption("WDIR"));
+ findExpr += "/*";
+ gl.RecurseOn();
+ if ( !gl.FindFiles(findExpr) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find any files in the installed directory" << std::endl);
+ return 0;
+ }
+ packageFiles = gl.GetFiles();
+
+ int res = createDeb();
+ if (res != 1)
+ {
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ return retval;
+}
+
+//----------------------------------------------------------------------
int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
{
int retval = 1;
@@ -71,53 +127,24 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
<< compGIt->first
<< std::endl);
// Begin the archive for this group
- std::string localToplevel(initialTopLevel);
- std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
- );
- std::string outputFileName(
- std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
- +"-"+compGIt->first + this->GetOutputExtension()
- );
-
- localToplevel += "/"+ compGIt->first;
- /* replace the TEMP DIRECTORY with the component one */
- this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
- packageFileName += "/"+ outputFileName;
- /* replace proposed CPACK_OUTPUT_FILE_NAME */
- this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
- /* replace the TEMPORARY package file name */
- this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
- packageFileName.c_str());
- // Tell CPackDeb.cmake the name of the component GROUP.
- this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",compGIt->first.c_str());
- if (!this->ReadListFile("CPackDeb.cmake"))
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error while execution CPackDeb.cmake" << std::endl);
- retval = 0;
- return retval;
- }
-
- cmsys::Glob gl;
- std::string findExpr(this->GetOption("WDIR"));
- findExpr += "/*";
- gl.RecurseOn();
- if ( !gl.FindFiles(findExpr) )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find any files in the installed directory" << std::endl);
- return 0;
- }
- packageFiles = gl.GetFiles();
-
- int res = createDeb();
- if (res != 1)
+ retval &= PackageOnePack(initialTopLevel,compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ // Does the component belong to a group?
+ if (compIt->second.Group==NULL)
{
- retval = 0;
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ // Begin the archive for this orphan component
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
}
- // add the generated package to package file names list
- packageFileNames.push_back(packageFileName);
}
}
// CPACK_COMPONENTS_IGNORE_GROUPS is set
@@ -128,59 +155,14 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
for (compIt=this->Components.begin();
compIt!=this->Components.end(); ++compIt )
{
- std::string localToplevel(initialTopLevel);
- std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
- );
- std::string outputFileName(
- std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")
- )
- +"-"+compIt->first + this->GetOutputExtension());
-
- localToplevel += "/"+ compIt->first;
- /* replace the TEMP DIRECTORY with the component one */
- this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
- packageFileName += "/"+ outputFileName;
- /* replace proposed CPACK_OUTPUT_FILE_NAME */
- this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
- /* replace the TEMPORARY package file name */
- this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
- packageFileName.c_str());
-
- this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",compIt->first.c_str());
- if (!this->ReadListFile("CPackDeb.cmake"))
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error while execution CPackDeb.cmake" << std::endl);
- retval = 0;
- return retval;
- }
- cmsys::Glob gl;
- std::string findExpr(this->GetOption("WDIR"));
- findExpr += "/*";
- gl.RecurseOn();
- if ( !gl.FindFiles(findExpr) )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find any files in the installed directory" << std::endl);
- return 0;
- }
- packageFiles = gl.GetFiles();
-
- int res = createDeb();
- if (res != 1)
- {
- retval = 0;
- }
- // add the generated package to package file names list
- packageFileNames.push_back(packageFileName);
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
}
}
return retval;
}
//----------------------------------------------------------------------
-int cmCPackDebGenerator::PackageComponentsAllInOne(bool allComponent)
+int cmCPackDebGenerator::PackageComponentsAllInOne()
{
int retval = 1;
std::string compInstDirName;
@@ -189,15 +171,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(bool allComponent)
packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
- // all GROUP in one vs all COMPONENT in one
- if (allComponent)
- {
- compInstDirName = "ALL_COMPONENTS_IN_ONE";
- }
- else
- {
- compInstDirName = "ALL_GROUPS_IN_ONE";
- }
+ compInstDirName = "ALL_COMPONENTS_IN_ONE";
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging all groups in one package..."
@@ -266,19 +240,18 @@ int cmCPackDebGenerator::PackageFiles()
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (allComponentInOne ||
- (allGroupInOne && (!this->ComponentGroups.empty()))
- )
+ if (componentPackageMethod == ONE_PACKAGE)
{
- return PackageComponentsAllInOne(allComponentInOne);
+ return PackageComponentsAllInOne();
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup))
+ else
{
- return PackageComponents(ignoreComponentGroup);
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
}
// CASE 3 : NON COMPONENT package.
@@ -518,7 +491,7 @@ int cmCPackDebGenerator::createDeb()
{
std::string filenamename =
cmsys::SystemTools::GetFilenameName(i->c_str());
- std::string localcopy = toplevel;
+ std::string localcopy = this->GetOption("WDIR");
localcopy += "/";
localcopy += filenamename;
// if we can copy the file, it means it does exist, let's add it:
@@ -588,11 +561,11 @@ bool cmCPackDebGenerator::SupportsComponentInstallation() const
std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
const std::string& componentName)
{
- if (ignoreComponentGroup) {
+ if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
return componentName;
}
- if (allComponentInOne) {
+ if (componentPackageMethod == ONE_PACKAGE) {
return std::string("ALL_COMPONENTS_IN_ONE");
}
// We have to find the name of the COMPONENT GROUP
@@ -601,14 +574,7 @@ std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
cmSystemTools::UpperCase(componentName) + "_GROUP";
if (NULL != GetOption(groupVar.c_str()))
{
- if (allGroupInOne)
- {
- return std::string("ALL_GROUPS_IN_ONE");
- }
- else
- {
- return std::string(GetOption(groupVar.c_str()));
- }
+ return std::string(GetOption(groupVar.c_str()));
}
else
{
diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h
index de1ea77..f536c47 100644
--- a/Source/CPack/cmCPackDebGenerator.h
+++ b/Source/CPack/cmCPackDebGenerator.h
@@ -34,6 +34,10 @@ public:
protected:
virtual int InitializeInternal();
/**
+ * This method factors out the work done in component packaging case.
+ */
+ int PackageOnePack(std::string initialToplevel, std::string packageName);
+ /**
* The method used to package files when component
* install is used. This will create one
* archive for each component group.
@@ -43,7 +47,7 @@ protected:
* Special case of component install where all
* components will be put in a single installer.
*/
- int PackageComponentsAllInOne(bool allComponent);
+ int PackageComponentsAllInOne();
virtual int PackageFiles();
virtual const char* GetOutputExtension() { return ".deb"; }
virtual bool SupportsComponentInstallation() const;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index e9ce76c..83b6b64 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -51,6 +51,8 @@ static const char* SLASTREnglish =
//----------------------------------------------------------------------
cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
{
+ // default to one package file for components
+ this->componentPackageMethod = ONE_PACKAGE;
}
//----------------------------------------------------------------------
@@ -106,8 +108,57 @@ const char* cmCPackDragNDropGenerator::GetOutputExtension()
//----------------------------------------------------------------------
int cmCPackDragNDropGenerator::PackageFiles()
{
+ // gather which directories to make dmg files for
+ // multiple directories occur if packaging components or groups separately
- return this->CreateDMG();
+ // monolith
+ if(this->Components.empty())
+ {
+ return this->CreateDMG(toplevel, packageFileNames[0]);
+ }
+
+ // component install
+ std::vector<std::string> package_files;
+
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ std::string name = GetComponentInstallDirNameSuffix(compIt->first);
+ package_files.push_back(name);
+ }
+ std::sort(package_files.begin(), package_files.end());
+ package_files.erase(std::unique(package_files.begin(),
+ package_files.end()),
+ package_files.end());
+
+
+ // loop to create dmg files
+ packageFileNames.clear();
+ for(size_t i=0; i<package_files.size(); i++)
+ {
+ std::string full_package_name = std::string(toplevel) + std::string("/");
+ if(package_files[i] == "ALL_IN_ONE")
+ {
+ full_package_name += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ }
+ else
+ {
+ full_package_name += package_files[i];
+ }
+ full_package_name += std::string(GetOutputExtension());
+ packageFileNames.push_back(full_package_name);
+
+ std::string src_dir = toplevel;
+ src_dir += "/";
+ src_dir += package_files[i];
+
+ if(0 == this->CreateDMG(src_dir, full_package_name))
+ {
+ return 0;
+ }
+ }
+ return 1;
}
//----------------------------------------------------------------------
@@ -159,10 +210,11 @@ bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command,
}
//----------------------------------------------------------------------
-int cmCPackDragNDropGenerator::CreateDMG()
+int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
+ const std::string& output_file)
{
// Get optional arguments ...
- const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON")
+ const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON")
? this->GetOption("CPACK_PACKAGE_ICON") : "";
const std::string cpack_dmg_volume_name =
@@ -197,7 +249,7 @@ int cmCPackDragNDropGenerator::CreateDMG()
// The staging directory contains everything that will end-up inside the
// final disk image ...
cmOStringStream staging;
- staging << toplevel;
+ staging << src_dir;
// Add a symlink to /Applications so users can drag-and-drop the bundle
// into it
@@ -472,7 +524,7 @@ int cmCPackDragNDropGenerator::CreateDMG()
final_image_command << cpack_dmg_format;
final_image_command << " -imagekey";
final_image_command << " zlib-level=9";
- final_image_command << " -o \"" << packageFileNames[0] << "\"";
+ final_image_command << " -o \"" << output_file << "\"";
if(!this->RunCommand(final_image_command))
{
@@ -485,3 +537,47 @@ int cmCPackDragNDropGenerator::CreateDMG()
return 1;
}
+
+bool cmCPackDragNDropGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+std::string
+cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+{
+ // we want to group components together that go in the same dmg package
+ std::string package_file_name = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ // we have 3 mutually exclusive modes to work in
+ // 1. all components in one package
+ // 2. each group goes in its own package with left over
+ // components in their own package
+ // 3. ignore groups - if grouping is defined, it is ignored
+ // and each component goes in its own package
+
+ if(this->componentPackageMethod == ONE_PACKAGE)
+ {
+ return "ALL_IN_ONE";
+ }
+
+ if(this->componentPackageMethod == ONE_PACKAGE_PER_GROUP)
+ {
+ // We have to find the name of the COMPONENT GROUP
+ // the current COMPONENT belongs to.
+ std::string groupVar = "CPACK_COMPONENT_" +
+ cmSystemTools::UpperCase(componentName) + "_GROUP";
+ const char* _groupName = GetOption(groupVar.c_str());
+ if (_groupName)
+ {
+ std::string groupName = _groupName;
+
+ groupName = GetComponentPackageFileName(package_file_name,
+ groupName, true);
+ return groupName;
+ }
+ }
+
+ return GetComponentPackageFileName(package_file_name, componentName, false);
+}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index dcef7fb..808c618 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -30,11 +30,16 @@ protected:
virtual int InitializeInternal();
virtual const char* GetOutputExtension();
int PackageFiles();
+ bool SupportsComponentInstallation() const;
+
bool CopyFile(cmOStringStream& source, cmOStringStream& target);
bool RunCommand(cmOStringStream& command, std::string* output = 0);
- int CreateDMG();
+ std::string
+ GetComponentInstallDirNameSuffix(const std::string& componentName);
+
+ int CreateDMG(const std::string& src_dir, const std::string& output_file);
std::string InstallPrefix;
};
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index c343acf..7e5b26d 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -36,9 +36,7 @@ cmCPackGenerator::cmCPackGenerator()
this->GeneratorVerbose = false;
this->MakefileMap = 0;
this->Logger = 0;
- this->allGroupInOne = false;
- this->allComponentInOne = false;
- this->ignoreComponentGroup = false;
+ this->componentPackageMethod = ONE_PACKAGE_PER_GROUP;
}
//----------------------------------------------------------------------
@@ -869,6 +867,28 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Got some ABSOLUTE DESTINATION FILES: "
<< absoluteDestFiles << std::endl);
+ // define component specific var
+ if (componentInstall)
+ {
+ std::string absoluteDestFileComponent =
+ std::string("CPACK_ABSOLUTE_DESTINATION_FILES")
+ + "_" + GetComponentInstallDirNameSuffix(installComponent);
+ if (NULL != this->GetOption(absoluteDestFileComponent.c_str()))
+ {
+ std::string absoluteDestFilesListComponent =
+ this->GetOption(absoluteDestFileComponent.c_str());
+ absoluteDestFilesListComponent +=";";
+ absoluteDestFilesListComponent +=
+ mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+ this->SetOption(absoluteDestFileComponent.c_str(),
+ absoluteDestFilesListComponent.c_str());
+ }
+ else
+ {
+ this->SetOption(absoluteDestFileComponent.c_str(),
+ mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
+ }
+ }
}
if ( cmSystemTools::GetErrorOccuredFlag() || !res )
{
@@ -1264,17 +1284,23 @@ int cmCPackGenerator::CleanTemporaryDirectory()
//----------------------------------------------------------------------
int cmCPackGenerator::PrepareGroupingKind()
{
- // The default behavior is to create 1 package by component group
- // unless the user asked to put all COMPONENTS in a single package
- allGroupInOne = (NULL !=
- (this->GetOption(
- "CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE")));
- allComponentInOne = (NULL !=
- (this->GetOption(
- "CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE")));
- ignoreComponentGroup = (NULL !=
- (this->GetOption(
- "CPACK_COMPONENTS_IGNORE_GROUPS")));
+ // find a component package method specified by the user
+ ComponentPackageMethod method = UNKNOWN_COMPONENT_PACKAGE_METHOD;
+
+ if(this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))
+ {
+ method = ONE_PACKAGE;
+ }
+
+ if(this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))
+ {
+ method = ONE_PACKAGE_PER_COMPONENT;
+ }
+
+ if(this->GetOption("CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP"))
+ {
+ method = ONE_PACKAGE_PER_GROUP;
+ }
std::string groupingType;
@@ -1288,47 +1314,66 @@ int cmCPackGenerator::PrepareGroupingKind()
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
<< this->Name << "]"
<< " requested component grouping = "<< groupingType <<std::endl);
- if (groupingType == "ALL_GROUPS_IN_ONE")
+ if (groupingType == "ALL_COMPONENTS_IN_ONE")
{
- allGroupInOne = true;
+ method = ONE_PACKAGE;
}
- else if (groupingType == "ALL_COMPONENTS_IN_ONE")
+ else if (groupingType == "IGNORE")
{
- allComponentInOne = true;
+ method = ONE_PACKAGE_PER_COMPONENT;
}
- else if (groupingType == "IGNORE")
+ else if (groupingType == "ONE_PER_GROUP")
{
- ignoreComponentGroup = true;
+ method = ONE_PACKAGE_PER_GROUP;
}
else
{
cmCPackLogger(cmCPackLog::LOG_WARNING, "["
- << this->Name << "]"
- << " requested component grouping type <"<< groupingType
- << "> UNKNOWN not in (ALL_GROUPS_IN_ONE,"
- "ALL_COMPONENTS_IN_ONE,IGNORE)" <<std::endl);
+ << this->Name << "]"
+ << " requested component grouping type <"<< groupingType
+ << "> UNKNOWN not in (ALL_COMPONENTS_IN_ONE,IGNORE,ONE_PER_GROUP)"
+ << std::endl);
}
}
+ // Some components were defined but NO group
+ // fallback to default if not group based
+ if(method == ONE_PACKAGE_PER_GROUP &&
+ this->ComponentGroups.empty() && !this->Components.empty())
+ {
+ if(componentPackageMethod == ONE_PACKAGE)
+ {
+ method = ONE_PACKAGE;
+ }
+ else
+ {
+ method = ONE_PACKAGE_PER_COMPONENT;
+ }
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "["
+ << this->Name << "]"
+ << " One package per component group requested, "
+ << "but NO component groups exist: Ignoring component group."
+ << std::endl);
+ }
+
+ // if user specified packaging method, override the default packaging method
+ if(method != UNKNOWN_COMPONENT_PACKAGE_METHOD)
+ {
+ componentPackageMethod = method;
+ }
+
+ const char* method_names[] =
+ {
+ "ALL_COMPONENTS_IN_ONE",
+ "IGNORE_GROUPS",
+ "ONE_PER_GROUP"
+ };
+
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
<< this->Name << "]"
- << " requested component grouping = ("
- << "ALL_GROUPS_IN_ONE=" << allGroupInOne
- << ", ALL_COMPONENTS_IN_ONE=" << allComponentInOne
- << ", IGNORE_GROUPS=" << ignoreComponentGroup
- << ")"
+ << " requested component grouping = "
+ << method_names[componentPackageMethod]
<< std::endl);
- // Some components were defined but NO group
- // force ignoreGroups
- if (this->ComponentGroups.empty() && (!this->Components.empty())
- && (!ignoreComponentGroup)) {
- cmCPackLogger(cmCPackLog::LOG_WARNING, "["
- << this->Name << "]"
- << " Some Components defined but NO component group:"
- << " Ignoring component group."
- << std::endl);
- ignoreComponentGroup = true;
- }
return 1;
}
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 0497d1c..05d95b8 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -122,11 +122,10 @@ protected:
/**
* Prepare requested grouping kind from CPACK_xxx vars
- * CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE
* CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE
* CPACK_COMPONENTS_IGNORE_GROUPS
* or
- * CPACK_COMPONENTS_GROUPING
+ * CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP
* @return 1 on success 0 on failure.
*/
virtual int PrepareGroupingKind();
@@ -238,20 +237,30 @@ protected:
*/
std::map<std::string, cmCPackComponent> Components;
std::map<std::string, cmCPackComponentGroup> ComponentGroups;
+
/**
- * If true All component groups will be put in a single package.
- */
- bool allGroupInOne;
- /**
- * If true All component will be put in a single package.
+ * If components are enabled, this enum represents the different
+ * ways of mapping components to package files.
*/
- bool allComponentInOne;
+ enum ComponentPackageMethod
+ {
+ /* one package for all components */
+ ONE_PACKAGE,
+ /* one package for each component */
+ ONE_PACKAGE_PER_COMPONENT,
+ /* one package for each group,
+ * with left over components in their own package */
+ ONE_PACKAGE_PER_GROUP,
+ UNKNOWN_COMPONENT_PACKAGE_METHOD
+ };
+
/**
- * If true component grouping will be ignored.
- * You will still get 1 package for each component unless
- * allComponentInOne is true.
+ * The component package method
+ * The default is ONE_PACKAGE_PER_GROUP,
+ * and generators may override the default
+ * before PrepareGroupingKind() is called.
*/
- bool ignoreComponentGroup;
+ ComponentPackageMethod componentPackageMethod;
cmCPackLog* Logger;
private:
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 0e8cbc0..75ad640 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -21,6 +21,7 @@
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
+#include <sys/stat.h>
//----------------------------------------------------------------------
cmCPackOSXX11Generator::cmCPackOSXX11Generator()
@@ -135,6 +136,32 @@ int cmCPackOSXX11Generator::PackageFiles()
return 0;
}
+ // Two of the files need to have execute permission, so ensure they do:
+ std::string runTimeScript = dir;
+ runTimeScript += "/";
+ runTimeScript += "RuntimeScript";
+
+ std::string appScriptName = appdir;
+ appScriptName += "/";
+ appScriptName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ mode_t mode;
+ if (cmsys::SystemTools::GetPermissions(runTimeScript.c_str(), mode))
+ {
+ mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
+ cmsys::SystemTools::SetPermissions(runTimeScript.c_str(), mode);
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << runTimeScript
+ << " to permission: " << mode << std::endl);
+ }
+
+ if (cmsys::SystemTools::GetPermissions(appScriptName.c_str(), mode))
+ {
+ mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
+ cmsys::SystemTools::SetPermissions(appScriptName.c_str(), mode);
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << appScriptName
+ << " to permission: " << mode << std::endl);
+ }
+
std::string output;
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/hdiutilOutput.log";
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 0b0c6b1..1a6c3be 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -50,6 +50,45 @@ int cmCPackRPMGenerator::InitializeInternal()
}
//----------------------------------------------------------------------
+int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel,
+ std::string packageName)
+{
+ int retval = 1;
+ // Begin the archive for this pack
+ std::string localToplevel(initialToplevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ packageName,
+ true)
+ + this->GetOutputExtension()
+ );
+
+ localToplevel += "/"+ packageName;
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackRPM.cmake the name of the component NAME.
+ this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",packageName.c_str());
+ if (!this->ReadListFile("CPackRPM.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackRPM.cmake" << std::endl);
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ return retval;
+}
+
+//----------------------------------------------------------------------
int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
{
int retval = 1;
@@ -69,37 +108,23 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
<< compGIt->first
<< std::endl);
- // Begin the archive for this group
- std::string localToplevel(initialTopLevel);
- std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
- );
- std::string outputFileName(
- GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
- compGIt->first,
- true)
- + this->GetOutputExtension()
- );
-
- localToplevel += "/"+ compGIt->first;
- /* replace the TEMP DIRECTORY with the component one */
- this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
- packageFileName += "/"+ outputFileName;
- /* replace proposed CPACK_OUTPUT_FILE_NAME */
- this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
- /* replace the TEMPORARY package file name */
- this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
- packageFileName.c_str());
- // Tell CPackRPM.cmake the name of the component GROUP.
- this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compGIt->first.c_str());
- if (!this->ReadListFile("CPackRPM.cmake"))
+ retval &= PackageOnePack(initialTopLevel,compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ // Does the component belong to a group?
+ if (compIt->second.Group==NULL)
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error while execution CPackRPM.cmake" << std::endl);
- retval = 0;
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
}
- // add the generated package to package file names list
- packageFileNames.push_back(packageFileName);
}
}
// CPACK_COMPONENTS_IGNORE_GROUPS is set
@@ -110,42 +135,14 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
for (compIt=this->Components.begin();
compIt!=this->Components.end(); ++compIt )
{
- std::string localToplevel(initialTopLevel);
- std::string packageFileName(
- cmSystemTools::GetParentDirectory(toplevel.c_str())
- );
- std::string outputFileName(
- GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
- compIt->first,
- false)
- + this->GetOutputExtension());
-
- localToplevel += "/"+ compIt->first;
- /* replace the TEMP DIRECTORY with the component one */
- this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
- packageFileName += "/"+ outputFileName;
- /* replace proposed CPACK_OUTPUT_FILE_NAME */
- this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
- /* replace the TEMPORARY package file name */
- this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
- packageFileName.c_str());
-
- this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compIt->first.c_str());
- if (!this->ReadListFile("CPackRPM.cmake"))
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error while execution CPackRPM.cmake" << std::endl);
- retval = 0;
- }
- // add the generated package to package file names list
- packageFileNames.push_back(packageFileName);
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
}
}
return retval;
}
//----------------------------------------------------------------------
-int cmCPackRPMGenerator::PackageComponentsAllInOne(bool allComponent)
+int cmCPackRPMGenerator::PackageComponentsAllInOne()
{
int retval = 1;
std::string compInstDirName;
@@ -154,15 +151,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(bool allComponent)
packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
- // all GROUP in one vs all COMPONENT in one
- if (allComponent)
- {
- compInstDirName = "ALL_COMPONENTS_IN_ONE";
- }
- else
- {
- compInstDirName = "ALL_GROUPS_IN_ONE";
- }
+ compInstDirName = "ALL_COMPONENTS_IN_ONE";
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging all groups in one package..."
@@ -214,21 +203,20 @@ int cmCPackRPMGenerator::PackageFiles()
/* Are we in the component packaging case */
if (SupportsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
- // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
+ // If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
- if (allComponentInOne ||
- (allGroupInOne && (!this->ComponentGroups.empty()))
- )
+ if (componentPackageMethod == ONE_PACKAGE)
{
- return PackageComponentsAllInOne(allComponentInOne);
+ return PackageComponentsAllInOne();
}
// CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
// There will be 1 package for each component group
// however one may require to ignore component group and
// in this case you'll get 1 package for each component.
- else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup))
+ else
{
- return PackageComponents(ignoreComponentGroup);
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
}
}
// CASE 3 : NON COMPONENT package.
@@ -265,11 +253,11 @@ bool cmCPackRPMGenerator::SupportsComponentInstallation() const
std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
const std::string& componentName)
{
- if (ignoreComponentGroup) {
+ if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
return componentName;
}
- if (allComponentInOne) {
+ if (componentPackageMethod == ONE_PACKAGE) {
return std::string("ALL_COMPONENTS_IN_ONE");
}
// We have to find the name of the COMPONENT GROUP
@@ -278,14 +266,7 @@ std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
cmSystemTools::UpperCase(componentName) + "_GROUP";
if (NULL != GetOption(groupVar.c_str()))
{
- if (allGroupInOne)
- {
- return std::string("ALL_GROUPS_IN_ONE");
- }
- else
- {
- return std::string(GetOption(groupVar.c_str()));
- }
+ return std::string(GetOption(groupVar.c_str()));
}
else
{
diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h
index 7c2e434..4883a0d 100644
--- a/Source/CPack/cmCPackRPMGenerator.h
+++ b/Source/CPack/cmCPackRPMGenerator.h
@@ -39,6 +39,10 @@ protected:
virtual int InitializeInternal();
virtual int PackageFiles();
/**
+ * This method factors out the work done in component packaging case.
+ */
+ int PackageOnePack(std::string initialToplevel, std::string packageName);
+ /**
* The method used to package files when component
* install is used. This will create one
* archive for each component group.
@@ -48,7 +52,7 @@ protected:
* Special case of component install where all
* components will be put in a single installer.
*/
- int PackageComponentsAllInOne(bool allComponent);
+ int PackageComponentsAllInOne();
virtual const char* GetOutputExtension() { return ".rpm"; }
virtual bool SupportsComponentInstallation() const;
virtual std::string GetComponentInstallDirNameSuffix(
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 13a25cb..0612449 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -344,9 +344,21 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
}
this->MemoryTesterGlobalResults[kk] += memcheckresults[kk];
}
+
+ std::string logTag;
+ if(this->CTest->ShouldCompressMemCheckOutput())
+ {
+ this->CTest->CompressString(memcheckstr);
+ logTag = "\t<Log compression=\"gzip\" encoding=\"base64\">\n";
+ }
+ else
+ {
+ logTag = "\t<Log>\n";
+ }
+
os
<< "\t\t</Results>\n"
- << "\t<Log>\n" << memcheckstr << std::endl
+ << logTag << memcheckstr << std::endl
<< "\t</Log>\n";
this->WriteTestResultFooter(os, result);
if ( current < cc )
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 42a4cff..60695da 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -135,7 +135,10 @@ void cmCTestRunTest::CompressOutput()
//---------------------------------------------------------
bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
{
- if (this->CTest->ShouldCompressTestOutput())
+ if ((!this->TestHandler->MemCheck &&
+ this->CTest->ShouldCompressTestOutput()) ||
+ (this->TestHandler->MemCheck &&
+ this->CTest->ShouldCompressMemCheckOutput()))
{
this->CompressOutput();
}
@@ -279,11 +282,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
// Output since that is what is parsed by cmCTestMemCheckHandler
if(!this->TestHandler->MemCheck && started)
{
- this->TestHandler->CleanTestOutput(this->ProcessOutput,
- static_cast<size_t>
- (this->TestResult.Status == cmCTestTestHandler::COMPLETED ?
- this->TestHandler->CustomMaximumPassedTestOutputSize :
- this->TestHandler->CustomMaximumFailedTestOutputSize));
+ this->TestHandler->CleanTestOutput(this->ProcessOutput,
+ static_cast<size_t>
+ (this->TestResult.Status == cmCTestTestHandler::COMPLETED ?
+ this->TestHandler->CustomMaximumPassedTestOutputSize :
+ this->TestHandler->CustomMaximumFailedTestOutputSize));
}
this->TestResult.Reason = reason;
if (this->TestHandler->LogFile)
@@ -332,7 +335,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
// record the results in TestResult
if(started)
{
- bool compress = this->CompressionRatio < 1 &&
+ bool compress = !this->TestHandler->MemCheck &&
+ this->CompressionRatio < 1 &&
this->CTest->ShouldCompressTestOutput();
this->TestResult.Output = compress ? this->CompressedOutput
: this->ProcessOutput;
@@ -408,6 +412,30 @@ bool cmCTestRunTest::StartTest(size_t total)
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory.c_str();
+
+ if(args.size() >= 2 && args[1] == "NOT_AVAILABLE")
+ {
+ this->TestProcess = new cmProcess;
+ std::string msg;
+ if(this->CTest->GetConfigType().empty())
+ {
+ msg = "Test not available without configuration.";
+ msg += " (Missing \"-C <config>\"?)";
+ }
+ else
+ {
+ msg = "Test not available in configuration \"";
+ msg += this->CTest->GetConfigType();
+ msg += "\".";
+ }
+ *this->TestHandler->LogFile << msg << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
+ this->TestResult.Output = msg;
+ this->TestResult.FullCommandLine = "";
+ this->TestResult.CompletionStatus = "Not Run";
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ return false;
+ }
// Check if all required files exist
for(std::vector<std::string>::iterator i =
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 12d5fd1..5841b8d 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -50,6 +50,7 @@
#include "cmCTestSubmitCommand.h"
#include "cmCTestTestCommand.h"
#include "cmCTestUpdateCommand.h"
+#include "cmCTestUploadCommand.h"
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
@@ -357,6 +358,7 @@ void cmCTestScriptHandler::CreateCMake()
this->AddCTestCommand(new cmCTestSubmitCommand);
this->AddCTestCommand(new cmCTestTestCommand);
this->AddCTestCommand(new cmCTestUpdateCommand);
+ this->AddCTestCommand(new cmCTestUploadCommand);
}
void cmCTestScriptHandler::GetCommandDocumentation(
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 43441c0..142bb46 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -1204,6 +1204,7 @@ int cmCTestSubmitHandler::ProcessHandler()
this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis.xml");
this->CTest->AddIfExists(cmCTest::PartMemCheck, "Purify.xml");
this->CTest->AddIfExists(cmCTest::PartNotes, "Notes.xml");
+ this->CTest->AddIfExists(cmCTest::PartUpload, "Upload.xml");
// Query parts for files to submit.
for(cmCTest::Part p = cmCTest::PartStart;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index f87c929..e3b81df 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1282,7 +1282,7 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
result->Properties->AttachedFiles.begin();
file != result->Properties->AttachedFiles.end(); ++file)
{
- std::string base64 = this->EncodeFile(*file);
+ std::string base64 = this->CTest->Base64GzipEncodeFile(*file);
std::string fname = cmSystemTools::GetFilenameName(*file);
os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" "
"compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">"
@@ -1293,48 +1293,6 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os,
}
//----------------------------------------------------------------------
-std::string cmCTestTestHandler::EncodeFile(std::string file)
-{
- std::string tarFile = file + "_temp.tar.gz";
- std::vector<cmStdString> files;
- files.push_back(file);
-
- if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false))
- {
- cmCTestLog(this->CTest, ERROR_MESSAGE, "Error creating tar while "
- "attaching file: " << file << std::endl);
- return "";
- }
- long len = cmSystemTools::FileLength(tarFile.c_str());
- std::ifstream ifs(tarFile.c_str(), std::ios::in
-#ifdef _WIN32
- | std::ios::binary
-#endif
- );
- unsigned char *file_buffer = new unsigned char [ len + 1 ];
- ifs.read(reinterpret_cast<char*>(file_buffer), len);
- ifs.close();
- cmSystemTools::RemoveFile(tarFile.c_str());
-
- unsigned char *encoded_buffer
- = new unsigned char [ static_cast<int>(
- static_cast<double>(len) * 1.5 + 5.0) ];
-
- unsigned long rlen
- = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
-
- std::string base64 = "";
- for(unsigned long i = 0; i < rlen; i++)
- {
- base64 += encoded_buffer[i];
- }
- delete [] file_buffer;
- delete [] encoded_buffer;
-
- return base64;
-}
-
-//----------------------------------------------------------------------
int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
{
std::vector<cmStdString>::iterator it;
@@ -1362,6 +1320,10 @@ std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
std::string resConfig;
std::vector<std::string> extraPaths;
std::vector<std::string> failedPaths;
+ if(strcmp(exe, "NOT_AVAILABLE") == 0)
+ {
+ return exe;
+ }
return cmCTestTestHandler::FindExecutable(this->CTest,
exe, resConfig,
extraPaths,
@@ -1978,6 +1940,7 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
fin.getline(buff, filelen);
buff[fin.gcount()] = 0;
this->TestsToRunString = buff;
+ delete [] buff;
}
}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 2c4b230..3089d35 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -151,8 +151,6 @@ protected:
void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
// Write attached test files into the xml
void AttachFiles(std::ostream& os, cmCTestTestResult* result);
- // Helper function to encode attached test files
- std::string EncodeFile(std::string file);
//! Clean test output to specified length
bool CleanTestOutput(std::string& output, size_t length);
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
new file mode 100644
index 0000000..731c1c7
--- /dev/null
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -0,0 +1,69 @@
+/*============================================================================
+ 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 "cmCTestUploadCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+#include "cmCTestUploadHandler.h"
+
+cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+{
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("upload");
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate upload handler");
+ return 0;
+ }
+ static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files);
+
+ return handler;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ if(arg == "FILES")
+ {
+ this->ArgumentDoing = ArgumentDoingFiles;
+ return true;
+ }
+ return false;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
+{
+ if(this->ArgumentDoing == ArgumentDoingFiles)
+ {
+ cmStdString filename(arg);
+ if(cmSystemTools::FileExists(filename.c_str()))
+ {
+ this->Files.insert(filename);
+ return true;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "File \"" << filename << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->ArgumentDoing = ArgumentDoingError;
+ return false;
+ }
+ }
+
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentValue(arg);
+}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
new file mode 100644
index 0000000..6c2a4c2
--- /dev/null
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#ifndef cmCTestUploadCommand_h
+#define cmCTestUploadCommand_h
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCTest.h"
+
+/** \class cmCTestUpload
+ * \brief Run a ctest script
+ *
+ * cmCTestUploadCommand defines the command to upload result files for
+ * the project.
+ */
+class cmCTestUploadCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestUploadCommand()
+ {
+ }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestUploadCommand* ni = new cmCTestUploadCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual const char* GetName() { return "ctest_upload";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation()
+ {
+ return "Upload files to a dashboard server.";
+ }
+
+ /**
+ * More documentation.
+ */
+ virtual const char* GetFullDocumentation()
+ {
+ return
+ " ctest_upload(FILES ...)\n"
+ "Pass a list of files to be sent along with the build results to "
+ "the dashboard server.\n";
+ }
+
+ cmTypeMacro(cmCTestUploadCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+
+ enum
+ {
+ ArgumentDoingFiles = Superclass::ArgumentDoingLast1,
+ ArgumentDoingLast2
+ };
+
+ cmCTest::SetOfStrings Files;
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
new file mode 100644
index 0000000..caf2e53
--- /dev/null
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -0,0 +1,77 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ 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 "cmCTestUploadHandler.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmVersion.h"
+#include "cmXMLSafe.h"
+
+//----------------------------------------------------------------------------
+cmCTestUploadHandler::cmCTestUploadHandler()
+{
+ this->Initialize();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestUploadHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->Files.clear();
+}
+
+void cmCTestUploadHandler::SetFiles(const cmCTest::SetOfStrings& files)
+{
+ this->Files = files;
+}
+
+//----------------------------------------------------------------------------
+int cmCTestUploadHandler::ProcessHandler()
+{
+ cmGeneratedFileStream ofs;
+ if ( !this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(),
+ "Upload.xml", ofs))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open Upload.xml file" << std::endl);
+ return -1;
+ }
+
+ cmCTest::SetOfStrings::const_iterator it;
+ ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ << "<?xml-stylesheet type=\"text/xsl\" "
+ "href=\"Dart/Source/Server/XSL/Build.xsl "
+ "<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
+ << "<Site BuildName=\""
+ << this->CTest->GetCTestConfiguration("BuildName")
+ << "\" BuildStamp=\""
+ << this->CTest->GetCurrentTag() << "-"
+ << this->CTest->GetTestModelString() << "\" Name=\""
+ << this->CTest->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
+ << cmVersion::GetCMakeVersion()
+ << "\">\n";
+ this->CTest->AddSiteProperties(ofs);
+ ofs << "<Upload>\n";
+
+ for ( it = this->Files.begin(); it != this->Files.end(); it ++ )
+ {
+ cmCTestLog(this->CTest, OUTPUT,
+ "\tUpload file: " << it->c_str() << std::endl);
+ ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n"
+ << "<Content encoding=\"base64\">\n";
+ ofs << this->CTest->Base64EncodeFile(*it);
+ ofs << "\n</Content>\n"
+ << "</File>\n";
+ }
+ ofs << "</Upload>\n"
+ << "</Site>\n";
+ return 0;
+}
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
new file mode 100644
index 0000000..23ed35a
--- /dev/null
+++ b/Source/CTest/cmCTestUploadHandler.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#ifndef cmCTestUploadHandler_h
+#define cmCTestUploadHandler_h
+
+#include "cmCTestGenericHandler.h"
+
+/** \class cmCTestUploadHandler
+ * \brief Helper class for CTest
+ *
+ * Submit arbitrary files
+ *
+ */
+class cmCTestUploadHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestUploadHandler, cmCTestGenericHandler);
+
+ cmCTestUploadHandler();
+ ~cmCTestUploadHandler() {}
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ void Initialize();
+
+ /** Specify a set of files to submit. */
+ void SetFiles(cmCTest::SetOfStrings const& files);
+
+private:
+ cmCTest::SetOfStrings Files;
+};
+
+#endif
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 502829e..5634849 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -195,11 +195,13 @@ bool cmAddCustomCommandCommand
{
// An implicit dependency starting point is also an
// explicit dependency.
- depends.push_back(copy);
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
// Add the implicit dependency language and file.
cmCustomCommand::ImplicitDependsPair
- entry(implicit_depends_lang, copy);
+ entry(implicit_depends_lang, dep);
implicit_depends.push_back(entry);
// Switch back to looking for a language.
@@ -213,7 +215,11 @@ bool cmAddCustomCommandCommand
target = copy;
break;
case doing_depends:
- depends.push_back(copy);
+ {
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
+ }
break;
case doing_outputs:
outputs.push_back(filename);
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 27dea98..4eba886 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -123,7 +123,11 @@ bool cmAddCustomTargetCommand
currentLine.push_back(copy);
break;
case doing_depends:
- depends.push_back(copy);
+ {
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
+ }
break;
case doing_comment:
comment_buffer = copy;
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index d9e4742..25dc8ba 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -236,6 +236,9 @@ bool cmArchiveWrite::AddFile(const char* file,
this->Error += archive_error_string(this->Disk);
return false;
}
+ // Clear acl and xattr fields not useful for distribution.
+ archive_entry_acl_clear(e);
+ archive_entry_xattr_clear(e);
if(archive_write_header(this->Archive, e) != ARCHIVE_OK)
{
this->Error = "archive_write_header: ";
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 411a28d..e237913 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -518,7 +518,7 @@ public:
};
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
-void * CCONV cmCreateSourceFile()
+void * CCONV cmCreateSourceFile(void)
{
return (void*)new cmCPluginAPISourceFile;
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 2e05883..75a564e 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,6 +16,7 @@
#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
+#include <cmsys/Base64.h>
#include <cmsys/Directory.hxx>
#include <cmsys/SystemInformation.hxx>
#include "cmDynamicLoader.h"
@@ -31,9 +32,10 @@
#include "cmCTestCoverageHandler.h"
#include "cmCTestMemCheckHandler.h"
#include "cmCTestScriptHandler.h"
+#include "cmCTestSubmitHandler.h"
#include "cmCTestTestHandler.h"
#include "cmCTestUpdateHandler.h"
-#include "cmCTestSubmitHandler.h"
+#include "cmCTestUploadHandler.h"
#include "cmVersion.h"
@@ -48,6 +50,9 @@
#include <memory> // auto_ptr
+#include <cm_zlib.h>
+#include <cmsys/Base64.h>
+
#if defined(__BEOS__) && !defined(__HAIKU__)
#include <be/kernel/OS.h> /* disable_debugger() API. */
#endif
@@ -306,7 +311,7 @@ cmCTest::cmCTest()
this->UseHTTP10 = false;
this->PrintLabels = false;
this->CompressTestOutput = true;
- this->ComputedCompressOutput = false;
+ this->CompressMemCheckOutput = true;
this->TestModel = cmCTest::EXPERIMENTAL;
this->MaxTestNameWidth = 30;
this->InteractiveDebugMode = true;
@@ -323,6 +328,8 @@ cmCTest::cmCTest()
this->SuppressUpdatingCTestConfiguration = false;
this->DartVersion = 1;
this->OutputTestOutputOnTestFailure = false;
+ this->ComputedCompressTestOutput = false;
+ this->ComputedCompressMemCheckOutput = false;
if(cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE"))
{
this->OutputTestOutputOnTestFailure = true;
@@ -339,6 +346,7 @@ cmCTest::cmCTest()
this->Parts[PartSubmit].SetName("Submit");
this->Parts[PartNotes].SetName("Notes");
this->Parts[PartExtraFiles].SetName("ExtraFiles");
+ this->Parts[PartUpload].SetName("Upload");
// Fill the part name-to-id map.
for(Part p = PartStart; p != PartCount; p = Part(p+1))
@@ -357,6 +365,7 @@ cmCTest::cmCTest()
this->TestingHandlers["configure"] = new cmCTestConfigureHandler;
this->TestingHandlers["memcheck"] = new cmCTestMemCheckHandler;
this->TestingHandlers["submit"] = new cmCTestSubmitHandler;
+ this->TestingHandlers["upload"] = new cmCTestUploadHandler;
cmCTest::t_TestingHandlers::iterator it;
for ( it = this->TestingHandlers.begin();
@@ -390,7 +399,7 @@ void cmCTest::SetParallelLevel(int level)
//----------------------------------------------------------------------------
bool cmCTest::ShouldCompressTestOutput()
{
- if(!this->ComputedCompressOutput)
+ if(!this->ComputedCompressTestOutput)
{
std::string cdashVersion = this->GetCDashVersion();
//version >= 1.6?
@@ -399,12 +408,27 @@ bool cmCTest::ShouldCompressTestOutput()
cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
cdashVersion.c_str(), "1.6");
this->CompressTestOutput &= cdashSupportsGzip;
- this->ComputedCompressOutput = true;
+ this->ComputedCompressTestOutput = true;
}
return this->CompressTestOutput;
}
//----------------------------------------------------------------------------
+bool cmCTest::ShouldCompressMemCheckOutput()
+{
+ if(!this->ComputedCompressMemCheckOutput)
+ {
+ std::string cdashVersion = this->GetCDashVersion();
+
+ bool compressionSupported = cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER, cdashVersion.c_str(), "1.9.0");
+ this->CompressMemCheckOutput &= compressionSupported;
+ this->ComputedCompressMemCheckOutput = true;
+ }
+ return this->CompressMemCheckOutput;
+}
+
+//----------------------------------------------------------------------------
std::string cmCTest::GetCDashVersion()
{
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -1584,6 +1608,56 @@ int cmCTest::GenerateNotesFile(const char* cfiles)
}
//----------------------------------------------------------------------
+std::string cmCTest::Base64GzipEncodeFile(std::string file)
+{
+ std::string tarFile = file + "_temp.tar.gz";
+ std::vector<cmStdString> files;
+ files.push_back(file);
+
+ if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false))
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while "
+ "encoding file: " << file << std::endl);
+ return "";
+ }
+ std::string base64 = this->Base64EncodeFile(tarFile);
+ cmSystemTools::RemoveFile(tarFile.c_str());
+ return base64;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::Base64EncodeFile(std::string file)
+{
+ long len = cmSystemTools::FileLength(file.c_str());
+ std::ifstream ifs(file.c_str(), std::ios::in
+#ifdef _WIN32
+ | std::ios::binary
+#endif
+ );
+ unsigned char *file_buffer = new unsigned char [ len + 1 ];
+ ifs.read(reinterpret_cast<char*>(file_buffer), len);
+ ifs.close();
+
+ unsigned char *encoded_buffer
+ = new unsigned char [ static_cast<int>(
+ static_cast<double>(len) * 1.5 + 5.0) ];
+
+ unsigned long rlen
+ = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+
+ std::string base64 = "";
+ for(unsigned long i = 0; i < rlen; i++)
+ {
+ base64 += encoded_buffer[i];
+ }
+ delete [] file_buffer;
+ delete [] encoded_buffer;
+
+ return base64;
+}
+
+
+//----------------------------------------------------------------------
bool cmCTest::SubmitExtraFiles(const std::vector<cmStdString> &files)
{
std::vector<cmStdString>::const_iterator it;
@@ -1872,6 +1946,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
if(this->CheckArgument(arg, "--no-compress-output"))
{
this->CompressTestOutput = false;
+ this->CompressMemCheckOutput = false;
}
if(this->CheckArgument(arg, "--print-labels"))
@@ -3001,3 +3076,56 @@ void cmCTest::OutputTestErrors(std::vector<char> const &process_output)
}
cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl << std::flush);
}
+
+//----------------------------------------------------------------------
+bool cmCTest::CompressString(std::string& str)
+{
+ int ret;
+ z_stream strm;
+
+ unsigned char* in = reinterpret_cast<unsigned char*>(
+ const_cast<char*>(str.c_str()));
+ //zlib makes the guarantee that this is the maximum output size
+ int outSize = static_cast<int>(
+ static_cast<double>(str.size()) * 1.001 + 13.0);
+ unsigned char* out = new unsigned char[outSize];
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ ret = deflateInit(&strm, -1); //default compression level
+ if (ret != Z_OK)
+ {
+ return false;
+ }
+
+ strm.avail_in = static_cast<uInt>(str.size());
+ strm.next_in = in;
+ strm.avail_out = outSize;
+ strm.next_out = out;
+ ret = deflate(&strm, Z_FINISH);
+
+ if(ret == Z_STREAM_ERROR || ret != Z_STREAM_END)
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Error during gzip compression."
+ << std::endl);
+ return false;
+ }
+
+ (void)deflateEnd(&strm);
+
+ // Now base64 encode the resulting binary string
+ unsigned char* base64EncodedBuffer
+ = new unsigned char[static_cast<int>(outSize * 1.5)];
+
+ unsigned long rlen
+ = cmsysBase64_Encode(out, strm.total_out, base64EncodedBuffer, 1);
+
+ str = "";
+ str.append(reinterpret_cast<char*>(base64EncodedBuffer), rlen);
+
+ delete [] base64EncodedBuffer;
+ delete [] out;
+
+ return true;
+}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index e54a205..44a5349 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -61,6 +61,7 @@ public:
PartSubmit,
PartNotes,
PartExtraFiles,
+ PartUpload,
PartCount // Update names in constructor when adding a part
};
@@ -192,8 +193,13 @@ public:
///! Get the current time as string
std::string CurrentTime();
+ //! tar/gzip and then base 64 encode a file
+ std::string Base64GzipEncodeFile(std::string file);
+ //! base64 encode a file
+ std::string Base64EncodeFile(std::string file);
+
/**
- * Return the time remaianing that the script is allowed to run in
+ * Return the time remaining that the script is allowed to run in
* seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
* not been set it returns 1e7 seconds
*/
@@ -213,6 +219,8 @@ public:
bool ShouldPrintLabels() { return this->PrintLabels; }
bool ShouldCompressTestOutput();
+ bool ShouldCompressMemCheckOutput();
+ bool CompressString(std::string& str);
std::string GetCDashVersion();
@@ -424,7 +432,8 @@ private:
bool RunConfigurationScript;
//flag for lazy getter (optimization)
- bool ComputedCompressOutput;
+ bool ComputedCompressTestOutput;
+ bool ComputedCompressMemCheckOutput;
int GenerateNotesFile(const char* files);
@@ -481,8 +490,8 @@ private:
bool ShortDateFormat;
bool CompressXMLFiles;
-
bool CompressTestOutput;
+ bool CompressMemCheckOutput;
void InitStreams();
std::ostream* StreamOut;
@@ -515,7 +524,7 @@ private:
//! Reread the configuration file
bool UpdateCTestConfiguration();
- //! Create not from files.
+ //! Create note from files.
int GenerateCTestNotesOutput(std::ostream& os,
const VectorOfStrings& files);
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index f2431e6..ea25e60 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -546,7 +546,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"make based generators. If this variable is supported, "
"then CMake will also provide initial values for the "
"variables with the name "
- " CMAKE_C_FLAGS_[Debug|Release|RelWithDebInfo|MinSizeRel]."
+ " CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]."
" For example, if CMAKE_BUILD_TYPE is Debug, then "
"CMAKE_C_FLAGS_DEBUG will be added to the CMAKE_C_FLAGS.",false,
"Variables That Change Behavior");
@@ -822,6 +822,18 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"set to the output of uname -r. On other "
"systems this is set to major-minor version numbers.",false,
"Variables That Describe the System");
+ cm->DefineProperty
+ ("CMAKE_LIBRARY_ARCHITECTURE", cmProperty::VARIABLE,
+ "Target architecture library directory name, if detected.",
+ "This is the value of CMAKE_<lang>_LIBRARY_ARCHITECTURE as "
+ "detected for one of the enabled languages.",false,
+ "Variables That Describe the System");
+ cm->DefineProperty
+ ("CMAKE_LIBRARY_ARCHITECTURE_REGEX", cmProperty::VARIABLE,
+ "Regex matching possible target architecture library directory names.",
+ "This is used to detect CMAKE_<lang>_LIBRARY_ARCHITECTURE from the "
+ "implicit linker search path by matching the <arch> name.",false,
+ "Variables That Describe the System");
cm->DefineProperty
("CMAKE_HOST_SYSTEM", cmProperty::VARIABLE,
@@ -1360,6 +1372,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Variables for Languages");
cm->DefineProperty
+ ("CMAKE_<LANG>_LIBRARY_ARCHITECTURE", cmProperty::VARIABLE,
+ "Target architecture library directory name detected for <lang>.",
+ "If the <lang> compiler passes to the linker an architecture-specific "
+ "system library search directory such as <prefix>/lib/<arch> this "
+ "variable contains the <arch> name if/as detected by CMake.",false,
+ "Variables for Languages");
+
+ cm->DefineProperty
("CMAKE_<LANG>_LINKER_PREFERENCE_PROPAGATES", cmProperty::VARIABLE,
"True if CMAKE_<LANG>_LINKER_PREFERENCE propagates across targets.",
"This is used when CMake selects a linker language for a target. "
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index c4ea425..8e26b8e 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -403,7 +403,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// for each sub project create a linked resource to the source dir
// - only if it is an out-of-source build
this->AppendLinkedResource(fout, "[Subprojects]",
- "virtual:/virtual");
+ "virtual:/virtual", true);
for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
@@ -1082,17 +1082,24 @@ void cmExtraEclipseCDT4Generator
void cmExtraEclipseCDT4Generator
::AppendLinkedResource (cmGeneratedFileStream& fout,
const std::string& name,
- const std::string& path)
+ const std::string& path,
+ bool isVirtualFolder)
{
+ const char* locationTag = "location";
+ if (isVirtualFolder) // ... and not a linked folder
+ {
+ locationTag = "locationURI";
+ }
+
fout <<
"\t\t<link>\n"
"\t\t\t<name>"
<< cmExtraEclipseCDT4Generator::EscapeForXML(name)
<< "</name>\n"
"\t\t\t<type>2</type>\n"
- "\t\t\t<locationURI>"
+ "\t\t\t<" << locationTag << ">"
<< cmExtraEclipseCDT4Generator::EscapeForXML(path)
- << "</locationURI>\n"
+ << "</" << locationTag << ">\n"
"\t\t</link>\n"
;
}
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index 99e69c4..a683731 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -87,7 +87,8 @@ private:
static void AppendLinkedResource (cmGeneratedFileStream& fout,
const std::string& name,
- const std::string& path);
+ const std::string& path,
+ bool isVirtualFolder = false);
bool AppendOutLinkedResource(cmGeneratedFileStream& fout,
const std::string& defname,
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d28de08..9a3de9b 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2614,6 +2614,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
++i;
long timeout = 0;
+ long inactivity_timeout = 0;
std::string verboseLog;
std::string statusVar;
std::string expectedMD5sum;
@@ -2634,6 +2635,19 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
}
+ else if(*i == "INACTIVITY_TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ inactivity_timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
+ return false;
+ }
+ }
else if(*i == "LOG")
{
++i;
@@ -2770,6 +2784,13 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
check_curl_result(res, "DOWNLOAD cannot set timeout: ");
}
+ if(inactivity_timeout > 0)
+ {
+ // Give up if there is no progress for a long time.
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
+ }
+
// Need the progress helper's scope to last through the duration of
// the curl_easy_perform call... so this object is declared at function
// scope intentionally, rather than inside the "if(showProgress)"
@@ -2883,6 +2904,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
++i;
long timeout = 0;
+ long inactivity_timeout = 0;
std::string logVar;
std::string statusVar;
bool showProgress = false;
@@ -2902,6 +2924,19 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
return false;
}
}
+ else if(*i == "INACTIVITY_TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ inactivity_timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
+ return false;
+ }
+ }
else if(*i == "LOG")
{
++i;
@@ -3003,6 +3038,13 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
check_curl_result(res, "UPLOAD cannot set timeout: ");
}
+ if(inactivity_timeout > 0)
+ {
+ // Give up if there is no progress for a long time.
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
+ }
+
// Need the progress helper's scope to last through the duration of
// the curl_easy_perform call... so this object is declared at function
// scope intentionally, rather than inside the "if(showProgress)"
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 1b6dbbf..162890a 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -80,10 +80,11 @@ public:
" file(RELATIVE_PATH variable directory file)\n"
" file(TO_CMAKE_PATH path result)\n"
" file(TO_NATIVE_PATH path result)\n"
- " file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log]\n"
- " [EXPECTED_MD5 sum] [SHOW_PROGRESS])\n"
- " file(UPLOAD filename url [TIMEOUT timeout] [STATUS status]\n"
- " [LOG log] [SHOW_PROGRESS])\n"
+ " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n"
+ " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n"
+ " [EXPECTED_MD5 sum])\n"
+ " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
+ " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
"WRITE will write a message into a file called 'filename'. It "
"overwrites the file if it already exists, and creates the file "
"if it does not exist.\n"
@@ -161,6 +162,8 @@ public:
"numeric error means no error in the operation. "
"If TIMEOUT time is specified, the operation will "
"timeout after time seconds, time should be specified as an integer. "
+ "The INACTIVITY_TIMEOUT specifies an integer number of seconds of "
+ "inactivity after which the operation should terminate. "
"If EXPECTED_MD5 sum is specified, the operation will verify that the "
"downloaded file's actual md5 sum matches the expected value. If it "
"does not match, the operation fails with an error. "
@@ -176,6 +179,8 @@ public:
"numeric error means no error in the operation. "
"If TIMEOUT time is specified, the operation will "
"timeout after time seconds, time should be specified as an integer. "
+ "The INACTIVITY_TIMEOUT specifies an integer number of seconds of "
+ "inactivity after which the operation should terminate. "
"If SHOW_PROGRESS is specified, progress information will be printed "
"as status messages until the operation is complete."
"\n"
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index d0fe99f..ce9deb1 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -72,12 +72,14 @@ void cmFindBase::GenerateDocumentation()
"1. Search paths specified in cmake-specific cache variables. "
"These are intended to be used on the command line with a -DVAR=value. "
"This can be skipped if NO_CMAKE_PATH is passed.\n"
+ "XXX_EXTRA_PREFIX_ENTRY"
" <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_PREFIX_PATH\n"
" CMAKE_XXX_PATH\n"
" CMAKE_XXX_MAC_PATH\n"
"2. Search paths specified in cmake-specific environment variables. "
"These are intended to be set in the user's shell configuration. "
"This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed.\n"
+ "XXX_EXTRA_PREFIX_ENTRY"
" <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_PREFIX_PATH\n"
" CMAKE_XXX_PATH\n"
" CMAKE_XXX_MAC_PATH\n"
@@ -92,6 +94,7 @@ void cmFindBase::GenerateDocumentation()
"5. Search cmake variables defined in the Platform files "
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
"is passed.\n"
+ "XXX_EXTRA_PREFIX_ENTRY"
" <prefix>/XXX_SUBDIR for each <prefix> in CMAKE_SYSTEM_PREFIX_PATH\n"
" CMAKE_SYSTEM_XXX_PATH\n"
" CMAKE_SYSTEM_XXX_MAC_PATH\n"
@@ -346,6 +349,15 @@ void cmFindBase::AddPrefixPaths(std::vector<std::string> const& in_paths,
{
dir += "/";
}
+ if(subdir == "lib")
+ {
+ const char* arch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
+ if(arch && *arch)
+ {
+ this->AddPathInternal(dir+"lib/"+arch, pathType);
+ }
+ }
std::string add = dir + subdir;
if(add != "/")
{
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index b309376..6355a85 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -44,6 +44,10 @@ void cmFindLibraryCommand::GenerateDocumentation()
"SEARCH_XXX", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"XXX_SUBDIR", "lib");
+ cmSystemTools::ReplaceString(
+ this->GenericDocumentation,
+ "XXX_EXTRA_PREFIX_ENTRY",
+ " <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index fdc1a01..5f106bc 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -54,7 +54,8 @@ cmFindPackageCommand::cmFindPackageCommand()
this->CMakePathName = "PACKAGE";
this->Quiet = false;
this->Required = false;
- this->NoRegistry = false;
+ this->NoUserRegistry = false;
+ this->NoSystemRegistry = false;
this->NoBuilds = false;
this->NoModule = false;
this->DebugMode = false;
@@ -101,9 +102,10 @@ void cmFindPackageCommand::GenerateDocumentation()
"The [version] argument requests a version with which the package found "
"should be compatible (format is major[.minor[.patch[.tweak]]]). "
"The EXACT option requests that the version be matched exactly. "
- "If no [version] is given to a recursive invocation inside a "
- "find-module, the [version] and EXACT arguments are forwarded "
- "automatically from the outer call. "
+ "If no [version] and/or component list is given to a recursive "
+ "invocation inside a find-module, the corresponding arguments "
+ "are forwarded automatically from the outer call (including the "
+ "EXACT flag for [version]). "
"Version support is currently provided only on a package-by-package "
"basis (details below).\n"
"User code should generally look for packages using the above simple "
@@ -139,6 +141,7 @@ void cmFindPackageCommand::GenerateDocumentation()
" [NO_CMAKE_PACKAGE_REGISTRY]\n"
" [NO_CMAKE_BUILDS_PATH]\n"
" [NO_CMAKE_SYSTEM_PATH]\n"
+ " [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n"
" [CMAKE_FIND_ROOT_PATH_BOTH |\n"
" ONLY_CMAKE_FIND_ROOT_PATH |\n"
" NO_CMAKE_FIND_ROOT_PATH])\n"
@@ -240,9 +243,9 @@ void cmFindPackageCommand::GenerateDocumentation()
" <prefix>/(cmake|CMake)/ (W)\n"
" <prefix>/<name>*/ (W)\n"
" <prefix>/<name>*/(cmake|CMake)/ (W)\n"
- " <prefix>/(share|lib)/cmake/<name>*/ (U)\n"
- " <prefix>/(share|lib)/<name>*/ (U)\n"
- " <prefix>/(share|lib)/<name>*/(cmake|CMake)/ (U)\n"
+ " <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)\n"
+ " <prefix>/(lib/<arch>|lib|share)/<name>*/ (U)\n"
+ " <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)\n"
"On systems supporting OS X Frameworks and Application Bundles "
"the following directories are searched for frameworks or bundles "
"containing a configuration file:\n"
@@ -254,6 +257,7 @@ void cmFindPackageCommand::GenerateDocumentation()
" <prefix>/<name>.app/Contents/Resources/CMake/ (A)\n"
"In all cases the <name> is treated as case-insensitive and corresponds "
"to any of the names specified (<package> or names given by NAMES). "
+ "Paths with lib/<arch> are enabled if CMAKE_LIBRARY_ARCHITECTURE is set. "
"If PATH_SUFFIXES is specified the suffixes are appended to each "
"(W) or (U) directory entry one-by-one.\n"
"This set of directories is intended to work in cooperation with "
@@ -298,9 +302,16 @@ void cmFindPackageCommand::GenerateDocumentation()
"dependent projects one after another.\n"
"6. Search paths stored in the CMake user package registry. "
"This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
- "Paths are stored in the registry when CMake configures a project "
- "that invokes export(PACKAGE <name>). "
- "See the export(PACKAGE) command documentation for more details."
+ "On Windows a <package> may appear under registry key\n"
+ " HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\<package>\n"
+ "as a REG_SZ value, with arbitrary name, that specifies the directory "
+ "containing the package configuration file. "
+ "On UNIX platforms a <package> may appear under the directory\n"
+ " ~/.cmake/packages/<package>\n"
+ "as a file, with arbitrary name, whose content specifies the directory "
+ "containing the package configuration file. "
+ "See the export(PACKAGE) command to create user package registry entries "
+ "for project build trees."
"\n"
"7. Search cmake variables defined in the Platform files "
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
@@ -308,7 +319,15 @@ void cmFindPackageCommand::GenerateDocumentation()
" CMAKE_SYSTEM_PREFIX_PATH\n"
" CMAKE_SYSTEM_FRAMEWORK_PATH\n"
" CMAKE_SYSTEM_APPBUNDLE_PATH\n"
- "8. Search paths specified by the PATHS option. "
+ "8. Search paths stored in the CMake system package registry. "
+ "This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed. "
+ "On Windows a <package> may appear under registry key\n"
+ " HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\<package>\n"
+ "as a REG_SZ value, with arbitrary name, that specifies the directory "
+ "containing the package configuration file. "
+ "There is no system package registry on non-Windows platforms."
+ "\n"
+ "9. Search paths specified by the PATHS option. "
"These are typically hard-coded guesses.\n"
;
this->CommandDocumentation += this->GenericDocumentationMacPolicy;
@@ -344,6 +363,13 @@ bool cmFindPackageCommand
// Check for debug mode.
this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
+ // Lookup target architecture, if any.
+ if(const char* arch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
+ {
+ this->LibraryArchitecture = arch;
+ }
+
// Lookup whether lib64 paths should be used.
if(this->Makefile->PlatformIs64Bit() &&
this->Makefile->GetCMakeInstance()
@@ -443,7 +469,14 @@ bool cmFindPackageCommand
}
else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
{
- this->NoRegistry = true;
+ this->NoUserRegistry = true;
+ this->NoModule = true;
+ this->Compatibility_1_6 = false;
+ doing = DoingNone;
+ }
+ else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
+ {
+ this->NoSystemRegistry = true;
this->NoModule = true;
this->Compatibility_1_6 = false;
doing = DoingNone;
@@ -524,7 +557,7 @@ bool cmFindPackageCommand
cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
}
- if(this->Version.empty())
+ if(this->Version.empty() || components.empty())
{
// Check whether we are recursing inside "Find<name>.cmake" within
// another find_package(<name>) call.
@@ -532,16 +565,24 @@ bool cmFindPackageCommand
mod += "_FIND_MODULE";
if(this->Makefile->IsOn(mod.c_str()))
{
- // Get version information from the outer call if necessary.
- // Requested version string.
- std::string ver = this->Name;
- ver += "_FIND_VERSION";
- this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
-
- // Whether an exact version is required.
- std::string exact = this->Name;
- exact += "_FIND_VERSION_EXACT";
- this->VersionExact = this->Makefile->IsOn(exact.c_str());
+ if(this->Version.empty())
+ {
+ // Get version information from the outer call if necessary.
+ // Requested version string.
+ std::string ver = this->Name;
+ ver += "_FIND_VERSION";
+ this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
+
+ // Whether an exact version is required.
+ std::string exact = this->Name;
+ exact += "_FIND_VERSION_EXACT";
+ this->VersionExact = this->Makefile->IsOn(exact.c_str());
+ }
+ if(components.empty())
+ {
+ std::string components_var = this->Name + "_FIND_COMPONENTS";
+ components = this->Makefile->GetSafeDefinition(components_var.c_str());
+ }
}
}
@@ -1172,9 +1213,10 @@ void cmFindPackageCommand::ComputePrefixes()
this->AddPrefixesCMakeEnvironment();
this->AddPrefixesUserHints();
this->AddPrefixesSystemEnvironment();
- this->AddPrefixesRegistry();
+ this->AddPrefixesUserRegistry();
this->AddPrefixesBuilds();
this->AddPrefixesCMakeSystemVariable();
+ this->AddPrefixesSystemRegistry();
this->AddPrefixesUserGuess();
this->ComputeFinalPrefixes();
}
@@ -1240,15 +1282,15 @@ void cmFindPackageCommand::AddPrefixesSystemEnvironment()
}
//----------------------------------------------------------------------------
-void cmFindPackageCommand::AddPrefixesRegistry()
+void cmFindPackageCommand::AddPrefixesUserRegistry()
{
- if(this->NoRegistry || this->NoDefaultPath)
+ if(this->NoUserRegistry || this->NoDefaultPath)
{
return;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- this->LoadPackageRegistryWin();
+ this->LoadPackageRegistryWinUser();
#elif defined(__HAIKU__)
BPath dir;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK)
@@ -1268,18 +1310,63 @@ void cmFindPackageCommand::AddPrefixesRegistry()
#endif
}
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesSystemRegistry()
+{
+ if(this->NoSystemRegistry || this->NoDefaultPath)
+ {
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LoadPackageRegistryWinSystem();
+#endif
+}
+
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <windows.h>
# undef GetCurrentDirectory
+ // http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
+# if !defined(KEY_WOW64_32KEY)
+# define KEY_WOW64_32KEY 0x0200
+# endif
+# if !defined(KEY_WOW64_64KEY)
+# define KEY_WOW64_64KEY 0x0100
+# endif
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryWinUser()
+{
+ // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
+ this->LoadPackageRegistryWin(true, 0);
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryWinSystem()
+{
+ // HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views.
+ // Prefer the target platform view first.
+ if(this->Makefile->PlatformIs64Bit())
+ {
+ this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
+ }
+ else
+ {
+ this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
+ }
+}
+
//----------------------------------------------------------------------------
-void cmFindPackageCommand::LoadPackageRegistryWin()
+void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
+ unsigned int view)
{
std::string key = "Software\\Kitware\\CMake\\Packages\\";
key += this->Name;
std::set<cmStdString> bad;
HKEY hKey;
- if(RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
- 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
+ 0, KEY_QUERY_VALUE|view, &hKey) == ERROR_SUCCESS)
{
DWORD valueType = REG_NONE;
char name[16384];
@@ -1299,13 +1386,12 @@ void cmFindPackageCommand::LoadPackageRegistryWin()
{
data[dataSize] = 0;
cmsys_ios::stringstream ss(&data[0]);
- if(this->CheckPackageRegistryEntry(ss))
+ if(!this->CheckPackageRegistryEntry(ss))
{
- // The entry is okay.
- continue;
+ // The entry is invalid.
+ bad.insert(name);
}
}
- bad.insert(name);
break;
case ERROR_MORE_DATA:
data.resize(dataSize+1);
@@ -1317,9 +1403,9 @@ void cmFindPackageCommand::LoadPackageRegistryWin()
}
// Remove bad values if possible.
- if(!bad.empty() &&
+ if(user && !bad.empty() &&
RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
- 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
+ 0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS)
{
for(std::set<cmStdString>::const_iterator vi = bad.begin();
vi != bad.end(); ++vi)
@@ -2111,6 +2197,10 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
// Construct list of common install locations (lib and share).
std::vector<std::string> common;
+ if(!this->LibraryArchitecture.empty())
+ {
+ common.push_back("lib/"+this->LibraryArchitecture);
+ }
if(this->UseLib64Paths)
{
common.push_back("lib64");
@@ -2118,7 +2208,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
common.push_back("lib");
common.push_back("share");
- // PREFIX/(share|lib)/cmake/(Foo|foo|FOO).*/
+ // PREFIX/(lib/ARCH|lib|share)/cmake/(Foo|foo|FOO).*/
{
cmFindPackageFileList lister(this);
lister
@@ -2132,7 +2222,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
}
}
- // PREFIX/(share|lib)/(Foo|foo|FOO).*/
+ // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/
{
cmFindPackageFileList lister(this);
lister
@@ -2145,7 +2235,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
}
}
- // PREFIX/(share|lib)/(Foo|foo|FOO).*/(cmake|CMake)/
+ // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/(cmake|CMake)/
{
cmFindPackageFileList lister(this);
lister
@@ -2277,11 +2367,3 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
}
// TODO: Debug cmsys::Glob double slash problem.
-
-// TODO: Add registry entries after cmake system search path?
-// Currently the user must specify them with the PATHS option.
-//
-// [HKEY_CURRENT_USER\Software\*\Foo*;InstallDir]
-// [HKEY_CURRENT_USER\Software\*\*\Foo*;InstallDir]
-// [HKEY_LOCAL_MACHINE\Software\*\Foo*;InstallDir]
-// [HKEY_LOCAL_MACHINE\Software\*\*\Foo*;InstallDir]
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 19d2b10..2b2e1da 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -87,14 +87,17 @@ private:
void AddPrefixesCMakeEnvironment();
void AddPrefixesCMakeVariable();
void AddPrefixesSystemEnvironment();
- void AddPrefixesRegistry();
+ void AddPrefixesUserRegistry();
+ void AddPrefixesSystemRegistry();
void AddPrefixesBuilds();
void AddPrefixesCMakeSystemVariable();
void AddPrefixesUserGuess();
void AddPrefixesUserHints();
void ComputeFinalPrefixes();
void LoadPackageRegistryDir(std::string const& dir);
- void LoadPackageRegistryWin();
+ void LoadPackageRegistryWinUser();
+ void LoadPackageRegistryWinSystem();
+ void LoadPackageRegistryWin(bool user, unsigned int view);
bool CheckPackageRegistryEntry(std::istream& is);
bool SearchDirectory(std::string const& dir);
bool CheckDirectory(std::string const& dir);
@@ -132,11 +135,13 @@ private:
bool Required;
bool Compatibility_1_6;
bool NoModule;
- bool NoRegistry;
+ bool NoUserRegistry;
+ bool NoSystemRegistry;
bool NoBuilds;
bool DebugMode;
bool UseLib64Paths;
bool PolicyScope;
+ std::string LibraryArchitecture;
std::vector<std::string> Names;
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 83b651b..846d187 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -46,6 +46,8 @@ void cmFindPathCommand::GenerateDocumentation()
cmSystemTools::ReplaceString(this->GenericDocumentation,
"XXX_SUBDIR", "include");
cmSystemTools::ReplaceString(this->GenericDocumentation,
+ "XXX_EXTRA_PREFIX_ENTRY", "");
+ cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
if(!this->IncludeFileInPath)
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 71cfdcb..7c56ad7 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -42,6 +42,8 @@ void cmFindProgramCommand::GenerateDocumentation()
cmSystemTools::ReplaceString(this->GenericDocumentation,
"XXX_SUBDIR", "[s]bin");
cmSystemTools::ReplaceString(this->GenericDocumentation,
+ "XXX_EXTRA_PREFIX_ENTRY", "");
+ cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
}
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 8710dfc..f88ab0b 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -23,7 +23,7 @@ cmGeneratorExpression::cmGeneratorExpression(
this->TargetInfo.compile("^\\$<TARGET"
"(|_SONAME|_LINKER)" // File with what purpose?
"_FILE(|_NAME|_DIR):" // Filename component.
- "([A-Za-z0-9_-]+)" // Target name.
+ "([A-Za-z0-9_.-]+)" // Target name.
">$");
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index d47fb6f..6c8938e 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -903,8 +903,6 @@ void cmGlobalGenerator::Generate()
}
this->CMakeInstance->UpdateProgress("Generating done", -1);
-
- this->CMakeInstance->RunCheckForUnusedVariables("generation");
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index d9a341c..169d77d 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -24,13 +24,13 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
this->ToolSupportsColor = true;
- this->NoRuleMessages = false;
#if defined(_WIN32) || defined(__VMS)
this->UseLinkScript = false;
#else
this->UseLinkScript = true;
#endif
+ this->CommandDatabase = NULL;
}
void cmGlobalUnixMakefileGenerator3
@@ -139,56 +139,87 @@ void cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
+std::string EscapeJSON(const std::string& s) {
+ std::string result;
+ for (std::string::size_type i = 0; i < s.size(); ++i) {
+ if (s[i] == '"' || s[i] == '\\') {
+ result += '\\';
+ }
+ result += s[i];
+ }
+ return result;
+}
+
void cmGlobalUnixMakefileGenerator3::Generate()
{
// first do superclass method
this->cmGlobalGenerator::Generate();
- cmake* cm = this->GetCMakeInstance();
- if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
+ // initialize progress
+ unsigned long total = 0;
+ for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin();
+ pmi != this->ProgressMap.end(); ++pmi)
{
- this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
+ total += pmi->second.NumberOfActions;
}
- if(!this->NoRuleMessages)
+ // write each target's progress.make this loop is done twice. Bascially the
+ // Generate pass counts all the actions, the first loop below determines
+ // how many actions have progress updates for each target and writes to
+ // corrrect variable values for everything except the all targets. The
+ // second loop actually writes out correct values for the all targets as
+ // well. This is because the all targets require more information that is
+ // computed in the first loop.
+ unsigned long current = 0;
+ for(ProgressMapType::iterator pmi = this->ProgressMap.begin();
+ pmi != this->ProgressMap.end(); ++pmi)
{
- // initialize progress
- unsigned long total = 0;
- for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin();
- pmi != this->ProgressMap.end(); ++pmi)
- {
- total += pmi->second.NumberOfActions;
- }
-
- // write each target's progress.make this loop is done twice. Bascially the
- // Generate pass counts all the actions, the first loop below determines
- // how many actions have progress updates for each target and writes to
- // corrrect variable values for everything except the all targets. The
- // second loop actually writes out correct values for the all targets as
- // well. This is because the all targets require more information that is
- // computed in the first loop.
- unsigned long current = 0;
- for(ProgressMapType::iterator pmi = this->ProgressMap.begin();
- pmi != this->ProgressMap.end(); ++pmi)
- {
- pmi->second.WriteProgressVariables(total, current);
- }
- for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
- {
- cmLocalUnixMakefileGenerator3 *lg =
- static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
- std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
- markFileName += "/";
- markFileName += cmake::GetCMakeFilesDirectory();
- markFileName += "/progress.marks";
- cmGeneratedFileStream markFile(markFileName.c_str());
- markFile << this->CountProgressMarksInAll(lg) << "\n";
- }
+ pmi->second.WriteProgressVariables(total, current);
+ }
+ for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ cmLocalUnixMakefileGenerator3 *lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+ std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
+ markFileName += "/";
+ markFileName += cmake::GetCMakeFilesDirectory();
+ markFileName += "/progress.marks";
+ cmGeneratedFileStream markFile(markFileName.c_str());
+ markFile << this->CountProgressMarksInAll(lg) << "\n";
}
// write the main makefile
this->WriteMainMakefile2();
this->WriteMainCMakefile();
+
+ if (this->CommandDatabase != NULL) {
+ *this->CommandDatabase << std::endl << "]";
+ delete this->CommandDatabase;
+ this->CommandDatabase = NULL;
+ }
+}
+
+void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
+ const std::string &sourceFile, const std::string &workingDirectory,
+ const std::string &compileCommand) {
+ if (this->CommandDatabase == NULL)
+ {
+ std::string commandDatabaseName =
+ std::string(this->GetCMakeInstance()->GetHomeOutputDirectory())
+ + "/compile_commands.json";
+ this->CommandDatabase =
+ new cmGeneratedFileStream(commandDatabaseName.c_str());
+ *this->CommandDatabase << "[" << std::endl;
+ } else {
+ *this->CommandDatabase << "," << std::endl;
+ }
+ *this->CommandDatabase << "{" << std::endl
+ << " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
+ << std::endl
+ << " \"command\": \"" << EscapeJSON(compileCommand) << "\","
+ << std::endl
+ << " \"file\": \"" << EscapeJSON(sourceFile) << "\""
+ << std::endl << "}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
@@ -747,34 +778,30 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
localName += "/all";
depends.clear();
- std::string progressDir;
- if(!this->NoRuleMessages)
+ std::string progressDir =
+ lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
{
- progressDir =
- lg->GetMakefile()->GetHomeOutputDirectory();
- progressDir += cmake::GetCMakeFilesDirectory();
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
+ // all target counts
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " ";
+ std::vector<unsigned long>& progFiles =
+ this->ProgressMap[&t->second].Marks;
+ for (std::vector<unsigned long>::iterator i = progFiles.begin();
+ i != progFiles.end(); ++i)
{
- cmOStringStream progCmd;
- progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
- // all target counts
- progCmd << lg->Convert(progressDir.c_str(),
- cmLocalGenerator::FULL,
- cmLocalGenerator::SHELL);
- progCmd << " ";
- std::vector<unsigned long>& progFiles =
- this->ProgressMap[&t->second].Marks;
- for (std::vector<unsigned long>::iterator i = progFiles.begin();
- i != progFiles.end(); ++i)
- {
- progCmd << " " << *i;
- }
- commands.push_back(progCmd.str());
+ progCmd << " " << *i;
}
- progressDir = "Built target ";
- progressDir += t->first;
- lg->AppendEcho(commands,progressDir.c_str());
+ commands.push_back(progCmd.str());
}
+ progressDir = "Built target ";
+ progressDir += t->first;
+ lg->AppendEcho(commands,progressDir.c_str());
this->AppendGlobalTargetDepends(depends,t->second);
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
@@ -790,42 +817,38 @@ cmGlobalUnixMakefileGenerator3
"all", depends, commands, true);
}
- if(!this->NoRuleMessages)
- {
- // Write the rule.
- commands.clear();
- progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
- progressDir += cmake::GetCMakeFilesDirectory();
+ // Write the rule.
+ commands.clear();
+ progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
- {
- // TODO: Convert the total progress count to a make variable.
- cmOStringStream progCmd;
- progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
- // # in target
- progCmd << lg->Convert(progressDir.c_str(),
- cmLocalGenerator::FULL,
- cmLocalGenerator::SHELL);
- //
- std::set<cmTarget *> emitted;
- progCmd << " "
- << this->CountProgressMarksInTarget(&t->second, emitted);
- commands.push_back(progCmd.str());
- }
- }
+ {
+ // TODO: Convert the total progress count to a make variable.
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+ // # in target
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ //
+ std::set<cmTarget *> emitted;
+ progCmd << " "
+ << this->CountProgressMarksInTarget(&t->second, emitted);
+ commands.push_back(progCmd.str());
+ }
std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
(tmp.c_str(),localName.c_str()));
- if(!this->NoRuleMessages)
- {
- cmOStringStream progCmd;
- progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << lg->Convert(progressDir.c_str(),
- cmLocalGenerator::FULL,
- cmLocalGenerator::SHELL);
- progCmd << " 0";
- commands.push_back(progCmd.str());
- }
+ {
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " 0";
+ commands.push_back(progCmd.str());
+ }
depends.clear();
depends.push_back("cmake_check_build_system");
localName = lg->GetRelativeTargetDirectory(t->second);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index cdc9460..d21d5b9 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -112,6 +112,10 @@ public:
/** Record per-target progress information. */
void RecordTargetProgress(cmMakefileTargetGenerator* tg);
+ void AddCXXCompileCommand(const std::string &sourceFile,
+ const std::string &workingDirectory,
+ const std::string &compileCommand);
+
protected:
void WriteMainMakefile2();
void WriteMainCMakefile();
@@ -159,8 +163,6 @@ protected:
// in the rule to satisfy the make program.
std::string EmptyRuleHackCommand;
- bool NoRuleMessages;
-
// Store per-target progress counters.
struct TargetProgress
{
@@ -178,6 +180,8 @@ protected:
size_t CountProgressMarksInTarget(cmTarget* target,
std::set<cmTarget*>& emitted);
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
+
+ cmGeneratedFileStream *CommandDatabase;
};
#endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d5c0fef..2cbd3ed 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -147,7 +147,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::New()
}
return gg.release();
#else
- std::cerr << "CMake should be built with cmake to use XCode, "
+ std::cerr << "CMake should be built with cmake to use Xcode, "
"default to Xcode 1.5\n";
return new cmGlobalXCodeGenerator;
#endif
@@ -323,6 +323,19 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
}
//----------------------------------------------------------------------------
+std::string
+cmGlobalXCodeGenerator::PostBuildMakeTarget(std::string const& tName,
+ std::string const& configName)
+{
+ std::string out = "PostBuild." + tName;
+ if(this->XcodeVersion > 20)
+ {
+ out += "." + configName;
+ }
+ return out;
+}
+
+//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& gens)
@@ -351,12 +364,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
makecommand.push_back(dir.c_str());
makecommand.push_back("-f");
makecommand.push_back(this->CurrentXCodeHackMakefile.c_str());
- if(this->XcodeVersion > 20)
- {
- makecommand.push_back("all.$(CONFIGURATION)");
- }
- cmCustomCommandLines commandLines;
- commandLines.push_back(makecommand);
+ makecommand.push_back(""); // placeholder, see below
+
// Add Re-Run CMake rules
this->CreateReRunCMakeFile(root, gens);
@@ -383,6 +392,10 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
target.GetType() == cmTarget::SHARED_LIBRARY ||
target.GetType() == cmTarget::MODULE_LIBRARY))
{
+ makecommand[makecommand.size()-1] =
+ this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)");
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(makecommand);
lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
no_depends,
commandLines,
@@ -963,7 +976,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
this->CreateString("0"));
}
- // create list of build phases and create the XCode target
+ // create list of build phases and create the Xcode target
cmXCodeObject* buildPhases =
this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -2437,6 +2450,10 @@ void cmGlobalXCodeGenerator
{
linkLibs += li->Value;
}
+ if(li->Target && !li->Target->IsImported())
+ {
+ target->AddDependTarget(configName, li->Target->GetName());
+ }
}
this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
linkLibs.c_str(), configName);
@@ -2500,62 +2517,119 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
}
}
+cmXCodeObject *cmGlobalXCodeGenerator
+::CreatePBXGroup(cmXCodeObject *parent, cmStdString name)
+{
+ cmXCodeObject* parentChildren = NULL;
+ if(parent)
+ parentChildren = parent->GetObject("children");
+ cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
+ cmXCodeObject* groupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ group->AddAttribute("name", this->CreateString(name.c_str()));
+ group->AddAttribute("children", groupChildren);
+ if(this->XcodeVersion == 15)
+ {
+ group->AddAttribute("refType", this->CreateString("4"));
+ }
+ group->AddAttribute("sourceTree", this->CreateString("<group>"));
+ if(parentChildren)
+ parentChildren->AddObject(group);
+ return group;
+}
+
//----------------------------------------------------------------------------
cmXCodeObject* cmGlobalXCodeGenerator
::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg)
{
- cmStdString s = cmtarget.GetName();
- s += "/";
- s += sg->GetName();
- std::map<cmStdString, cmXCodeObject* >::iterator i =
+ cmStdString s;
+ cmStdString target;
+ const char *targetFolder= cmtarget.GetProperty("FOLDER");
+ if(targetFolder) {
+ target = targetFolder;
+ target += "/";
+ }
+ target += cmtarget.GetName();
+ s = target + "/";
+ s += sg->GetFullName();
+ std::map<cmStdString, cmXCodeObject* >::iterator it =
this->GroupNameMap.find(s);
- if(i != this->GroupNameMap.end())
+ if(it != this->GroupNameMap.end())
{
- return i->second;
+ return it->second;
}
- i = this->TargetGroup.find(cmtarget.GetName());
+
+ it = this->TargetGroup.find(target);
cmXCodeObject* tgroup = 0;
- if(i != this->TargetGroup.end())
+ if(it != this->TargetGroup.end())
{
- tgroup = i->second;
+ tgroup = it->second;
}
else
{
- tgroup = this->CreateObject(cmXCodeObject::PBXGroup);
- this->TargetGroup[cmtarget.GetName()] = tgroup;
- cmXCodeObject* tgroupChildren =
- this->CreateObject(cmXCodeObject::OBJECT_LIST);
- tgroup->AddAttribute("name", this->CreateString(cmtarget.GetName()));
- tgroup->AddAttribute("children", tgroupChildren);
- if(this->XcodeVersion == 15)
+ std::vector<std::string> tgt_folders =
+ cmSystemTools::tokenize(target, "/");
+ cmStdString curr_tgt_folder;
+ for(std::vector<std::string>::size_type i = 0; i < tgt_folders.size();i++)
{
- tgroup->AddAttribute("refType", this->CreateString("4"));
+ curr_tgt_folder += tgt_folders[i];
+ it = this->TargetGroup.find(curr_tgt_folder);
+ if(it == this->TargetGroup.end())
+ {
+ tgroup = this->CreatePBXGroup(tgroup,tgt_folders[i]);
+ this->TargetGroup[curr_tgt_folder] = tgroup;
+ }
+ else
+ {
+ tgroup = it->second;
+ continue;
+ }
+ if(i == 0)
+ {
+ this->SourcesGroupChildren->AddObject(tgroup);
+ }
+ curr_tgt_folder += "/";
}
- tgroup->AddAttribute("sourceTree", this->CreateString("<group>"));
- this->SourcesGroupChildren->AddObject(tgroup);
}
+ this->TargetGroup[target] = tgroup;
// If it's the default source group (empty name) then put the source file
// directly in the tgroup...
//
- if (cmStdString(sg->GetName()) == "")
+ if (cmStdString(sg->GetFullName()) == "")
{
this->GroupNameMap[s] = tgroup;
return tgroup;
}
- cmXCodeObject* tgroupChildren = tgroup->GetObject("children");
- cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
- cmXCodeObject* groupChildren =
- this->CreateObject(cmXCodeObject::OBJECT_LIST);
- group->AddAttribute("name", this->CreateString(sg->GetName()));
- group->AddAttribute("children", groupChildren);
- if(this->XcodeVersion == 15)
+ //It's a recursive folder structure, let's find the real parent group
+ if(std::string(sg->GetFullName()) != std::string(sg->GetName()))
{
- group->AddAttribute("refType", this->CreateString("4"));
+ std::vector<std::string> folders =
+ cmSystemTools::tokenize(sg->GetFullName(), "\\");
+ cmStdString curr_folder = cmtarget.GetName();
+ curr_folder += "/";
+ for(std::vector<std::string>::size_type i = 0; i < folders.size();i++)
+ {
+ curr_folder += folders[i];
+ std::map<cmStdString, cmXCodeObject* >::iterator i_folder =
+ this->GroupNameMap.find(curr_folder);
+ //Create new folder
+ if(i_folder == this->GroupNameMap.end())
+ {
+ cmXCodeObject *group = this->CreatePBXGroup(tgroup,folders[i]);
+ this->GroupNameMap[curr_folder] = group;
+ tgroup = group;
+ }
+ else
+ {
+ tgroup = i_folder->second;
+ }
+ curr_folder = curr_folder + "\\";
+ }
+ return tgroup;
}
- group->AddAttribute("sourceTree", this->CreateString("<group>"));
- tgroupChildren->AddObject(group);
+ cmXCodeObject *group = this->CreatePBXGroup(tgroup,sg->GetName());
this->GroupNameMap[s] = group;
return group;
}
@@ -2882,41 +2956,10 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
// correctly by xcode
makefileStream << "# DO NOT EDIT\n";
makefileStream << "# This makefile makes sure all linkable targets are\n";
- makefileStream << "# up-to-date with anything they link to, avoiding a "
- "bug in XCode 1.5\n";
- for(std::vector<std::string>::const_iterator
- ct = this->CurrentConfigurationTypes.begin();
- ct != this->CurrentConfigurationTypes.end(); ++ct)
- {
- if(this->XcodeVersion < 21 || ct->empty())
- {
- makefileStream << "all: ";
- }
- else
- {
- makefileStream << "all." << *ct << ": ";
- }
- const char* configName = 0;
- if(!ct->empty())
- {
- configName = ct->c_str();
- }
- for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
- i != targets.end(); ++i)
- {
- cmXCodeObject* target = *i;
- cmTarget* t =target->GetTarget();
- if(t->GetType() == cmTarget::EXECUTABLE ||
- t->GetType() == cmTarget::SHARED_LIBRARY ||
- t->GetType() == cmTarget::MODULE_LIBRARY)
- {
- std::string tfull = t->GetFullPath(configName);
- makefileStream << "\\\n\t" <<
- this->ConvertToRelativeForMake(tfull.c_str());
- }
- }
- makefileStream << "\n\n";
- }
+ makefileStream << "# up-to-date with anything they link to\n"
+ "default:\n"
+ "\techo \"Do not invoke directly\"\n"
+ "\n";
makefileStream
<< "# For each target create a dummy rule "
"so the target does not have to exist\n";
@@ -2962,14 +3005,40 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
{
cmXCodeObject* target = *i;
cmTarget* t =target->GetTarget();
+
+ if(t->GetType() == cmTarget::EXECUTABLE ||
+ t->GetType() == cmTarget::STATIC_LIBRARY ||
+ t->GetType() == cmTarget::SHARED_LIBRARY ||
+ t->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ // Declare an entry point for the target post-build phase.
+ makefileStream << this->PostBuildMakeTarget(t->GetName(), *ct)
+ << ":\n";
+ }
+
if(t->GetType() == cmTarget::EXECUTABLE ||
t->GetType() == cmTarget::SHARED_LIBRARY ||
t->GetType() == cmTarget::MODULE_LIBRARY)
{
- // Create a rule for this target.
std::string tfull = t->GetFullPath(configName);
- makefileStream << this->ConvertToRelativeForMake(tfull.c_str())
- << ":";
+ std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
+
+ // Add this target to the post-build phases of its dependencies.
+ std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
+ y = target->GetDependTargets().find(*ct);
+ if(y != target->GetDependTargets().end())
+ {
+ std::vector<cmStdString> const& deptgts = y->second;
+ for(std::vector<cmStdString>::const_iterator d = deptgts.begin();
+ d != deptgts.end(); ++d)
+ {
+ makefileStream << this->PostBuildMakeTarget(*d, *ct) << ": "
+ << trel << "\n";
+ }
+ }
+
+ // Create a rule for this target.
+ makefileStream << trel << ":";
// List dependencies if any exist.
std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
@@ -3112,7 +3181,7 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
const
{
entry.Name = this->GetName();
- entry.Brief = "Generate XCode project files.";
+ entry.Brief = "Generate Xcode project files.";
entry.Full = "";
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 290532a..39a5fd7 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -88,6 +88,8 @@ public:
private:
cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
cmSourceGroup* sg);
+ cmXCodeObject* CreatePBXGroup(cmXCodeObject *parent,
+ cmStdString name);
void CreateGroups(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>&
generators);
@@ -198,6 +200,8 @@ protected:
std::vector<cmXCodeObject*> XCodeObjects;
cmXCodeObject* RootObject;
private:
+ std::string PostBuildMakeTarget(std::string const& tName,
+ std::string const& configName);
cmXCodeObject* MainGroupChildren;
cmXCodeObject* SourcesGroupChildren;
cmXCodeObject* ResourcesGroupChildren;
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index de95aa5..15bad52 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -54,6 +54,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
,GenerateForStaticLibs(true)
,GenerateForSharedLibs(true)
,GenerateForModuleLibs(true)
+,GenerateForExternals(true)
,LocalGenerators(localGenerators)
,HaveTargetsAndLibs(false)
{
@@ -115,36 +116,85 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
__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");
+ __set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS");
+ __set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS");
- cmStdString tmpRegexString;
- __set_if_set(tmpRegexString, "GRAPHVIZ_TARGET_IGNORE_REGEX");
- if (tmpRegexString.size() > 0)
+ cmStdString ignoreTargetsRegexes;
+ __set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS");
+
+ this->TargetsToIgnoreRegex.clear();
+ if (ignoreTargetsRegexes.size() > 0)
{
- if (!this->TargetIgnoreRegex.compile(tmpRegexString.c_str()))
+ std::vector<std::string> ignoreTargetsRegExVector;
+ cmSystemTools::ExpandListArgument(ignoreTargetsRegexes,
+ ignoreTargetsRegExVector);
+ for(std::vector<std::string>::const_iterator itvIt
+ = ignoreTargetsRegExVector.begin();
+ itvIt != ignoreTargetsRegExVector.end();
+ ++ itvIt )
{
- std::cerr << "Could not compile bad regex \"" << tmpRegexString << "\""
- << std::endl;
+ cmStdString currentRegexString(*itvIt);
+ cmsys::RegularExpression currentRegex;
+ if (!currentRegex.compile(currentRegexString.c_str()))
+ {
+ std::cerr << "Could not compile bad regex \"" << currentRegexString
+ << "\"" << std::endl;
+ }
+ this->TargetsToIgnoreRegex.push_back(currentRegex);
}
}
- this->TargetsToIgnore.clear();
- const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
- if ( ignoreTargets )
+}
+
+
+// Iterate over all targets and write for each one a graph which shows
+// which other targets depend on it.
+void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
+{
+ this->CollectTargetsAndLibs();
+
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ this->TargetPtrs.begin();
+ ptrIt != this->TargetPtrs.end();
+ ++ptrIt)
{
- std::vector<std::string> ignoreTargetsVector;
- cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
- for(std::vector<std::string>::iterator itvIt = ignoreTargetsVector.begin();
- itvIt != ignoreTargetsVector.end();
- ++ itvIt )
+ if (ptrIt->second == NULL)
{
- this->TargetsToIgnore.insert(itvIt->c_str());
+ continue;
+ }
+
+ if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
+ {
+ continue;
}
- }
+ std::string currentFilename = fileName;
+ currentFilename += ".";
+ currentFilename += ptrIt->first;
+ currentFilename += ".dependers";
+
+ cmGeneratedFileStream str(currentFilename.c_str());
+ if ( !str )
+ {
+ return;
+ }
+
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
+
+ std::cout << "Writing " << currentFilename << "..." << std::endl;
+ this->WriteHeader(str);
+
+ this->WriteDependerConnections(ptrIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+
+ this->WriteFooter(str);
+ }
}
+// Iterate over all targets and write for each one a graph which shows
+// on which targets it depends.
void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
{
this->CollectTargetsAndLibs();
@@ -297,6 +347,91 @@ void cmGraphVizWriter::WriteConnections(const char* targetName,
}
+void cmGraphVizWriter::WriteDependerConnections(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;
+
+ // now search who links against me
+ for(std::map<cmStdString, const cmTarget*>::const_iterator dependerIt =
+ this->TargetPtrs.begin();
+ dependerIt != this->TargetPtrs.end();
+ ++dependerIt)
+ {
+ if (dependerIt->second == NULL)
+ {
+ continue;
+ }
+
+ if (this->GenerateForTargetType(dependerIt->second->GetType()) == false)
+ {
+ continue;
+ }
+
+ // Now we have a target, check whether it links against targetName.
+ // If so, draw a connection, and then continue with dependers on that one.
+ const cmTarget::LinkLibraryVectorType* ll =
+ &(dependerIt->second->GetOriginalLinkLibraries());
+
+ for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
+ llit != ll->end();
+ ++ llit )
+ {
+ std::string libName = llit->first.c_str();
+ if (libName == targetName)
+ {
+ // So this target links against targetName.
+ std::map<cmStdString, cmStdString>::const_iterator dependerNodeNameIt =
+ this->TargetNamesNodes.find(dependerIt->first);
+
+ if(dependerNodeNameIt != this->TargetNamesNodes.end())
+ {
+ std::string connectionName = dependerNodeNameIt->second;
+ connectionName += "-";
+ connectionName += myNodeName;
+
+ if (insertedConnections.find(connectionName) ==
+ insertedConnections.end())
+ {
+ insertedConnections.insert(connectionName);
+ this->WriteNode(dependerIt->first.c_str(), dependerIt->second,
+ insertedNodes, str);
+
+ str << " \"" << dependerNodeNameIt->second << "\" -> \""
+ << myNodeName << "\"";
+ str << " // " <<targetName<< " -> " <<dependerIt->first<<std::endl;
+ this->WriteDependerConnections(dependerIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+ }
+
+
+ }
+ break;
+ }
+ }
+ }
+
+}
+
+
void cmGraphVizWriter::WriteNode(const char* targetName,
const cmTarget* target,
std::set<std::string>& insertedNodes,
@@ -321,7 +456,10 @@ void cmGraphVizWriter::CollectTargetsAndLibs()
{
this->HaveTargetsAndLibs = true;
int cnt = this->CollectAllTargets();
- this->CollectAllExternalLibs(cnt);
+ if (this->GenerateForExternals)
+ {
+ this->CollectAllExternalLibs(cnt);
+ }
}
}
@@ -410,14 +548,22 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
bool cmGraphVizWriter::IgnoreThisTarget(const char* name)
{
- if (this->TargetIgnoreRegex.is_valid())
+ for(std::vector<cmsys::RegularExpression>::iterator itvIt
+ = this->TargetsToIgnoreRegex.begin();
+ itvIt != this->TargetsToIgnoreRegex.end();
+ ++ itvIt )
{
- if (this->TargetIgnoreRegex.find(name))
+ cmsys::RegularExpression& regEx = *itvIt;
+ if (regEx.is_valid())
{
- return true;
+ if (regEx.find(name))
+ {
+ return true;
+ }
}
}
- return (this->TargetsToIgnore.find(name) != this->TargetsToIgnore.end());
+
+ return false;
}
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 105eb96..f784aa0 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -30,6 +30,7 @@ public:
const char* fallbackSettingsFileName);
void WritePerTargetFiles(const char* fileName);
+ void WriteTargetDependersFiles(const char* fileName);
void WriteGlobalFile(const char* fileName);
@@ -48,6 +49,11 @@ protected:
std::set<std::string>& insertedConnections,
cmGeneratedFileStream& str) const;
+ void WriteDependerConnections(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;
@@ -67,10 +73,9 @@ protected:
bool GenerateForStaticLibs;
bool GenerateForSharedLibs;
bool GenerateForModuleLibs;
+ bool GenerateForExternals;
- cmsys::RegularExpression TargetIgnoreRegex;
-
- std::set<cmStdString> TargetsToIgnore;
+ std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
const std::vector<cmLocalGenerator*>& LocalGenerators;
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index d00f843..3b35d55 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -61,7 +61,7 @@ public:
"Add the given directories to those searched by the compiler for "
"include files. By default the directories are appended onto "
"the current list of directories. This default behavior can be "
- "changed by setting CMAKE_include_directories_BEFORE to ON. "
+ "changed by setting CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. "
"By using BEFORE or AFTER you can select between appending and "
"prepending, independent from the default. "
"If the SYSTEM option is given the compiler will be told that the "
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7b3fc86..7da35eb 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1904,7 +1904,6 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
{
// This is a full path. Return it as given.
dep = inName;
- cmSystemTools::ConvertToUnixSlashes(dep);
return true;
}
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d1214d2..5c2cda1 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2228,17 +2228,23 @@ void cmLocalUnixMakefileGenerator3
return;
}
+ // In a Windows shell we must change drive letter too. The shell
+ // used by NMake and Borland make does not support "cd /d" so this
+ // feature simply cannot work with them (Borland make does not even
+ // support changing the drive letter with just "d:").
+ const char* cd_cmd = this->MinGWMake? "cd /d " : "cd ";
+
if(!this->UnixCD)
{
// On Windows we must perform each step separately and then change
// back because the shell keeps the working directory between
// commands.
- std::string cmd = "cd ";
+ std::string cmd = cd_cmd;
cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
commands.insert(commands.begin(),cmd);
// Change back to the starting directory.
- cmd = "cd ";
+ cmd = cd_cmd;
cmd += this->ConvertToOutputForExisting(relRetDir, tgtDir);
commands.push_back(cmd);
}
@@ -2250,7 +2256,7 @@ void cmLocalUnixMakefileGenerator3
std::vector<std::string>::iterator i = commands.begin();
for (; i != commands.end(); ++i)
{
- std::string cmd = "cd ";
+ std::string cmd = cd_cmd;
cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
cmd += " && ";
cmd += *i;
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index de2a837..1850c16 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -119,7 +119,7 @@ void cmLocalVisualStudio10Generator
}
//----------------------------------------------------------------------------
-std::string cmLocalVisualStudio10Generator::CheckForErrorLine()
+const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
{
- return "if errorlevel 1 goto :VCEnd";
+ return ":VCEnd";
}
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index 06b8b09..0fccdb0 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -38,7 +38,8 @@ public:
const char* path);
protected:
- virtual std::string CheckForErrorLine();
+ virtual const char* ReportErrorLabel() const;
+ virtual bool CustomCommandUseLocal() const { return true; }
private:
};
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index b9ffe62..7a62b9c 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1770,10 +1770,14 @@ cmLocalVisualStudio7Generator
vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
cmSystemTools::KeyWOW64_32);
-
- // Version 10.1 actually uses 9.10 in project files!
- if(intelVersion == "10.1")
+ if (intelVersion == "12.0")
+ {
+ // Version 12 actually uses 11.0 in project files!
+ intelVersion = "11.0" ;
+ }
+ else if(intelVersion == "10.1")
{
+ // Version 10.1 actually uses 9.10 in project files!
intelVersion = "9.10";
}
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 39f9962..4390a08 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -154,15 +154,15 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
}
//----------------------------------------------------------------------------
-std::string cmLocalVisualStudioGenerator::CheckForErrorLine()
+const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const
{
- return "if errorlevel 1 goto :VCReportError";
+ return ":VCReportError";
}
//----------------------------------------------------------------------------
-std::string cmLocalVisualStudioGenerator::GetCheckForErrorLine()
+const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
{
- return this->CheckForErrorLine();
+ return this->ReportErrorLabel();
}
//----------------------------------------------------------------------------
@@ -172,6 +172,7 @@ cmLocalVisualStudioGenerator
const char* configName,
const char* newline_text)
{
+ bool useLocal = this->CustomCommandUseLocal();
const cmCustomCommandLines& commandLines = cc.GetCommandLines();
const char* workingDirectory = cc.GetWorkingDirectory();
cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
@@ -180,8 +181,29 @@ cmLocalVisualStudioGenerator
// Avoid leading or trailing newlines.
const char* newline = "";
+ // Line to check for error between commands.
+ std::string check_error = newline_text;
+ if(useLocal)
+ {
+ check_error += "if %errorlevel% neq 0 goto :cmEnd";
+ }
+ else
+ {
+ check_error += "if errorlevel 1 goto ";
+ check_error += this->GetReportErrorLabel();
+ }
+
// Store the script in a string.
std::string script;
+
+ // Open a local context.
+ if(useLocal)
+ {
+ script += newline;
+ newline = newline_text;
+ script += "setlocal";
+ }
+
if(workingDirectory)
{
// Change the working directory.
@@ -189,6 +211,7 @@ cmLocalVisualStudioGenerator
newline = newline_text;
script += "cd ";
script += this->Convert(workingDirectory, FULL, SHELL);
+ script += check_error;
// Change the working drive.
if(workingDirectory[0] && workingDirectory[1] == ':')
@@ -197,8 +220,10 @@ cmLocalVisualStudioGenerator
newline = newline_text;
script += workingDirectory[0];
script += workingDirectory[1];
+ script += check_error;
}
}
+
// for visual studio IDE add extra stuff to the PATH
// if CMAKE_MSVCIDE_RUN_PATH is set.
if(this->Makefile->GetDefinition("MSVC_IDE"))
@@ -214,6 +239,7 @@ cmLocalVisualStudioGenerator
script += ";%PATH%";
}
}
+
// Write each command on a single line.
for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
{
@@ -230,9 +256,25 @@ cmLocalVisualStudioGenerator
// If there was an error, jump to the VCReportError label,
// skipping the run of any subsequent commands in this
// sequence.
- //
- script += newline_text;
- script += this->GetCheckForErrorLine();
+ script += check_error;
+ }
+
+ // Close the local context.
+ if(useLocal)
+ {
+ script += newline;
+ script += ":cmEnd";
+ script += newline;
+ script += "endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone";
+ script += newline;
+ script += ":cmErrorLevel";
+ script += newline;
+ script += "exit /b %1";
+ script += newline;
+ script += ":cmDone";
+ script += newline;
+ script += "if %errorlevel% neq 0 goto ";
+ script += this->GetReportErrorLabel();
}
return script;
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index 22112b3..a38bc30 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -37,13 +37,13 @@ public:
const char* configName,
const char* newline = "\n");
- /** Line of batch file text that skips to the end after
- * a failed step in a sequence of custom commands.
- */
- std::string GetCheckForErrorLine();
+ /** Label to which to jump in a batch file after a failed step in a
+ sequence of custom commands. */
+ const char* GetReportErrorLabel() const;
protected:
- virtual std::string CheckForErrorLine();
+ virtual const char* ReportErrorLabel() const;
+ virtual bool CustomCommandUseLocal() const { return false; }
/** Construct a custom command to make exe import lib dir. */
cmsys::auto_ptr<cmCustomCommand>
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 69320da..d0df8f0 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -249,51 +249,17 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
}
//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
+std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
{
- // write language flags for target
- std::set<cmStdString> languages;
- this->Target->GetLanguages(languages);
- // put the compiler in the rules.make file so that if it changes
- // things rebuild
- for(std::set<cmStdString>::const_iterator l = languages.begin();
- l != languages.end(); ++l)
- {
- cmStdString compiler = "CMAKE_";
- compiler += *l;
- compiler += "_COMPILER";
- *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
- this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
- }
-
- for(std::set<cmStdString>::const_iterator l = languages.begin();
- l != languages.end(); ++l)
+ ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
+ if (i == this->FlagsByLanguage.end())
{
- const char *lang = l->c_str();
std::string flags;
- std::string defines;
+ const char *lang = l.c_str();
+
bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
(this->Target->GetType() == cmTarget::MODULE_LIBRARY));
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro, lang);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AppendDefines
- (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang);
- this->LocalGenerator->AppendDefines
- (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang);
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName +=
- cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
- this->LocalGenerator->AppendDefines
- (defines, this->Makefile->GetProperty(defPropName.c_str()), lang);
- this->LocalGenerator->AppendDefines
- (defines, this->Target->GetProperty(defPropName.c_str()), lang);
-
// Add language feature flags.
this->AddFeatureFlags(flags, lang);
@@ -301,7 +267,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
lang, this->ConfigName);
// Fortran-specific flags computed for this target.
- if(*l == "Fortran")
+ if(l == "Fortran")
{
this->AddFortranFlags(flags);
}
@@ -320,14 +286,73 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
this->LocalGenerator->
AppendFlags(flags,this->GetFrameworkFlags().c_str());
- *this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n";
- *this->FlagFileStream << lang << "_DEFINES = " << defines << "\n\n";
+ ByLanguageMap::value_type entry(l, flags);
+ i = this->FlagsByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
+{
+ ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
+ if (i == this->DefinesByLanguage.end())
+ {
+ std::string defines;
+ const char *lang = l.c_str();
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro = this->Target->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro, lang);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName +=
+ cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty(defPropName.c_str()), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty(defPropName.c_str()), lang);
+
+ ByLanguageMap::value_type entry(l, defines);
+ i = this->DefinesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
+{
+ // write language flags for target
+ std::set<cmStdString> languages;
+ this->Target->GetLanguages(languages);
+ // put the compiler in the rules.make file so that if it changes
+ // things rebuild
+ for(std::set<cmStdString>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ cmStdString compiler = "CMAKE_";
+ compiler += *l;
+ compiler += "_COMPILER";
+ *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
+ this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
+ }
+
+ for(std::set<cmStdString>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
+ *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
+ "\n\n";
}
// Add target-specific flags.
if(this->Target->GetProperty("COMPILE_FLAGS"))
{
- std::string flags;
+ std::string flags;
this->LocalGenerator->AppendFlags
(flags, this->Target->GetProperty("COMPILE_FLAGS"));
*this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
@@ -641,6 +666,9 @@ cmMakefileTargetGenerator
vars.Flags = flags.c_str();
vars.Defines = defines.c_str();
+ bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
+ (strcmp(lang, "CXX") == 0));
+
// Construct the compile rules.
{
std::string compileRuleVar = "CMAKE_";
@@ -651,6 +679,23 @@ cmMakefileTargetGenerator
std::vector<std::string> compileCommands;
cmSystemTools::ExpandListArgument(compileRule, compileCommands);
+ if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
+ lang_is_c_or_cxx && compileCommands.size() == 1)
+ {
+ std::string compileCommand = compileCommands[0];
+ this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
+ std::string workingDirectory =
+ this->LocalGenerator->Convert(
+ this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
+ compileCommand.replace(compileCommand.find(langFlags),
+ langFlags.size(), this->GetFlags(lang));
+ std::string langDefines = std::string("$(") + lang + "_DEFINES)";
+ compileCommand.replace(compileCommand.find(langDefines),
+ langDefines.size(), this->GetDefines(lang));
+ this->GlobalGenerator->AddCXXCompileCommand(
+ source.GetFullPath(), workingDirectory, compileCommand);
+ }
+
// Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i)
@@ -691,8 +736,6 @@ cmMakefileTargetGenerator
}
}
- bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
- (strcmp(lang, "CXX") == 0));
bool do_preprocess_rules = lang_is_c_or_cxx &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
bool do_assembly_rules = lang_is_c_or_cxx &&
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index bd26795..b68f8bf 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -216,6 +216,12 @@ protected:
std::string MacContentDirectory;
std::set<cmStdString> MacContentFolders;
+ typedef std::map<cmStdString, cmStdString> ByLanguageMap;
+ std::string GetFlags(const std::string &l);
+ ByLanguageMap FlagsByLanguage;
+ std::string GetDefines(const std::string &l);
+ ByLanguageMap DefinesByLanguage;
+
// Target-wide Fortran module output directory.
bool FortranModuleDirectoryComputed;
std::string FortranModuleDirectory;
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 0da7724..6038472 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -47,8 +47,7 @@ public:
*/
virtual const char* GetTerseDocumentation()
{
- return
- "Output a list of required source files for a specified source file.";
+ return "Deprecated. Approximate C preprocessor dependency scanning.";
}
/**
@@ -57,12 +56,22 @@ public:
virtual const char* GetFullDocumentation()
{
return
+ "This command exists only because ancient CMake versions provided it. "
+ "CMake handles preprocessor dependency scanning automatically using a "
+ "more advanced scanner.\n"
" output_required_files(srcfile outputfile)\n"
"Outputs a list of all the source files that are required by the "
"specified srcfile. This list is written into outputfile. This is "
"similar to writing out the dependencies for srcfile except that it "
"jumps from .h files into .cxx, .c and .cpp files if possible.";
}
+
+ /** This command is kept for compatibility with older CMake versions. */
+ virtual bool IsDiscouraged()
+ {
+ return true;
+ }
+
cmTypeMacro(cmOutputRequiredFilesCommand, cmCommand);
void ListDependencies(cmDependInformation const *info,
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 86ecebe..cabe98a 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -209,6 +209,7 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os,
// In a multi-configuration generator we produce a separate rule
// in a block for each configuration that is built. We restrict
// the list of configurations to those to which this rule applies.
+ bool first = true;
for(std::vector<std::string>::const_iterator i =
this->ConfigurationTypes->begin();
i != this->ConfigurationTypes->end(); ++i)
@@ -218,10 +219,19 @@ void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os,
{
// Generate a per-configuration block.
std::string config_test = this->CreateConfigTest(config);
- os << indent << "IF(" << config_test << ")\n";
+ os << indent << (first? "IF(" : "ELSEIF(") << config_test << ")\n";
this->GenerateScriptForConfig(os, config, indent.Next());
- os << indent << "ENDIF(" << config_test << ")\n";
+ first = false;
}
}
+ if(!first)
+ {
+ if(this->NeedsScriptNoConfig())
+ {
+ os << indent << "ELSE()\n";
+ this->GenerateScriptNoConfig(os, indent.Next());
+ }
+ os << indent << "ENDIF()\n";
+ }
}
}
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index e2a0da5..8b2ca33 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -65,6 +65,8 @@ protected:
virtual void GenerateScriptForConfig(std::ostream& os,
const char* config,
Indent const& indent);
+ virtual void GenerateScriptNoConfig(std::ostream&, Indent const&) {}
+ virtual bool NeedsScriptNoConfig() const { return false; }
// Test if this generator does something for a given configuration.
bool GeneratesForConfig(const char*);
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 27d90db..8e61d0a 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -11,37 +11,6 @@
============================================================================*/
#include "cmSourceGroupCommand.h"
-inline std::vector<std::string> tokenize(const std::string& str,
- const std::string& sep)
-{
- std::vector<std::string> tokens;
- std::string::size_type tokend = 0;
-
- do
- {
- std::string::size_type tokstart=str.find_first_not_of(sep, tokend);
- if (tokstart==std::string::npos)
- {
- break; // no more tokens
- }
- tokend=str.find_first_of(sep,tokstart);
- if (tokend==std::string::npos)
- {
- tokens.push_back(str.substr(tokstart));
- }
- else
- {
- tokens.push_back(str.substr(tokstart,tokend-tokstart));
- }
- } while (tokend!=std::string::npos);
-
- if (tokens.empty())
- {
- tokens.push_back("");
- }
- return tokens;
-}
-
// cmSourceGroupCommand
bool cmSourceGroupCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -58,7 +27,8 @@ bool cmSourceGroupCommand
delimiter = this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER");
}
- std::vector<std::string> folders = tokenize(args[0], delimiter);
+ std::vector<std::string> folders =
+ cmSystemTools::tokenize(args[0], delimiter);
cmSourceGroup* sg = 0;
sg = this->Makefile->GetSourceGroup(folders);
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 19d2369..d239c06 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -677,7 +677,7 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
if ( end < -1 || end > leftOverLength )
{
cmOStringStream ostr;
- ostr << "end index: " << end << " is out of range " << 0 << " - "
+ ostr << "end index: " << end << " is out of range -1 - "
<< leftOverLength;
this->SetError(ostr.str().c_str());
return false;
@@ -770,7 +770,7 @@ bool cmStringCommand
static bool seeded = false;
bool force_seed = false;
- int seed = (int) time(NULL);
+ unsigned int seed = 0;
int length = 5;
const char cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
"QWERTYUIOPASDFGHJKLZXCVBNM"
@@ -797,7 +797,7 @@ bool cmStringCommand
else if ( args[i] == "RANDOM_SEED" )
{
++i;
- seed = atoi(args[i].c_str());
+ seed = static_cast<unsigned int>(atoi(args[i].c_str()));
force_seed = true;
}
}
@@ -825,7 +825,7 @@ bool cmStringCommand
if (!seeded || force_seed)
{
seeded = true;
- srand(seed);
+ srand(force_seed? seed : cmSystemTools::RandomSeed());
}
const char* alphaPtr = alphabet.c_str();
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 9586449..52b83d9 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -110,7 +110,8 @@ public:
"a file.\n"
"TOUPPER/TOLOWER will convert string to upper/lower characters.\n"
"LENGTH will return a given string's length.\n"
- "SUBSTRING will return a substring of a given string.\n"
+ "SUBSTRING will return a substring of a given string. If length is "
+ "-1 the remainder of the string starting at begin will be returned.\n"
"STRIP will return a substring of a given string with leading "
"and trailing spaces removed.\n"
"RANDOM will return a random string of given length consisting of "
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 7bc89a4..dbb2226 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -9,6 +9,9 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
+#if defined(_MSC_VER) && _MSC_VER < 1300
+# define _WIN32_WINNT 0x0400 /* for wincrypt.h */
+#endif
#include "cmSystemTools.h"
#include <ctype.h>
#include <errno.h>
@@ -31,7 +34,9 @@
#if defined(_WIN32)
# include <windows.h>
+# include <wincrypt.h>
#else
+# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
# include <utime.h>
@@ -440,6 +445,13 @@ public:
args.push_back(*arg);
}
}
+ void Store(std::vector<cmStdString>& args) const
+ {
+ for(char** arg = this->ArgV; arg && *arg; ++arg)
+ {
+ args.push_back(*arg);
+ }
+ }
};
//----------------------------------------------------------------------------
@@ -451,6 +463,15 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
argv.Store(args);
}
+//----------------------------------------------------------------------------
+void cmSystemTools::ParseUnixCommandLine(const char* command,
+ std::vector<cmStdString>& args)
+{
+ // Invoke the underlying parser.
+ cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
+ argv.Store(args);
+}
+
std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
int shell_flags)
{
@@ -2233,6 +2254,71 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
}
//----------------------------------------------------------------------------
+#ifdef _WIN32
+# ifndef CRYPT_SILENT
+# define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header. */
+# endif
+static int WinCryptRandom(void* data, size_t size)
+{
+ int result = 0;
+ HCRYPTPROV hProvider = 0;
+ if(CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ result = CryptGenRandom(hProvider, (DWORD)size, (BYTE*)data)? 1:0;
+ CryptReleaseContext(hProvider, 0);
+ }
+ return result;
+}
+#endif
+
+//----------------------------------------------------------------------------
+unsigned int cmSystemTools::RandomSeed()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ unsigned int seed = 0;
+
+ // Try using a real random source.
+ if(WinCryptRandom(&seed, sizeof(seed)))
+ {
+ return seed;
+ }
+
+ // Fall back to the time and pid.
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ unsigned int t1 = static_cast<unsigned int>(ft.dwHighDateTime);
+ unsigned int t2 = static_cast<unsigned int>(ft.dwLowDateTime);
+ unsigned int pid = static_cast<unsigned int>(GetCurrentProcessId());
+ return t1 ^ t2 ^ pid;
+#else
+ union
+ {
+ unsigned int integer;
+ char bytes[sizeof(unsigned int)];
+ } seed;
+
+ // Try using a real random source.
+ std::ifstream fin("/dev/urandom");
+ if(fin && fin.read(seed.bytes, sizeof(seed)) &&
+ fin.gcount() == sizeof(seed))
+ {
+ return seed.integer;
+ }
+
+ // Fall back to the time and pid.
+ struct timeval t;
+ gettimeofday(&t, 0);
+ unsigned int pid = static_cast<unsigned int>(getpid());
+ unsigned int tv_sec = static_cast<unsigned int>(t.tv_sec);
+ unsigned int tv_usec = static_cast<unsigned int>(t.tv_usec);
+ // Since tv_usec never fills more than 11 bits we shift it to fill
+ // in the slow-changing high-order bits of tv_sec.
+ return tv_sec ^ (tv_usec << 21) ^ pid;
+#endif
+}
+
+//----------------------------------------------------------------------------
static std::string cmSystemToolsExecutableDirectory;
void cmSystemTools::FindExecutableDirectory(const char* argv0)
{
@@ -2603,7 +2689,7 @@ bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
else if(lhs[i] > rhs[i])
{
// lhs > rhs, so true if operation is GREATER
- return op == cmSystemTools::OP_GREATER;
+ return op == cmSystemTools::OP_GREATER;
}
}
// lhs == rhs, so true if operation is EQUAL
@@ -2833,3 +2919,35 @@ bool cmSystemTools::RepeatedRemoveDirectory(const char* dir)
}
return false;
}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
+ const std::string& sep)
+{
+ std::vector<std::string> tokens;
+ std::string::size_type tokend = 0;
+
+ do
+ {
+ std::string::size_type tokstart=str.find_first_not_of(sep, tokend);
+ if (tokstart==std::string::npos)
+ {
+ break; // no more tokens
+ }
+ tokend=str.find_first_of(sep,tokstart);
+ if (tokend==std::string::npos)
+ {
+ tokens.push_back(str.substr(tokstart));
+ }
+ else
+ {
+ tokens.push_back(str.substr(tokstart,tokend-tokstart));
+ }
+ } while (tokend!=std::string::npos);
+
+ if (tokens.empty())
+ {
+ tokens.push_back("");
+ }
+ return tokens;
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 6f9147c..ce49959 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -237,6 +237,8 @@ public:
/** Parse arguments out of a unix command line string. */
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
+ static void ParseUnixCommandLine(const char* command,
+ std::vector<cmStdString>& args);
/** Compute an escaped version of the given argument for use in a
windows shell. See kwsys/System.h.in for details. */
@@ -402,6 +404,9 @@ public:
static bool FileTimeGet(const char* fname, cmSystemToolsFileTime* t);
static bool FileTimeSet(const char* fname, cmSystemToolsFileTime* t);
+ /** Random seed generation. */
+ static unsigned int RandomSeed();
+
/** Find the directory containing the running executable. Save it
in a global location to be queried by GetExecutableDirectory
later. */
@@ -439,6 +444,9 @@ public:
/** Remove a directory; repeat a few times in case of locked files. */
static bool RepeatedRemoveDirectory(const char* dir);
+ /** Tokenize a string */
+ static std::vector<std::string> tokenize(const std::string& str,
+ const std::string& sep);
private:
static bool s_ForceUnixPaths;
static bool s_RunCommandHideConsole;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 39f8638..e0892b2 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -130,6 +130,22 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
}
//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os,
+ Indent const& indent)
+{
+ os << indent << "ADD_TEST(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
+}
+
+//----------------------------------------------------------------------------
+bool cmTestGenerator::NeedsScriptNoConfig() const
+{
+ return (this->TestGenerated && // test generated for at least one config
+ this->ActionsPerConfig && // test is config-aware
+ this->Configurations.empty() && // test runs in all configs
+ !this->ConfigurationTypes->empty()); // config-dependent command
+}
+
+//----------------------------------------------------------------------------
void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
Indent const& indent)
{
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 85d9091..2c69fc3 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -34,6 +34,8 @@ protected:
virtual void GenerateScriptForConfig(std::ostream& os,
const char* config,
Indent const& indent);
+ virtual void GenerateScriptNoConfig(std::ostream& os, Indent const& indent);
+ virtual bool NeedsScriptNoConfig() const;
void GenerateOldStyle(std::ostream& os, Indent const& indent);
cmTest* Test;
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index 0c67a8b..9923d03 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -77,14 +77,20 @@ public:
"Specify COPY_FILE to get a copy of the linked executable at the "
"given fileName."
"\n"
- "In this version all files in bindir/CMakeFiles/CMakeTmp, "
- "will be cleaned automatically, for debugging a --debug-trycompile can "
- "be passed to cmake to avoid the clean. Some extra flags that "
- " can be included are, "
+ "In this version all files in bindir/CMakeFiles/CMakeTmp "
+ "will be cleaned automatically. For debugging, --debug-trycompile can "
+ "be passed to cmake to avoid this clean. However, multiple sequential "
+ "try_compile operations reuse this single output directory. If you "
+ "use --debug-trycompile, you can only debug one try_compile call at a "
+ "time. The recommended procedure is to configure with cmake all the "
+ "way through once, then delete the cache entry associated with "
+ "the try_compile call of interest, and then re-run cmake again with "
+ "--debug-trycompile."
+ "\n"
+ "Some extra flags that can be included are, "
"INCLUDE_DIRECTORIES, LINK_DIRECTORIES, and LINK_LIBRARIES. "
"COMPILE_DEFINITIONS are -Ddefinition that will be passed to the "
"compile line. "
-
"try_compile creates a CMakeList.txt "
"file on the fly that looks like this:\n"
" add_definitions( <expanded COMPILE_DEFINITIONS from calling "
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8a27ffd..2a4ff92 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -351,6 +351,9 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
{
if(!cmSystemTools::FileExists(sourcePath.c_str()))
{
+ // Make sure the path exists for the file
+ std::string path = cmSystemTools::GetFilenamePath(sourcePath);
+ cmSystemTools::MakeDirectory(path.c_str());
std::ofstream fout(sourcePath.c_str());
if(fout)
{
@@ -358,6 +361,14 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
fout.flush();
fout.close();
}
+ else
+ {
+ std::string error = "Could not create file: [";
+ error += sourcePath;
+ error += "] ";
+ cmSystemTools::Error
+ (error.c_str(), cmSystemTools::GetLastSystemError().c_str());
+ }
}
}
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
@@ -367,10 +378,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
static_cast<cmGlobalVisualStudio7Generator *>
(this->GlobalGenerator)->GetConfigurations();
this->WriteString("<CustomBuild Include=\"", 2);
- std::string path =
- cmSystemTools::RelativePath(
- this->Makefile->GetCurrentOutputDirectory(),
- sourcePath.c_str());
+ std::string path = sourcePath;
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream ) << path << "\">\n";
for(std::vector<std::string>::iterator i = configs->begin();
@@ -452,11 +460,17 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
bool header = (*s)->GetPropertyAsBool("HEADER_FILE_ONLY")
|| this->GlobalGenerator->IgnoreFile
((*s)->GetExtension().c_str());
+ std::string ext =
+ cmSystemTools::LowerCase((*s)->GetExtension());
if(!lang)
{
lang = "None";
}
- if(lang[0] == 'C')
+ if(header)
+ {
+ headers.push_back(sf);
+ }
+ else if(lang[0] == 'C')
{
clCompile.push_back(sf);
}
@@ -468,11 +482,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
customBuild.push_back(sf);
}
- else if(header)
- {
- headers.push_back(sf);
- }
- else if(sf->GetExtension() == "idl")
+ else if(ext == "idl")
{
idls.push_back(sf);
}
@@ -609,9 +619,6 @@ WriteGroupSources(const char* name,
const char* filter = sourceGroup.GetFullName();
this->WriteString("<", 2);
std::string path = source;
- path = cmSystemTools::RelativePath(
- this->Makefile->GetCurrentOutputDirectory(),
- source.c_str());
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << name << " Include=\""
<< path;
@@ -642,14 +649,28 @@ void cmVisualStudio10TargetGenerator::WriteObjSources()
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
{
- if((*source)->GetExtension() == "obj")
+ std::string ext =
+ cmSystemTools::LowerCase((*source)->GetExtension());
+ if(ext == "obj" || ext == "o")
{
if(first)
{
this->WriteString("<ItemGroup>\n", 1);
first = false;
}
- this->WriteString("<None Include=\"", 2);
+ // If an object file is generated, then vs10
+ // will use it in the build, and we have to list
+ // it as None instead of Object
+ if((*source)->GetPropertyAsBool("GENERATED"))
+ {
+ this->WriteString("<None Include=\"", 2);
+ }
+ // If it is not a generated object then we have
+ // to use the Object type
+ else
+ {
+ this->WriteString("<Object Include=\"", 2);
+ }
(*this->BuildFileStream ) << (*source)->GetFullPath() << "\" />\n";
}
}
@@ -671,8 +692,8 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source)
{
- std::string ext = (*source)->GetExtension();
- if((*source)->GetCustomCommand() || ext == "obj")
+ std::string ext = cmSystemTools::LowerCase((*source)->GetExtension());
+ if((*source)->GetCustomCommand() || ext == "o" || ext == "obj")
{
continue;
}
@@ -685,9 +706,6 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
bool rc = lang && (strcmp(lang, "RC") == 0);
bool idl = ext == "idl";
std::string sourceFile = (*source)->GetFullPath();
- sourceFile = cmSystemTools::RelativePath(
- this->Makefile->GetCurrentOutputDirectory(),
- sourceFile.c_str());
this->ConvertToWindowsSlash(sourceFile);
// output the source file
if(header)
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index ed0d60c..ae496ad 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -299,7 +299,12 @@ cmVisualStudioGeneratorOptions
{
fout << "<" << m->first << ">";
}
- fout << m->second << "</" << m->first << ">\n";
+ fout << m->second;
+ if (m->first == "AdditionalIncludeDirectories")
+ {
+ fout << ";%(AdditionalIncludeDirectories)";
+ }
+ fout << "</" << m->first << ">\n";
}
}
else
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index 5920470..71c7c25 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -146,13 +146,15 @@ void cmXCodeObject::Print(std::ostream& out)
if(j->second->TypeValue == STRING)
{
- out << j->first << " = ";
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = ";
j->second->PrintString(out);
out << ";";
}
else if(j->second->TypeValue == OBJECT_LIST)
{
- out << j->first << " = (";
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = (";
for(unsigned int k = 0; k < j->second->List.size(); k++)
{
if(j->second->List[k]->TypeValue == STRING)
@@ -169,7 +171,8 @@ void cmXCodeObject::Print(std::ostream& out)
}
else
{
- out << j->first << " = error_unexpected_TypeValue_" <<
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = error_unexpected_TypeValue_" <<
j->second->TypeValue << ";";
}
@@ -180,7 +183,8 @@ void cmXCodeObject::Print(std::ostream& out)
}
else if(object->TypeValue == OBJECT_REF)
{
- out << i->first << " = " << object->Object->Id;
+ cmXCodeObject::PrintString(out,i->first);
+ out << " = " << object->Object->Id;
if(object->Object->HasComment() && i->first != "remoteGlobalIDString")
{
out << " ";
@@ -190,7 +194,8 @@ void cmXCodeObject::Print(std::ostream& out)
}
else if(object->TypeValue == STRING)
{
- out << i->first << " = ";
+ cmXCodeObject::PrintString(out,i->first);
+ out << " = ";
object->PrintString(out);
out << ";" << separator;
}
@@ -230,19 +235,19 @@ void cmXCodeObject::CopyAttributes(cmXCodeObject* copy)
}
//----------------------------------------------------------------------------
-void cmXCodeObject::PrintString(std::ostream& os) const
+void cmXCodeObject::PrintString(std::ostream& os,cmStdString String)
{
// The string needs to be quoted if it contains any characters
// considered special by the Xcode project file parser.
bool needQuote =
- (this->String.empty() ||
- this->String.find_first_of(" <>.+-=@$") != this->String.npos);
+ (String.empty() ||
+ String.find_first_of(" <>.+-=@$[]") != String.npos);
const char* quote = needQuote? "\"" : "";
// Print the string, quoted and escaped as necessary.
os << quote;
- for(std::string::const_iterator i = this->String.begin();
- i != this->String.end(); ++i)
+ for(std::string::const_iterator i = String.begin();
+ i != String.end(); ++i)
{
if(*i == '"')
{
@@ -254,6 +259,11 @@ void cmXCodeObject::PrintString(std::ostream& os) const
os << quote;
}
+void cmXCodeObject::PrintString(std::ostream& os) const
+{
+ cmXCodeObject::PrintString(os,this->String);
+}
+
//----------------------------------------------------------------------------
void cmXCodeObject::SetString(const char* s)
{
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index 2bea63b..369fe66 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -139,8 +139,22 @@ public:
{
return this->DependLibraries;
}
+ void AddDependTarget(const char* configName,
+ const char* tName)
+ {
+ if(!configName)
+ {
+ configName = "";
+ }
+ this->DependTargets[configName].push_back(tName);
+ }
+ std::map<cmStdString, StringVec> const& GetDependTargets()
+ {
+ return this->DependTargets;
+ }
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List;}
void SetComment(const char* c) { this->Comment = c;}
+ static void PrintString(std::ostream& os,cmStdString String);
protected:
void PrintString(std::ostream& os) const;
@@ -155,6 +169,7 @@ protected:
cmXCodeObject* PBXTargetDependencyValue;
std::vector<cmXCodeObject*> List;
std::map<cmStdString, StringVec> DependLibraries;
+ std::map<cmStdString, StringVec> DependTargets;
std::map<cmStdString, cmXCodeObject*> ObjectAttributes;
};
#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index ea8cdfd..45927cb 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2346,11 +2346,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
std::string oldstartoutputdir = this->GetStartOutputDirectory();
this->SetStartDirectory(this->GetHomeDirectory());
this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
- const bool warncli = this->WarnUnusedCli;
- if (!this->ScriptMode)
- {
- this->WarnUnusedCli = false;
- }
int ret = this->Configure();
if (ret || this->ScriptMode)
{
@@ -2372,7 +2367,6 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
#endif
return ret;
}
- this->WarnUnusedCli = warncli;
ret = this->Generate();
std::string message = "Build files have been written to: ";
message += this->GetHomeOutputDirectory();
@@ -2394,6 +2388,10 @@ int cmake::Generate()
return -1;
}
this->GlobalGenerator->Generate();
+ if(this->WarnUnusedCli)
+ {
+ this->RunCheckForUnusedVariables();
+ }
if(cmSystemTools::GetErrorOccuredFlag())
{
return -1;
@@ -2934,6 +2932,7 @@ void cmake::GenerateGraphViz(const char* fileName) const
gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str());
gvWriter->WritePerTargetFiles(fileName);
+ gvWriter->WriteTargetDependersFiles(fileName);
gvWriter->WriteGlobalFile(fileName);
#endif
@@ -4347,7 +4346,10 @@ void cmake::WatchUnusedCli(const char* var)
{
#ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
- this->UsedCliVariables[var] = false;
+ if(this->UsedCliVariables.find(var) == this->UsedCliVariables.end())
+ {
+ this->UsedCliVariables[var] = false;
+ }
#endif
}
@@ -4355,27 +4357,29 @@ void cmake::UnwatchUnusedCli(const char* var)
{
#ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning);
- this->UsedCliVariables[var] = true;
+ this->UsedCliVariables.erase(var);
#endif
}
-void cmake::RunCheckForUnusedVariables(const std::string& reason) const
+void cmake::RunCheckForUnusedVariables()
{
#ifdef CMAKE_BUILD_WITH_CMAKE
- if(this->WarnUnusedCli)
+ bool haveUnused = false;
+ cmOStringStream msg;
+ msg << "Manually-specified variables were not used by the project:";
+ for(std::map<cmStdString, bool>::const_iterator
+ it = this->UsedCliVariables.begin();
+ it != this->UsedCliVariables.end(); ++it)
+ {
+ if(!it->second)
{
- std::map<std::string, bool>::const_iterator it;
- for(it = this->UsedCliVariables.begin();
- it != this->UsedCliVariables.end(); ++it)
- {
- if(!it->second)
- {
- std::string message = "CMake Warning: The variable, '" + it->first +
- "', specified manually, was not used during the " + reason +
- ".";
- cmSystemTools::Message(message.c_str());
- }
- }
+ haveUnused = true;
+ msg << "\n " << it->first;
}
+ }
+ if(haveUnused)
+ {
+ this->IssueMessage(cmake::WARNING, msg.str(), cmListFileBacktrace());
+ }
#endif
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 132a86d..fac86c1 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -368,8 +368,8 @@ class cmake
void UnwatchUnusedCli(const char* var);
void WatchUnusedCli(const char* var);
- void RunCheckForUnusedVariables(const std::string& reason) const;
protected:
+ void RunCheckForUnusedVariables();
void InitializeProperties();
int HandleDeleteCacheVariables(const char* var);
cmPropertyMap Properties;
@@ -467,7 +467,7 @@ private:
bool WarnUnused;
bool WarnUnusedCli;
bool CheckSystemVars;
- std::map<std::string, bool> UsedCliVariables;
+ std::map<cmStdString, bool> UsedCliVariables;
std::string CMakeEditCommand;
std::string CMakeCommand;
std::string CXXEnvironment;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index a5dca18..663ce8f 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -109,7 +109,8 @@ static const char * cmDocumentationOptions[][3] =
"Dump a wide range of information about the current system. If run "
"from the top of a binary tree for a CMake project it will dump "
"additional information such as the cache, log files etc."},
- {"--debug-trycompile", "Do not delete the try compile directories..",
+ {"--debug-trycompile", "Do not delete the try_compile build tree. Only "
+ "useful on one try_compile at a time.",
"Do not delete the files and directories created for try_compile calls. "
"This is useful in debugging failed try_compiles. It may however "
"change the results of the try-compiles as old junk from a previous "
diff --git a/Source/kwsys/CheckCXXSourceRuns.cmake b/Source/kwsys/CheckCXXSourceRuns.cmake
deleted file mode 100644
index 7bcc873..0000000
--- a/Source/kwsys/CheckCXXSourceRuns.cmake
+++ /dev/null
@@ -1,62 +0,0 @@
-# - Check if the source code provided in the SOURCE argument compiles.
-# CHECK_CXX_SOURCE_COMPILES(SOURCE VAR)
-# - macro which checks if the source code compiles\
-# SOURCE - source code to try to compile
-# VAR - variable to store size if the type exists.
-#
-# The following variables may be set before calling this macro to
-# modify the way the check is run:
-#
-# CMAKE_REQUIRED_FLAGS = string of compile command line flags
-# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
-# CMAKE_REQUIRED_INCLUDES = list of include directories
-# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
-
-MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR COMMENT)
- IF("HAVE_${VAR}" MATCHES "^HAVE_${VAR}$")
- SET(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
- IF(CMAKE_REQUIRED_LIBRARIES)
- SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
- "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
- ELSE(CMAKE_REQUIRED_LIBRARIES)
- SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
- ENDIF(CMAKE_REQUIRED_LIBRARIES)
- IF(CMAKE_REQUIRED_INCLUDES)
- SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES
- "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
- ELSE(CMAKE_REQUIRED_INCLUDES)
- SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES)
- ENDIF(CMAKE_REQUIRED_INCLUDES)
- SET(CMAKE_EMPTY_INPUT_FILE_CONTENT "${SOURCE}")
- CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/CMakeEmptyInputFile.in"
- "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.cxx" IMMEDIATE)
-
- MESSAGE(STATUS "Performing Test ${COMMENT}")
- TRY_RUN(${VAR} HAVE_${VAR}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.cxx
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
- "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
- "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
- OUTPUT_VARIABLE OUTPUT)
- IF(HAVE_${VAR})
- SET(${VAR} 1 CACHE INTERNAL "Test ${COMMENT}")
- MESSAGE(STATUS "Performing Test ${COMMENT} - Success")
- FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log
- "Performing C++ SOURCE FILE Test ${COMMENT} succeded with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- ELSE(HAVE_${VAR})
- MESSAGE(STATUS "Performing Test ${COMMENT} - Failed")
- SET(${VAR} "" CACHE INTERNAL "Test ${COMMENT}")
- FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log
- "Performing C++ SOURCE FILE Test ${COMMENT} failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- ENDIF(HAVE_${VAR})
- ENDIF("HAVE_${VAR}" MATCHES "^HAVE_${VAR}$")
-ENDMACRO(CHECK_CXX_SOURCE_RUNS)
-
-
diff --git a/Source/kwsys/EncodeExecutable.c b/Source/kwsys/EncodeExecutable.c
index ba474b8..bc30568 100644
--- a/Source/kwsys/EncodeExecutable.c
+++ b/Source/kwsys/EncodeExecutable.c
@@ -41,6 +41,7 @@ int main(int argc, char* argv[])
if(!ofp)
{
fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]);
+ fclose(ifp);
return 2;
}
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index 3bf2579..25832c2 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -160,8 +160,10 @@ static const char* kwsysTerminalVT100Names[] =
"rxvt-cygwin",
"rxvt-cygwin-native",
"rxvt-unicode",
+ "rxvt-unicode-256color",
"screen",
"screen-256color",
+ "screen-256color-bce",
"screen-bce",
"screen-w",
"screen.linux",
diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake
index 685baf6..06fe745 100644
--- a/Source/kwsys/kwsysDateStamp.cmake
+++ b/Source/kwsys/kwsysDateStamp.cmake
@@ -15,7 +15,7 @@
SET(KWSYS_DATE_STAMP_YEAR 2011)
# KWSys version date month component. Format is MM.
-SET(KWSYS_DATE_STAMP_MONTH 03)
+SET(KWSYS_DATE_STAMP_MONTH 06)
# KWSys version date day component. Format is DD.
-SET(KWSYS_DATE_STAMP_DAY 28)
+SET(KWSYS_DATE_STAMP_DAY 20)