diff options
Diffstat (limited to 'Source')
61 files changed, 1889 insertions, 612 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7722c19..278d4df 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -343,7 +343,7 @@ TARGET_LINK_LIBRARIES(CMakeLib cmsys ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES} ${CMAKE_CURL_LIBRARIES} ) -# On Apple we need Carbon +# On Apple we need CoreFoundation IF(APPLE) TARGET_LINK_LIBRARIES(CMakeLib "-framework CoreFoundation") ENDIF(APPLE) @@ -465,7 +465,7 @@ IF(APPLE) ADD_EXECUTABLE(OSXScriptLauncher CPack/OSXScriptLauncher.cxx) TARGET_LINK_LIBRARIES(OSXScriptLauncher cmsys) - TARGET_LINK_LIBRARIES(OSXScriptLauncher "-framework Carbon") + TARGET_LINK_LIBRARIES(OSXScriptLauncher "-framework CoreFoundation") ENDIF(APPLE) # Build CMake executable diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx index 99ffecc..e0fbe9b 100644 --- a/Source/CPack/OSXScriptLauncher.cxx +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -14,7 +14,6 @@ #include <cmsys/ios/fstream> #include <cmsys/ios/iostream> -#include <Carbon/Carbon.h> #include <CoreFoundation/CoreFoundation.h> // For the PATH_MAX constant diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 46be99b..b629c63 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -121,9 +121,11 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) << std::endl); // Begin the archive for this group std::string packageFileName= std::string(toplevel); - packageFileName += "/" - +std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) - +"-"+compGIt->first + this->GetOutputExtension(); + packageFileName += "/"+ + GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), + compGIt->first, + true) + + this->GetOutputExtension(); // open a block in order to automatically close archive // at the end of the block { @@ -141,6 +143,39 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) // add the generated package to package file names list packageFileNames.push_back(packageFileName); } + // 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_VERBOSE, + "Component <" + << compIt->second.Name + << "> does not belong to any group, package it separately." + << std::endl); + std::string localToplevel( + this->GetOption("CPACK_TEMPORARY_DIRECTORY") + ); + std::string packageFileName = std::string(toplevel); + + localToplevel += "/"+ compIt->first; + packageFileName += "/"+ + GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), + compIt->first, + false) + + this->GetOutputExtension(); + { + DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); + // Add the files of this component to the archive + addOneComponentToArchive(archive,&(compIt->second)); + } + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); + } + } } // CPACK_COMPONENTS_IGNORE_GROUPS is set // We build 1 package per component @@ -154,9 +189,11 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) std::string packageFileName = std::string(toplevel); localToplevel += "/"+ compIt->first; - packageFileName += "/" - +std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) - +"-"+compIt->first + this->GetOutputExtension(); + packageFileName += "/"+ + GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), + compIt->first, + false) + + this->GetOutputExtension(); { DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); // Add the files of this component to the archive @@ -177,7 +214,7 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponent) packageFileNames.push_back(std::string(toplevel)); packageFileNames[0] += "/" +std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) - +"-ALL" + this->GetOutputExtension(); + + this->GetOutputExtension(); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package..." "(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)" @@ -226,8 +263,6 @@ int cmCPackArchiveGenerator::PackageFiles() cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); - PrepareGroupingKind(); - if (SupportsComponentInstallation()) { // CASE 1 : COMPONENT ALL-IN-ONE package // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 47a1ff6..d3320c0 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -51,14 +51,256 @@ int cmCPackDebGenerator::InitializeInternal() } //---------------------------------------------------------------------- +int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) +{ + int retval = 1; + /* Reset package file name list it will be populated during the + * component packaging run*/ + packageFileNames.clear(); + std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + + // The default behavior is to have one package by component group + // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. + if (!ignoreGroup) + { + 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); + // 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; + } + + 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); + } + } + // CPACK_COMPONENTS_IGNORE_GROUPS is set + // We build 1 package per component + else + { + std::map<std::string, cmCPackComponent>::iterator compIt; + 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; + } + + 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::PackageComponentsAllInOne(bool allComponent) +{ + int retval = 1; + std::string compInstDirName; + /* Reset package file name list it will be populated during the + * component packaging run*/ + 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"; + } + + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "Packaging all groups in one package..." + "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)" + << std::endl); + + // The ALL GROUPS in ONE package case + std::string localToplevel(initialTopLevel); + std::string packageFileName( + cmSystemTools::GetParentDirectory(toplevel.c_str()) + ); + std::string outputFileName( + std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + + this->GetOutputExtension() + ); + // all GROUP in one vs all COMPONENT in one + localToplevel += "/"+compInstDirName; + + /* 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",compInstDirName.c_str()); + if (!this->ReadListFile("CPackDeb.cmake")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while execution CPackDeb.cmake" << std::endl); + retval = 0; + } + + 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::PackageFiles() { - this->ReadListFile("CPackDeb.cmake"); + int retval = -1; + + /* 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 + // then the package file is unique and should be open here. + if (allComponentInOne || + (allGroupInOne && (!this->ComponentGroups.empty())) + ) + { + return PackageComponentsAllInOne(allComponentInOne); + } + // 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)) + { + return PackageComponents(ignoreComponentGroup); + } + } + // CASE 3 : NON COMPONENT package. + else + { + if (!this->ReadListFile("CPackDeb.cmake")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while execution CPackDeb.cmake" << std::endl); + retval = 0; + } + packageFiles = files; + return createDeb(); + } + return retval; +} + +int cmCPackDebGenerator::createDeb() +{ const char* cmakeExecutable = this->GetOption("CMAKE_COMMAND"); // debian-binary file std::string dbfilename; - dbfilename = toplevel; + dbfilename += this->GetOption("WDIR"); dbfilename += "/debian-binary"; { // the scope is needed for cmGeneratedFileStream cmGeneratedFileStream out(dbfilename.c_str()); @@ -68,7 +310,7 @@ int cmCPackDebGenerator::PackageFiles() // control file std::string ctlfilename; - ctlfilename = toplevel; + ctlfilename = this->GetOption("WDIR"); ctlfilename += "/control"; // debian policy enforce lower case for package name @@ -158,8 +400,9 @@ int cmCPackDebGenerator::PackageFiles() { std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); dirName += '/'; - for (std::vector<std::string>::const_iterator fileIt = files.begin(); - fileIt != files.end(); ++ fileIt ) + for (std::vector<std::string>::const_iterator fileIt = + packageFiles.begin(); + fileIt != packageFiles.end(); ++ fileIt ) { totalSize += cmSystemTools::FileLength(fileIt->c_str()); } @@ -178,14 +421,22 @@ int cmCPackDebGenerator::PackageFiles() // now add all directories which have to be compressed // collect all top level install dirs for that // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt - size_t topLevelLength = toplevel.length(); + size_t topLevelLength = std::string(this->GetOption("WDIR")).length(); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \"" << this->GetOption("WDIR") + << "\", length = " << topLevelLength + << std::endl); std::set<std::string> installDirs; - for (std::vector<std::string>::const_iterator fileIt = files.begin(); - fileIt != files.end(); ++ fileIt ) + for (std::vector<std::string>::const_iterator fileIt = + packageFiles.begin(); + fileIt != packageFiles.end(); ++ fileIt ) { + cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\"" + << std::endl); std::string::size_type slashPos = fileIt->find('/', topLevelLength+1); - std::string relativeDir = fileIt->substr(topLevelLength, + std::string relativeDir = fileIt->substr(topLevelLength, slashPos - topLevelLength); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir + << "\"" << std::endl); if (installDirs.find(relativeDir) == installDirs.end()) { installDirs.insert(relativeDir); @@ -195,11 +446,11 @@ int cmCPackDebGenerator::PackageFiles() } std::string output; - int retVal = -1; + int retval = -1; int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, - &retVal, toplevel.c_str(), this->GeneratorVerbose, 0); + &retval, this->GetOption("WDIR"), this->GeneratorVerbose, 0); - if ( !res || retVal ) + if ( !res || retval ) { std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/Deb.log"; @@ -215,15 +466,18 @@ int cmCPackDebGenerator::PackageFiles() } std::string md5filename; - md5filename = toplevel; + md5filename = this->GetOption("WDIR"); md5filename += "/md5sums"; { // the scope is needed for cmGeneratedFileStream cmGeneratedFileStream out(md5filename.c_str()); std::vector<std::string>::const_iterator fileIt; - std::string topLevelWithTrailingSlash = toplevel; +// std::string topLevelWithTrailingSlash = toplevel; + std::string topLevelWithTrailingSlash = + this->GetOption("CPACK_TEMPORARY_DIRECTORY"); topLevelWithTrailingSlash += '/'; - for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt ) + for ( fileIt = packageFiles.begin(); + fileIt != packageFiles.end(); ++ fileIt ) { cmd = "\""; cmd += cmakeExecutable; @@ -233,32 +487,31 @@ int cmCPackDebGenerator::PackageFiles() //std::string output; //int retVal = -1; res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, - &retVal, toplevel.c_str(), this->GeneratorVerbose, 0); + &retval, toplevel.c_str(), this->GeneratorVerbose, 0); // debian md5sums entries are like this: // 014f3604694729f3bf19263bac599765 usr/bin/ccmake // thus strip the full path (with the trailing slash) - cmSystemTools::ReplaceString(output, + cmSystemTools::ReplaceString(output, topLevelWithTrailingSlash.c_str(), ""); out << output; } - // each line contains a eol. + // each line contains a eol. // Do not end the md5sum file with yet another (invalid) } - cmd = "\""; cmd += cmakeExecutable; cmd += "\" -E tar cfz control.tar.gz ./control ./md5sums"; - const char* controlExtra = + const char* controlExtra = this->GetOption("CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"); if( controlExtra ) - { + { std::vector<std::string> controlExtraList; cmSystemTools::ExpandListArgument(controlExtra, controlExtraList); - for(std::vector<std::string>::iterator i = + for(std::vector<std::string>::iterator i = controlExtraList.begin(); i != controlExtraList.end(); ++i) { - std::string filenamename = + std::string filenamename = cmsys::SystemTools::GetFilenameName(i->c_str()); std::string localcopy = toplevel; localcopy += "/"; @@ -274,9 +527,9 @@ int cmCPackDebGenerator::PackageFiles() } } res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, - &retVal, toplevel.c_str(), this->GeneratorVerbose, 0); + &retval, this->GetOption("WDIR"), this->GeneratorVerbose, 0); - if ( !res || retVal ) + if ( !res || retval ) { std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/Deb.log"; @@ -295,24 +548,70 @@ int cmCPackDebGenerator::PackageFiles() // since debian packages require BSD ar (most Linux distros and even // FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here. std::vector<std::string> arFiles; - std::string topLevelString = toplevel; + std::string topLevelString = this->GetOption("WDIR"); topLevelString += "/"; arFiles.push_back(topLevelString + "debian-binary"); arFiles.push_back(topLevelString + "control.tar.gz"); arFiles.push_back(topLevelString + "data.tar.gz"); - res = ar_append(packageFileNames[0].c_str(), arFiles); + std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + outputFileName += "/"; + outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME"); + res = ar_append(outputFileName.c_str(), arFiles); if ( res!=0 ) { - std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME"); tmpFile += "/Deb.log"; cmGeneratedFileStream ofs(tmpFile.c_str()); ofs << "# Problem creating archive using: " << res << std::endl; return 0; } - return 1; } +bool cmCPackDebGenerator::SupportsComponentInstallation() const + { + if (IsOn("CPACK_DEB_COMPONENT_INSTALL")) + { + return true; + } + else + { + return false; + } + } + +std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) + { + if (ignoreComponentGroup) { + return componentName; + } + + if (allComponentInOne) { + return std::string("ALL_COMPONENTS_IN_ONE"); + } + // We have to find the name of the COMPONENT GROUP + // the current COMPONENT belongs to. + std::string groupVar = "CPACK_COMPONENT_" + + 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())); + } + } + else + { + return componentName; + } + } + + // The following code is taken from OpenBSD ar: // http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ar/ // It has been slightly modified: diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index 4a357d1..de1ea77 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -33,8 +33,26 @@ public: protected: virtual int InitializeInternal(); + /** + * The method used to package files when component + * install is used. This will create one + * archive for each component group. + */ + int PackageComponents(bool ignoreGroup); + /** + * Special case of component install where all + * components will be put in a single installer. + */ + int PackageComponentsAllInOne(bool allComponent); virtual int PackageFiles(); virtual const char* GetOutputExtension() { return ".deb"; } + virtual bool SupportsComponentInstallation() const; + virtual std::string GetComponentInstallDirNameSuffix( + const std::string& componentName); + +private: + int createDeb(); + std::vector<std::string> packageFiles; }; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index feda52c..5f314c6 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -24,6 +24,7 @@ #include <cmsys/SystemTools.hxx> #include <cmsys/Glob.hxx> #include <memory> // auto_ptr +#include <algorithm> #if defined(__HAIKU__) #include <StorageKit.h> @@ -684,7 +685,14 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( if (componentInstall) { tempInstallDirectory += "/"; - tempInstallDirectory += installComponent; + // Some CPack generators would rather chose + // the local installation directory suffix. + // Some (e.g. RPM) use + // one install directory for each component **GROUP** + // instead of the default + // one install directory for each component. + tempInstallDirectory += + GetComponentInstallDirNameSuffix(installComponent); } if (!setDestDir) @@ -803,7 +811,55 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( { mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); } + // Remember the list of files before installation + // of the current component (if we are in component install) + const char* InstallPrefix = tempInstallDirectory.c_str(); + std::vector<std::string> filesBefore; + std::string findExpr(InstallPrefix); + if (componentInstall) + { + cmsys::Glob glB; + findExpr += "/*"; + glB.RecurseOn(); + glB.FindFiles(findExpr); + filesBefore = glB.GetFiles(); + std::sort(filesBefore.begin(),filesBefore.end()); + } + // do installation int res = mf->ReadListFile(0, installFile.c_str()); + // Now rebuild the list of files after installation + // of the current component (if we are in component install) + if (componentInstall) + { + cmsys::Glob glA; + glA.RecurseOn(); + glA.FindFiles(findExpr); + std::vector<std::string> filesAfter = glA.GetFiles(); + std::sort(filesAfter.begin(),filesAfter.end()); + std::vector<std::string>::iterator diff; + std::vector<std::string> result(filesAfter.size()); + diff = std::set_difference ( + filesAfter.begin(),filesAfter.end(), + filesBefore.begin(),filesBefore.end(), + result.begin()); + + std::vector<std::string>::iterator fit; + std::string localFileName; + // Populate the File field of each component + for (fit=result.begin();fit!=diff;++fit) + { + localFileName = + cmSystemTools::RelativePath(InstallPrefix, fit->c_str()); + localFileName = + localFileName.substr(localFileName.find('/')+1, + std::string::npos); + Components[installComponent].Files.push_back(localFileName); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" + <<localFileName<<"> to component <" + <<installComponent<<">"<<std::endl); + } + } + if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { if (absoluteDestFiles.length()>0) { absoluteDestFiles +=";"; @@ -873,6 +929,12 @@ int cmCPackGenerator::DoPackage() return 0; } + // Digest Component grouping specification + if ( !this->PrepareGroupingKind() ) + { + return 0; + } + if ( cmSystemTools::IsOn( this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) ) { @@ -939,35 +1001,6 @@ int cmCPackGenerator::DoPackage() // The files to be installed files = gl.GetFiles(); - // For component installations, determine which files go into which - // components. - if (!this->Components.empty()) - { - std::vector<std::string>::const_iterator it; - for ( it = files.begin(); it != files.end(); ++ it ) - { - // beware we cannot just use tempDirectory as before - // because some generator will "CPACK_INCLUDE_TOPLEVEL_DIRECTORY" - // we really want "CPACK_TEMPORARY_DIRECTORY" - std::string fileN = - cmSystemTools::RelativePath( - this->GetOption("CPACK_TEMPORARY_DIRECTORY"), it->c_str()); - - // Determine which component we are in. - std::string componentName = fileN.substr(0, fileN.find('/')); - - // Strip off the component part of the path. - fileN = fileN.substr(fileN.find('/')+1, std::string::npos); - - // Add this file to the list of files for the component. - this->Components[componentName].Files.push_back(fileN); - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" - <<fileN<<"> to component <" - <<componentName<<">"<<std::endl); - } - } - - packageFileNames.clear(); /* Put at least one file name into the list of * wanted packageFileNames. The specific generator @@ -1251,11 +1284,11 @@ int cmCPackGenerator::PrepareGroupingKind() cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" << this->Name << "]" << " requested component grouping = "<< groupingType <<std::endl); - if (groupingType == "ALL_GROUP_IN_ONE") + if (groupingType == "ALL_GROUPS_IN_ONE") { allGroupInOne = true; } - else if (groupingType == "ALL_COMPONENT_IN_ONE") + else if (groupingType == "ALL_COMPONENTS_IN_ONE") { allComponentInOne = true; } @@ -1268,11 +1301,19 @@ int cmCPackGenerator::PrepareGroupingKind() cmCPackLogger(cmCPackLog::LOG_WARNING, "[" << this->Name << "]" << " requested component grouping type <"<< groupingType - << "> UNKNOWN not in (ALL_GROUP_IN_ONE," - "ALL_COMPONENT_IN_ONE,IGNORE)" <<std::endl); + << "> UNKNOWN not in (ALL_GROUPS_IN_ONE," + "ALL_COMPONENTS_IN_ONE,IGNORE)" <<std::endl); } } + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" + << this->Name << "]" + << " requested component grouping = (" + << "ALL_GROUPS_IN_ONE=" << allGroupInOne + << ", ALL_COMPONENTS_IN_ONE=" << allComponentInOne + << ", IGNORE_GROUPS=" << ignoreComponentGroup + << ")" + << std::endl); // Some components were defined but NO group // force ignoreGroups if (this->ComponentGroups.empty() && (!this->Components.empty()) @@ -1289,6 +1330,52 @@ int cmCPackGenerator::PrepareGroupingKind() } //---------------------------------------------------------------------- +std::string cmCPackGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) { + return componentName; +} +//---------------------------------------------------------------------- +std::string cmCPackGenerator::GetComponentPackageFileName( + const std::string& initialPackageFileName, + const std::string& groupOrComponentName, + bool isGroupName) { + + /* + * the default behavior is to use the + * component [group] name as a suffix + */ + std::string suffix="-"+groupOrComponentName; + /* check if we should use DISPLAY name */ + std::string dispNameVar = "CPACK_"+Name+"_USE_DISPLAY_NAME_IN_FILENAME"; + if (IsOn(dispNameVar.c_str())) + { + /* the component Group case */ + if (isGroupName) + { + std::string groupDispVar = "CPACK_COMPONENT_GROUP_" + + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; + const char* groupDispName = GetOption(groupDispVar.c_str()); + if (groupDispName) + { + suffix = "-"+std::string(groupDispName); + } + } + /* the [single] component case */ + else + { + std::string dispVar = "CPACK_COMPONENT_" + + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; + const char* dispName = GetOption(dispVar.c_str()); + if(dispName) + { + suffix = "-"+std::string(dispName); + } + } + } + return initialPackageFileName + suffix; +} + +//---------------------------------------------------------------------- bool cmCPackGenerator::SupportsComponentInstallation() const { return false; diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index f44a334..0497d1c 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -132,6 +132,32 @@ protected: virtual int PrepareGroupingKind(); /** + * Some CPack generators may prefer to have + * CPack install all components belonging to the same + * [component] group to be install in the same directory. + * The default behavior is to install each component in + * a separate directory. + * @param[in] componentName the name of the component to be installed + * @return the name suffix the generator wants for the specified component + * default is "componentName" + */ + virtual std::string GetComponentInstallDirNameSuffix( + const std::string& componentName); + + /** + * CPack specific generator may mangle CPACK_PACKAGE_FILE_NAME + * with CPACK_COMPONENT_xxxx_<NAME>_DISPLAY_NAME if + * CPACK_<GEN>_USE_DISPLAY_NAME_IN_FILENAME is ON. + * @param[in] initialPackageFileName + * @param[in] groupOrComponentName + * @param[in] isGroupName + */ + virtual std::string GetComponentPackageFileName( + const std::string& initialPackageFileName, + const std::string& groupOrComponentName, + bool isGroupName); + + /** * Package the list of files and/or components which * has been prepared by the beginning of DoPackage. * @pre @ref toplevel has been filled-in diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index a5db78f..0b0c6b1 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -31,39 +31,94 @@ int cmCPackRPMGenerator::InitializeInternal() { this->SetOption("CPACK_SET_DESTDIR", "I_ON"); } + /* Replace space in CPACK_PACKAGE_NAME in order to avoid + * rpmbuild scream on unwanted space in filename issue + * Moreover RPM file do not usually embed space in filename + */ + if (this->GetOption("CPACK_PACKAGE_NAME")) { + std::string packageName=this->GetOption("CPACK_PACKAGE_NAME"); + cmSystemTools::ReplaceString(packageName," ","-"); + this->SetOption("CPACK_PACKAGE_NAME",packageName.c_str()); + } + /* same for CPACK_PACKAGE_FILE_NAME */ + if (this->GetOption("CPACK_PACKAGE_FILE_NAME")) { + std::string packageName=this->GetOption("CPACK_PACKAGE_FILE_NAME"); + cmSystemTools::ReplaceString(packageName," ","-"); + this->SetOption("CPACK_PACKAGE_FILE_NAME",packageName.c_str()); + } return this->Superclass::InitializeInternal(); } //---------------------------------------------------------------------- -int cmCPackRPMGenerator::PackageFiles() +int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) { int retval = 1; - /* Digest Component grouping specification */ - retval = PrepareGroupingKind(); - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " - << toplevel << std::endl); + /* Reset package file name list it will be populated during the + * component packaging run*/ + packageFileNames.clear(); + std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - /* Are we in the component packaging case */ - if (SupportsComponentInstallation() & (!this->ComponentGroups.empty())) + // The default behavior is to have one package by component group + // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. + if (!ignoreGroup) + { + 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); + // 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")) + { + 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); + } + } + // CPACK_COMPONENTS_IGNORE_GROUPS is set + // We build 1 package per component + else { - /* Reset package file name list it will be populated during the - * component packaging run*/ - packageFileNames.clear(); - std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - /* One Package per component CASE */ - /* Iterate over components */ std::map<std::string, cmCPackComponent>::iterator compIt; for (compIt=this->Components.begin(); - compIt!=this->Components.end(); ++compIt ) + 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()); + GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), + compIt->first, + false) + + this->GetOutputExtension()); localToplevel += "/"+ compIt->first; /* replace the TEMP DIRECTORY with the component one */ @@ -82,12 +137,101 @@ int cmCPackRPMGenerator::PackageFiles() "Error while execution CPackRPM.cmake" << std::endl); retval = 0; } - // add the generated package to package file names list packageFileNames.push_back(packageFileName); } } - /* This is the non component case */ + return retval; +} + +//---------------------------------------------------------------------- +int cmCPackRPMGenerator::PackageComponentsAllInOne(bool allComponent) +{ + int retval = 1; + std::string compInstDirName; + /* Reset package file name list it will be populated during the + * component packaging run*/ + 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"; + } + + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "Packaging all groups in one package..." + "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)" + << std::endl); + + // The ALL GROUPS in ONE package case + std::string localToplevel(initialTopLevel); + std::string packageFileName( + cmSystemTools::GetParentDirectory(toplevel.c_str()) + ); + std::string outputFileName( + std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + + this->GetOutputExtension() + ); + // all GROUP in one vs all COMPONENT in one + localToplevel += "/"+compInstDirName; + + /* 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",compInstDirName.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::PackageFiles() +{ + int retval = 1; + + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " + << toplevel << std::endl); + + /* 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 + // then the package file is unique and should be open here. + if (allComponentInOne || + (allGroupInOne && (!this->ComponentGroups.empty())) + ) + { + return PackageComponentsAllInOne(allComponentInOne); + } + // 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)) + { + return PackageComponents(ignoreComponentGroup); + } + } + // CASE 3 : NON COMPONENT package. else { if (!this->ReadListFile("CPackRPM.cmake")) @@ -118,3 +262,33 @@ bool cmCPackRPMGenerator::SupportsComponentInstallation() const } } +std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) + { + if (ignoreComponentGroup) { + return componentName; + } + + if (allComponentInOne) { + return std::string("ALL_COMPONENTS_IN_ONE"); + } + // We have to find the name of the COMPONENT GROUP + // the current COMPONENT belongs to. + std::string groupVar = "CPACK_COMPONENT_" + + 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())); + } + } + else + { + return componentName; + } + } diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h index 57d5cca..7c2e434 100644 --- a/Source/CPack/cmCPackRPMGenerator.h +++ b/Source/CPack/cmCPackRPMGenerator.h @@ -38,8 +38,21 @@ public: protected: virtual int InitializeInternal(); virtual int PackageFiles(); + /** + * The method used to package files when component + * install is used. This will create one + * archive for each component group. + */ + int PackageComponents(bool ignoreGroup); + /** + * Special case of component install where all + * components will be put in a single installer. + */ + int PackageComponentsAllInOne(bool allComponent); virtual const char* GetOutputExtension() { return ".rpm"; } virtual bool SupportsComponentInstallation() const; + virtual std::string GetComponentInstallDirNameSuffix( + const std::string& componentName); }; diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 9678ac4..86bd85d 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -93,6 +93,7 @@ static const char* cmCTestErrorMatches[] = { ": No such file or directory", ": Invalid argument", "^The project cannot be built\\.", + "^\\[ERROR\\]", 0 }; @@ -119,7 +120,7 @@ static const char* cmCTestWarningMatches[] = { "^\"[^\"]+\", line [0-9]+: [Ww](arning|arnung)", "([^:]+): warning[ \\t]*[0-9]+[ \\t]*:", "^(Warning|Warnung) ([0-9]+):", - "^(Warning|Warnung) ", + "^(Warning|Warnung)[ :]", "WARNING: ", "([^ :]+) : warning", "([^:]+): warning", @@ -131,6 +132,7 @@ static const char* cmCTestWarningMatches[] = { "\".*\", line [0-9]+: remark\\([0-9]*\\):", "cc-[0-9]* CC: REMARK File = .*, Line = [0-9]*", "^CMake Warning.*:", + "^\\[WARNING\\]", 0 }; diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 6863adc..005651f 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -825,7 +825,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( // Call gcov to get coverage data for this *.gcda file: // std::string fileDir = cmSystemTools::GetFilenamePath(it->c_str()); - std::string command = "\"" + gcovCommand + "\" -l -o \"" + fileDir + std::string command = "\"" + gcovCommand + "\" -l -p -o \"" + fileDir + "\" \"" + *it + "\""; cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index aa9e55b..2c1a0af 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -24,10 +24,19 @@ #include <ctype.h> //---------------------------------------------------------------------------- +static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major, + unsigned int minor, unsigned int fix) +{ + // 1.6.5.0 maps to 10605000 + return fix + minor*1000 + major*100000 + epic*10000000; +} + +//---------------------------------------------------------------------------- cmCTestGIT::cmCTestGIT(cmCTest* ct, std::ostream& log): cmCTestGlobalVC(ct, log) { this->PriorRev = this->Unknown; + this->CurrentGitVersion = 0; } //---------------------------------------------------------------------------- @@ -263,7 +272,20 @@ bool cmCTestGIT::UpdateImpl() std::string top_dir = this->FindTopDir(); const char* git = this->CommandLineTool.c_str(); - char const* git_submodule[] = {git, "submodule", "update", 0}; + const char* recursive = "--recursive"; + + // Git < 1.6.5.0 did not support --recursive + if(this->GetGitVersion() < cmCTestGITVersion(1,6,5,0)) + { + recursive = 0; + // No need to require >= 1.6.5.0 if there are no submodules. + if(cmSystemTools::FileExists((top_dir + "/.gitmodules").c_str())) + { + this->Log << "Git < 1.6.5.0 cannot update submodules recursively\n"; + } + } + + char const* git_submodule[] = {git, "submodule", "update", recursive, 0}; OutputLogger submodule_out(this->Log, "submodule-out> "); OutputLogger submodule_err(this->Log, "submodule-err> "); return this->RunChild(git_submodule, &submodule_out, &submodule_err, @@ -271,6 +293,27 @@ bool cmCTestGIT::UpdateImpl() } //---------------------------------------------------------------------------- +unsigned int cmCTestGIT::GetGitVersion() +{ + if(!this->CurrentGitVersion) + { + const char* git = this->CommandLineTool.c_str(); + char const* git_version[] = {git, "--version", 0}; + std::string version; + OneLineParser version_out(this, "version-out> ", version); + OutputLogger version_err(this->Log, "version-err> "); + unsigned int v[4] = {0,0,0,0}; + if(this->RunChild(git_version, &version_out, &version_err) && + sscanf(version.c_str(), "git version %u.%u.%u.%u", + &v[0], &v[1], &v[2], &v[3]) >= 3) + { + this->CurrentGitVersion = cmCTestGITVersion(v[0], v[1], v[2], v[3]); + } + } + return this->CurrentGitVersion; +} + +//---------------------------------------------------------------------------- /* Diff format: :src-mode dst-mode src-sha1 dst-sha1 status\0 diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h index 1765340..f4fae8f 100644 --- a/Source/CTest/cmCTestGIT.h +++ b/Source/CTest/cmCTestGIT.h @@ -27,6 +27,8 @@ public: virtual ~cmCTestGIT(); private: + unsigned int CurrentGitVersion; + unsigned int GetGitVersion(); std::string GetWorkingRevision(); virtual void NoteOldRevision(); virtual void NoteNewRevision(); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index f3a4457..2cae802 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -484,7 +484,7 @@ void cmCTestMultiProcessHandler::CreateTestCostList() } TestComparator comp(this); - std::sort(SortedTests.begin(), SortedTests.end(), comp); + std::stable_sort(SortedTests.begin(), SortedTests.end(), comp); } //--------------------------------------------------------- diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index fdf17e0..12d5fd1 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -164,7 +164,7 @@ cmCTestScriptHandler::~cmCTestScriptHandler() //---------------------------------------------------------------------- // just adds an argument to the vector -void cmCTestScriptHandler::AddConfigurationScript(const char *script, +void cmCTestScriptHandler::AddConfigurationScript(const char *script, bool pscope) { this->ConfigurationScripts.push_back(script); @@ -224,12 +224,12 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) argv.push_back("-SR"); argv.push_back(total_script_arg.c_str()); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Executable for CTest is: " << + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Executable for CTest is: " << this->CTest->GetCTestExecutable() << "\n"); // now pass through all the other arguments - std::vector<cmStdString> &initArgs = + std::vector<cmStdString> &initArgs = this->CTest->GetInitialCommandLineArguments(); //*** need to make sure this does not have the current script *** for(size_t i=1; i < initArgs.size(); ++i) @@ -252,7 +252,7 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) int pipe = cmSystemTools::WaitForLine(cp, line, 100.0, out, err); while(pipe != cmsysProcess_Pipe_None) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Output: " + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Output: " << line << "\n"); if(pipe == cmsysProcess_Pipe_STDERR) { @@ -264,7 +264,7 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) } pipe = cmSystemTools::WaitForLine(cp, line, 100, out, err); } - + // Properly handle output of the build command cmsysProcess_WaitForExit(cp, 0); int result = cmsysProcess_GetState(cp); @@ -278,7 +278,7 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) { retVal = cmsysProcess_GetExitException(cp); cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was an exception: " - << cmsysProcess_GetExceptionString(cp) << " " << + << cmsysProcess_GetExceptionString(cp) << " " << retVal << std::endl); failed = true; } @@ -338,7 +338,7 @@ void cmCTestScriptHandler::CreateCMake() this->Makefile->SetStartDirectory(cwd.c_str()); this->Makefile->SetStartOutputDirectory(cwd.c_str()); - // remove all cmake commands which are not scriptable, since they can't be + // remove all cmake commands which are not scriptable, since they can't be // used in ctest scripts this->CMake->RemoveUnscriptableCommands(); @@ -418,17 +418,17 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) this->Makefile->AddFunctionBlocker(f); - /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and - CMakeSystemSpecificInformation, so + /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and + CMakeSystemSpecificInformation, so that variables like CMAKE_SYSTEM and also the search paths for libraries, header and executables are set correctly and can be used. Makes new-style ctest scripting easier. */ - std::string systemFile = + std::string systemFile = this->Makefile->GetModulesFile("CTestScriptMode.cmake"); if (!this->Makefile->ReadListFile(0, systemFile.c_str()) || cmSystemTools::GetErrorOccuredFlag()) - { - cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read:" + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read:" << systemFile.c_str() << "\n"); return 2; } @@ -440,8 +440,8 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read script: " << script.c_str() << std::endl); - // Reset the error flag so that it can run more than - // one script with an error when you + // Reset the error flag so that it can run more than + // one script with an error when you // use ctest_run_script cmSystemTools::ResetErrorOccuredFlag(); return 2; @@ -880,7 +880,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() // put the initial cache into the bin dir if (!this->InitialCache.empty()) { - if (!this->WriteInitialCache(this->BinaryDir.c_str(), + if (!this->WriteInitialCache(this->BinaryDir.c_str(), this->InitialCache.c_str())) { this->RestoreBackupDirectories(); @@ -986,7 +986,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() } //------------------------------------------------------------------------- -bool cmCTestScriptHandler::WriteInitialCache(const char* directory, +bool cmCTestScriptHandler::WriteInitialCache(const char* directory, const char* text) { std::string cacheFile = directory; @@ -1032,7 +1032,7 @@ void cmCTestScriptHandler::RestoreBackupDirectories() } } -bool cmCTestScriptHandler::RunScript(cmCTest* ctest, const char *sname, +bool cmCTestScriptHandler::RunScript(cmCTest* ctest, const char *sname, bool InProcess, int* returnValue) { cmCTestScriptHandler* sh = new cmCTestScriptHandler(); @@ -1076,13 +1076,13 @@ double cmCTestScriptHandler::GetRemainingTimeAllowed() const char *timelimitS = this->Makefile->GetDefinition("CTEST_TIME_LIMIT"); - + if (!timelimitS) { return 1.0e7; } double timelimit = atof(timelimitS); - + return timelimit - cmSystemTools::GetTime() + this->ScriptStartTime; } diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 9f9f85a..43441c0 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -296,7 +296,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix, *this->LogFile << " Error when uploading file: " << local_file.c_str() << std::endl - << " Error message was: " + << " Error message was: " << error_buffer << std::endl << " Curl output was: "; // avoid dereference of empty vector @@ -364,13 +364,13 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix, { if(verifyPeerOff) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Set CURLOPT_SSL_VERIFYPEER to off\n"); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); } if(verifyHostOff) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Set CURLOPT_SSL_VERIFYHOST to off\n"); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); } @@ -601,7 +601,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix, *this->LogFile << " Error when uploading file: " << local_file.c_str() << std::endl - << " Error message was: " << error_buffer + << " Error message was: " << error_buffer << std::endl; // avoid deref of begin for zero size array if(chunk.size()) @@ -763,7 +763,7 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( << error_buffer << std::endl); *this->LogFile << "\tTriggering failed with error: " << error_buffer << std::endl - << " Error message was: " << error_buffer + << " Error message was: " << error_buffer << std::endl; if(chunk.size()) { @@ -913,8 +913,8 @@ bool cmCTestSubmitHandler::SubmitUsingCP( { if ( !localprefix.size() || !files.size() || !remoteprefix.size() || !destination.size() ) - { - cmCTestLog(this->CTest, ERROR_MESSAGE, + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Missing arguments for submit via cp:\n" << "\tlocalprefix: " << localprefix << "\n" << "\tNumber of files: " << files.size() << "\n" @@ -1285,7 +1285,7 @@ int cmCTestSubmitHandler::ProcessHandler() << std::endl); ofs << " Problems when submitting via FTP" << std::endl; return -1; - } + } if(!this->CDash) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method" @@ -1369,7 +1369,7 @@ int cmCTestSubmitHandler::ProcessHandler() { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" << (this->HasWarnings ? ", with warnings." : "") << std::endl); - ofs << " Submission successful" << + ofs << " Submission successful" << (this->HasWarnings ? ", with warnings." : "") << std::endl; } @@ -1439,20 +1439,20 @@ int cmCTestSubmitHandler::ProcessHandler() { std::string location = this->CTest->GetCTestConfiguration("DropLocation"); - + // change to the build directory so that we can uses a relative path // on windows since scp dosn't support "c:" a drive in the path - std::string + std::string oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(buildDirectory.c_str()); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Change directory: " << buildDirectory.c_str() << std::endl); if ( !this->SubmitUsingCP( - "Testing/"+this->CTest->GetCurrentTag(), - files, - prefix, + "Testing/"+this->CTest->GetCurrentTag(), + files, + prefix, location) ) { cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str()); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 87c75eb..f87c929 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -108,7 +108,7 @@ bool cmCTestSubdirCommand // does the CTestTestfile.cmake exist ? testFilename = "CTestTestfile.cmake"; } - else if( cmSystemTools::FileExists("DartTestfile.txt") ) + else if( cmSystemTools::FileExists("DartTestfile.txt") ) { // does the DartTestfile.txt exist ? testFilename = "DartTestfile.txt"; @@ -121,7 +121,7 @@ bool cmCTestSubdirCommand } fname += "/"; fname += testFilename; - bool readit = + bool readit = this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), fname.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str()); @@ -212,7 +212,7 @@ bool cmCTestAddSubdirectoryCommand } fname += "/"; fname += testFilename; - bool readit = + bool readit = this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), fname.c_str()); cmSystemTools::ChangeDirectory(cwd.c_str()); @@ -538,7 +538,7 @@ int cmCTestTestHandler::ProcessHandler() this->UseExcludeRegExp(); this->SetExcludeRegExp(val); } - + this->TestResults.clear(); cmCTestLog(this->CTest, HANDLER_OUTPUT, @@ -616,7 +616,7 @@ int cmCTestTestHandler::ProcessHandler() cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl << "The following tests FAILED:" << std::endl); this->StartLogFile("TestsFailed", ofs); - + std::vector<cmCTestTestHandler::cmCTestTestResult>::iterator ftit; for(ftit = this->TestResults.begin(); ftit != this->TestResults.end(); ++ftit) @@ -625,9 +625,9 @@ int cmCTestTestHandler::ProcessHandler() { ofs << ftit->TestCount << ":" << ftit->Name << std::endl; cmCTestLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3) - << ftit->TestCount << " - " + << ftit->TestCount << " - " << ftit->Name.c_str() << " (" - << this->GetTestStatus(ftit->Status) << ")" + << this->GetTestStatus(ftit->Status) << ")" << std::endl); } } @@ -696,18 +696,18 @@ void cmCTestTestHandler::PrintLabelSummary() // fill maps for(; ri != this->TestResults.end(); ++ri) { - cmCTestTestResult &result = *ri; + cmCTestTestResult &result = *ri; cmCTestTestProperties& p = *result.Properties; if(p.Labels.size() != 0) { for(std::vector<std::string>::iterator l = p.Labels.begin(); l != p.Labels.end(); ++l) - { + { labelTimes[*l] += result.ExecutionTime; } } } - // now print times + // now print times if(labels.size()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:"); @@ -728,7 +728,7 @@ void cmCTestTestHandler::PrintLabelSummary() } } if(labels.size()) - { + { if(this->LogFile) { *this->LogFile << "\n"; @@ -840,7 +840,7 @@ void cmCTestTestHandler::ComputeTestList() // Now create a final list of tests to run int cnt = 0; inREcnt = 0; - std::string last_directory = ""; + std::string last_directory = ""; ListOfTests finalList; for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ ) { @@ -888,13 +888,13 @@ void cmCTestTestHandler::ComputeTestList() max = p.Name.size(); } } - if(static_cast<std::string::size_type>(this->CTest->GetMaxTestNameWidth()) + if(static_cast<std::string::size_type>(this->CTest->GetMaxTestNameWidth()) != max) { this->CTest->SetMaxTestNameWidth(static_cast<int>(max)); } } - + bool cmCTestTestHandler::GetValue(const char* tag, int& value, std::ifstream& fin) @@ -984,7 +984,7 @@ bool cmCTestTestHandler::GetValue(const char* tag, ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line } else - { + { cmCTestLog(this->CTest, ERROR_MESSAGE, "parse error: missing tag: " << tag << " found [" << line.c_str() << "]" << std::endl); @@ -1036,7 +1036,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed, cmCTestMultiProcessHandler::TestMap tests; cmCTestMultiProcessHandler::PropertiesMap properties; - + bool randomSchedule = this->CTest->GetScheduleType() == "Random"; if(randomSchedule) { @@ -1045,7 +1045,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed, for (ListOfTests::iterator it = this->TestList.begin(); it != this->TestList.end(); ++it) - { + { cmCTestTestProperties& p = *it; cmCTestMultiProcessHandler::TestSet depends; @@ -1158,7 +1158,7 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os) << result->ExecutionTime << "</Value></NamedMeasurement>\n"; if(result->Reason.size()) - { + { const char* reasonType = "Pass Reason"; if(result->Status != cmCTestTestHandler::COMPLETED && result->Status != cmCTestTestHandler::NOT_RUN) @@ -1195,7 +1195,7 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os) os << "\t\t\t<Measurement>\n" << "\t\t\t\t<Value" - << (result->CompressOutput ? + << (result->CompressOutput ? " encoding=\"base64\" compression=\"gzip\">" : ">"); os << cmXMLSafe(result->Output); @@ -1278,7 +1278,7 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os, result->Properties->AttachOnFail.begin(), result->Properties->AttachOnFail.end()); } - for(std::vector<std::string>::const_iterator file = + for(std::vector<std::string>::const_iterator file = result->Properties->AttachedFiles.begin(); file != result->Properties->AttachedFiles.end(); ++file) { @@ -1322,7 +1322,7 @@ std::string cmCTestTestHandler::EncodeFile(std::string file) unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); - + std::string base64 = ""; for(unsigned long i = 0; i < rlen; i++) { @@ -1370,7 +1370,7 @@ std::string cmCTestTestHandler::FindTheExecutable(const char *exe) // add additional configurations to the search path void cmCTestTestHandler -::AddConfigurations(cmCTest *ctest, +::AddConfigurations(cmCTest *ctest, std::vector<std::string> &attempted, std::vector<std::string> &attemptedConfigs, std::string filepath, @@ -1378,7 +1378,7 @@ void cmCTestTestHandler { std::string tempPath; - if (filepath.size() && + if (filepath.size() && filepath[filepath.size()-1] != '/') { filepath += "/"; @@ -1386,7 +1386,7 @@ void cmCTestTestHandler tempPath = filepath + filename; attempted.push_back(tempPath); attemptedConfigs.push_back(""); - + if(ctest->GetConfigType().size()) { tempPath = filepath; @@ -1425,7 +1425,7 @@ void cmCTestTestHandler tempPath = filepath; tempPath += "RelWithDebInfo/"; tempPath += filename; - attempted.push_back(tempPath); + attempted.push_back(tempPath); attemptedConfigs.push_back("RelWithDebInfo"); tempPath = filepath; tempPath += "Deployment/"; @@ -1472,8 +1472,8 @@ std::string cmCTestTestHandler attemptedConfigs, localfilepath,filename); } - - + + // if extraPaths are provided and we were not passed a full path, try them, // try any extra paths if (filepath.size() == 0) @@ -1489,8 +1489,8 @@ std::string cmCTestTestHandler filepathExtra, filenameExtra); } - } - + } + // store the final location in fullPath std::string fullPath; @@ -1523,7 +1523,7 @@ std::string cmCTestTestHandler } } } - + // if everything else failed, check the users path, but only if a full path // wasn't specified if (fullPath.size() == 0 && filepath.size() == 0) @@ -1547,7 +1547,7 @@ std::string cmCTestTestHandler i->c_str() << "\n"); } } - + return fullPath; } @@ -1589,13 +1589,13 @@ void cmCTestTestHandler::GetListOfTests() cm.AddCommand(newCom1); // Add handler for SUBDIRS - cmCTestSubdirCommand* newCom2 = + cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand; newCom2->TestHandler = this; cm.AddCommand(newCom2); // Add handler for ADD_SUBDIRECTORY - cmCTestAddSubdirectoryCommand* newCom3 = + cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand; newCom3->TestHandler = this; cm.AddCommand(newCom3); @@ -2156,7 +2156,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if ( key == "ENVIRONMENT" ) - { + { std::vector<std::string> lval; cmSystemTools::ExpandListArgument(val.c_str(), lval); std::vector<std::string>::iterator crit; @@ -2272,7 +2272,7 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) test.Directory = cmSystemTools::GetCurrentWorkingDirectory(); cmCTestLog(this->CTest, DEBUG, "Set test directory: " << test.Directory << std::endl); - + test.IsInBasedOnREOptions = true; test.WillFail = false; test.RunSerial = false; diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index 7aa8522..2c4b230 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -126,7 +126,7 @@ public: }; // add configuraitons to a search path for an executable - static void AddConfigurations(cmCTest *ctest, + static void AddConfigurations(cmCTest *ctest, std::vector<std::string> &attempted, std::vector<std::string> &attemptedConfigs, std::string filepath, @@ -205,7 +205,7 @@ private: // compute the lists of tests that will actually run // based on union regex and -I stuff void ComputeTestList(); - + bool GetValue(const char* tag, std::string& value, std::ifstream& fin); diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c index 03896c2..f234722 100644 --- a/Source/CursesDialog/form/frm_driver.c +++ b/Source/CursesDialog/form/frm_driver.c @@ -1086,7 +1086,7 @@ _nc_Synchronize_Options(FIELD *field, Field_Options newopts) if (form->status & _POSTED) { - if ((form->curpage == field->page)) + if (form->curpage == field->page) { if (changed_opts & O_VISIBLE) { diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 562396d..72e9b24 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -293,6 +293,8 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) parentItems.append(new QStandardItem()); parentItems[0]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole); parentItems[1]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole); + parentItems[0]->setData(1, GroupRole); + parentItems[1]->setData(1, GroupRole); root->appendRow(parentItems); int num = props2.size(); @@ -314,6 +316,7 @@ void QCMakeCacheModel::setProperties(const QCMakePropertyList& props) QStandardItem* parentItem = new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key); root->appendRow(parentItem); + parentItem->setData(1, GroupRole); int num = props2.size(); for(int i=0; i<num; i++) @@ -478,10 +481,13 @@ QCMakePropertyList QCMakeCacheModel::properties() const } else { - // get data - QCMakeProperty prop; - this->getPropertyData(idx, prop); - props.append(prop); + if(!data(idx, GroupRole).toInt()) + { + // get data + QCMakeProperty prop; + this->getPropertyData(idx, prop); + props.append(prop); + } // go to the next in the tree while(!idxs.isEmpty() && !idxs.last().sibling(idxs.last().row()+1, 0).isValid()) diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h index 58bbd2d..0a628b9 100644 --- a/Source/QtDialog/QCMakeCacheView.h +++ b/Source/QtDialog/QCMakeCacheView.h @@ -67,7 +67,9 @@ public: enum { HelpRole = Qt::ToolTipRole, TypeRole = Qt::UserRole, AdvancedRole, - StringsRole}; + StringsRole, + GroupRole + }; enum ViewType { FlatView, GroupView }; diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 7af6ec8..502829e 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -286,6 +286,13 @@ bool cmAddCustomCommandCommand return false; } + // Convert working directory to a full path. + if(!working.empty()) + { + const char* build_dir = this->Makefile->GetCurrentOutputDirectory(); + working = cmSystemTools::CollapseFullPath(working.c_str(), build_dir); + } + // Choose which mode of the command to use. bool escapeOldStyle = !verbatim; if(source.empty() && output.empty()) diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 490e043..47b542c 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -110,6 +110,8 @@ public: "will be treated as PRE_LINK.\n" "If WORKING_DIRECTORY is specified the command will be executed " "in the directory given. " + "If it is a relative path it will be interpreted relative to the " + "build tree directory corresponding to the current source directory. " "If COMMENT is set, the value will be displayed as a " "message before the commands are executed at build time. " "If APPEND is specified the COMMAND and DEPENDS option values " diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index edb787b..27dea98 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -166,6 +166,14 @@ bool cmAddCustomTargetCommand } } + // Convert working directory to a full path. + if(!working_directory.empty()) + { + const char* build_dir = this->Makefile->GetCurrentOutputDirectory(); + working_directory = + cmSystemTools::CollapseFullPath(working_directory.c_str(), build_dir); + } + // Add the utility target to the makefile. bool escapeOldStyle = !verbatim; cmTarget* target = diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h index 7a2b396..6d94fb2 100644 --- a/Source/cmAddCustomTargetCommand.h +++ b/Source/cmAddCustomTargetCommand.h @@ -79,6 +79,8 @@ public: "empty target will be created. " "If WORKING_DIRECTORY is set, then the command will be run in that " "directory. " + "If it is a relative path it will be interpreted relative to the " + "build tree directory corresponding to the current source directory. " "If COMMENT is set, the value will be displayed as a " "message before the commands are executed at build time. " "Dependencies listed with the DEPENDS argument may reference files " diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index d53200c..e3c33a2 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -817,9 +817,9 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo() this->SharedLinkTypeFlag = shared_link_type_flag; } - // TODO: Lookup the starting link type from the target (is it being - // linked statically?). - this->StartLinkType = LinkShared; + // Lookup the starting link type from the target (linked statically?). + const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC"); + this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared; this->CurrentLinkType = this->StartLinkType; } diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 14a1062..f2431e6 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -97,6 +97,30 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Provide Information"); cm->DefineProperty + ("CMAKE_SCRIPT_MODE_FILE", cmProperty::VARIABLE, + "Full path to the -P script file currently being processed. ", + "When run in -P script mode, CMake sets this variable to the full " + "path of the script file. When run to configure a CMakeLists.txt " + "file, this variable is not set.", false, + "Variables that Provide Information"); + + cm->DefineProperty + ("CMAKE_ARGC", cmProperty::VARIABLE, + "Number of command line arguments passed to CMake in script mode. ", + "When run in -P script mode, CMake sets this variable to the number " + "of command line arguments. See also CMAKE_ARGV0, 1, 2 ... ", false, + "Variables that Provide Information"); + + cm->DefineProperty + ("CMAKE_ARGV0", cmProperty::VARIABLE, + "Command line argument passed to CMake in script mode. ", + "When run in -P script mode, CMake sets this variable to " + "the first command line argument. It then also sets CMAKE_ARGV1, " + "CMAKE_ARGV2, ... and so on, up to the number of command line arguments " + "given. See also CMAKE_ARGC.", false, + "Variables that Provide Information"); + + cm->DefineProperty ("CMAKE_BUILD_TOOL", cmProperty::VARIABLE, "Tool used for the actual build process.", "This variable is set to the program that will be" diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index e2a6035..9e5c91e 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -325,6 +325,12 @@ cmExportFileGenerator os << "SET_PROPERTY(TARGET " << targetName << " PROPERTY MACOSX_BUNDLE 1)\n"; } + + if (target->IsCFBundleOnApple()) + { + os << "SET_PROPERTY(TARGET " << targetName + << " PROPERTY BUNDLE 1)\n"; + } os << "\n"; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 717571c..23ff5fb 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -263,6 +263,20 @@ cmExportInstallFileGenerator value += ".framework/"; value += itgen->GetInstallFilename(target, config); } + else if(target->IsCFBundleOnApple()) + { + const char *ext = target->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + + value += itgen->GetInstallFilename(target, config); + value += "."; + value += ext; + value += "/"; + value += itgen->GetInstallFilename(target, config); + } else if(target->IsAppBundleOnApple()) { value += itgen->GetInstallFilename(target, config); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index a5650d4..4f93067 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -416,11 +416,18 @@ void cmExtraCodeBlocksGenerator case cmTarget::STATIC_LIBRARY: case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + case cmTarget::UTILITY: // can have sources since 2.6.3 { const std::vector<cmSourceFile*>&sources=ti->second.GetSourceFiles(); for (std::vector<cmSourceFile*>::const_iterator si=sources.begin(); si!=sources.end(); si++) { + // don't add source files which have the GENERATED property set: + if ((*si)->GetPropertyAsBool("GENERATED")) + { + continue; + } + // check whether it is a C/C++ implementation file bool isCFile = false; if ((*si)->GetLanguage() && (*(*si)->GetLanguage() == 'C')) diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 0ef771f..c4ea425 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -102,7 +102,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() const fout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<projectDescription>\n" - "\t<name>" << name << "</name>\n" + "\t<name>" << this->EscapeForXML(name) << "</name>\n" "\t<comment></comment>\n" "\t<projects>\n" "\t</projects>\n" @@ -376,11 +376,10 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() "\t</natures>\n" ; - // TODO: refactor this + fout << "\t<linkedResources>\n"; // create linked resources if (this->IsOutOfSourceBuild) { - fout << "\t<linkedResources>\n"; // create a linked resource to CMAKE_SOURCE_DIR // (this is not done anymore for each project because of // http://public.kitware.com/Bug/view.php?id=9978 and because I found it @@ -399,18 +398,48 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() this->SrcLinkedResources.push_back(sourceLinkedResourceName); } - // for EXECUTABLE_OUTPUT_PATH when not in binary dir - this->AppendOutLinkedResource(fout, - mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"), - mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH")); - // for LIBRARY_OUTPUT_PATH when not in binary dir - this->AppendOutLinkedResource(fout, - mf->GetSafeDefinition("CMAKE_LIBRARY_OUTPUT_DIRECTORY"), - mf->GetSafeDefinition("LIBRARY_OUTPUT_PATH")); + } + + // 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"); - fout << "\t</linkedResources>\n"; + for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator + it = this->GlobalGenerator->GetProjectMap().begin(); + it != this->GlobalGenerator->GetProjectMap().end(); + ++it) + { + std::string linkSourceDirectory = this->GetEclipsePath( + it->second[0]->GetMakefile()->GetStartDirectory()); + // a linked resource must not point to a parent directory of .project or + // .project itself + if ((this->HomeOutputDirectory != linkSourceDirectory) && + !cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(), + linkSourceDirectory.c_str())) + { + std::string linkName = "[Subprojects]/"; + linkName += it->first; + this->AppendLinkedResource(fout, linkName, + this->GetEclipsePath(linkSourceDirectory)); + this->SrcLinkedResources.push_back(it->first); + } } + // I'm not sure this makes too much sense. There can be different + // output directories in different subdirs, so we would need more of them. + + // for EXECUTABLE_OUTPUT_PATH when not in binary dir + this->AppendOutLinkedResource(fout, + mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"), + mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH")); + // for LIBRARY_OUTPUT_PATH when not in binary dir + this->AppendOutLinkedResource(fout, + mf->GetSafeDefinition("CMAKE_LIBRARY_OUTPUT_DIRECTORY"), + mf->GetSafeDefinition("LIBRARY_OUTPUT_PATH")); + + fout << "\t</linkedResources>\n"; + fout << "</projectDescription>\n"; } @@ -431,7 +460,8 @@ void cmExtraEclipseCDT4Generator::AppendIncludeDirectories( { emittedDirs.insert(dir); fout << "<pathentry include=\"" - << cmExtraEclipseCDT4Generator::GetEclipsePath(dir) + << cmExtraEclipseCDT4Generator::EscapeForXML( + cmExtraEclipseCDT4Generator::GetEclipsePath(dir)) << "\" kind=\"inc\" path=\"\" system=\"true\"/>\n"; } } @@ -550,14 +580,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const it != this->SrcLinkedResources.end(); ++it) { - fout << "<pathentry kind=\"src\" path=\"" << *it << "\"/>\n"; + fout << "<pathentry kind=\"src\" path=\"" << this->EscapeForXML(*it) + << "\"/>\n"; // exlude source directory from output search path // - only if not named the same as an output directory if (!cmSystemTools::FileIsDirectory( std::string(this->HomeOutputDirectory + "/" + *it).c_str())) { - excludeFromOut += *it + "/|"; + excludeFromOut += this->EscapeForXML(*it) + "/|"; } } excludeFromOut += "**/CMakeFiles/"; @@ -572,7 +603,8 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const it != this->OutLinkedResources.end(); ++it) { - fout << "<pathentry kind=\"out\" path=\"" << *it << "\"/>\n"; + fout << "<pathentry kind=\"out\" path=\"" << this->EscapeForXML(*it) + << "\"/>\n"; } // add pre-processor definitions to allow eclipse to gray out sections @@ -875,8 +907,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const fout << "</cconfiguration>\n" "</storageModule>\n" "<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n" - "<project id=\"" << mf->GetProjectName() << ".null.1\"" - " name=\"" << mf->GetProjectName() << "\"/>\n" + "<project id=\"" << this->EscapeForXML(mf->GetProjectName()) + << ".null.1\" name=\"" << this->EscapeForXML(mf->GetProjectName()) + << "\"/>\n" "</storageModule>\n" "</cproject>\n" ; @@ -927,7 +960,8 @@ cmExtraEclipseCDT4Generator::GenerateProjectName(const std::string& name, const std::string& type, const std::string& path) { - return name + (type.empty() ? "" : "-") + type + "@" + path; + return cmExtraEclipseCDT4Generator::EscapeForXML(name) + +(type.empty() ? "" : "-") + type + "@" + path; } std::string cmExtraEclipseCDT4Generator::EscapeForXML(const std::string& value) @@ -999,15 +1033,17 @@ void cmExtraEclipseCDT4Generator::AppendTarget(cmGeneratedFileStream& fout, const std::string& path, const char* prefix) { + std::string targetXml = cmExtraEclipseCDT4Generator::EscapeForXML(target); + std::string pathXml = cmExtraEclipseCDT4Generator::EscapeForXML(path); fout << - "<target name=\"" << prefix << target << "\"" - " path=\"" << path.c_str() << "\"" + "<target name=\"" << prefix << targetXml << "\"" + " path=\"" << pathXml.c_str() << "\"" " targetID=\"org.eclipse.cdt.make.MakeTargetBuilder\">\n" "<buildCommand>" << cmExtraEclipseCDT4Generator::GetEclipsePath(make) << "</buildCommand>\n" "<buildArguments>" << makeArgs << "</buildArguments>\n" - "<buildTarget>" << target << "</buildTarget>\n" + "<buildTarget>" << targetXml << "</buildTarget>\n" "<stopOnError>true</stopOnError>\n" "<useDefaultCommand>false</useDefaultCommand>\n" "</target>\n" @@ -1050,11 +1086,13 @@ void cmExtraEclipseCDT4Generator { fout << "\t\t<link>\n" - "\t\t\t<name>" << name << "</name>\n" + "\t\t\t<name>" + << cmExtraEclipseCDT4Generator::EscapeForXML(name) + << "</name>\n" "\t\t\t<type>2</type>\n" - "\t\t\t<location>" - << path - << "</location>\n" + "\t\t\t<locationURI>" + << cmExtraEclipseCDT4Generator::EscapeForXML(path) + << "</locationURI>\n" "\t\t</link>\n" ; } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 8ebd41f..d28de08 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -75,6 +75,10 @@ bool cmFileCommand { return this->HandleDownloadCommand(args); } + else if ( subCommand == "UPLOAD" ) + { + return this->HandleUploadCommand(args); + } else if ( subCommand == "READ" ) { return this->HandleReadCommand(args); @@ -1707,7 +1711,7 @@ protected: { DoingType = DoingLast1, DoingRename, - DoingSelf24 + DoingLast2 }; virtual bool CheckKeyword(std::string const& arg); virtual bool CheckValue(std::string const& arg); @@ -1846,22 +1850,12 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg) else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" || arg == "PROPERTIES") { - if(this->Makefile->IsOn("CMAKE_INSTALL_SELF_2_4")) - { - // When CMake 2.4 builds this CMake version we need to support - // the install scripts it generates since it asks this CMake - // to install itself using the rules it generated. - this->Doing = DoingSelf24; - } - else - { - cmOStringStream e; - e << "INSTALL called with old-style " << arg << " argument. " - << "This script was generated with an older version of CMake. " - << "Re-run this cmake version on your build tree."; - this->FileCommand->SetError(e.str().c_str()); - this->Doing = DoingError; - } + cmOStringStream e; + e << "INSTALL called with old-style " << arg << " argument. " + << "This script was generated with an older version of CMake. " + << "Re-run this cmake version on your build tree."; + this->FileCommand->SetError(e.str().c_str()); + this->Doing = DoingError; } else { @@ -1884,12 +1878,6 @@ bool cmFileInstaller::CheckValue(std::string const& arg) case DoingRename: this->Rename = arg; break; - case DoingSelf24: - // Ignore these arguments for compatibility. This should be - // reached only when CMake 2.4 is installing the current - // CMake. It can be removed when CMake 2.6 or higher is - // required to build CMake. - break; default: return this->cmFileCopier::CheckValue(arg); } @@ -2432,53 +2420,66 @@ bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string> this->Makefile->AddDefinition(var, value.c_str()); return true; } + + #if defined(CMAKE_BUILD_WITH_CMAKE) -// Stuff for curl download +// Stuff for curl download/upload typedef std::vector<char> cmFileCommandVectorOfChar; -namespace{ + +namespace { + size_t - cmFileCommandWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, - void *data) - { + cmWriteToFileCallback(void *ptr, size_t size, size_t nmemb, + void *data) + { register int realsize = (int)(size * nmemb); std::ofstream* fout = static_cast<std::ofstream*>(data); const char* chPtr = static_cast<char*>(ptr); fout->write(chPtr, realsize); return realsize; - } + } + + + size_t + cmWriteToMemoryCallback(void *ptr, size_t size, size_t nmemb, + void *data) + { + register int realsize = (int)(size * nmemb); + cmFileCommandVectorOfChar *vec + = static_cast<cmFileCommandVectorOfChar*>(data); + const char* chPtr = static_cast<char*>(ptr); + vec->insert(vec->end(), chPtr, chPtr + realsize); + return realsize; + } static size_t cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr, - size_t size, void *data) - { + size_t size, void *data) + { cmFileCommandVectorOfChar *vec = static_cast<cmFileCommandVectorOfChar*>(data); vec->insert(vec->end(), chPtr, chPtr + size); - return size; - } + } class cURLProgressHelper { public: - cURLProgressHelper(cmFileCommand *fc) + cURLProgressHelper(cmFileCommand *fc, const char *text) { this->CurrentPercentage = -1; this->FileCommand = fc; + this->Text = text; } bool UpdatePercentage(double value, double total, std::string &status) { int OldPercentage = this->CurrentPercentage; - if (0.0 == total) - { - this->CurrentPercentage = 100; - } - else + if (total > 0.0) { this->CurrentPercentage = static_cast<int>(value/total*100.0 + 0.5); } @@ -2488,7 +2489,8 @@ namespace{ if (updated) { cmOStringStream oss; - oss << "[download " << this->CurrentPercentage << "% complete]"; + oss << "[" << this->Text << " " << this->CurrentPercentage + << "% complete]"; status = oss.str(); } @@ -2503,14 +2505,15 @@ namespace{ private: int CurrentPercentage; cmFileCommand *FileCommand; + std::string Text; }; static int - cmFileCommandCurlProgressCallback(void *clientp, - double dltotal, double dlnow, - double ultotal, double ulnow) - { + cmFileDownloadProgressCallback(void *clientp, + double dltotal, double dlnow, + double ultotal, double ulnow) + { cURLProgressHelper *helper = reinterpret_cast<cURLProgressHelper *>(clientp); @@ -2526,12 +2529,33 @@ namespace{ } return 0; - } + } + + + static int + cmFileUploadProgressCallback(void *clientp, + double dltotal, double dlnow, + double ultotal, double ulnow) + { + cURLProgressHelper *helper = + reinterpret_cast<cURLProgressHelper *>(clientp); + + static_cast<void>(dltotal); + static_cast<void>(dlnow); + + std::string status; + if (helper->UpdatePercentage(ulnow, ultotal, status)) + { + cmFileCommand *fc = helper->GetFileCommand(); + cmMakefile *mf = fc->GetMakefile(); + mf->DisplayStatus(status.c_str(), -1); + } + + return 0; + } } -#endif -#if defined(CMAKE_BUILD_WITH_CMAKE) namespace { class cURLEasyGuard @@ -2563,9 +2587,18 @@ namespace { #endif +#define check_curl_result(result, errstr) \ + if (result != CURLE_OK) \ + { \ + std::string e(errstr); \ + e += ::curl_easy_strerror(result); \ + this->SetError(e.c_str()); \ + return false; \ + } + + bool -cmFileCommand::HandleDownloadCommand(std::vector<std::string> - const& args) +cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) { #if defined(CMAKE_BUILD_WITH_CMAKE) std::vector<std::string>::const_iterator i = args.begin(); @@ -2658,10 +2691,6 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> if (expectedMD5sum == actualMD5sum) { - this->Makefile->DisplayStatus( - "FILE(DOWNLOAD) returning early: file already exists with " - "expected MD5 sum", -1); - if(statusVar.size()) { cmOStringStream result; @@ -2708,88 +2737,37 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> cURLEasyGuard g_curl(curl); ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set url: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set url: "); res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, - cmFileCommandWriteMemoryCallback); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set write function: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + cmWriteToFileCallback); + check_curl_result(res, "DOWNLOAD cannot set write function: "); res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, cmFileCommandCurlDebugCallback); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set debug function: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set debug function: "); cmFileCommandVectorOfChar chunkDebug; res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout); - - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set write data: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set write data: "); res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set debug data: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set debug data: "); res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set follow-redirect option: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: "); if(verboseLog.size()) { res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set verbose: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set verbose: "); } if(timeout > 0) { res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout ); - - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set timeout: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set timeout: "); } // Need the progress helper's scope to last through the duration of @@ -2797,39 +2775,20 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> // scope intentionally, rather than inside the "if(showProgress)" // block... // - cURLProgressHelper helper(this); + cURLProgressHelper helper(this, "download"); if(showProgress) { - res = ::curl_easy_setopt(curl, - CURLOPT_NOPROGRESS, 0); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set noprogress value: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + check_curl_result(res, "DOWNLOAD cannot set noprogress value: "); res = ::curl_easy_setopt(curl, - CURLOPT_PROGRESSFUNCTION, cmFileCommandCurlProgressCallback); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set progress function: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + CURLOPT_PROGRESSFUNCTION, cmFileDownloadProgressCallback); + check_curl_result(res, "DOWNLOAD cannot set progress function: "); res = ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper)); - if (res != CURLE_OK) - { - std::string e = "DOWNLOAD cannot set progress data: "; - e += ::curl_easy_strerror(res); - this->SetError(e.c_str()); - return false; - } + check_curl_result(res, "DOWNLOAD cannot set progress data: "); } res = ::curl_easy_perform(curl); @@ -2905,3 +2864,220 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> return false; #endif } + + +bool +cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) +{ +#if defined(CMAKE_BUILD_WITH_CMAKE) + if(args.size() < 3) + { + this->SetError("UPLOAD must be called with at least three arguments."); + return false; + } + std::vector<std::string>::const_iterator i = args.begin(); + ++i; + std::string filename = *i; + ++i; + std::string url = *i; + ++i; + + long timeout = 0; + std::string logVar; + std::string statusVar; + bool showProgress = false; + + while(i != args.end()) + { + if(*i == "TIMEOUT") + { + ++i; + if(i != args.end()) + { + timeout = atol(i->c_str()); + } + else + { + this->SetError("UPLOAD missing time for TIMEOUT."); + return false; + } + } + else if(*i == "LOG") + { + ++i; + if( i == args.end()) + { + this->SetError("UPLOAD missing VAR for LOG."); + return false; + } + logVar = *i; + } + else if(*i == "STATUS") + { + ++i; + if( i == args.end()) + { + this->SetError("UPLOAD missing VAR for STATUS."); + return false; + } + statusVar = *i; + } + else if(*i == "SHOW_PROGRESS") + { + showProgress = true; + } + + ++i; + } + + // Open file for reading: + // + FILE *fin = fopen(filename.c_str(), "rb"); + if(!fin) + { + std::string errStr = "UPLOAD cannot open file '"; + errStr += filename + "' for reading."; + this->SetError(errStr.c_str()); + return false; + } + + struct stat st; + if(::stat(filename.c_str(), &st)) + { + std::string errStr = "UPLOAD cannot stat file '"; + errStr += filename + "'."; + this->SetError(errStr.c_str()); + return false; + } + + ::CURL *curl; + ::curl_global_init(CURL_GLOBAL_DEFAULT); + curl = ::curl_easy_init(); + if(!curl) + { + this->SetError("UPLOAD error initializing curl."); + return false; + } + + cURLEasyGuard g_curl(curl); + + // enable HTTP ERROR parsing + ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + + // enable uploading + res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + check_curl_result(res, "UPLOAD cannot set upload flag: "); + + res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + check_curl_result(res, "UPLOAD cannot set url: "); + + res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + cmWriteToMemoryCallback); + check_curl_result(res, "UPLOAD cannot set write function: "); + + res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, + cmFileCommandCurlDebugCallback); + check_curl_result(res, "UPLOAD cannot set debug function: "); + + cmFileCommandVectorOfChar chunkResponse; + cmFileCommandVectorOfChar chunkDebug; + + res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunkResponse); + check_curl_result(res, "UPLOAD cannot set write data: "); + + res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug); + check_curl_result(res, "UPLOAD cannot set debug data: "); + + res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + check_curl_result(res, "UPLOAD cannot set follow-redirect option: "); + + if(logVar.size()) + { + res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + check_curl_result(res, "UPLOAD cannot set verbose: "); + } + + if(timeout > 0) + { + res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout ); + check_curl_result(res, "UPLOAD cannot set 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)" + // block... + // + cURLProgressHelper helper(this, "upload"); + + if(showProgress) + { + res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + check_curl_result(res, "UPLOAD cannot set noprogress value: "); + + res = ::curl_easy_setopt(curl, + CURLOPT_PROGRESSFUNCTION, cmFileUploadProgressCallback); + check_curl_result(res, "UPLOAD cannot set progress function: "); + + res = ::curl_easy_setopt(curl, + CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper)); + check_curl_result(res, "UPLOAD cannot set progress data: "); + } + + // now specify which file to upload + res = ::curl_easy_setopt(curl, CURLOPT_INFILE, fin); + check_curl_result(res, "UPLOAD cannot set input file: "); + + // and give the size of the upload (optional) + res = ::curl_easy_setopt(curl, + CURLOPT_INFILESIZE, static_cast<long>(st.st_size)); + check_curl_result(res, "UPLOAD cannot set input file size: "); + + res = ::curl_easy_perform(curl); + + /* always cleanup */ + g_curl.release(); + ::curl_easy_cleanup(curl); + + if(statusVar.size()) + { + cmOStringStream result; + result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\""; + this->Makefile->AddDefinition(statusVar.c_str(), + result.str().c_str()); + } + + ::curl_global_cleanup(); + + fclose(fin); + fin = NULL; + + if(logVar.size()) + { + std::string log; + + if(chunkResponse.size()) + { + chunkResponse.push_back(0); + log += "Response:\n"; + log += &*chunkResponse.begin(); + log += "\n"; + } + + if(chunkDebug.size()) + { + chunkDebug.push_back(0); + log += "Debug:\n"; + log += &*chunkDebug.begin(); + log += "\n"; + } + + this->Makefile->AddDefinition(logVar.c_str(), log.c_str()); + } + + return true; +#else + this->SetError("UPLOAD not supported by bootstrap cmake."); + return false; +#endif +} diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index b11dcde..1b6dbbf 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -82,6 +82,8 @@ public: " 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" "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" @@ -165,6 +167,18 @@ public: "If SHOW_PROGRESS is specified, progress information will be printed " "as status messages until the operation is complete." "\n" + "UPLOAD will upload the given file to the given URL. " + "If LOG var is specified a log of the upload will be put in var. " + "If STATUS var is specified the status of the operation will" + " be put in var. The status is returned in a list of length 2. " + "The first element is the numeric return value for the operation, " + "and the second element is a string value for the error. A 0 " + "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. " + "If SHOW_PROGRESS is specified, progress information will be printed " + "as status messages until the operation is complete." + "\n" "The file() command also provides COPY and INSTALL signatures:\n" " file(<COPY|INSTALL> files... DESTINATION <dir>\n" " [FILE_PERMISSIONS permissions...]\n" @@ -223,6 +237,7 @@ protected: bool HandleCopyCommand(std::vector<std::string> const& args); bool HandleInstallCommand(std::vector<std::string> const& args); bool HandleDownloadCommand(std::vector<std::string> const& args); + bool HandleUploadCommand(std::vector<std::string> const& args); }; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index e3448de..8bb5487 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -22,21 +22,22 @@ bool cmGetCMakePropertyCommand this->SetError("called with incorrect number of arguments"); return false; } - + std::vector<std::string>::size_type cc; std::string variable = args[0]; std::string output = "NOTFOUND"; - if ( args[1] == "VARIABLES") + if ( args[1] == "VARIABLES" ) { int cacheonly = 0; std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly); - for ( cc = 0; cc < vars.size(); cc ++ ) + if (vars.size()>0) { - if ( cc > 0 ) - { - output += ";"; - } + output = vars[0]; + } + for ( cc = 1; cc < vars.size(); ++cc ) + { + output += ";"; output += vars[cc]; } } @@ -62,15 +63,15 @@ bool cmGetCMakePropertyCommand } else { - const char *prop = + const char *prop = this->Makefile->GetCMakeInstance()->GetProperty(args[1].c_str()); if (prop) { output = prop; } } + this->Makefile->AddDefinition(variable.c_str(), output.c_str()); - + return true; } - diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 2d080df..ef723b7 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -358,6 +358,15 @@ static cmVS7FlagTable cmVS8ExtraFlagTable[] = {"ExceptionHandling", "EHsc", "enable c++ exceptions", "1", 0}, {"ExceptionHandling", "EHa", "enable SEH exceptions", "2", 0}, + {"EnablePREfast", "analyze", "", "true", 0}, + {"EnablePREfast", "analyze-", "", "false", 0}, + + // Language options + {"TreatWChar_tAsBuiltInType", "Zc:wchar_t", + "wchar_t is a built-in type", "true", 0}, + {"TreatWChar_tAsBuiltInType", "Zc:wchar_t-", + "wchar_t is not a built-in type", "false", 0}, + {0,0,0,0,0} }; cmIDEFlagTable const* cmGlobalVisualStudio8Generator::GetExtraFlagTableVS8() diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 358721f..d5c0fef 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -165,13 +165,16 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const& } else { - mf->AddCacheDefinition( - "CMAKE_CONFIGURATION_TYPES", - "Debug;Release;MinSizeRel;RelWithDebInfo", - "Semicolon separated list of supported configuration types, " - "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " - "anything else will be ignored.", - cmCacheManager::STRING); + if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) + { + mf->AddCacheDefinition( + "CMAKE_CONFIGURATION_TYPES", + "Debug;Release;MinSizeRel;RelWithDebInfo", + "Semicolon separated list of supported configuration types, " + "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, " + "anything else will be ignored.", + cmCacheManager::STRING); + } } mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc"); mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++"); @@ -578,6 +581,12 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, } } + if(cmtarget.IsCFBundleOnApple()) + { + cmtarget.SetProperty("PREFIX", ""); + cmtarget.SetProperty("SUFFIX", ""); + } + // Add the fileRef to the top level Resources group/folder if it is not // already there. // @@ -812,6 +821,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, // some build phases only apply to bundles and/or frameworks bool isFrameworkTarget = cmtarget.IsFrameworkOnApple(); bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"); + bool isCFBundleTarget = cmtarget.IsCFBundleOnApple(); cmXCodeObject* buildFiles = 0; @@ -857,7 +867,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, // create resource build phase - only for framework or bundle targets cmXCodeObject* resourceBuildPhase = 0; - if (!resourceFiles.empty() && (isFrameworkTarget || isBundleTarget)) + if (!resourceFiles.empty() && + (isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { resourceBuildPhase = this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase); @@ -878,7 +889,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, // create vector of "non-resource content file" build phases - only for // framework or bundle targets std::vector<cmXCodeObject*> contentBuildPhases; - if (isFrameworkTarget || isBundleTarget) + if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) { typedef std::map<cmStdString, std::vector<cmSourceFile*> > mapOfVectorOfSourceFiles; @@ -1605,7 +1616,33 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { buildSettings->AddAttribute("LIBRARY_STYLE", this->CreateString("BUNDLE")); - if(this->XcodeVersion >= 22) + if (target.GetPropertyAsBool("BUNDLE")) + { + // It turns out that a BUNDLE is basically the same + // in many ways as an application bundle, as far as + // link flags go + std::string createFlags = + this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS", + "-bundle"); + if(!createFlags.empty()) + { + extraLinkOptions += " "; + extraLinkOptions += createFlags; + } + std::string plist = this->ComputeInfoPListLocation(target); + // Xcode will create the final version of Info.plist at build time, + // so let it replace the cfbundle name. This avoids creating + // a per-configuration Info.plist file. The cfbundle plist + // is very similar to the application bundle plist + this->CurrentLocalGenerator + ->GenerateAppleInfoPList(&target, "$(EXECUTABLE_NAME)", + plist.c_str()); + std::string path = + this->ConvertToRelativeForXCode(plist.c_str()); + buildSettings->AddAttribute("INFOPLIST_FILE", + this->CreateString(path.c_str())); + } + else if(this->XcodeVersion >= 22) { buildSettings->AddAttribute("MACH_O_TYPE", this->CreateString("mh_bundle")); @@ -1644,7 +1681,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, std::string plist = this->ComputeInfoPListLocation(target); // Xcode will create the final version of Info.plist at build time, - // so let it replace the framework name. This avoids creating + // so let it replace the framework name. This avoids creating // a per-configuration Info.plist file. this->CurrentLocalGenerator ->GenerateFrameworkInfoPList(&target, "$(EXECUTABLE_NAME)", @@ -2043,7 +2080,10 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget) case cmTarget::STATIC_LIBRARY: return "archive.ar"; case cmTarget::MODULE_LIBRARY: - return ((this->XcodeVersion >= 22)? + if (cmtarget.IsCFBundleOnApple()) + return "wrapper.plug-in"; + else + return ((this->XcodeVersion >= 22)? "compiled.mach-o.executable" : "compiled.mach-o.dylib"); case cmTarget::SHARED_LIBRARY: return (cmtarget.GetPropertyAsBool("FRAMEWORK")? @@ -2063,8 +2103,12 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget) case cmTarget::STATIC_LIBRARY: return "com.apple.product-type.library.static"; case cmTarget::MODULE_LIBRARY: - return ((this->XcodeVersion >= 22)? "com.apple.product-type.tool" : - "com.apple.product-type.library.dynamic"); + if (cmtarget.IsCFBundleOnApple()) + return "com.apple.product-type.bundle"; + else + return ((this->XcodeVersion >= 22)? + "com.apple.product-type.tool" : + "com.apple.product-type.library.dynamic"); case cmTarget::SHARED_LIBRARY: return (cmtarget.GetPropertyAsBool("FRAMEWORK")? "com.apple.product-type.framework" : diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index 7acb0f0..d9c0e87 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -171,3 +171,9 @@ void cmIDEOptions::AddFlag(const char* flag, const char* value) { this->FlagMap[flag] = value; } + +//---------------------------------------------------------------------------- +void cmIDEOptions::RemoveFlag(const char* flag) +{ + this->FlagMap.erase(flag); +} diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h index a156b23..a5be8fb 100644 --- a/Source/cmIDEOptions.h +++ b/Source/cmIDEOptions.h @@ -28,6 +28,7 @@ public: void AddDefine(const std::string& define); void AddDefines(const char* defines); void AddFlag(const char* flag, const char* value); + void RemoveFlag(const char* flag); protected: // create a map of xml tags to the values they should have in the output diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h index 7f229fa..d215295 100644 --- a/Source/cmListCommand.h +++ b/Source/cmListCommand.h @@ -83,6 +83,14 @@ public: "REMOVE_DUPLICATES will remove duplicated items in the list.\n" "REVERSE reverses the contents of the list in-place.\n" "SORT sorts the list in-place alphabetically.\n" + "The list subcommands APPEND, INSERT, REMOVE_AT, REMOVE_ITEM, " + "REMOVE_DUPLICATES, REVERSE and SORT may create new values for " + "the list within the current CMake variable scope. Similar to " + "the SET command, the LIST command creates new variable values " + "in the current scope, even if the list itself is actually " + "defined in a parent scope. To propagate the results of these " + "operations upwards, use SET with PARENT_SCOPE, SET with CACHE " + "INTERNAL, or some other means of value propagation.\n" "NOTES: A list in cmake is a ; separated group of strings. " "To create a list the set command can be used. For example, " "set(var a b c d e) creates a list with a;b;c;d;e, and " diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7da35eb..7b3fc86 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1904,6 +1904,7 @@ 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/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 7aabf4d..095e1a7 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -863,7 +863,7 @@ cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target, event.Write(target.GetPreBuildCommands()); event.Write(target.GetPreLinkCommands()); cmsys::auto_ptr<cmCustomCommand> pcc( - this->MaybeCreateImplibDir(target, configName)); + this->MaybeCreateImplibDir(target, configName, false)); if(pcc.get()) { event.Write(*pcc); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e839ed3..b9ffe62 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -381,6 +381,11 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = "Use sse2 instructions", "2", 0}, {"EnableEnhancedInstructionSet", "arch:SSE", "Use sse instructions", "1", 0}, + {"FloatingPointModel", "fp:precise", + "Use precise floating point model", "0", 0}, + {"FloatingPointModel", "fp:strict", + "Use strict floating point model", "1", 0}, + {"FloatingPointModel", "fp:fast", "Use fast floating point model", "2", 0}, {"FavorSizeOrSpeed", "Ot", "Favor fast code", "1", 0}, {"FavorSizeOrSpeed", "Os", "Favor small code", "2", 0}, {"CompileAs", "TC", "Compile as c code", "1", 0}, @@ -451,8 +456,13 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = "Turn off Run time type information for c++", "FALSE", 0}, {"SmallerTypeCheck", "RTCc", "smaller type check", "TRUE", 0}, {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "TRUE", 0}, + {"WholeProgramOptimization", "GL", + "Enables whole program optimization", "TRUE", 0}, + {"WholeProgramOptimization", "GL-", + "Disables whole program optimization", "FALSE", 0}, {"WarnAsError", "WX", "Treat warnings as errors", "TRUE", 0}, {"BrowseInformation", "FR", "Generate browse information", "1", 0}, + {"StringPooling", "GF", "Enable StringPooling", "TRUE", 0}, {0,0,0,0,0} }; @@ -466,6 +476,14 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE", 0}, {"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0}, {"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0}, + {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0}, + {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0}, + {"DataExecutionPrevention", "NXCOMPAT:NO", + "Not known to work with Windows Data Execution Prevention", "1", 0}, + {"DataExecutionPrevention", "NXCOMPAT", + "Known to work with Windows Data Execution Prevention", "2", 0}, + {"DelaySign", "DELAYSIGN:NO", "", "false", 0}, + {"DelaySign", "DELAYSIGN", "", "true", 0}, {"EntryPointSymbol", "ENTRY:", "sets the starting address", "", cmVS7FlagTable::UserValue}, {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "", @@ -478,8 +496,16 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs", "1", 0}, {"EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "2", 0}, + {"ResourceOnlyDLL", "NOENTRY", "Create DLL with no entry point", "true", 0}, {"OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", "1", 0}, {"OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0}, + {"Profile", "PROFILE", "", "true", 0}, + {"RandomizedBaseAddress", "DYNAMICBASE:NO", + "Image may not be rebased at load-time", "1", 0}, + {"RandomizedBaseAddress", "DYNAMICBASE", + "Image may be rebased at load-time", "2", 0}, + {"SetChecksum", "RELEASE", "Enable setting checksum in header", "true", 0}, + {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0}, {"TargetMachine", "MACHINE:I386", "Machine x86", "1", 0}, {"TargetMachine", "MACHINE:X86", "Machine x86", "1", 0}, {"TargetMachine", "MACHINE:AM33", "Machine AM33", "2", 0}, @@ -498,6 +524,8 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"TargetMachine", "MACHINE:SH5", "Machine SH5", "15", 0}, {"TargetMachine", "MACHINE:THUMB", "Machine THUMB", "16", 0}, {"TargetMachine", "MACHINE:X64", "Machine x64", "17", 0}, + {"TurnOffAssemblyGeneration", "NOASSEMBLY", + "No assembly even if CLR information is present in objects.", "true", 0}, {"ModuleDefinitionFile", "DEF:", "add an export def file", "", cmVS7FlagTable::UserValue}, {"GenerateMapFile", "MAP", "enable generation of map file", "TRUE", 0}, @@ -1695,7 +1723,7 @@ void cmLocalVisualStudio7Generator event.Start(tool); event.Write(target.GetPreLinkCommands()); cmsys::auto_ptr<cmCustomCommand> pcc( - this->MaybeCreateImplibDir(target, configName)); + this->MaybeCreateImplibDir(target, configName, this->FortranProject)); if(pcc.get()) { event.Write(*pcc); diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 9164beb..39f9962 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -32,13 +32,17 @@ cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator() //---------------------------------------------------------------------------- cmsys::auto_ptr<cmCustomCommand> cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, - const char* config) + const char* config, + bool isFortran) { cmsys::auto_ptr<cmCustomCommand> pcc; // If an executable exports symbols then VS wants to create an // import library but forgets to create the output directory. - if(target.GetType() != cmTarget::EXECUTABLE) { return pcc; } + // The Intel Fortran plugin always forgets to the directory. + if(target.GetType() != cmTarget::EXECUTABLE && + !(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY)) + { return pcc; } std::string outDir = target.GetDirectory(config, false); std::string impDir = target.GetDirectory(config, true); if(impDir == outDir) { return pcc; } diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index 1954ac5..22112b3 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -47,7 +47,7 @@ protected: /** Construct a custom command to make exe import lib dir. */ cmsys::auto_ptr<cmCustomCommand> - MaybeCreateImplibDir(cmTarget& target, const char* config); + MaybeCreateImplibDir(cmTarget& target, const char* config, bool isFortran); // Safe object file name generation. void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index e14e44d..63bf03b 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -893,6 +893,20 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, return; } + // Validate custom commands. TODO: More strict? + for(cmCustomCommandLines::const_iterator i=commandLines.begin(); + i != commandLines.end(); ++i) + { + cmCustomCommandLine const& cl = *i; + if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"') + { + cmOStringStream e; + e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; + this->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + } + // Choose a source file on which to store the custom command. cmSourceFile* file = 0; if(main_dependency && main_dependency[0]) @@ -2744,6 +2758,27 @@ void cmMakefile::SetHomeOutputDirectory(const char* lib) } } +void cmMakefile::SetScriptModeFile(const char* scriptfile) +{ + this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile); +} + +void cmMakefile::SetArgcArgv(const std::vector<std::string>& args) +{ + cmOStringStream strStream; + strStream << args.size(); + this->AddDefinition("CMAKE_ARGC", strStream.str().c_str()); + //this->MarkVariableAsUsed("CMAKE_ARGC"); + + for (unsigned int t = 0; t < args.size(); ++t) + { + cmOStringStream tmpStream; + tmpStream << "CMAKE_ARGV" << t; + this->AddDefinition(tmpStream.str().c_str(), args[t].c_str()); + //this->MarkVariableAsUsed(tmpStream.str().c_str()); + } +} + //---------------------------------------------------------------------------- cmSourceFile* cmMakefile::GetSource(const char* sourceName) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 837a352..1c1aef3 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -411,7 +411,17 @@ public: return this->HomeOutputDirectory.c_str(); } //@} - + + /** + * Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script. + */ + void SetScriptModeFile(const char* scriptfile); + + /** + * Set CMAKE_ARGC, CMAKE_ARGV0 ... variables. + */ + void SetArgcArgv(const std::vector<std::string>& args); + //@{ /** * Set/Get the start directory (or output directory). The start directory diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index c5900f1..31f7be5 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -26,6 +26,12 @@ cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): cmMakefileTargetGenerator(target) { + if(this->Target->IsCFBundleOnApple()) + { + target->SetProperty("PREFIX", ""); + target->SetProperty("SUFFIX", ""); + } + this->CustomCommandDriver = OnDepends; this->Target->GetLibraryNames( this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, @@ -41,6 +47,20 @@ cmMakefileLibraryTargetGenerator this->MacContentDirectory += this->FrameworkVersion; this->MacContentDirectory += "/"; } + else if(this->Target->IsCFBundleOnApple()) + { + this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); + this->MacContentDirectory += "/"; + this->MacContentDirectory += this->TargetNameOut; + this->MacContentDirectory += "."; + const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + this->MacContentDirectory += ext; + this->MacContentDirectory += "/Contents/"; + } } //---------------------------------------------------------------------------- @@ -301,6 +321,27 @@ cmMakefileLibraryTargetGenerator } //---------------------------------------------------------------------------- +void +cmMakefileLibraryTargetGenerator::CreateCFBundle(std::string& targetName, + std::string& outpath) +{ + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + outpath += "/"; + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory + "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteLibraryRules (const char* linkRuleVar, const char* extraFlags, bool relink) { @@ -354,6 +395,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules outpath = this->MacContentDirectory; this->CreateFramework(targetName); } + else if(this->Target->IsCFBundleOnApple()) + { + outpath = this->Target->GetDirectory(this->ConfigName); + outpath += "/"; + this->CreateCFBundle(targetName, outpath); + } else if(relink) { outpath = this->Makefile->GetStartOutputDirectory(); @@ -417,6 +464,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules buildEcho += " shared library "; break; case cmTarget::MODULE_LIBRARY: + if (this->Target->IsCFBundleOnApple()) + buildEcho += " CFBundle"; buildEcho += " shared module "; break; default: diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index 2f085ad..f3c47db 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -33,6 +33,7 @@ protected: // MacOSX Framework support methods void WriteFrameworkRules(bool relink); void CreateFramework(std::string const& targetName); + void CreateCFBundle(std::string& targetName, std::string& outpath); // Store the computd framework version for OS X Frameworks. std::string FrameworkVersion; diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 2d1f792..37070b6 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -453,7 +453,7 @@ cmPolicies::cmPolicies() "Starting with CMake 2.8.4, if a cmake-module shipped with CMake (i.e. " "located in the CMake module directory) calls include() or " "find_package(), the files located in the the CMake module directory are " - "prefered over the files in CMAKE_MODULE_PATH. " + "preferred over the files in CMAKE_MODULE_PATH. " "This makes sure that the modules belonging to " "CMake always get those files included which they expect, and against " "which they were developed and tested. " diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index ed1da7b..42d3f06 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -482,17 +482,21 @@ void cmSourceFile::DefineProperties(cmake *cm) cm->DefineProperty ("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE, - "Place a source file inside a Mac OS X bundle or framework.", + "Place a source file inside a Mac OS X bundle, CFBundle, or framework.", "Executable targets with the MACOSX_BUNDLE property set are built " "as Mac OS X application bundles on Apple platforms. " "Shared library targets with the FRAMEWORK property set are built " "as Mac OS X frameworks on Apple platforms. " + "Module library targets with the BUNDLE property set are built " + "as Mac OS X CFBundle bundles on Apple platforms. " "Source files listed in the target with this property set will " "be copied to a directory inside the bundle or framework content " "folder specified by the property value. " "For bundles the content folder is \"<name>.app/Contents\". " "For frameworks the content folder is " "\"<name>.framework/Versions/<version>\". " + "For cfbundles the content folder is " + "\"<name>.bundle/Contents\" (unless the extension is changed). " "See the PUBLIC_HEADER, PRIVATE_HEADER, and RESOURCE target " "properties for specifying files meant for Headers, PrivateHeaders, " "or Resources directories."); diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 949fcf5..19d2369 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -72,7 +72,11 @@ bool cmStringCommand { return this->HandleRandomCommand(args); } - + else if(subCommand == "FIND") + { + return this->HandleFindCommand(args); + } + std::string e = "does not recognize sub-command "+subCommand; this->SetError(e.c_str()); return false; @@ -499,6 +503,68 @@ void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re) } //---------------------------------------------------------------------------- +bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& + args) +{ + // check if all required parameters were passed + if(args.size() < 4 || args.size() > 5) + { + this->SetError("sub-command FIND requires 3 or 4 parameters."); + return false; + } + + // check if the reverse flag was set or not + bool reverseMode = false; + if(args.size() == 5 && args[4] == "REVERSE") + { + reverseMode = true; + } + + // if we have 5 arguments the last one must be REVERSE + if(args.size() == 5 && args[4] != "REVERSE") + { + this->SetError("sub-command FIND: unknown last parameter"); + return false; + } + + // local parameter names. + const std::string& sstring = args[1]; + const std::string& schar = args[2]; + const std::string& outvar = args[3]; + + // ensure that the user cannot accidentally specify REVERSE as a variable + if(outvar == "REVERSE") + { + this->SetError("sub-command FIND does not allow to select REVERSE as " + "the output variable. " + "Maybe you missed the actual output variable?"); + return false; + } + + // try to find the character and return its position + size_t pos; + if(!reverseMode) + { + pos = sstring.find(schar); + } + else + { + pos = sstring.rfind(schar); + } + if(std::string::npos != pos) + { + cmOStringStream s; + s << pos; + this->Makefile->AddDefinition(outvar.c_str(), s.str().c_str()); + return true; + } + + // the character was not found, but this is not really an error + this->Makefile->AddDefinition(outvar.c_str(), "-1"); + return true; +} + +//---------------------------------------------------------------------------- bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const& args) { diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 2a916b4..9586449 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -90,6 +90,7 @@ public: " string(STRIP <string> <output variable>)\n" " string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n" " [RANDOM_SEED <seed>] <output variable>)\n" + " string(FIND <string> <substring> <output variable> [REVERSE])\n" "REGEX MATCH will match the regular expression once and store the " "match in the output variable.\n" "REGEX MATCHALL will match the regular expression as many times as " @@ -117,6 +118,10 @@ public: "characters and default alphabet is all numbers and upper and " "lower case letters. If an integer RANDOM_SEED is given, its " "value will be used to seed the random number generator.\n" + "FIND will return the position where the given substring was found " + "in the supplied string. If the REVERSE flag was used, the command " + "will search for the position of the last occurrence of the " + "specified substring.\n" "The following characters have special meaning in regular expressions:\n" " ^ Matches at beginning of a line\n" " $ Matches at end of a line\n" @@ -152,6 +157,7 @@ protected: bool HandleSubstringCommand(std::vector<std::string> const& args); bool HandleStripCommand(std::vector<std::string> const& args); bool HandleRandomCommand(std::vector<std::string> const& args); + bool HandleFindCommand(std::vector<std::string> const& args); class RegexReplacement { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 72efce3..7bd5372 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -188,6 +188,22 @@ void cmTarget::DefineProperties(cmake *cm) "the target is built."); cm->DefineProperty + ("BUNDLE", cmProperty::TARGET, + "This target is a CFBundle on the Mac.", + "If a module library target has this property set to true it will " + "be built as a CFBundle when built on the mac. It will have the " + "directory structure required for a CFBundle and will be suitable " + "to be used for creating Browser Plugins or other application " + "resources."); + + cm->DefineProperty + ("BUNDLE_EXTENSION", cmProperty::TARGET, + "The file extension used to name a BUNDLE target on the Mac.", + "The default value is \"bundle\" - you can also use \"plugin\" or " + "whatever file extension is required by the host app for your " + "bundle."); + + cm->DefineProperty ("FRAMEWORK", cmProperty::TARGET, "This target is a framework on the Mac.", "If a shared library target has this property set to true it will " @@ -471,17 +487,32 @@ void cmTarget::DefineProperties(cmake *cm) "Per-configuration linker flags for a target.", "This is the configuration-specific version of LINK_FLAGS."); +#define CM_LINK_SEARCH_SUMMARY \ + "Some linkers support switches such as -Bstatic and -Bdynamic " \ + "to determine whether to use static or shared libraries for -lXXX " \ + "options. CMake uses these options to set the link type for " \ + "libraries whose full paths are not known or (in some cases) are in " \ + "implicit link directories for the platform. " + + cm->DefineProperty + ("LINK_SEARCH_START_STATIC", cmProperty::TARGET, + "Assume the linker looks for static libraries by default.", + CM_LINK_SEARCH_SUMMARY + "By default the linker search type is assumed to be -Bdynamic at " + "the beginning of the library list. This property switches the " + "assumption to -Bstatic. It is intended for use when linking an " + "executable statically (e.g. with the GNU -static option). " + "See also LINK_SEARCH_END_STATIC."); + cm->DefineProperty ("LINK_SEARCH_END_STATIC", cmProperty::TARGET, "End a link line such that static system libraries are used.", - "Some linkers support switches such as -Bstatic and -Bdynamic " - "to determine whether to use static or shared libraries for -lXXX " - "options. CMake uses these options to set the link type for " - "libraries whose full paths are not known or (in some cases) are in " - "implicit link directories for the platform. By default the " - "linker search type is left at -Bdynamic by the end of the library " - "list. This property switches the final linker search type to " - "-Bstatic."); + CM_LINK_SEARCH_SUMMARY + "By default CMake adds an option at the end of the library list (if " + "necessary) to set the linker search type back to its starting type. " + "This property switches the final linker search type to -Bstatic " + "regardless of how it started. " + "See also LINK_SEARCH_START_STATIC."); cm->DefineProperty ("LINKER_LANGUAGE", cmProperty::TARGET, @@ -1211,6 +1242,14 @@ bool cmTarget::IsAppBundleOnApple() } //---------------------------------------------------------------------------- +bool cmTarget::IsCFBundleOnApple() +{ + return (this->GetType() == cmTarget::MODULE_LIBRARY && + this->Makefile->IsOn("APPLE") && + this->GetPropertyAsBool("BUNDLE")); +} + +//---------------------------------------------------------------------------- class cmTargetTraceDependencies { public: @@ -4278,9 +4317,13 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) } } - // There is no implicit link interface for executables, so if none - // was explicitly set, there is no link interface. - if(!explicitLibraries && this->GetType() == cmTarget::EXECUTABLE) + // There is no implicit link interface for executables or modules + // so if none was explicitly set then there is no link interface. + // Note that CMake versions 2.2 and below allowed linking to modules. + bool canLinkModules = this->Makefile->NeedBackwardsCompatibility(2,2); + if(!explicitLibraries && + (this->GetType() == cmTarget::EXECUTABLE || + (this->GetType() == cmTarget::MODULE_LIBRARY && !canLinkModules))) { return false; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f2b7d61..3b1f016 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -326,7 +326,7 @@ public: */ bool FindSourceFiles(); - ///! Return the prefered linker language for this target + ///! Return the preferred linker language for this target const char* GetLinkerLanguage(const char* config = 0); ///! Return the rule variable used to create this type of target, @@ -430,6 +430,9 @@ public: Apple. */ bool IsFrameworkOnApple(); + /** Return whether this target is a CFBundle (plugin) on Apple. */ + bool IsCFBundleOnApple(); + /** Return whether this target is an executable Bundle on Apple. */ bool IsAppBundleOnApple(); diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h index 141995d..fec2265 100644 --- a/Source/cmUseMangledMesaCommand.h +++ b/Source/cmUseMangledMesaCommand.h @@ -30,7 +30,7 @@ public: /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() + virtual cmCommand* Clone() { return new cmUseMangledMesaCommand; } @@ -41,7 +41,7 @@ public: */ virtual bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus &status); - + /** * The name of the command as specified in CMakeList.txt. */ @@ -50,11 +50,11 @@ public: /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() { return "Copy mesa headers for use in combination with system GL."; } - + /** * More documentation. */ @@ -68,6 +68,11 @@ public: "being added to the include directory path earlier."; } + /** + * This determines if the command is invoked when in script mode. + */ + virtual bool IsScriptable() { return true; } + /** This command is kept for compatibility with older CMake versions. */ virtual bool IsDiscouraged() { @@ -80,5 +85,4 @@ protected: }; - #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4cb745e..8a27ffd 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -167,6 +167,7 @@ void cmVisualStudio10TargetGenerator::Generate() // Write the encoding header into the file char magic[] = {0xEF,0xBB, 0xBF}; this->BuildFileStream->write(magic, 3); + this->WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",0); this->WriteString("<Project DefaultTargets=\"Build\" " "ToolsVersion=\"4.0\" " "xmlns=\"http://schemas.microsoft.com/" @@ -998,6 +999,15 @@ OutputLinkIncremental(std::string const& configName) this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3); *this->BuildFileStream << incremental << "</LinkIncremental>\n"; + + const char* manifest = "true"; + if(flags.find("MANIFEST:NO") != flags.npos) + { + manifest = "false"; + } + this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3); + *this->BuildFileStream << manifest + << "</GenerateManifest>\n"; } //---------------------------------------------------------------------------- @@ -1326,7 +1336,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& linkDirs += "%(AdditionalLibraryDirectories)"; linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs.c_str()); linkOptions.AddFlag("AdditionalDependencies", libs.c_str()); - linkOptions.AddFlag("Version", "0.0"); + linkOptions.AddFlag("Version", ""); if(linkOptions.IsDebug() || flags.find("/debug") != flags.npos) { linkOptions.AddFlag("GenerateDebugInformation", "true"); @@ -1369,6 +1379,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& linkOptions.AddFlag("ModuleDefinitionFile", this->ModuleDefinitionFile.c_str()); } + + linkOptions.RemoveFlag("GenerateManifest"); linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); linkOptions.OutputFlagMap(*this->BuildFileStream, " "); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index bab0aaf..ea8cdfd 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -462,7 +462,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) } } std::cerr << "loading initial cache file " << path.c_str() << "\n"; - this->ReadListFile(path.c_str()); + this->ReadListFile(args, path.c_str()); } else if(arg.find("-P",0) == 0) { @@ -478,13 +478,14 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) cmSystemTools::Error("No cmake script provided."); return false; } - this->ReadListFile(path.c_str()); + this->ReadListFile(args, path.c_str()); } } return true; } -void cmake::ReadListFile(const char *path) +void cmake::ReadListFile(const std::vector<std::string>& args, + const char *path) { // if a generator was not yet created, temporarily create one cmGlobalGenerator *gg = this->GetGlobalGenerator(); @@ -510,6 +511,14 @@ void cmake::ReadListFile(const char *path) (cmSystemTools::GetCurrentWorkingDirectory().c_str()); lg->GetMakefile()->SetStartDirectory (cmSystemTools::GetCurrentWorkingDirectory().c_str()); + if (this->GetScriptMode()) + { + std::string file(cmSystemTools::CollapseFullPath(path)); + cmSystemTools::ConvertToUnixSlashes(file); + lg->GetMakefile()->SetScriptModeFile(file.c_str()); + + lg->GetMakefile()->SetArgcArgv(args); + } if (!lg->GetMakefile()->ReadListFile(0, path)) { cmSystemTools::Error("Error processing file:", path); @@ -979,37 +988,39 @@ void CMakeCommandUsage(const char* program) errorStream << "Usage: " << program << " -E [command] [arguments ...]\n" << "Available commands: \n" + << " build build_dir - build the project in build_dir.\n" << " chdir dir cmd [args]... - run command in a given directory\n" - << " rename oldname newname - rename a file or directory " - "(on one volume)\n" + << " compare_files file1 file2 - check if file1 is same as file2\n" << " copy file destination - copy file to destination (either file " "or directory)\n" - << " copy_if_different in-file out-file - copy file if input has " - "changed\n" << " copy_directory source destination - copy directory 'source' " "content to directory 'destination'\n" - << " compare_files file1 file2 - check if file1 is same as file2\n" + << " copy_if_different in-file out-file - copy file if input has " + "changed\n" << " echo [string]... - displays arguments as text\n" << " echo_append [string]... - displays arguments as text but no new " "line\n" << " environment - display the current environment\n" << " make_directory dir - create a directory\n" << " md5sum file1 [...] - compute md5sum of files\n" - << " remove_directory dir - remove a directory and its contents\n" << " remove [-f] file1 file2 ... - remove the file(s), use -f to force " "it\n" + << " remove_directory dir - remove a directory and its contents\n" + << " rename oldname newname - rename a file or directory " + "(on one volume)\n" << " tar [cxt][vfz][cvfj] file.tar " "file/dir1 file/dir2 ... - create a tar " "archive\n" << " time command [args] ... - run command and return elapsed time\n" << " touch file - touch a file.\n" << " touch_nocreate file - touch a file but do not create it.\n" - << " build build_dir - build the project in build_dir.\n" #if defined(_WIN32) && !defined(__CYGWIN__) - << " write_regv key value - write registry value\n" - << " delete_regv key - delete registry value\n" + << "Available on Windows only:\n" << " comspec - on windows 9x use this for RunCommand\n" + << " delete_regv key - delete registry value\n" + << " write_regv key value - write registry value\n" #else + << "Available on UNIX only:\n" << " create_symlink old new - create a symbolic link new -> old\n" #endif ; @@ -1984,8 +1995,32 @@ int cmake::Configure() } +bool cmake::RejectUnsupportedPaths(const char* desc, std::string const& path) +{ + // Some characters are not well-supported by native build systems. + std::string::size_type pos = path.find_first_of("="); + if(pos == std::string::npos) + { + return false; + } + cmOStringStream e; + e << "The path to the " << desc << " directory:\n" + << " " << path << "\n" + << "contains unsupported character '" << path[pos] << "'.\n" + << "Please use a different " << desc << " directory name."; + cmListFileBacktrace bt; + this->IssueMessage(cmake::FATAL_ERROR, e.str(), bt); + return true; +} + int cmake::ActualConfigure() { + if(this->RejectUnsupportedPaths("source", this->cmHomeDirectory) || + this->RejectUnsupportedPaths("binary", this->HomeOutputDirectory)) + { + return 1; + } + // Construct right now our path conversion table before it's too late: this->UpdateConversionPathTable(); this->CleanupCommandsAndMacros(); @@ -2197,13 +2232,14 @@ int cmake::ActualConfigure() void cmake::PreLoadCMakeFiles() { + std::vector<std::string> args; std::string pre_load = this->GetHomeDirectory(); if ( pre_load.size() > 0 ) { pre_load += "/PreLoad.cmake"; if ( cmSystemTools::FileExists(pre_load.c_str()) ) { - this->ReadListFile(pre_load.c_str()); + this->ReadListFile(args, pre_load.c_str()); } } pre_load = this->GetHomeOutputDirectory(); @@ -2212,7 +2248,7 @@ void cmake::PreLoadCMakeFiles() pre_load += "/PreLoad.cmake"; if ( cmSystemTools::FileExists(pre_load.c_str()) ) { - this->ReadListFile(pre_load.c_str()); + this->ReadListFile(args, pre_load.c_str()); } } } @@ -4108,7 +4144,10 @@ int cmake::VisualStudioLinkNonIncremental(std::vector<std::string>& args, return -1; } // Run the link command as given - linkCommand.push_back("/MANIFEST"); + if (hasManifest) + { + linkCommand.push_back("/MANIFEST"); + } if(!cmake::RunCommand("LINK", linkCommand, verbose)) { return -1; diff --git a/Source/cmake.h b/Source/cmake.h index 1bb42d3..132a86d 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -406,7 +406,7 @@ protected: bool DoSuppressDevWarnings; ///! read in a cmake list file to initialize the cache - void ReadListFile(const char *path); + void ReadListFile(const std::vector<std::string>& args, const char *path); ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file. /// If it is set, truncate it to 50kb @@ -451,6 +451,8 @@ protected: ///! Find the full path to one of the cmake programs like ctest, cpack, etc. std::string FindCMakeProgram(const char* name) const; + + bool RejectUnsupportedPaths(const char* desc, std::string const& path); private: cmake(const cmake&); // Not implemented. void operator=(const cmake&); // Not implemented. diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index a51673c..a5dca18 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -71,11 +71,13 @@ static const char * cmDocumentationOptions[][3] = {"-E", "CMake command mode.", "For true platform independence, CMake provides a list of commands " "that can be used on all systems. Run with -E help for the usage " - "information. Commands available are: chdir, copy, copy_if_different " - "copy_directory, compare_files, echo, echo_append, environment, " - "make_directory, md5sum, remove_directory, remove, tar, time, " - "touch, touch_nocreate, write_regv, delete_regv, comspec, " - "create_symlink."}, + "information. Commands available are: build, chdir, compare_files, copy, " + "copy_directory, copy_if_different, echo, echo_append, environment, " + "make_directory, md5sum, remove, remove_directory, rename, tar, time, " + "touch, touch_nocreate. In addition, some platform specific commands " + "are available. " + "On Windows: comspec, delete_regv, write_regv. " + "On UNIX: create_symlink."}, {"-i", "Run in wizard mode.", "Wizard mode runs cmake interactively without a GUI. The user is " "prompted to answer questions about the project configuration. " diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index a35a01f..f5f317c 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # KWSys - Kitware System Library -# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium +# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -44,9 +44,7 @@ # SET(KWSYS_IOS_FORCE_OLD 1) # # -# Optional settings to setup install rules work in one of two ways. -# The modern way utilizes the CMake 2.4 INSTALL command. Settings -# for this mode are as follows: +# Optional settings to setup install rules are as follows: # # KWSYS_INSTALL_BIN_DIR = The installation target directories into # KWSYS_INSTALL_LIB_DIR which the libraries and headers from @@ -70,25 +68,6 @@ # SET(KWSYS_INSTALL_INCLUDE_DIR include) # SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime) # SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development) -# -# The old way uses the original CMake INSTALL_* commands. Settings -# for this mode are as follows: -# -# KWSYS_LIBRARY_INSTALL_DIR = The installation target directories into -# KWSYS_HEADER_INSTALL_DIR which the libraries and headers from -# kwsys should be installed by a "make install". -# The values should be specified relative to -# the installation prefix and start with a '/'. -# Example: -# -# SET(KWSYS_LIBRARY_INSTALL_DIR /lib) -# SET(KWSYS_HEADER_INSTALL_DIR /include) -# -# The modern way will be used whenever the INSTALL command is -# available. If the settings are not available the old names will be -# used to construct them. The old way will be used whenever the -# INSTALL command is not available. If the settings are not available -# the new names will be used to construct them. # Once configured, kwsys should be used as follows from C or C++ code: # @@ -105,13 +84,7 @@ # any outside mailing list and no documentation of the change will be # written. -CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5 FATAL_ERROR) -IF(COMMAND CMAKE_POLICY) - CMAKE_POLICY(SET CMP0003 NEW) -ENDIF(COMMAND CMAKE_POLICY) - -# Allow empty endif() and such with CMake 2.4. -SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 1) +CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR) #----------------------------------------------------------------------------- # If a namespace is not specified, use "kwsys" and enable testing. @@ -126,23 +99,11 @@ ENDIF(NOT KWSYS_NAMESPACE) # The project name is that of the specified namespace. PROJECT(${KWSYS_NAMESPACE}) -# Some properties we set only with CMake 2.6 and above. -IF(COMMAND SET_PROPERTY) - MACRO(KWSYS_SET_PROPERTY) - SET_PROPERTY(${ARGV}) - ENDMACRO(KWSYS_SET_PROPERTY) -ELSE(COMMAND SET_PROPERTY) - MACRO(KWSYS_SET_PROPERTY) - ENDMACRO(KWSYS_SET_PROPERTY) -ENDIF(COMMAND SET_PROPERTY) - # Tell CMake how to follow dependencies of sources in this directory. -IF(COMMAND SET_PROPERTY) - SET_PROPERTY(DIRECTORY - PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM - "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>" - ) -ENDIF(COMMAND SET_PROPERTY) +SET_PROPERTY(DIRECTORY + PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM + "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>" + ) # Select library components. IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) @@ -208,97 +169,75 @@ INCLUDE(CheckTypeSize) # Do full dependency headers. INCLUDE_REGULAR_EXPRESSION("^.*$") -# Choose which kind of install commands to use. -IF(COMMAND INSTALL) - # Use new KWSYS_INSTALL_*_DIR variable names to control installation. - # Take defaults from the old names. Note that there was no old name - # for the bin dir, so we take the old lib dir name so DLLs will be - # installed in a compatible way for old code. - IF(NOT KWSYS_INSTALL_INCLUDE_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR - "${KWSYS_HEADER_INSTALL_DIR}") - ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR) - IF(NOT KWSYS_INSTALL_LIB_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR - "${KWSYS_LIBRARY_INSTALL_DIR}") - ENDIF(NOT KWSYS_INSTALL_LIB_DIR) - IF(NOT KWSYS_INSTALL_BIN_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR - "${KWSYS_LIBRARY_INSTALL_DIR}") - ENDIF(NOT KWSYS_INSTALL_BIN_DIR) - - # Setup header install rules. - SET(KWSYS_INSTALL_INCLUDE_OPTIONS) - IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} - ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) +# Use new KWSYS_INSTALL_*_DIR variable names to control installation. +# Take defaults from the old names. Note that there was no old name +# for the bin dir, so we take the old lib dir name so DLLs will be +# installed in a compatible way for old code. +IF(NOT KWSYS_INSTALL_INCLUDE_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR + "${KWSYS_HEADER_INSTALL_DIR}") +ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR) +IF(NOT KWSYS_INSTALL_LIB_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR + "${KWSYS_LIBRARY_INSTALL_DIR}") +ENDIF(NOT KWSYS_INSTALL_LIB_DIR) +IF(NOT KWSYS_INSTALL_BIN_DIR) + STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR + "${KWSYS_LIBRARY_INSTALL_DIR}") +ENDIF(NOT KWSYS_INSTALL_BIN_DIR) + +# Setup header install rules. +SET(KWSYS_INSTALL_INCLUDE_OPTIONS) +IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) + SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} + ) +ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - # Setup library install rules. - SET(KWSYS_INSTALL_LIBRARY_RULE) - IF(KWSYS_INSTALL_LIB_DIR) - IF(KWSYS_INSTALL_EXPORT_NAME) - LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME}) - ENDIF() - # Install the shared library to the lib directory. +# Setup library install rules. +SET(KWSYS_INSTALL_LIBRARY_RULE) +IF(KWSYS_INSTALL_LIB_DIR) + IF(KWSYS_INSTALL_EXPORT_NAME) + LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME}) + ENDIF() + # Install the shared library to the lib directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} + ) + # Assign the shared library to the runtime component. + IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} ) - # Assign the shared library to the runtime component. - IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} - ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - # Install the archive to the lib directory. + # Install the archive to the lib directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR} + ) + # Assign the archive to the development component. + IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} ) - # Assign the archive to the development component. - IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} - ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - ENDIF(KWSYS_INSTALL_LIB_DIR) - IF(KWSYS_INSTALL_BIN_DIR) - # Install the runtime library to the bin directory. + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) +ENDIF(KWSYS_INSTALL_LIB_DIR) +IF(KWSYS_INSTALL_BIN_DIR) + # Install the runtime library to the bin directory. + SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} + RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR} + ) + # Assign the runtime library to the runtime component. + IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR} + COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} ) - # Assign the runtime library to the runtime component. - IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} - ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - ENDIF(KWSYS_INSTALL_BIN_DIR) - - # Do not support old KWSYS_*_INSTALL_DIR variable names. - SET(KWSYS_HEADER_INSTALL_DIR) - SET(KWSYS_LIBRARY_INSTALL_DIR) - -ELSE(COMMAND INSTALL) - # Use old KWSYS_*_INSTALL_DIR variable names. - # Take defaults from the new names. - IF(KWSYS_INSTALL_LIB_DIR) - IF(NOT KWSYS_LIBRARY_INSTALL_DIR) - SET(KWSYS_LIBRARY_INSTALL_DIR "/${KWSYS_INSTALL_LIB_DIR}") - ENDIF(NOT KWSYS_LIBRARY_INSTALL_DIR) - ENDIF(KWSYS_INSTALL_LIB_DIR) - IF(KWSYS_INSTALL_INCLUDE_DIR) - IF(NOT KWSYS_HEADER_INSTALL_DIR) - SET(KWSYS_HEADER_INSTALL_DIR "/${KWSYS_INSTALL_INCLUDE_DIR}") - ENDIF(NOT KWSYS_HEADER_INSTALL_DIR) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) + ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) +ENDIF(KWSYS_INSTALL_BIN_DIR) - # Do not support new KWSYS_INSTALL_*_DIR variable names. - SET(KWSYS_INSTALL_BIN_DIR) - SET(KWSYS_INSTALL_INCLUDE_DIR) - SET(KWSYS_INSTALL_LIB_DIR) -ENDIF(COMMAND INSTALL) +# Do not support old KWSYS_*a_INSTALL_DIR variable names. +SET(KWSYS_HEADER_INSTALL_DIR) +SET(KWSYS_LIBRARY_INSTALL_DIR) # Generated source files will need this header. STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" @@ -680,10 +619,6 @@ FOREACH(header DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/stl - FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ELSE(KWSYS_STL_HEADER_EXTRA_${header}) SET(KWSYS_STL_HEADER_EXTRA "") ENDIF(KWSYS_STL_HEADER_EXTRA_${header}) @@ -697,10 +632,6 @@ FOREACH(header DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/stl - FILES ${KWSYS_HEADER_DIR}/stl/${header}) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDFOREACH(header) # Provide cstddef header. @@ -711,10 +642,6 @@ IF(KWSYS_INSTALL_INCLUDE_DIR) INSTALL(FILES ${KWSYS_HEADER_DIR}/cstddef DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} - FILES ${KWSYS_HEADER_DIR}/cstddef) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) #----------------------------------------------------------------------------- @@ -732,10 +659,6 @@ FOREACH(header iostream fstream sstream iosfwd) DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/ios ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/ios - FILES ${KWSYS_HEADER_DIR}/ios/${header}) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDFOREACH(header) #----------------------------------------------------------------------------- @@ -824,10 +747,6 @@ FOREACH(c ${KWSYS_CLASSES}) DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} - FILES ${KWSYS_HEADER_DIR}/${c}.hxx) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDFOREACH(c) # Configure C headers. @@ -843,10 +762,6 @@ FOREACH(h ${KWSYS_H_FILES}) DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} - FILES ${KWSYS_HEADER_DIR}/${h}.h) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDFOREACH(h) # Configure other C++ headers. @@ -862,10 +777,6 @@ FOREACH(h ${KWSYS_HXX_FILES}) DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - IF(KWSYS_HEADER_INSTALL_DIR) - INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE} - FILES ${KWSYS_HEADER_DIR}/${h}.hxx) - ENDIF(KWSYS_HEADER_INSTALL_DIR) ENDFOREACH(h) #----------------------------------------------------------------------------- @@ -873,7 +784,7 @@ ENDFOREACH(h) IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) ADD_LIBRARY(${KWSYS_NAMESPACE} ${KWSYS_LIBRARY_TYPE} ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS}) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY LABELS ${KWSYS_LABELS_LIB}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY LABELS ${KWSYS_LABELS_LIB}) IF(KWSYS_USE_DynamicLoader) IF(UNIX) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS}) @@ -895,15 +806,12 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) IF(KWSYS_INSTALL_LIBRARY_RULE) INSTALL(TARGETS ${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LIBRARY_RULE}) ENDIF(KWSYS_INSTALL_LIBRARY_RULE) - IF(KWSYS_LIBRARY_INSTALL_DIR) - INSTALL_TARGETS(${KWSYS_LIBRARY_INSTALL_DIR} ${KWSYS_NAMESPACE}) - ENDIF(KWSYS_LIBRARY_INSTALL_DIR) ENDIF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) # Add a C-only library if requested. IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) ADD_LIBRARY(${KWSYS_NAMESPACE}_c ${KWSYS_LIBRARY_TYPE} ${KWSYS_C_SRCS}) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}_c PROPERTY LABELS ${KWSYS_LABELS_LIB}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}_c PROPERTY LABELS ${KWSYS_LABELS_LIB}) # Apply user-defined target properties to the library. IF(KWSYS_PROPERTIES_C) @@ -916,9 +824,6 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) IF(KWSYS_INSTALL_LIBRARY_RULE) INSTALL(TARGETS ${KWSYS_NAMESPACE}_c ${KWSYS_INSTALL_LIBRARY_RULE}) ENDIF(KWSYS_INSTALL_LIBRARY_RULE) - IF(KWSYS_LIBRARY_INSTALL_DIR) - INSTALL_TARGETS(${KWSYS_LIBRARY_INSTALL_DIR} ${KWSYS_NAMESPACE}_c) - ENDIF(KWSYS_LIBRARY_INSTALL_DIR) ENDIF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) # For building kwsys itself, we use a macro defined on the command @@ -942,8 +847,8 @@ IF(KWSYS_USE_Process) # encode it into a C file. ADD_EXECUTABLE(${KWSYS_NAMESPACE}ProcessFwd9x ProcessFwd9x.c) ADD_EXECUTABLE(${KWSYS_NAMESPACE}EncodeExecutable EncodeExecutable.c) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE}) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE}) # Construct the location of the executable to be encoded. SET(BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -959,23 +864,12 @@ IF(KWSYS_USE_Process) # Take advantage of a better custom command syntax if possible. SET(CMD ${BIN_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}EncodeExecutable.exe) SET(FWD ${BIN_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}ProcessFwd9x.exe) - IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" GREATER 1.6) - ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - COMMAND ${CMD} - ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - ${KWSYS_NAMESPACE} ProcessFwd9x - DEPENDS ${CMD} ${FWD}) - ELSE("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" GREATER 1.6) - ADD_CUSTOM_COMMAND( - TARGET ${KWSYS_NAMESPACE} - SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/ProcessFwd9x.c - COMMAND ${CMD} - ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - ${KWSYS_NAMESPACE} ProcessFwd9x - OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - DEPENDS ${CMD} ${FWD}) - ENDIF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" GREATER 1.6) + ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c + COMMAND ${CMD} + ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c + ${KWSYS_NAMESPACE} ProcessFwd9x + DEPENDS ${CMD} ${FWD}) # Make sure build occurs in proper order. ADD_DEPENDENCIES(${KWSYS_NAMESPACE} ${KWSYS_NAMESPACE}ProcessFwd9x @@ -998,19 +892,19 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) testEncode testTerminal ) - IF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) + IF(KWSYS_STANDALONE) SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail) - ENDIF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) + ENDIF() CREATE_TEST_SOURCELIST( KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c ${KWSYS_C_TESTS} ) ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS}) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE}) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_NAMESPACE}_c) FOREACH(test ${KWSYS_C_TESTS}) ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}}) - KWSYS_SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) + SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) ENDFOREACH(test) # C++ tests @@ -1034,7 +928,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader) # If kwsys contains the DynamicLoader, need extra library ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB}) ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_NAMESPACE}) ENDIF(KWSYS_USE_DynamicLoader) CREATE_TEST_SOURCELIST( @@ -1042,7 +936,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ${KWSYS_CXX_TESTS} ) ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS}) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE}) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_NAMESPACE}) SET(TEST_SYSTEMTOOLS_BIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.bin") @@ -1089,19 +983,19 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ) FOREACH(test ${KWSYS_CXX_TESTS}) ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}}) - KWSYS_SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) + SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) ENDFOREACH(test) # Process tests. ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE}) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_NAMESPACE}_c) IF(NOT CYGWIN) SET(KWSYS_TEST_PROCESS_7 7) ENDIF(NOT CYGWIN) FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7}) ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}) - KWSYS_SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) + SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120) ENDFOREACH(n) @@ -1115,13 +1009,13 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE) ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward ${PROJECT_BINARY_DIR}/testSharedForward.c) - KWSYS_SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE}) + SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE}) ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_NAMESPACE}_c) ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1) - KWSYS_SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST}) + SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST}) # Configure some test properties. - IF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) + IF(KWSYS_STANDALONE) # We expect test to fail SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON) GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv) @@ -1129,7 +1023,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES PASS_REGULAR_EXPRESSION "Test passed") SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value") MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}") - ENDIF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY AND KWSYS_STANDALONE) + ENDIF() # Suppress known consistent failures on buggy systems. IF(KWSYS_TEST_BOGUS_FAILURES) diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 2fc5086..3ec53f7 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 02) +SET(KWSYS_DATE_STAMP_MONTH 03) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 15) +SET(KWSYS_DATE_STAMP_DAY 22) |