summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt16
-rw-r--r--Source/CMakeVersion.cmake6
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx552
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.h135
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx406
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h95
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx540
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.h133
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx58
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx149
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.h46
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx17
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.h3
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h5
-rw-r--r--Source/CPack/cmCPack7zGenerator.cxx25
-rw-r--r--Source/CPack/cmCPack7zGenerator.h36
-rw-r--r--Source/CPack/cmCPackGenerator.cxx7
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx18
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackTXZGenerator.cxx25
-rw-r--r--Source/CPack/cmCPackTXZGenerator.h35
-rw-r--r--Source/CPack/cpack.cxx3
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.cxx8
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.h5
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx15
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.h1
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx9
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx9
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx2
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx40
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h5
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx4
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx617
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h45
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx8
-rw-r--r--Source/CTest/cmCTestRunTest.cxx15
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx11
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx19
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx2
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx5
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx5
-rw-r--r--Source/CTest/cmCTestVC.cxx15
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx1
-rw-r--r--Source/CTest/cmParseJacocoCoverage.cxx170
-rw-r--r--Source/CTest/cmParseJacocoCoverage.h59
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx8
-rw-r--r--Source/CursesDialog/ccmake.cxx18
-rw-r--r--Source/QtDialog/CMakeLists.txt28
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx3
-rw-r--r--Source/QtIFW/cmake.org.html7
-rw-r--r--Source/QtIFW/installscript.qs.in24
-rw-r--r--Source/cmArchiveWrite.cxx36
-rw-r--r--Source/cmArchiveWrite.h3
-rw-r--r--Source/cmBootstrapCommands2.cxx2
-rw-r--r--Source/cmCTest.cxx62
-rw-r--r--Source/cmCTest.h2
-rw-r--r--Source/cmComputeLinkDepends.cxx108
-rw-r--r--Source/cmComputeLinkDepends.h16
-rw-r--r--Source/cmComputeLinkInformation.cxx20
-rw-r--r--Source/cmComputeLinkInformation.h4
-rw-r--r--Source/cmComputeTargetDepends.cxx46
-rw-r--r--Source/cmComputeTargetDepends.h7
-rw-r--r--Source/cmConditionEvaluator.cxx770
-rw-r--r--Source/cmConditionEvaluator.h96
-rw-r--r--Source/cmCoreTryCompile.cxx6
-rw-r--r--Source/cmDefinitions.cxx16
-rw-r--r--Source/cmDefinitions.h7
-rw-r--r--Source/cmDepends.cxx7
-rw-r--r--Source/cmDependsC.cxx12
-rw-r--r--Source/cmDependsFortran.cxx76
-rw-r--r--Source/cmDocumentation.cxx20
-rw-r--r--Source/cmDocumentation.h3
-rw-r--r--Source/cmDocumentationFormatter.h2
-rw-r--r--Source/cmExpandedCommandArgument.cxx51
-rw-r--r--Source/cmExpandedCommandArgument.h45
-rw-r--r--Source/cmExportFileGenerator.cxx8
-rw-r--r--Source/cmExportFileGenerator.h4
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx10
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx2
-rw-r--r--Source/cmFileCommand.cxx215
-rw-r--r--Source/cmGeneratorExpression.cxx8
-rw-r--r--Source/cmGeneratorExpression.h5
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx358
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h1
-rw-r--r--Source/cmGeneratorTarget.cxx82
-rw-r--r--Source/cmGeneratorTarget.h4
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx2
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h2
-rw-r--r--Source/cmGlobalGenerator.cxx212
-rw-r--r--Source/cmGlobalGenerator.h32
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h2
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h2
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h2
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h2
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx65
-rw-r--r--Source/cmGlobalNinjaGenerator.h20
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx210
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h53
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx92
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h10
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx71
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h7
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx113
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h43
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx1
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h12
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx68
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h31
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx62
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h12
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx23
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h7
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx10
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h10
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx63
-rw-r--r--Source/cmGlobalXCodeGenerator.h12
-rw-r--r--Source/cmIDEOptions.cxx48
-rw-r--r--Source/cmIDEOptions.h23
-rw-r--r--Source/cmIfCommand.cxx723
-rw-r--r--Source/cmIfCommand.h14
-rw-r--r--Source/cmInstallCommand.cxx31
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx4
-rw-r--r--Source/cmInstallDirectoryGenerator.h1
-rw-r--r--Source/cmInstallExportGenerator.cxx3
-rw-r--r--Source/cmInstallExportGenerator.h1
-rw-r--r--Source/cmInstallFilesCommand.cxx4
-rw-r--r--Source/cmInstallFilesGenerator.cxx3
-rw-r--r--Source/cmInstallFilesGenerator.h1
-rw-r--r--Source/cmInstallGenerator.cxx38
-rw-r--r--Source/cmInstallGenerator.h16
-rw-r--r--Source/cmInstallProgramsCommand.cxx4
-rw-r--r--Source/cmInstallScriptGenerator.cxx2
-rw-r--r--Source/cmInstallTargetGenerator.cxx100
-rw-r--r--Source/cmInstallTargetGenerator.h10
-rw-r--r--Source/cmInstalledFile.cxx18
-rw-r--r--Source/cmInstalledFile.h5
-rw-r--r--Source/cmListFileCache.cxx3
-rw-r--r--Source/cmListFileLexer.c75
-rw-r--r--Source/cmListFileLexer.in.l7
-rw-r--r--Source/cmLocalGenerator.cxx45
-rw-r--r--Source/cmLocalGenerator.h6
-rw-r--r--Source/cmLocalNinjaGenerator.cxx30
-rw-r--r--Source/cmLocalNinjaGenerator.h4
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx4
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx97
-rw-r--r--Source/cmLocalVisualStudio7Generator.h3
-rw-r--r--Source/cmLocalVisualStudioGenerator.h4
-rw-r--r--Source/cmMakefile.cxx159
-rw-r--r--Source/cmMakefile.h44
-rw-r--r--Source/cmMakefileTargetGenerator.cxx18
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx14
-rw-r--r--Source/cmNinjaTargetGenerator.cxx32
-rw-r--r--Source/cmNinjaTargetGenerator.h3
-rw-r--r--Source/cmOrderDirectories.cxx18
-rw-r--r--Source/cmPolicies.cxx5
-rw-r--r--Source/cmPolicies.h2
-rw-r--r--Source/cmQtAutoGenerators.cxx53
-rw-r--r--Source/cmQtAutoGenerators.h24
-rw-r--r--Source/cmStandardIncludes.h6
-rw-r--r--Source/cmStringCommand.cxx116
-rw-r--r--Source/cmStringCommand.h1
-rw-r--r--Source/cmSystemTools.cxx92
-rw-r--r--Source/cmTarget.cxx2409
-rw-r--r--Source/cmTarget.h209
-rw-r--r--Source/cmTimestamp.cxx8
-rw-r--r--Source/cmUuid.cxx214
-rw-r--r--Source/cmUuid.h55
-rw-r--r--Source/cmVS10MASMFlagTable.h96
-rw-r--r--Source/cmVS10RCFlagTable.h7
-rw-r--r--Source/cmVS11MASMFlagTable.h96
-rw-r--r--Source/cmVS11RCFlagTable.h7
-rw-r--r--Source/cmVS12MASMFlagTable.h96
-rw-r--r--Source/cmVS12RCFlagTable.h7
-rw-r--r--Source/cmVS14CLFlagTable.h296
-rw-r--r--Source/cmVS14LibFlagTable.h102
-rw-r--r--Source/cmVS14LinkFlagTable.h340
-rw-r--r--Source/cmVS14MASMFlagTable.h96
-rw-r--r--Source/cmVS14RCFlagTable.h7
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx1688
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h45
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx46
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h3
-rw-r--r--Source/cmWhileCommand.cxx17
-rw-r--r--Source/cmXMLParser.cxx13
-rw-r--r--Source/cmXMLParser.h9
-rw-r--r--Source/cmake.cxx76
-rw-r--r--Source/cmake.h10
-rw-r--r--Source/cmakemain.cxx18
-rw-r--r--Source/cmcmd.cxx51
-rwxr-xr-xSource/cmparseMSBuildXML.py3
-rw-r--r--Source/ctest.cxx7
-rw-r--r--Source/kwsys/CMakeLists.txt7
-rw-r--r--Source/kwsys/CPU.h.in4
-rw-r--r--Source/kwsys/Directory.cxx46
-rw-r--r--Source/kwsys/Directory.hxx.in17
-rw-r--r--Source/kwsys/Glob.cxx14
-rw-r--r--Source/kwsys/ProcessUNIX.c2
-rw-r--r--Source/kwsys/ProcessWin32.c17
-rw-r--r--Source/kwsys/SharedForward.h.in2
-rw-r--r--Source/kwsys/SystemInformation.cxx17
-rw-r--r--Source/kwsys/SystemTools.cxx701
-rw-r--r--Source/kwsys/SystemTools.hxx.in99
-rw-r--r--Source/kwsys/Terminal.c6
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake8
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx2
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testProcess.c17
-rw-r--r--Source/kwsys/testSystemTools.cxx322
-rw-r--r--Source/kwsys/testSystemTools.h.in5
216 files changed, 11953 insertions, 4132 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index fe6cc1b..f9405b3 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -308,6 +308,7 @@ set(SRCS
cmTest.h
cmTestGenerator.cxx
cmTestGenerator.h
+ cmUuid.cxx
cmVariableWatch.cxx
cmVariableWatch.h
cmVersion.cxx
@@ -426,6 +427,8 @@ if (WIN32)
cmGlobalVisualStudio11Generator.cxx
cmGlobalVisualStudio12Generator.h
cmGlobalVisualStudio12Generator.cxx
+ cmGlobalVisualStudio14Generator.h
+ cmGlobalVisualStudio14Generator.cxx
cmGlobalVisualStudioGenerator.cxx
cmGlobalVisualStudioGenerator.h
cmIDEFlagTable.h
@@ -448,7 +451,7 @@ if (WIN32)
endif ()
# Watcom support
-if(WIN32 OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_property(SOURCE cmake.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_USE_WMAKE)
list(APPEND SRCS
cmGlobalWatcomWMakeGenerator.cxx
@@ -518,6 +521,7 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmParseMumpsCoverage.cxx
CTest/cmParseCacheCoverage.cxx
CTest/cmParseGTMCoverage.cxx
+ CTest/cmParseJacocoCoverage.cxx
CTest/cmParsePHPCoverage.cxx
CTest/cmParseCoberturaCoverage.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -574,11 +578,16 @@ set(CPACK_SRCS
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
CPack/cmCPackNSISGenerator.cxx
+ CPack/IFW/cmCPackIFWPackage.cxx
+ CPack/IFW/cmCPackIFWInstaller.cxx
+ CPack/IFW/cmCPackIFWGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
CPack/cmCPackTGZGenerator.cxx
+ CPack/cmCPackTXZGenerator.cxx
CPack/cmCPackTarBZip2Generator.cxx
CPack/cmCPackTarCompressGenerator.cxx
CPack/cmCPackZIPGenerator.cxx
+ CPack/cmCPack7zGenerator.cxx
)
if(CYGWIN)
@@ -598,13 +607,14 @@ endif()
if(WIN32)
set(CPACK_SRCS ${CPACK_SRCS}
CPack/WiX/cmCPackWIXGenerator.cxx
- CPack/WiX/cmWIXSourceWriter.cxx
+ CPack/WiX/cmWIXAccessControlList.cxx
CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
CPack/WiX/cmWIXFeaturesSourceWriter.cxx
CPack/WiX/cmWIXFilesSourceWriter.cxx
- CPack/WiX/cmWIXRichTextFormatWriter.cxx
CPack/WiX/cmWIXPatch.cxx
CPack/WiX/cmWIXPatchParser.cxx
+ CPack/WiX/cmWIXRichTextFormatWriter.cxx
+ CPack/WiX/cmWIXSourceWriter.cxx
)
endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 34aefb4..716f229 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 0)
-set(CMake_VERSION_PATCH 20140609)
-#set(CMake_VERSION_RC 1)
+set(CMake_VERSION_MINOR 1)
+set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
new file mode 100644
index 0000000..7f06e2d
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -0,0 +1,552 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWGenerator.h"
+
+#include "cmCPackIFWPackage.h"
+#include "cmCPackIFWInstaller.h"
+
+#include <CPack/cmCPackLog.h>
+#include <CPack/cmCPackComponentGroup.h>
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#include <cmGlobalGenerator.h>
+#include <cmLocalGenerator.h>
+#include <cmSystemTools.h>
+#include <cmMakefile.h>
+#include <cmGeneratedFileStream.h>
+#include <cmXMLSafe.h>
+
+//----------------------------------------------------------------------------
+cmCPackIFWGenerator::cmCPackIFWGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWGenerator::~cmCPackIFWGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWGenerator::PackageFiles()
+{
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl);
+
+ // Installer configuragion
+ Installer.GenerateInstallerFile();
+
+ // Packages configuration
+ Installer.GeneratePackageFiles();
+
+ std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ std::string ifwTmpFile = ifwTLD;
+ ifwTmpFile += "/IFWOutput.log";
+
+ // Run repogen
+ if (!Installer.Repositories.empty())
+ {
+ std::string ifwCmd = RepoGen;
+ ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ ifwCmd += " -p " + this->toplevel + "/packages";
+
+ if(!PkgsDirsVector.empty())
+ {
+ for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
+ it != PkgsDirsVector.end(); ++it)
+ {
+ ifwCmd += " -p " + *it;
+ }
+ }
+
+ if (!OnlineOnly && !DownloadedPackages.empty())
+ {
+ ifwCmd += " -i ";
+ std::set<cmCPackIFWPackage*>::iterator it
+ = DownloadedPackages.begin();
+ ifwCmd += (*it)->Name;
+ ++it;
+ while(it != DownloadedPackages.end())
+ {
+ ifwCmd += "," + (*it)->Name;
+ ++it;
+ }
+ }
+ ifwCmd += " " + this->toplevel + "/repository";
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Generate repository" << std::endl);
+ bool res = cmSystemTools::RunSingleCommand(
+ ifwCmd.c_str(), &output, &retVal, 0, this->GeneratorVerbose, 0);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(ifwTmpFile.c_str());
+ ofs << "# Run command: " << ifwCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
+ << ifwCmd << std::endl
+ << "Please check " << ifwTmpFile << " for errors"
+ << std::endl);
+ return 0;
+ }
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: " << this->toplevel
+ << "/repository generated" << std::endl);
+ }
+
+ // Run binary creator
+ {
+ std::string ifwCmd = BinCreator;
+ ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+ ifwCmd += " -p " + this->toplevel + "/packages";
+
+ if(!PkgsDirsVector.empty())
+ {
+ for(std::vector<std::string>::iterator it = PkgsDirsVector.begin();
+ it != PkgsDirsVector.end(); ++it)
+ {
+ ifwCmd += " -p " + *it;
+ }
+ }
+
+ if (OnlineOnly)
+ {
+ ifwCmd += " --online-only";
+ }
+ else if (!DownloadedPackages.empty() && !Installer.Repositories.empty())
+ {
+ ifwCmd += " -e ";
+ std::set<cmCPackIFWPackage*>::iterator it
+ = DownloadedPackages.begin();
+ ifwCmd += (*it)->Name;
+ ++it;
+ while(it != DownloadedPackages.end())
+ {
+ ifwCmd += "," + (*it)->Name;
+ ++it;
+ }
+ }
+ else if (!DependentPackages.empty())
+ {
+ ifwCmd += " -i ";
+ // Binary
+ std::set<cmCPackIFWPackage*>::iterator bit = BinaryPackages.begin();
+ while(bit != BinaryPackages.end())
+ {
+ ifwCmd += (*bit)->Name + ",";
+ ++bit;
+ }
+ // Depend
+ DependenceMap::iterator it = DependentPackages.begin();
+ ifwCmd += it->second.Name;
+ ++it;
+ while(it != DependentPackages.end())
+ {
+ ifwCmd += "," + it->second.Name;
+ ++it;
+ }
+ }
+ // TODO: set correct name for multipackages
+ if (this->packageFileNames.size() > 0)
+ {
+ ifwCmd += " " + packageFileNames[0];
+ }
+ else
+ {
+ ifwCmd += " installer";
+ }
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl);
+ bool res = cmSystemTools::RunSingleCommand(
+ ifwCmd.c_str(), &output, &retVal, 0, this->GeneratorVerbose, 0);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(ifwTmpFile.c_str());
+ ofs << "# Run command: " << ifwCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: "
+ << ifwCmd << std::endl
+ << "Please check " << ifwTmpFile << " for errors"
+ << std::endl);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWGenerator::GetPackagingInstallPrefix()
+{
+ const char *defPrefix = cmCPackGenerator::GetPackagingInstallPrefix();
+
+ std::string tmpPref = defPrefix ? defPrefix : "";
+
+ if(this->Components.empty())
+ {
+ tmpPref += "packages/" + GetRootPackageName() + "/data";
+ }
+
+ this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str());
+
+ return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX");
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWGenerator::GetOutputExtension()
+{
+ const char *suffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX");
+ return suffix ? suffix : cmCPackGenerator::GetOutputExtension();
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWGenerator::InitializeInternal()
+{
+ // Search Qt Installer Framework tools
+
+ const std::string BinCreatorOpt = "CPACK_IFW_BINARYCREATOR_EXECUTABLE";
+ const std::string RepoGenOpt = "CPACK_IFW_REPOGEN_EXECUTABLE";
+
+ if(!this->IsSet(BinCreatorOpt) ||
+ !this->IsSet(RepoGenOpt))
+ {
+ this->ReadListFile("CPackIFW.cmake");
+ }
+
+ // Look 'binarycreator' executable (needs)
+
+ const char *BinCreatorStr = this->GetOption(BinCreatorOpt);
+ if(!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr))
+ {
+ BinCreator = "";
+ }
+ else
+ {
+ BinCreator = BinCreatorStr;
+ }
+
+ if (BinCreator.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find QtIFW compiler \"binarycreator\": "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+ return 0;
+ }
+
+ // Look 'repogen' executable (optional)
+
+ const char *RepoGenStr = this->GetOption(RepoGenOpt);
+ if(!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr))
+ {
+ RepoGen = "";
+ }
+ else
+ {
+ RepoGen = RepoGenStr;
+ }
+
+ // Variables that Change Behavior
+
+ // Resolve duplicate names
+ ResolveDuplicateNames = this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES");
+
+ // Additional packages dirs
+ PkgsDirsVector.clear();
+ if(const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES"))
+ {
+ cmSystemTools::ExpandListArgument(dirs,
+ PkgsDirsVector);
+ }
+
+ // Installer
+ Installer.Generator = this;
+ Installer.ConfigureFromOptions();
+
+ if (const char* ifwDownloadAll =
+ this->GetOption("CPACK_IFW_DOWNLOAD_ALL"))
+ {
+ OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll);
+ }
+ else if (const char* cpackDownloadAll =
+ this->GetOption("CPACK_DOWNLOAD_ALL"))
+ {
+ OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll);
+ }
+ else
+ {
+ OnlineOnly = false;
+ }
+
+ if (!Installer.Repositories.empty() && RepoGen.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find QtIFW repository generator \"repogen\": "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+ return 0;
+ }
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+{
+ const std::string prefix = "packages/";
+ const std::string suffix = "/data";
+
+ if (componentPackageMethod == ONE_PACKAGE) {
+ return std::string(prefix + GetRootPackageName() + suffix);
+ }
+
+ return prefix
+ + GetComponentPackageName(&Components[componentName])
+ + suffix;
+}
+
+//----------------------------------------------------------------------------
+cmCPackComponent*
+cmCPackIFWGenerator::GetComponent(const std::string &projectName,
+ const std::string &componentName)
+{
+ ComponentsMap::iterator cit = Components.find(componentName);
+ if ( cit != Components.end() ) return &(cit->second);
+
+ cmCPackComponent* component
+ = cmCPackGenerator::GetComponent(projectName, componentName);
+ if(!component) return component;
+
+ std::string name = GetComponentPackageName(component);
+ PackagesMap::iterator pit = Packages.find(name);
+ if(pit != Packages.end()) return component;
+
+ cmCPackIFWPackage *package = &Packages[name];
+ package->Name = name;
+ package->Generator = this;
+ if(package->ConfigureFromComponent(component))
+ {
+ package->Installer = &Installer;
+ Installer.Packages.insert(
+ std::pair<std::string, cmCPackIFWPackage*>(
+ name, package));
+ ComponentPackages.insert(
+ std::pair<cmCPackComponent*, cmCPackIFWPackage*>(
+ component, package));
+ if(component->IsDownloaded)
+ {
+ DownloadedPackages.insert(package);
+ }
+ else
+ {
+ BinaryPackages.insert(package);
+ }
+ }
+ else
+ {
+ Packages.erase(name);
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot configure package \"" << name <<
+ "\" for component \"" << component->Name << "\""
+ << std::endl);
+ }
+
+ return component;
+}
+
+//----------------------------------------------------------------------------
+cmCPackComponentGroup*
+cmCPackIFWGenerator::GetComponentGroup(const std::string &projectName,
+ const std::string &groupName)
+{
+ cmCPackComponentGroup* group
+ = cmCPackGenerator::GetComponentGroup(projectName, groupName);
+ if(!group) return group;
+
+ std::string name = GetGroupPackageName(group);
+ PackagesMap::iterator pit = Packages.find(name);
+ if(pit != Packages.end()) return group;
+
+ cmCPackIFWPackage *package = &Packages[name];
+ package->Name = name;
+ package->Generator = this;
+ if(package->ConfigureFromGroup(group))
+ {
+ package->Installer = &Installer;
+ Installer.Packages.insert(
+ std::pair<std::string, cmCPackIFWPackage*>(
+ name, package));
+ GroupPackages.insert(
+ std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(
+ group, package));
+ BinaryPackages.insert(package);
+ }
+ else
+ {
+ Packages.erase(name);
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot configure package \"" << name <<
+ "\" for component group \"" << group->Name << "\""
+ << std::endl);
+ }
+ return group;
+}
+
+//----------------------------------------------------------------------------
+enum cmCPackGenerator::CPackSetDestdirSupport
+cmCPackIFWGenerator::SupportsSetDestdir() const
+{
+ return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::SupportsAbsoluteDestination() const
+{
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWGenerator::IsOnePackage() const
+{
+ return componentPackageMethod == ONE_PACKAGE;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWGenerator::GetRootPackageName()
+{
+ // Default value
+ std::string name = "root";
+ if (const char* optIFW_PACKAGE_GROUP =
+ this->GetOption("CPACK_IFW_PACKAGE_GROUP"))
+ {
+ // Configure from root group
+ cmCPackIFWPackage package;
+ package.Generator = this;
+ package.ConfigureFromGroup(optIFW_PACKAGE_GROUP);
+ name = package.Name;
+ }
+ else if (const char* optIFW_PACKAGE_NAME =
+ this->GetOption("CPACK_IFW_PACKAGE_NAME"))
+ {
+ // Configure from root package name
+ name = optIFW_PACKAGE_NAME;
+ }
+ else if (const char* optPACKAGE_NAME =
+ this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ // Configure from package name
+ name = optPACKAGE_NAME;
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmCPackIFWGenerator::GetGroupPackageName(cmCPackComponentGroup *group) const
+{
+ std::string name;
+ if (!group) return name;
+ if (cmCPackIFWPackage* package = GetGroupPackage(group))
+ {
+ return package->Name;
+ }
+ const char* option = GetOption(
+ "CPACK_IFW_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(group->Name)
+ + "_NAME");
+ name = option ? option : group->Name;
+ if(group->ParentGroup)
+ {
+ cmCPackIFWPackage* package = GetGroupPackage(group->ParentGroup);
+ bool dot = !ResolveDuplicateNames;
+ if(dot && name.substr(0, package->Name.size()) == package->Name)
+ {
+ dot = false;
+ }
+ if(dot)
+ {
+ name = package->Name + "." + name;
+ }
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWGenerator::GetComponentPackageName(
+ cmCPackComponent *component) const
+{
+ std::string name;
+ if (!component) return name;
+ if (cmCPackIFWPackage* package = GetComponentPackage(component))
+ {
+ return package->Name;
+ }
+ std::string prefix = "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_";
+ const char* option = GetOption(prefix + "NAME");
+ name = option ? option : component->Name;
+ if(component->Group)
+ {
+ cmCPackIFWPackage* package = GetGroupPackage(component->Group);
+ if((componentPackageMethod == ONE_PACKAGE_PER_GROUP)
+ || IsOn(prefix + "COMMON"))
+ {
+ return package->Name;
+ }
+ bool dot = !ResolveDuplicateNames;
+ if(dot && name.substr(0, package->Name.size()) == package->Name)
+ {
+ dot = false;
+ }
+ if(dot)
+ {
+ name = package->Name + "." + name;
+ }
+ }
+ return name;
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage(
+ cmCPackComponentGroup *group) const
+{
+ std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit
+ = GroupPackages.find(group);
+ return pit != GroupPackages.end() ? pit->second : 0;
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage(
+ cmCPackComponent *component) const
+{
+ std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit
+ = ComponentPackages.find(component);
+ return pit != ComponentPackages.end() ? pit->second : 0;
+}
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h
new file mode 100644
index 0000000..1d4d67b
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.h
@@ -0,0 +1,135 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWGenerator_h
+#define cmCPackIFWGenerator_h
+
+#include <CPack/cmCPackGenerator.h>
+
+#include "cmCPackIFWPackage.h"
+#include "cmCPackIFWInstaller.h"
+
+/** \class cmCPackIFWGenerator
+ * \brief A generator for Qt Installer Framework tools
+ *
+ * http://qt-project.org/doc/qtinstallerframework/index.html
+ */
+class cmCPackIFWGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator);
+
+ typedef std::map<std::string, cmCPackIFWPackage> PackagesMap;
+ typedef std::map<std::string, cmCPackComponent> ComponentsMap;
+ typedef std::map<std::string, cmCPackComponentGroup> ComponentGoupsMap;
+ typedef std::map<std::string, cmCPackIFWPackage::DependenceStruct>
+ DependenceMap;
+
+ /**
+ * Construct IFW generator
+ */
+ cmCPackIFWGenerator();
+
+ /**
+ * Destruct IFW generator
+ */
+ virtual ~cmCPackIFWGenerator();
+
+protected: // cmCPackGenerator reimplementation
+
+ /**
+ * @brief Initialize generator
+ * @return 0 on failure
+ */
+ virtual int InitializeInternal();
+ virtual int PackageFiles();
+ virtual const char* GetPackagingInstallPrefix();
+
+ /**
+ * @brief Extension of binary installer
+ * @return Executable suffix or value from default implementation
+ */
+ virtual const char* GetOutputExtension();
+
+ virtual std::string GetComponentInstallDirNameSuffix(
+ const std::string& componentName);
+
+ /**
+ * @brief Get Component
+ * @param projectName Project name
+ * @param componentName Component name
+ *
+ * This method calls the base implementation.
+ *
+ * @return Pointer to component
+ */
+ virtual cmCPackComponent* GetComponent(
+ const std::string& projectName,
+ const std::string& componentName);
+
+ /**
+ * @brief Get group of component
+ * @param projectName Project name
+ * @param groupName Component group name
+ *
+ * This method calls the base implementation.
+ *
+ * @return Pointer to component group
+ */
+ virtual cmCPackComponentGroup* GetComponentGroup(
+ const std::string& projectName,
+ const std::string& groupName);
+
+ enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const;
+ virtual bool SupportsAbsoluteDestination() const;
+ virtual bool SupportsComponentInstallation() const;
+
+protected: // Methods
+
+ bool IsOnePackage() const;
+
+ std::string GetRootPackageName();
+
+ std::string GetGroupPackageName(cmCPackComponentGroup *group) const;
+ std::string GetComponentPackageName(cmCPackComponent *component) const;
+
+ cmCPackIFWPackage* GetGroupPackage(cmCPackComponentGroup *group) const;
+ cmCPackIFWPackage* GetComponentPackage(cmCPackComponent *component) const;
+
+protected: // Data
+
+ friend class cmCPackIFWPackage;
+ friend class cmCPackIFWInstaller;
+
+ // Installer
+ cmCPackIFWInstaller Installer;
+ // Collection of packages
+ PackagesMap Packages;
+ // Collection of binary packages
+ std::set<cmCPackIFWPackage*> BinaryPackages;
+ // Collection of downloaded packages
+ std::set<cmCPackIFWPackage*> DownloadedPackages;
+ // Dependent packages
+ DependenceMap DependentPackages;
+ std::map<cmCPackComponent*, cmCPackIFWPackage*> ComponentPackages;
+ std::map<cmCPackComponentGroup*, cmCPackIFWPackage*> GroupPackages;
+
+private:
+ std::string RepoGen;
+ std::string BinCreator;
+
+ bool OnlineOnly;
+ bool ResolveDuplicateNames;
+ std::vector<std::string> PkgsDirsVector;
+};
+
+#endif
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
new file mode 100644
index 0000000..0644ecb
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -0,0 +1,406 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWInstaller.h"
+
+#include "cmCPackIFWGenerator.h"
+
+#include <CPack/cmCPackLog.h>
+
+#include <cmGeneratedFileStream.h>
+#include <cmXMLSafe.h>
+
+#ifdef cmCPackLogger
+# undef cmCPackLogger
+#endif
+#define cmCPackLogger(logType, msg) \
+ do { \
+ cmOStringStream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ if(Generator) { \
+ Generator->Logger->Log(logType, __FILE__, __LINE__, \
+ cmCPackLog_msg.str().c_str()); \
+ } \
+ } while ( 0 )
+
+//----------------------------------------------------------------------------
+cmCPackIFWInstaller::cmCPackIFWInstaller() :
+ Generator(0)
+{
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWInstaller::GetOption(const std::string &op) const
+{
+ return Generator ? Generator->GetOption(op) : 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWInstaller::IsOn(const std::string &op) const
+{
+ return Generator ? Generator->IsOn(op) : false;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::ConfigureFromOptions()
+{
+ // Name;
+ if (const char* optIFW_PACKAGE_NAME =
+ this->GetOption("CPACK_IFW_PACKAGE_NAME"))
+ {
+ Name = optIFW_PACKAGE_NAME;
+ }
+ else if (const char* optPACKAGE_NAME =
+ this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ Name = optPACKAGE_NAME;
+ }
+ else
+ {
+ Name = "Your package";
+ }
+
+ // Title;
+ if (const char* optIFW_PACKAGE_TITLE =
+ GetOption("CPACK_IFW_PACKAGE_TITLE"))
+ {
+ Title = optIFW_PACKAGE_TITLE;
+ }
+ else if (const char* optPACKAGE_DESCRIPTION_SUMMARY =
+ GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"))
+ {
+ Title = optPACKAGE_DESCRIPTION_SUMMARY;
+ }
+ else
+ {
+ Title = "Your package description";
+ }
+
+ // Version;
+ if (const char* option = GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = option;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Publisher
+ if(const char* optIFW_PACKAGE_PUBLISHER =
+ GetOption("CPACK_IFW_PACKAGE_PUBLISHER"))
+ {
+ Publisher = optIFW_PACKAGE_PUBLISHER;
+ }
+ else if(const char* optPACKAGE_VENDOR = GetOption("CPACK_PACKAGE_VENDOR"))
+ {
+ Publisher = optPACKAGE_VENDOR;
+ }
+
+ // ProductUrl
+ if(const char* option = GetOption("CPACK_IFW_PRODUCT_URL"))
+ {
+ ProductUrl = option;
+ }
+
+ // ApplicationIcon
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_ICON"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ InstallerApplicationIcon = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // WindowIcon
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_WINDOW_ICON"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ InstallerWindowIcon = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // Logo
+ if(const char* option = GetOption("CPACK_IFW_PACKAGE_LOGO"))
+ {
+ if(cmSystemTools::FileExists(option))
+ {
+ Logo = option;
+ }
+ else
+ {
+ // TODO: implement warning
+ }
+ }
+
+ // Default target directory for installation
+ if (const char* optIFW_TARGET_DIRECTORY =
+ GetOption("CPACK_IFW_TARGET_DIRECTORY"))
+ {
+ TargetDir = optIFW_TARGET_DIRECTORY;
+ }
+ else if (const char *optPACKAGE_INSTALL_DIRECTORY =
+ GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY"))
+ {
+ TargetDir = "@ApplicationsDir@/";
+ TargetDir += optPACKAGE_INSTALL_DIRECTORY;
+ }
+ else
+ {
+ TargetDir = "@RootDir@/usr/local";
+ }
+
+ // Default target directory for installation with administrator rights
+ if (const char* option = GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY"))
+ {
+ AdminTargetDir = option;
+ }
+
+ // Repositories
+ Repositories.clear();
+ RepositoryStruct Repo;
+ if (const char *site = this->GetOption("CPACK_DOWNLOAD_SITE"))
+ {
+ Repo.Url = site;
+ Repositories.push_back(Repo);
+ }
+ if(const char *RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL"))
+ {
+ std::vector<std::string> RepoAllVector;
+ cmSystemTools::ExpandListArgument(RepoAllStr,
+ RepoAllVector);
+ for(std::vector<std::string>::iterator
+ rit = RepoAllVector.begin(); rit != RepoAllVector.end(); ++rit)
+ {
+ std::string prefix = "CPACK_IFW_REPOSITORY_"
+ + cmsys::SystemTools::UpperCase(*rit)
+ + "_";
+ // Url
+ if (const char* url = GetOption(prefix + "URL"))
+ {
+ Repo.Url = url;
+ }
+ else
+ {
+ Repo.Url = "";
+ }
+ // Enabled
+ if (IsOn(prefix + "DISABLED"))
+ {
+ Repo.Enabled = "0";
+ }
+ else
+ {
+ Repo.Enabled = "";
+ }
+ // Username
+ if (const char* username = GetOption(prefix + "USERNAME"))
+ {
+ Repo.Username = username;
+ }
+ else
+ {
+ Repo.Username = "";
+ }
+ // Password
+ if (const char* password = GetOption(prefix + "PASSWORD"))
+ {
+ Repo.Password = password;
+ }
+ else
+ {
+ Repo.Password = "";
+ }
+ // DisplayName
+ if (const char* displayName = GetOption(prefix + "DISPLAY_NAME"))
+ {
+ Repo.DisplayName = displayName;
+ }
+ else
+ {
+ Repo.DisplayName = "";
+ }
+
+ if(!Repo.Url.empty())
+ {
+ Repositories.push_back(Repo);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::GenerateInstallerFile()
+{
+ // Lazy directory initialization
+ if(Directory.empty() && Generator)
+ {
+ Directory = Generator->toplevel;
+ }
+
+ // Output stream
+ cmGeneratedFileStream xout((Directory + "/config/config.xml").data());
+
+ xout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+ xout << "<Installer>" << std::endl;
+
+ xout << " <Name>" << cmXMLSafe(Name).str() << "</Name>" << std::endl;
+
+ xout << " <Version>" << Version << "</Version>" << std::endl;
+
+ xout << " <Title>" << cmXMLSafe(Title).str() << "</Title>"
+ << std::endl;
+
+ if(!Publisher.empty())
+ {
+ xout << " <Publisher>" << cmXMLSafe(Publisher).str()
+ << "</Publisher>" << std::endl;
+ }
+
+ if(!ProductUrl.empty())
+ {
+ xout << " <ProductUrl>" << ProductUrl << "</ProductUrl>" << std::endl;
+ }
+
+ // ApplicationIcon
+ if(!InstallerApplicationIcon.empty())
+ {
+ std::string name =
+ cmSystemTools::GetFilenameName(InstallerApplicationIcon);
+ std::string path = Directory + "/config/" + name;
+ name = cmSystemTools::GetFilenameWithoutExtension(name);
+ cmsys::SystemTools::CopyFileIfDifferent(
+ InstallerApplicationIcon.data(), path.data());
+ xout << " <InstallerApplicationIcon>" << name
+ << "</InstallerApplicationIcon>" << std::endl;
+ }
+
+ // WindowIcon
+ if(!InstallerWindowIcon.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(InstallerWindowIcon);
+ std::string path = Directory + "/config/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(
+ InstallerWindowIcon.data(), path.data());
+ xout << " <InstallerWindowIcon>" << name
+ << "</InstallerWindowIcon>" << std::endl;
+ }
+
+ // Logo
+ if(!Logo.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(Logo);
+ std::string path = Directory + "/config/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(Logo.data(), path.data());
+ xout << " <Logo>" << name << "</Logo>" << std::endl;
+ }
+
+ if(!TargetDir.empty())
+ {
+ xout << " <TargetDir>" << TargetDir << "</TargetDir>" << std::endl;
+ }
+
+ if(!AdminTargetDir.empty())
+ {
+ xout << " <AdminTargetDir>" << AdminTargetDir
+ << "</AdminTargetDir>" << std::endl;
+ }
+
+ // Remote repositories
+ if (!Repositories.empty())
+ {
+ xout << " <RemoteRepositories>" << std::endl;
+ for(std::vector<RepositoryStruct>::iterator
+ rit = Repositories.begin(); rit != Repositories.end(); ++rit)
+ {
+ xout << " <Repository>" << std::endl;
+ // Url
+ xout << " <Url>" << rit->Url
+ << "</Url>" << std::endl;
+ // Enabled
+ if(!rit->Enabled.empty())
+ {
+ xout << " <Enabled>" << rit->Enabled
+ << "</Enabled>" << std::endl;
+ }
+ // Username
+ if(!rit->Username.empty())
+ {
+ xout << " <Username>" << rit->Username
+ << "</Username>" << std::endl;
+ }
+ // Password
+ if(!rit->Password.empty())
+ {
+ xout << " <Password>" << rit->Password
+ << "</Password>" << std::endl;
+ }
+ // DisplayName
+ if(!rit->DisplayName.empty())
+ {
+ xout << " <DisplayName>" << rit->DisplayName
+ << "</DisplayName>" << std::endl;
+ }
+ xout << " </Repository>" << std::endl;
+ }
+ xout << " </RemoteRepositories>" << std::endl;
+ }
+
+ // CPack IFW default policy
+ xout << " <!-- CPack IFW default policy -->" << std::endl;
+ xout << " <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>"
+ << std::endl;
+ xout << " <AllowSpaceInPath>true</AllowSpaceInPath>" << std::endl;
+
+ xout << "</Installer>" << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWInstaller::GeneratePackageFiles()
+{
+ if (Packages.empty() || Generator->IsOnePackage())
+ {
+ // Generate default package
+ cmCPackIFWPackage package;
+ package.Generator = Generator;
+ package.Installer = this;
+ // Check package group
+ if (const char* option = GetOption("CPACK_IFW_PACKAGE_GROUP"))
+ {
+ package.ConfigureFromGroup(option);
+ package.ForcedInstallation = "true";
+ }
+ else
+ {
+ package.ConfigureFromOptions();
+ }
+ package.GeneratePackageFile();
+ return;
+ }
+
+ // Generate packages meta information
+ for(PackagesMap::iterator pit = Packages.begin();
+ pit != Packages.end(); ++pit)
+ {
+ cmCPackIFWPackage* package = pit->second;
+ package->GeneratePackageFile();
+ }
+}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
new file mode 100644
index 0000000..5824d33
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -0,0 +1,95 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWInstaller_h
+#define cmCPackIFWInstaller_h
+
+#include <cmStandardIncludes.h>
+
+class cmCPackIFWPackage;
+class cmCPackIFWGenerator;
+
+/** \class cmCPackIFWInstaller
+ * \brief A binary installer to be created CPack IFW generator
+ */
+class cmCPackIFWInstaller
+{
+public: // Types
+
+ typedef std::map<std::string, cmCPackIFWPackage*> PackagesMap;
+
+ struct RepositoryStruct
+ {
+ std::string Url;
+ std::string Enabled;
+ std::string Username;
+ std::string Password;
+ std::string DisplayName;
+ };
+
+public: // Constructor
+
+ /**
+ * Construct installer
+ */
+ cmCPackIFWInstaller();
+
+public: // Configuration
+
+ /// Name of the product being installed
+ std::string Name;
+
+ /// Version number of the product being installed
+ std::string Version;
+
+ /// Name of the installer as displayed on the title bar
+ std::string Title;
+
+ /// Publisher of the software (as shown in the Windows Control Panel)
+ std::string Publisher;
+
+ /// URL to a page that contains product information on your web site
+ std::string ProductUrl;
+
+ /// Filename for a custom installer icon
+ std::string InstallerApplicationIcon;
+
+ /// Filename for a custom window icon
+ std::string InstallerWindowIcon;
+
+ /// Filename for a logo
+ std::string Logo;
+
+ /// Default target directory for installation
+ std::string TargetDir;
+
+ /// Default target directory for installation with administrator rights
+ std::string AdminTargetDir;
+
+public: // Internal implementation
+
+ const char* GetOption(const std::string& op) const;
+ bool IsOn(const std::string& op) const;
+
+ void ConfigureFromOptions();
+
+ void GenerateInstallerFile();
+
+ void GeneratePackageFiles();
+
+ cmCPackIFWGenerator* Generator;
+ PackagesMap Packages;
+ std::vector<RepositoryStruct> Repositories;
+ std::string Directory;
+};
+
+#endif // cmCPackIFWInstaller_h
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
new file mode 100644
index 0000000..3c45639
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -0,0 +1,540 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackIFWPackage.h"
+
+#include "cmCPackIFWGenerator.h"
+
+#include <CPack/cmCPackLog.h>
+
+#include <cmGeneratedFileStream.h>
+#include <cmTimestamp.h>
+
+//----------------------------------------------------------------- Logger ---
+#ifdef cmCPackLogger
+# undef cmCPackLogger
+#endif
+#define cmCPackLogger(logType, msg) \
+ do { \
+ cmOStringStream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ if(Generator) { \
+ Generator->Logger->Log(logType, __FILE__, __LINE__, \
+ cmCPackLog_msg.str().c_str()); \
+ } \
+ } while ( 0 )
+
+//---------------------------------------------------------- CompareStruct ---
+cmCPackIFWPackage::CompareStruct::CompareStruct() :
+ Type(CompareNone)
+{
+}
+
+//------------------------------------------------------- DependenceStruct ---
+cmCPackIFWPackage::DependenceStruct::DependenceStruct()
+{
+}
+
+//----------------------------------------------------------------------------
+cmCPackIFWPackage::DependenceStruct::DependenceStruct(
+ const std::string &dependence)
+{
+ // Search compare section
+ size_t pos = std::string::npos;
+ if((pos = dependence.find("<=")) != std::string::npos)
+ {
+ Compare.Type = CompareLessOrEqual;
+ Compare.Value = dependence.substr(pos + 2);
+ }
+ else if((pos = dependence.find(">=")) != std::string::npos)
+ {
+ Compare.Type = CompareGreaterOrEqual;
+ Compare.Value = dependence.substr(pos + 2);
+ }
+ else if((pos = dependence.find("<")) != std::string::npos)
+ {
+ Compare.Type = CompareLess;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ else if((pos = dependence.find("=")) != std::string::npos)
+ {
+ Compare.Type = CompareEqual;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ else if((pos = dependence.find(">")) != std::string::npos)
+ {
+ Compare.Type = CompareGreater;
+ Compare.Value = dependence.substr(pos + 1);
+ }
+ Name = pos == std::string::npos ? dependence : dependence.substr(0, pos);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
+{
+ if (Compare.Type == CompareNone) return Name;
+
+ std::string result = Name;
+
+ if (Compare.Type == CompareLessOrEqual)
+ {
+ result += "<=";
+ }
+ else if (Compare.Type == CompareGreaterOrEqual)
+ {
+ result += ">=";
+ }
+ else if (Compare.Type == CompareLess)
+ {
+ result += "<";
+ }
+ else if (Compare.Type == CompareEqual)
+ {
+ result += "=";
+ }
+ else if (Compare.Type == CompareGreater)
+ {
+ result += ">";
+ }
+
+ result += Compare.Value;
+
+ return result;
+}
+
+//------------------------------------------------------ cmCPackIFWPackage ---
+cmCPackIFWPackage::cmCPackIFWPackage() :
+ Generator(0),
+ Installer(0)
+{
+}
+
+//----------------------------------------------------------------------------
+const char *cmCPackIFWPackage::GetOption(const std::string &op) const
+{
+ const char *option = Generator ? Generator->GetOption(op) : 0;
+ return option && *option ? option : 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmCPackIFWPackage::IsOn(const std::string &op) const
+{
+ return Generator ? Generator->IsOn(op) : false;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent *component)
+{
+ if (!component) return "";
+ const char* option = GetOption(
+ "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_NAME");
+ return option ? option : component->Name;
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWPackage::DefaultConfiguration()
+{
+ DisplayName = "";
+ Description = "";
+ Version = "";
+ ReleaseDate = "";
+ Script = "";
+ Licenses.clear();
+ SortingPriority = "";
+ Default = "";
+ Virtual = "";
+ ForcedInstallation = "";
+}
+
+//----------------------------------------------------------------------------
+// Defaul configuration (all in one package)
+int cmCPackIFWPackage::ConfigureFromOptions()
+{
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ // Name
+ Name = Generator->GetRootPackageName();
+
+ // Display name
+ if (const char *option = this->GetOption("CPACK_PACKAGE_NAME"))
+ {
+ DisplayName = option;
+ }
+ else
+ {
+ DisplayName = "Your package";
+ }
+
+ // Description
+ if (const char* option =
+ this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY"))
+ {
+ Description = option;
+ }
+ else
+ {
+ Description = "Your package description";
+ }
+
+ // Version
+ if(const char* option = GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = option;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ ForcedInstallation = "true";
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent *component)
+{
+ if(!component) return 0;
+
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ std::string prefix = "CPACK_IFW_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(component->Name)
+ + "_";
+
+ // Display name
+ DisplayName = component->DisplayName;
+
+ // Description
+ Description = component->Description;
+
+ // Version
+ if(const char* optVERSION = GetOption(prefix + "VERSION"))
+ {
+ Version = optVERSION;
+ }
+ else if(const char* optPACKAGE_VERSION =
+ GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = optPACKAGE_VERSION;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Script
+ if (const char* option = GetOption(prefix + "SCRIPT"))
+ {
+ Script = option;
+ }
+
+ // CMake dependencies
+ if (!component->Dependencies.empty())
+ {
+ std::vector<cmCPackComponent*>::iterator dit;
+ for(dit = component->Dependencies.begin();
+ dit != component->Dependencies.end();
+ ++dit)
+ {
+ Dependencies.insert(Generator->ComponentPackages[*dit]);
+ }
+ }
+
+ // QtIFW dependencies
+ if(const char* option = this->GetOption(prefix + "DEPENDS"))
+ {
+ std::vector<std::string> deps;
+ cmSystemTools::ExpandListArgument(option,
+ deps);
+ for(std::vector<std::string>::iterator
+ dit = deps.begin(); dit != deps.end(); ++dit)
+ {
+ DependenceStruct dep(*dit);
+ if (!Generator->Packages.count(dep.Name))
+ {
+ bool hasDep = Generator->DependentPackages.count(dep.Name) > 0;
+ DependenceStruct &depRef =
+ Generator->DependentPackages[dep.Name];
+ if(!hasDep)
+ {
+ depRef = dep;
+ }
+ AlienDependencies.insert(&depRef);
+ }
+ }
+ }
+
+ // Licenses
+ if (const char* option = this->GetOption(prefix + "LICENSES"))
+ {
+ Licenses.clear();
+ cmSystemTools::ExpandListArgument( option, Licenses );
+ if ( Licenses.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, prefix << "LICENSES"
+ << " should contain pairs of <display_name> and <file_path>."
+ << std::endl);
+ Licenses.clear();
+ }
+ }
+
+ // Priority
+ if(const char* option = this->GetOption(prefix + "PRIORITY"))
+ {
+ SortingPriority = option;
+ }
+
+ // Default
+ Default = component->IsDisabledByDefault ? "false" : "true";
+
+ // Virtual
+ Virtual = component->IsHidden ? "true" : "";
+
+ // ForcedInstallation
+ ForcedInstallation = component->IsRequired ? "true" : "false";
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int
+cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup *group)
+{
+ if(!group) return 0;
+
+ // Restore defaul configuration
+ DefaultConfiguration();
+
+ std::string prefix = "CPACK_IFW_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(group->Name)
+ + "_";
+
+ DisplayName = group->DisplayName;
+ Description = group->Description;
+
+ // Version
+ if(const char* optVERSION = GetOption(prefix + "VERSION"))
+ {
+ Version = optVERSION;
+ }
+ else if(const char* optPACKAGE_VERSION =
+ GetOption("CPACK_PACKAGE_VERSION"))
+ {
+ Version = optPACKAGE_VERSION;
+ }
+ else
+ {
+ Version = "1.0.0";
+ }
+
+ // Script
+ if (const char* option = GetOption(prefix + "SCRIPT"))
+ {
+ Script = option;
+ }
+
+ // Licenses
+ if (const char* option = this->GetOption(prefix + "LICENSES"))
+ {
+ Licenses.clear();
+ cmSystemTools::ExpandListArgument( option, Licenses );
+ if ( Licenses.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, prefix << "LICENSES"
+ << " should contain pairs of <display_name> and <file_path>."
+ << std::endl);
+ Licenses.clear();
+ }
+ }
+
+ // Priority
+ if(const char* option = this->GetOption(prefix + "PRIORITY"))
+ {
+ SortingPriority = option;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmCPackIFWPackage::ConfigureFromGroup(const std::string &groupName)
+{
+ // Group configuration
+
+ cmCPackComponentGroup group;
+ std::string prefix = "CPACK_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(groupName)
+ + "_";
+
+ if (const char *option = GetOption(prefix + "DISPLAY_NAME"))
+ {
+ group.DisplayName = option;
+ }
+ else
+ {
+ group.DisplayName = group.Name;
+ }
+
+ if (const char* option = GetOption(prefix + "DESCRIPTION"))
+ {
+ group.Description = option;
+ }
+ group.IsBold = IsOn(prefix + "BOLD_TITLE");
+ group.IsExpandedByDefault = IsOn(prefix + "EXPANDED");
+
+ // Package configuration
+
+ group.Name = groupName;
+
+ if(Generator)
+ {
+ Name = Generator->GetGroupPackageName(&group);
+ }
+ else
+ {
+ Name = group.Name;
+ }
+
+ return ConfigureFromGroup(&group);
+}
+
+//----------------------------------------------------------------------------
+void cmCPackIFWPackage::GeneratePackageFile()
+{
+ // Lazy directory initialization
+ if (Directory.empty())
+ {
+ if(Installer)
+ {
+ Directory = Installer->Directory + "/packages/" + Name;
+ }
+ else if (Generator)
+ {
+ Directory = Generator->toplevel + "/packages/" + Name;
+ }
+ }
+
+ // Output stream
+ cmGeneratedFileStream xout((Directory + "/meta/package.xml").data());
+
+ xout << "<?xml version=\"1.0\"?>" << std::endl;
+ xout << "<Package>" << std::endl;
+
+ xout << " <DisplayName>" << DisplayName
+ << "</DisplayName>" << std::endl;
+
+ xout << " <Description>" << Description
+ << "</Description>" << std::endl;
+
+ xout << " <Name>" << Name << "</Name>" << std::endl;
+
+ xout << " <Version>" << Version
+ << "</Version>" << std::endl;
+
+ xout << " <ReleaseDate>";
+ if(ReleaseDate.empty())
+ {
+ xout << cmTimestamp().CurrentTime("%Y-%m-%d", true);
+ }
+ else
+ {
+ xout << ReleaseDate;
+ }
+ xout << "</ReleaseDate>" << std::endl;
+
+ // Script (copy to meta dir)
+ if(!Script.empty())
+ {
+ std::string name = cmSystemTools::GetFilenameName(Script);
+ std::string path = Directory + "/meta/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(Script.data(), path.data());
+ xout << " <Script>" << name << "</Script>" << std::endl;
+ }
+
+ // Dependencies
+ std::set<DependenceStruct> compDepSet;
+ for(std::set<DependenceStruct*>::iterator ait = AlienDependencies.begin();
+ ait != AlienDependencies.end(); ++ait)
+ {
+ compDepSet.insert(*(*ait));
+ }
+ for(std::set<cmCPackIFWPackage*>::iterator it = Dependencies.begin();
+ it != Dependencies.end(); ++it)
+ {
+ compDepSet.insert(DependenceStruct((*it)->Name));
+ }
+ // Write dependencies
+ if (!compDepSet.empty())
+ {
+ xout << " <Dependencies>";
+ std::set<DependenceStruct>::iterator it = compDepSet.begin();
+ xout << it->NameWithCompare();
+ ++it;
+ while(it != compDepSet.end())
+ {
+ xout << "," << it->NameWithCompare();
+ ++it;
+ }
+ xout << "</Dependencies>" << std::endl;
+ }
+
+ // Licenses (copy to meta dir)
+ std::vector<std::string> licenses = Licenses;
+ for(size_t i = 1; i < licenses.size(); i += 2)
+ {
+ std::string name = cmSystemTools::GetFilenameName(licenses[i]);
+ std::string path = Directory + "/meta/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(licenses[i].data(), path.data());
+ licenses[i] = name;
+ }
+ if(!licenses.empty())
+ {
+ xout << " <Licenses>" << std::endl;
+ for(size_t i = 0; i < licenses.size(); i += 2)
+ {
+ xout << " <License "
+ << "name=\"" << licenses[i] << "\" "
+ << "file=\"" << licenses[i + 1] << "\" "
+ << "/>" <<std::endl;
+ }
+ xout << " </Licenses>" << std::endl;
+ }
+
+ if (!ForcedInstallation.empty())
+ {
+ xout << " <ForcedInstallation>" << ForcedInstallation
+ << "</ForcedInstallation>" << std::endl;
+ }
+
+ if (!Virtual.empty())
+ {
+ xout << " <Virtual>" << Virtual << "</Virtual>" << std::endl;
+ }
+ else if (!Default.empty())
+ {
+ xout << " <Default>" << Default << "</Default>" << std::endl;
+ }
+
+ // Priority
+ if(!SortingPriority.empty())
+ {
+ xout << " <SortingPriority>" << SortingPriority
+ << "</SortingPriority>" << std::endl;
+ }
+
+ xout << "</Package>" << std::endl;
+}
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h
new file mode 100644
index 0000000..9fc9bd0
--- /dev/null
+++ b/Source/CPack/IFW/cmCPackIFWPackage.h
@@ -0,0 +1,133 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackIFWPackage_h
+#define cmCPackIFWPackage_h
+
+#include <cmStandardIncludes.h>
+
+class cmCPackComponent;
+class cmCPackComponentGroup;
+class cmCPackIFWInstaller;
+class cmCPackIFWGenerator;
+
+/** \class cmCPackIFWPackage
+ * \brief A single component to be installed by CPack IFW generator
+ */
+class cmCPackIFWPackage
+{
+public: // Types
+ enum CompareTypes
+ {
+ CompareNone = 0x0,
+ CompareEqual = 0x1,
+ CompareLess = 0x2,
+ CompareLessOrEqual = 0x3,
+ CompareGreater = 0x4,
+ CompareGreaterOrEqual = 0x5
+ };
+
+ struct CompareStruct
+ {
+ CompareStruct();
+
+ unsigned int Type;
+ std::string Value;
+ };
+
+ struct DependenceStruct
+ {
+ DependenceStruct();
+ DependenceStruct(const std::string &dependence);
+
+ std::string Name;
+ CompareStruct Compare;
+
+ std::string NameWithCompare() const;
+
+ bool operator < (const DependenceStruct &other) const
+ {
+ return Name < other.Name;
+ }
+ };
+
+public: // [Con|De]structor
+
+ /**
+ * Construct package
+ */
+ cmCPackIFWPackage();
+
+public: // Configuration
+
+ /// Human-readable name of the component
+ std::string DisplayName;
+
+ /// Human-readable description of the component
+ std::string Description;
+
+ /// Version number of the component
+ std::string Version;
+
+ /// Date when this component version was released
+ std::string ReleaseDate;
+
+ /// Domain-like identification for this component
+ std::string Name;
+
+ /// File name of a script being loaded
+ std::string Script;
+
+ /// List of license agreements to be accepted by the installing user
+ std::vector<std::string> Licenses;
+
+ /// Priority of the component in the tree
+ std::string SortingPriority;
+
+ /// Set to true to preselect the component in the installer
+ std::string Default;
+
+ /// Set to true to hide the component from the installer
+ std::string Virtual;
+
+ /// Determines that the package must always be installed
+ std::string ForcedInstallation;
+
+public: // Internal implementation
+
+ const char* GetOption(const std::string& op) const;
+ bool IsOn(const std::string& op) const;
+
+ std::string GetComponentName(cmCPackComponent *component);
+
+ void DefaultConfiguration();
+
+ int ConfigureFromOptions();
+ int ConfigureFromComponent(cmCPackComponent *component);
+ int ConfigureFromGroup(cmCPackComponentGroup *group);
+ int ConfigureFromGroup(const std::string &groupName);
+
+ void GeneratePackageFile();
+
+ // Pointer to generator
+ cmCPackIFWGenerator* Generator;
+ // Pointer to installer
+ cmCPackIFWInstaller* Installer;
+ // Collection of dependencies
+ std::set<cmCPackIFWPackage*> Dependencies;
+ // Collection of unresolved dependencies
+ std::set<DependenceStruct*> AlienDependencies;
+ // Patch to package directory
+ std::string Directory;
+};
+
+#endif // cmCPackIFWPackage_h
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index a2995d1..7e00027 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -360,6 +360,29 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
includeFile.EndElement("Property");
}
}
+
+ if(GetOption("CPACK_WIX_PROPERTY_ARPINSTALLLOCATION") == 0)
+ {
+ includeFile.BeginElement("Property");
+ includeFile.AddAttribute("Id", "INSTALL_ROOT");
+ includeFile.AddAttribute("Secure", "yes");
+
+ includeFile.BeginElement("RegistrySearch");
+ includeFile.AddAttribute("Id", "FindInstallLocation");
+ includeFile.AddAttribute("Root", "HKLM");
+ includeFile.AddAttribute("Key", "Software\\Microsoft\\Windows\\"
+ "CurrentVersion\\Uninstall\\[WIX_UPGRADE_DETECTED]");
+ includeFile.AddAttribute("Name", "InstallLocation");
+ includeFile.AddAttribute("Type", "raw");
+ includeFile.EndElement("RegistrySearch");
+ includeFile.EndElement("Property");
+
+ includeFile.BeginElement("SetProperty");
+ includeFile.AddAttribute("Id", "ARPINSTALLLOCATION");
+ includeFile.AddAttribute("Value", "[INSTALL_ROOT]");
+ includeFile.AddAttribute("After", "CostFinalize");
+ includeFile.EndElement("SetProperty");
+ }
}
void cmCPackWIXGenerator::CopyDefinition(
@@ -824,13 +847,42 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
cmsys::Directory dir;
dir.Load(topdir.c_str());
- if(dir.GetNumberOfFiles() == 2)
+ std::string relativeDirectoryPath =
+ cmSystemTools::RelativePath(toplevel.c_str(), topdir.c_str());
+
+ if(relativeDirectoryPath.empty())
{
- std::string componentId = fileDefinitions.EmitComponentCreateFolder(
- directoryId, GenerateGUID());
+ relativeDirectoryPath = ".";
+ }
+
+ cmInstalledFile const* directoryInstalledFile =
+ this->GetInstalledFile(relativeDirectoryPath);
+
+ bool emptyDirectory = dir.GetNumberOfFiles() == 2;
+ bool createDirectory = false;
+
+ if(emptyDirectory)
+ {
+ createDirectory = true;
+ }
+ if(directoryInstalledFile)
+ {
+ if(directoryInstalledFile->HasProperty("CPACK_WIX_ACL"))
+ {
+ createDirectory = true;
+ }
+ }
+
+ if(createDirectory)
+ {
+ std::string componentId = fileDefinitions.EmitComponentCreateFolder(
+ directoryId, GenerateGUID(), directoryInstalledFile);
featureDefinitions.EmitComponentRef(componentId);
+ }
+ if(emptyDirectory)
+ {
return;
}
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
new file mode 100644
index 0000000..aeec968
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -0,0 +1,149 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmWIXAccessControlList.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <cmSystemTools.h>
+
+cmWIXAccessControlList::cmWIXAccessControlList(
+ cmCPackLog *logger,
+ cmInstalledFile const& installedFile,
+ cmWIXSourceWriter &sourceWriter):
+ Logger(logger),
+ InstalledFile(installedFile),
+ SourceWriter(sourceWriter)
+{
+
+}
+
+bool cmWIXAccessControlList::Apply()
+{
+ std::vector<std::string> entries;
+ this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
+
+ for(size_t i = 0; i < entries.size(); ++i)
+ {
+ this->CreatePermissionElement(entries[i]);
+ }
+
+ return true;
+}
+
+void cmWIXAccessControlList::CreatePermissionElement(
+ std::string const& entry)
+{
+ std::string::size_type pos = entry.find('=');
+ if(pos == std::string::npos)
+ {
+ this->ReportError(entry, "Did not find mandatory '='");
+ return;
+ }
+
+ std::string user_and_domain = entry.substr(0, pos);
+ std::string permission_string = entry.substr(pos + 1);
+
+ pos = user_and_domain.find('@');
+ std::string user;
+ std::string domain;
+ if(pos != std::string::npos)
+ {
+ user = user_and_domain.substr(0, pos);
+ domain = user_and_domain.substr(pos + 1);
+ }
+ else
+ {
+ user = user_and_domain;
+ }
+
+ std::vector<std::string> permissions =
+ cmSystemTools::tokenize(permission_string, ",");
+
+ this->SourceWriter.BeginElement("Permission");
+ this->SourceWriter.AddAttribute("User", user);
+ if(domain.size())
+ {
+ this->SourceWriter.AddAttribute("Domain", domain);
+ }
+ for(size_t i = 0; i < permissions.size(); ++i)
+ {
+ this->EmitBooleanAttribute(entry,
+ cmSystemTools::TrimWhitespace(permissions[i]));
+ }
+ this->SourceWriter.EndElement("Permission");
+}
+
+void cmWIXAccessControlList::ReportError(
+ std::string const& entry,
+ std::string const& message)
+{
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed processing ACL entry '" << entry <<
+ "': " << message << std::endl);
+}
+
+bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
+{
+ static const char* validAttributes[] =
+ {
+ "Append",
+ "ChangePermission",
+ "CreateChild",
+ "CreateFile",
+ "CreateLink",
+ "CreateSubkeys",
+ "Delete",
+ "DeleteChild",
+ "EnumerateSubkeys",
+ "Execute",
+ "FileAllRights",
+ "GenericAll",
+ "GenericExecute",
+ "GenericRead",
+ "GenericWrite",
+ "Notify",
+ "Read",
+ "ReadAttributes",
+ "ReadExtendedAttributes",
+ "ReadPermission",
+ "SpecificRightsAll",
+ "Synchronize",
+ "TakeOwnership",
+ "Traverse",
+ "Write",
+ "WriteAttributes",
+ "WriteExtendedAttributes",
+ 0
+ };
+
+ size_t i = 0;
+ while(validAttributes[i])
+ {
+ if(name == validAttributes[i++]) return true;
+ }
+
+ return false;
+}
+
+void cmWIXAccessControlList::EmitBooleanAttribute(
+ std::string const& entry, std::string const& name)
+{
+ if(!this->IsBooleanAttribute(name))
+ {
+ std::stringstream message;
+ message << "Unknown boolean attribute '" << name << "'";
+ this->ReportError(entry, message.str());
+ }
+
+ this->SourceWriter.AddAttribute(name, "yes");
+}
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.h b/Source/CPack/WiX/cmWIXAccessControlList.h
new file mode 100644
index 0000000..20902f7
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXAccessControlList.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmWIXAccessControlList_h
+#define cmWIXAccessControlList_h
+
+#include <cmInstalledFile.h>
+#include <CPack/cmCPackLog.h>
+
+#include "cmWIXSourceWriter.h"
+
+class cmWIXAccessControlList
+{
+public:
+ cmWIXAccessControlList(
+ cmCPackLog *logger,
+ cmInstalledFile const& installedFile,
+ cmWIXSourceWriter &sourceWriter);
+
+ bool Apply();
+
+private:
+ void CreatePermissionElement(std::string const& entry);
+
+ void ReportError(std::string const& entry, std::string const& message);
+
+ bool IsBooleanAttribute(std::string const& name);
+
+ void EmitBooleanAttribute(
+ std::string const& entry, std::string const& name);
+
+ cmCPackLog* Logger;
+ cmInstalledFile const& InstalledFile;
+ cmWIXSourceWriter &SourceWriter;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index 451188e..1adb06a 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -11,6 +11,7 @@
============================================================================*/
#include "cmWIXFilesSourceWriter.h"
+#include "cmWIXAccessControlList.h"
#include <cmInstalledFile.h>
@@ -112,7 +113,9 @@ void cmWIXFilesSourceWriter::EmitUninstallShortcut(
}
std::string cmWIXFilesSourceWriter::EmitComponentCreateFolder(
- std::string const& directoryId, std::string const& guid)
+ std::string const& directoryId,
+ std::string const& guid,
+ cmInstalledFile const* installedFile)
{
std::string componentId =
std::string("CM_C_EMPTY_") + directoryId;
@@ -126,6 +129,12 @@ std::string cmWIXFilesSourceWriter::EmitComponentCreateFolder(
BeginElement("CreateFolder");
+ if(installedFile)
+ {
+ cmWIXAccessControlList acl(Logger, *installedFile, *this);
+ acl.Apply();
+ }
+
EndElement("CreateFolder");
EndElement("Component");
EndElement("DirectoryRef");
@@ -175,6 +184,12 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
AddAttribute("ReadOnly", "yes");
}
+ if(installedFile)
+ {
+ cmWIXAccessControlList acl(Logger, *installedFile, *this);
+ acl.Apply();
+ }
+
patch.ApplyFragment(fileId, *this);
EndElement("File");
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
index 23ef561..b0a4af8 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -47,7 +47,8 @@ public:
std::string EmitComponentCreateFolder(
std::string const& directoryId,
- std::string const& guid);
+ std::string const& guid,
+ cmInstalledFile const* installedFile);
std::string EmitComponentFile(
std::string const& directoryId,
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 65b7240..3957d96 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -45,6 +45,9 @@ public:
static std::string WindowsCodepageToUtf8(std::string const& value);
+protected:
+ cmCPackLog* Logger;
+
private:
enum State
{
@@ -58,8 +61,6 @@ private:
static std::string EscapeAttributeValue(std::string const& value);
- cmCPackLog* Logger;
-
cmsys::ofstream File;
State State;
diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx
new file mode 100644
index 0000000..ce31ad4
--- /dev/null
+++ b/Source/CPack/cmCPack7zGenerator.cxx
@@ -0,0 +1,25 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPack7zGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPack7zGenerator::cmCPack7zGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone,
+ cmArchiveWrite::Type7Zip)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPack7zGenerator::~cmCPack7zGenerator()
+{
+}
diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h
new file mode 100644
index 0000000..f5a323f
--- /dev/null
+++ b/Source/CPack/cmCPack7zGenerator.h
@@ -0,0 +1,36 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPack7zGenerator_h
+#define cmCPack7zGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPack7zGenerator
+ * \brief A generator for 7z files
+ */
+class cmCPack7zGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPack7zGenerator, cmCPackArchiveGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPack7zGenerator();
+ virtual ~cmCPack7zGenerator();
+
+protected:
+ virtual const char* GetOutputExtension() { return ".7z"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 91f92c5..1461bb1 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -637,8 +637,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
if ( globalGenerator->GetPreinstallTargetName() )
{
globalGenerator->FindMakeProgram(this->MakefileMap);
- const char* cmakeMakeProgram
- = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
+ std::string cmakeMakeProgram
+ = this->MakefileMap->GetSafeDefinition("CMAKE_MAKE_PROGRAM");
std::vector<std::string> buildCommand;
globalGenerator->GenerateBuildCommand(buildCommand, cmakeMakeProgram,
installProjectName, installDirectory,
@@ -1049,7 +1049,6 @@ int cmCPackGenerator::DoPackage()
const char* tempPackageFileName = this->GetOption(
"CPACK_TEMPORARY_PACKAGE_FILE_NAME");
- const char* packageFileName = this->GetOption("CPACK_OUTPUT_FILE_PATH");
const char* tempDirectory = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
@@ -1114,7 +1113,7 @@ int cmCPackGenerator::DoPackage()
std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
tempPackageFileName = it->c_str();
tmpPF += "/"+cmSystemTools::GetFilenameName(*it);
- packageFileName = tmpPF.c_str();
+ const char* packageFileName = tmpPF.c_str();
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
<< (tempPackageFileName ? tempPackageFileName : "(NULL)" )
<< " to "
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 9faf2b0..c8737f4 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -14,11 +14,14 @@
#include "cmCPackGenerator.h"
#include "cmCPackTGZGenerator.h"
+#include "cmCPackTXZGenerator.h"
#include "cmCPackTarBZip2Generator.h"
#include "cmCPackTarCompressGenerator.h"
#include "cmCPackZIPGenerator.h"
+#include "cmCPack7zGenerator.h"
#include "cmCPackSTGZGenerator.h"
#include "cmCPackNSISGenerator.h"
+#include "IFW/cmCPackIFWGenerator.h"
#ifdef __APPLE__
# include "cmCPackDragNDropGenerator.h"
@@ -56,6 +59,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("TGZ", "Tar GZip compression",
cmCPackTGZGenerator::CreateGenerator);
}
+ if (cmCPackTXZGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("TXZ", "Tar XZ compression",
+ cmCPackTXZGenerator::CreateGenerator);
+ }
if (cmCPackSTGZGenerator::CanGenerate())
{
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
@@ -68,6 +76,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)",
cmCPackNSISGenerator::CreateGenerator64);
}
+ if (cmCPackIFWGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("IFW", "Qt Installer Framework",
+ cmCPackIFWGenerator::CreateGenerator);
+ }
#ifdef __CYGWIN__
if (cmCPackCygwinBinaryGenerator::CanGenerate())
{
@@ -86,6 +99,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("ZIP", "ZIP file format",
cmCPackZIPGenerator::CreateGenerator);
}
+ if (cmCPack7zGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("7Z", "7-Zip file format",
+ cmCPack7zGenerator::CreateGenerator);
+ }
#ifdef _WIN32
if (cmCPackWIXGenerator::CanGenerate())
{
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 0113698..a5eee6b 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -588,8 +588,8 @@ void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
return;
}
- cmsys::RegularExpression urlRegex;
- urlRegex.compile("^(mailto:|(ftps?|https?|news)://).*$");
+ static cmsys::RegularExpression
+ urlRegex("^(mailto:|(ftps?|https?|news)://).*$");
std::vector<std::string>::iterator it;
for ( it = cpackMenuLinksVector.begin();
diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx
new file mode 100644
index 0000000..ecfc177
--- /dev/null
+++ b/Source/CPack/cmCPackTXZGenerator.cxx
@@ -0,0 +1,25 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackTXZGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPackTXZGenerator::cmCPackTXZGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ,
+ cmArchiveWrite::TypeTAR)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackTXZGenerator::~cmCPackTXZGenerator()
+{
+}
diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h
new file mode 100644
index 0000000..bf8152f
--- /dev/null
+++ b/Source/CPack/cmCPackTXZGenerator.h
@@ -0,0 +1,35 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackTXZGenerator_h
+#define cmCPackTXZGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPackTXZGenerator
+ * \brief A generator for TXZ files
+ *
+ */
+class cmCPackTXZGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackTXZGenerator, cmCPackArchiveGenerator);
+ /**
+ * Construct generator
+ */
+ cmCPackTXZGenerator();
+ virtual ~cmCPackTXZGenerator();
+protected:
+ virtual const char* GetOutputExtension() { return ".tar.xz"; }
+};
+
+#endif
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index ad37c42..c57028d 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -101,7 +101,7 @@ int cpackDefinitionArgument(const char* argument, const char* cValue,
// this is CPack.
int main (int argc, char const* const* argv)
{
- setlocale(LC_ALL, "");
+ setlocale(LC_CTYPE, "");
cmsys::Encoding::CommandLineArguments args =
cmsys::Encoding::CommandLineArguments::Main(argc, argv);
argc = args.argc();
@@ -343,7 +343,6 @@ int main (int argc, char const* const* argv)
{
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified" << std::endl);
- parsed = 0;
}
else
{
diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx
index 934481b..7f966aa 100644
--- a/Source/CTest/cmCTestBatchTestHandler.cxx
+++ b/Source/CTest/cmCTestBatchTestHandler.cxx
@@ -33,8 +33,8 @@ void cmCTestBatchTestHandler::WriteBatchScript()
{
this->Script = this->CTest->GetBinaryDir()
+ "/Testing/CTestBatch.txt";
- std::fstream fout;
- fout.open(this->Script.c_str(), std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(this->Script.c_str());
fout << "#!/bin/sh\n";
for(TestMap::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i)
@@ -48,7 +48,7 @@ void cmCTestBatchTestHandler::WriteBatchScript()
}
//---------------------------------------------------------
-void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
+void cmCTestBatchTestHandler::WriteSrunArgs(int test, cmsys::ofstream& fout)
{
cmCTestTestHandler::cmCTestTestProperties* properties =
this->Properties[test];
@@ -79,7 +79,7 @@ void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
}
//---------------------------------------------------------
-void cmCTestBatchTestHandler::WriteTestCommand(int test, std::fstream& fout)
+void cmCTestBatchTestHandler::WriteTestCommand(int test, cmsys::ofstream& fout)
{
std::vector<std::string> args = this->Properties[test]->Args;
std::vector<std::string> processArgs;
diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h
index ab0d081..e0c6e48 100644
--- a/Source/CTest/cmCTestBatchTestHandler.h
+++ b/Source/CTest/cmCTestBatchTestHandler.h
@@ -17,6 +17,7 @@
#include <cmCTestTestHandler.h>
#include <cmCTestMultiProcessHandler.h>
#include <cmCTestRunTest.h>
+#include <cmsys/FStream.hxx>
/** \class cmCTestBatchTestHandler
* \brief run parallel ctest
@@ -30,8 +31,8 @@ public:
virtual void RunTests();
protected:
void WriteBatchScript();
- void WriteSrunArgs(int test, std::fstream& fout);
- void WriteTestCommand(int test, std::fstream& fout);
+ void WriteSrunArgs(int test, cmsys::ofstream& fout);
+ void WriteTestCommand(int test, cmsys::ofstream& fout);
void SubmitBatchScript();
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index b4818be..41db042 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -68,6 +68,12 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
generator += this->BuildGenerator;
args.push_back(generator);
}
+ if(!this->BuildGeneratorPlatform.empty())
+ {
+ std::string platform = "-A";
+ platform += this->BuildGeneratorPlatform;
+ args.push_back(platform);
+ }
if(this->BuildGeneratorToolset.size())
{
std::string toolset = "-T";
@@ -246,6 +252,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
// Make the generator available for the Build call below.
cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
this->BuildGenerator));
+ cm.SetGeneratorPlatform(this->BuildGeneratorPlatform);
cm.SetGeneratorToolset(this->BuildGeneratorToolset);
// Load the cache to make CMAKE_MAKE_PROGRAM available.
@@ -301,7 +308,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
int retVal = cm.GetGlobalGenerator()->Build(
this->SourceDir, this->BinaryDir,
this->BuildProject, *tarIt,
- &output, this->BuildMakeProgram,
+ output, this->BuildMakeProgram,
config,
!this->BuildNoClean,
false, remainingTime);
@@ -490,6 +497,12 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++;
this->BuildGenerator = allArgs[idx];
}
+ if(currentArg == "--build-generator-platform" &&
+ idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildGeneratorPlatform = allArgs[idx];
+ }
if(currentArg == "--build-generator-toolset" &&
idx < allArgs.size() - 1)
{
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
index d1e9a4d..5a7b916 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.h
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -57,6 +57,7 @@ protected:
std::string Output;
std::string BuildGenerator;
+ std::string BuildGeneratorPlatform;
std::string BuildGeneratorToolset;
std::vector<std::string> BuildOptions;
bool BuildTwoConfig;
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 7922c9a..2ec1365 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -605,6 +605,9 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
typedef std::set<std::string, FragmentCompare> Fragments;
Fragments fragments(fragmentCompare);
+ // only report the first 50 warnings and first 50 errors
+ int numErrorsAllowed = this->MaxErrors;
+ int numWarningsAllowed = this->MaxWarnings;
// Identify fragments on disk.
cmsys::Directory launchDir;
launchDir.Load(this->CTestLaunchDir.c_str());
@@ -612,13 +615,15 @@ void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
for(unsigned long i=0; i < n; ++i)
{
const char* fname = launchDir.GetFile(i);
- if(this->IsLaunchedErrorFile(fname))
+ if(this->IsLaunchedErrorFile(fname) && numErrorsAllowed)
{
+ numErrorsAllowed--;
fragments.insert(this->CTestLaunchDir + "/" + fname);
++this->TotalErrors;
}
- else if(this->IsLaunchedWarningFile(fname))
+ else if(this->IsLaunchedWarningFile(fname) && numWarningsAllowed)
{
+ numWarningsAllowed--;
fragments.insert(this->CTestLaunchDir + "/" + fname);
++this->TotalWarnings;
}
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 1aa8768..ef62fd3 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -118,6 +118,15 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
cmakeConfigureCommand += cmakeGeneratorName;
cmakeConfigureCommand += "\"";
+ const char* cmakeGeneratorPlatform =
+ this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
+ if(cmakeGeneratorPlatform && *cmakeGeneratorPlatform)
+ {
+ cmakeConfigureCommand += " \"-A";
+ cmakeConfigureCommand += cmakeGeneratorPlatform;
+ cmakeConfigureCommand += "\"";
+ }
+
const char* cmakeGeneratorToolset =
this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
if(cmakeGeneratorToolset && *cmakeGeneratorToolset)
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
index a6e39a4..c492bf0 100644
--- a/Source/CTest/cmCTestConfigureHandler.cxx
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -77,7 +77,7 @@ int cmCTestConfigureHandler::ProcessHandler()
this->StartLogFile("Configure", ofs);
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Configure with command: "
<< cCommand << std::endl);
- res = this->CTest->RunMakeCommand(cCommand.c_str(), &output,
+ res = this->CTest->RunMakeCommand(cCommand.c_str(), output,
&retVal, buildDirectory.c_str(),
0, ofs);
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index da27c8c..76f6584 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -14,6 +14,7 @@
#include "cmParseCoberturaCoverage.h"
#include "cmParseGTMCoverage.h"
#include "cmParseCacheCoverage.h"
+#include "cmParseJacocoCoverage.h"
#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
@@ -415,6 +416,13 @@ int cmCTestCoverageHandler::ProcessHandler()
return error;
}
+ file_count += this->HandleJacocoCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+
std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
if ( file_count == 0 )
@@ -872,6 +880,38 @@ struct cmCTestCoverageHandlerLocale
};
//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleJacocoCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmParseJacocoCoverage cov =
+ cmParseJacocoCoverage(*cont, this->CTest);
+ cmsys::Glob g;
+ std::vector<std::string> files;
+ g.SetRecurse(true);
+
+ std::string SourceDir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+ std::string coverageFile = SourceDir+ "/*jacoco.xml";
+
+ g.FindFiles(coverageFile);
+ files=g.GetFiles();
+ if (files.size() > 0)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Found Jacoco Files, Performing Coverage" << std::endl);
+ cov.LoadCoverageData(files);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find Jacoco coverage files: " << coverageFile
+ << std::endl);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+
+
+//----------------------------------------------------------------------
int cmCTestCoverageHandler::HandleGCovCoverage(
cmCTestCoverageHandlerContainer* cont)
{
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 38a3353..d0f274c 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -81,7 +81,10 @@ private:
//! Handle coverage for mumps
int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont);
- //! Handle coverage using Bullseye
+ //! Handle coverage for Jacoco
+ int HandleJacocoCoverage(cmCTestCoverageHandlerContainer* cont);
+
+//! Handle coverage using Bullseye
int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont);
int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont);
int RunBullseyeCoverageBranch(cmCTestCoverageHandlerContainer* cont,
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 535c993..f144066 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -21,6 +21,10 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
= this->CTest->GetInitializedHandler("memcheck");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckSanitizerOptions", "CTEST_MEMORYCHECK_SANITIZER_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS");
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index ecaa474..4835010 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -18,6 +18,7 @@
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Base64.h>
+#include <cmsys/Glob.hxx>
#include <cmsys/FStream.hxx>
#include "cmMakefile.h"
#include "cmXMLSafe.h"
@@ -44,11 +45,23 @@ static CatToErrorType cmCTestMemCheckBoundsChecker[] = {
{0,0}
};
+static void xmlReportError(int line, const char* msg, void* data)
+{
+ cmCTest* ctest = (cmCTest*)data;
+ cmCTestLog(ctest, ERROR_MESSAGE,
+ "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl);
+}
+
// parse the xml file containing the results of last BoundsChecker run
class cmBoundsCheckerParser : public cmXMLParser
{
public:
- cmBoundsCheckerParser(cmCTest* c) { this->CTest = c;}
+ cmBoundsCheckerParser(cmCTest* c)
+ {
+ this->CTest = c;
+ this->SetErrorCallback(xmlReportError, (void*)c);
+ }
void StartElement(const std::string& name, const char** atts)
{
if(name == "MemoryLeak" ||
@@ -124,60 +137,7 @@ public:
#define BOUNDS_CHECKER_MARKER \
"******######*****Begin BOUNDS CHECKER XML******######******"
-//----------------------------------------------------------------------
-static const char* cmCTestMemCheckResultStrings[] = {
- "ABR",
- "ABW",
- "ABWL",
- "COR",
- "EXU",
- "FFM",
- "FIM",
- "FMM",
- "FMR",
- "FMW",
- "FUM",
- "IPR",
- "IPW",
- "MAF",
- "MLK",
- "MPK",
- "NPR",
- "ODS",
- "PAR",
- "PLK",
- "UMC",
- "UMR",
- 0
-};
-
-//----------------------------------------------------------------------
-static const char* cmCTestMemCheckResultLongStrings[] = {
- "Threading Problem",
- "ABW",
- "ABWL",
- "COR",
- "EXU",
- "FFM",
- "FIM",
- "Mismatched deallocation",
- "FMR",
- "FMW",
- "FUM",
- "IPR",
- "IPW",
- "MAF",
- "Memory Leak",
- "Potential Memory Leak",
- "NPR",
- "ODS",
- "Invalid syscall param",
- "PLK",
- "Uninitialized Memory Conditional",
- "Uninitialized Memory Read",
- 0
-};
//----------------------------------------------------------------------
@@ -186,12 +146,14 @@ cmCTestMemCheckHandler::cmCTestMemCheckHandler()
this->MemCheck = true;
this->CustomMaximumPassedTestOutputSize = 0;
this->CustomMaximumFailedTestOutputSize = 0;
+ this->LogWithPID = false;
}
//----------------------------------------------------------------------
void cmCTestMemCheckHandler::Initialize()
{
this->Superclass::Initialize();
+ this->LogWithPID = false;
this->CustomMaximumPassedTestOutputSize = 0;
this->CustomMaximumFailedTestOutputSize = 0;
this->MemoryTester = "";
@@ -199,12 +161,6 @@ void cmCTestMemCheckHandler::Initialize()
this->MemoryTesterOptions.clear();
this->MemoryTesterStyle = UNKNOWN;
this->MemoryTesterOutputFile = "";
- int cc;
- for ( cc = 0; cc < NO_MEMORY_FAULT; cc ++ )
- {
- this->MemoryTesterGlobalResults[cc] = 0;
- }
-
}
//----------------------------------------------------------------------
@@ -249,8 +205,8 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
index = stream.str();
for ( pp = 0; pp < this->MemoryTesterDynamicOptions.size(); pp ++ )
{
- std::string arg = this->MemoryTesterDynamicOptions[pp];
- std::string::size_type pos = arg.find("??");
+ std::string arg = this->MemoryTesterDynamicOptions[pp];
+ std::string::size_type pos = arg.find("??");
if (pos != std::string::npos)
{
arg.replace(pos, 2, index);
@@ -260,18 +216,125 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += arg;
memcheckcommand += "\"";
}
+ // Create a copy of the memory tester environment variable.
+ // This is used for memory testing programs that pass options
+ // via environment varaibles.
+ std::string memTesterEnvironmentVariable =
+ this->MemoryTesterEnvironmentVariable;
for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ )
{
- args.push_back(this->MemoryTesterOptions[pp]);
- memcheckcommand += " \"";
- memcheckcommand += this->MemoryTesterOptions[pp];
- memcheckcommand += "\"";
+ if(memTesterEnvironmentVariable.size())
+ {
+ // If we are using env to pass options, append all the options to
+ // this string with space separation.
+ memTesterEnvironmentVariable += " " + this->MemoryTesterOptions[pp];
+ }
+ // for regular options just add them to args and memcheckcommand
+ // which is just used for display
+ else
+ {
+ args.push_back(this->MemoryTesterOptions[pp]);
+ memcheckcommand += " \"";
+ memcheckcommand += this->MemoryTesterOptions[pp];
+ memcheckcommand += "\"";
+ }
+ }
+ // if this is an env option type, then add the env string as a single
+ // argument.
+ if(memTesterEnvironmentVariable.size())
+ {
+ std::string::size_type pos = memTesterEnvironmentVariable.find("??");
+ if (pos != std::string::npos)
+ {
+ memTesterEnvironmentVariable.replace(pos, 2, index);
+ }
+ memcheckcommand += " " + memTesterEnvironmentVariable;
+ args.push_back(memTesterEnvironmentVariable);
}
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Memory check command: "
<< memcheckcommand << std::endl);
}
//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::InitializeResultsVectors()
+{
+ // fill these members
+// cmsys::vector<std::string> ResultStrings;
+// cmsys::vector<std::string> ResultStringsLong;
+// cmsys::vector<int> GlobalResults;
+ this->ResultStringsLong.clear();
+ this->ResultStrings.clear();
+ this->GlobalResults.clear();
+ // If we are working with style checkers that dynamically fill
+ // the results strings then return.
+ if(this->MemoryTesterStyle > cmCTestMemCheckHandler::BOUNDS_CHECKER)
+ {
+ return;
+ }
+
+ // define the standard set of errors
+ //----------------------------------------------------------------------
+ static const char* cmCTestMemCheckResultStrings[] = {
+ "ABR",
+ "ABW",
+ "ABWL",
+ "COR",
+ "EXU",
+ "FFM",
+ "FIM",
+ "FMM",
+ "FMR",
+ "FMW",
+ "FUM",
+ "IPR",
+ "IPW",
+ "MAF",
+ "MLK",
+ "MPK",
+ "NPR",
+ "ODS",
+ "PAR",
+ "PLK",
+ "UMC",
+ "UMR",
+ 0
+ };
+//----------------------------------------------------------------------
+ static const char* cmCTestMemCheckResultLongStrings[] = {
+ "Threading Problem",
+ "ABW",
+ "ABWL",
+ "COR",
+ "EXU",
+ "FFM",
+ "FIM",
+ "Mismatched deallocation",
+ "FMR",
+ "FMW",
+ "FUM",
+ "IPR",
+ "IPW",
+ "MAF",
+ "Memory Leak",
+ "Potential Memory Leak",
+ "NPR",
+ "ODS",
+ "Invalid syscall param",
+ "PLK",
+ "Uninitialized Memory Conditional",
+ "Uninitialized Memory Read",
+ 0
+ };
+ this->GlobalResults.clear();
+ for(int i =0; cmCTestMemCheckResultStrings[i] != 0; ++i)
+ {
+ this->ResultStrings.push_back(cmCTestMemCheckResultStrings[i]);
+ this->ResultStringsLong.push_back(cmCTestMemCheckResultLongStrings[i]);
+ this->GlobalResults.push_back(0);
+ }
+}
+
+//----------------------------------------------------------------------
void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf)
{
this->cmCTestTestHandler::PopulateCustomVectors(mf);
@@ -283,6 +346,8 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf)
this->CTest->PopulateCustomVector(mf,
"CTEST_CUSTOM_MEMCHECK_IGNORE",
this->CustomTestsIgnore);
+ std::string cmake = cmSystemTools::GetCMakeCommand();
+ this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str());
}
//----------------------------------------------------------------------
@@ -292,7 +357,6 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
{
return;
}
-
this->CTest->StartXML(os, this->AppendXML);
os << "<DynamicAnalysis Checker=\"";
switch ( this->MemoryTesterStyle )
@@ -306,6 +370,18 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
os << "BoundsChecker";
break;
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ os << "AddressSanitizer";
+ break;
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ os << "ThreadSanitizer";
+ break;
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ os << "MemorySanitizer";
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ os << "UndefinedBehaviorSanitizer";
+ break;
default:
os << "Unknown";
}
@@ -333,8 +409,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
{
cmCTestTestResult *result = &this->TestResults[cc];
std::string memcheckstr;
- int memcheckresults[cmCTestMemCheckHandler::NO_MEMORY_FAULT];
- int kk;
+ std::vector<int> memcheckresults(this->ResultStrings.size(), 0);
bool res = this->ProcessMemCheckOutput(result->Output, memcheckstr,
memcheckresults);
if ( res && result->Status == cmCTestMemCheckHandler::COMPLETED )
@@ -345,16 +420,17 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
this->WriteTestResultHeader(os, result);
os << "\t\t<Results>" << std::endl;
- for ( kk = 0; cmCTestMemCheckResultLongStrings[kk]; kk ++ )
+ for(std::vector<int>::size_type kk = 0;
+ kk < memcheckresults.size(); ++kk)
{
if ( memcheckresults[kk] )
{
- os << "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings[kk]
+ os << "\t\t\t<Defect type=\"" << this->ResultStringsLong[kk]
<< "\">"
<< memcheckresults[kk]
<< "</Defect>" << std::endl;
}
- this->MemoryTesterGlobalResults[kk] += memcheckresults[kk];
+ this->GlobalResults[kk] += memcheckresults[kk];
}
std::string logTag;
@@ -383,9 +459,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:"
<< std::endl);
os << "\t<DefectList>" << std::endl;
- for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
+ for ( cc = 0; cc < this->GlobalResults.size(); cc ++ )
{
- if ( this->MemoryTesterGlobalResults[cc] )
+ if ( this->GlobalResults[cc] )
{
#ifdef cerr
# undef cerr
@@ -393,9 +469,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
std::cerr.width(35);
#define cerr no_cerr
cmCTestLog(this->CTest, HANDLER_OUTPUT,
- cmCTestMemCheckResultLongStrings[cc] << " - "
- << this->MemoryTesterGlobalResults[cc] << std::endl);
- os << "\t\t<Defect Type=\"" << cmCTestMemCheckResultLongStrings[cc]
+ this->ResultStringsLong[cc] << " - "
+ << this->GlobalResults[cc] << std::endl);
+ os << "\t\t<Defect Type=\"" << this->ResultStringsLong[cc]
<< "\"/>" << std::endl;
}
}
@@ -410,30 +486,33 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
os << "</DynamicAnalysis>" << std::endl;
this->CTest->EndXML(os);
-
-
}
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::InitializeMemoryChecking()
{
+ this->MemoryTesterEnvironmentVariable = "";
+ this->MemoryTester = "";
// Setup the command
if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
"MemoryCheckCommand").c_str()) )
{
this->MemoryTester
= this->CTest->GetCTestConfiguration("MemoryCheckCommand").c_str();
-
+ std::string testerName =
+ cmSystemTools::GetFilenameName(this->MemoryTester);
// determine the checker type
- if ( this->MemoryTester.find("valgrind") != std::string::npos )
+ if ( testerName.find("valgrind") != std::string::npos ||
+ this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "Valgrind")
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
}
- else if ( this->MemoryTester.find("purify") != std::string::npos )
+ else if ( testerName.find("purify") != std::string::npos )
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
}
- else if ( this->MemoryTester.find("BC") != std::string::npos )
+ else if ( testerName.find("BC") != std::string::npos )
{
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
}
@@ -463,12 +542,62 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
= this->CTest->GetCTestConfiguration("BoundsCheckerCommand").c_str();
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
}
- else
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "AddressSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "ThreadSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "MemorySanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "UndefinedBehaviorSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ // Check the MemoryCheckType
+ if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UNKNOWN)
+ {
+ std::string checkType =
+ this->CTest->GetCTestConfiguration("MemoryCheckType");
+ if(checkType == "Purify")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
+ }
+ else if(checkType == "BoundsChecker")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+ }
+ else if(checkType == "Valgrind")
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ }
+ }
+ if(this->MemoryTester.size() == 0 )
{
cmCTestLog(this->CTest, WARNING,
- "Memory checker (MemoryCheckCommand) "
- "not set, or cannot find the specified program."
- << std::endl);
+ "Memory checker (MemoryCheckCommand) "
+ "not set, or cannot find the specified program."
+ << std::endl);
return false;
}
@@ -567,6 +696,46 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOptions.push_back("/M");
break;
}
+ // these are almost the same but the env var used is different
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ {
+ // To pass arguments to ThreadSanitizer the environment variable
+ // TSAN_OPTIONS is used. This is done with the cmake -E env command.
+ // The MemoryTesterDynamicOptions is setup with the -E env
+ // Then the MemoryTesterEnvironmentVariable gets the
+ // TSAN_OPTIONS string with the log_path in it.
+ this->MemoryTesterDynamicOptions.push_back("-E");
+ this->MemoryTesterDynamicOptions.push_back("env");
+ std::string envVar;
+ std::string extraOptions =
+ this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
+ if(this->MemoryTesterStyle == cmCTestMemCheckHandler::ADDRESS_SANITIZER)
+ {
+ envVar = "ASAN_OPTIONS";
+ extraOptions += " detect_leaks=1";
+ }
+ else if(this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::THREAD_SANITIZER)
+ {
+ envVar = "TSAN_OPTIONS";
+ }
+ else if(this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::MEMORY_SANITIZER)
+ {
+ envVar = "MSAN_OPTIONS";
+ }
+ else if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UB_SANITIZER)
+ {
+ envVar = "UBSAN_OPTIONS";
+ }
+ std::string outputFile = envVar + "=log_path=\""
+ + this->MemoryTesterOutputFile + "\" ";
+ this->MemoryTesterEnvironmentVariable = outputFile + extraOptions;
+ break;
+ }
default:
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Do not understand memory checker: " << this->MemoryTester
@@ -574,24 +743,20 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
return false;
}
- std::vector<std::string>::size_type cc;
- for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
- {
- this->MemoryTesterGlobalResults[cc] = 0;
- }
+ this->InitializeResultsVectors();
+ // std::vector<std::string>::size_type cc;
+ // for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
+ // {
+ // this->MemoryTesterGlobalResults[cc] = 0;
+ // }
return true;
}
//----------------------------------------------------------------------
-bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
- std::string& log, int* results)
+bool cmCTestMemCheckHandler::
+ProcessMemCheckOutput(const std::string& str,
+ std::string& log, std::vector<int>& results)
{
- std::string::size_type cc;
- for ( cc = 0; cc < cmCTestMemCheckHandler::NO_MEMORY_FAULT; cc ++ )
- {
- results[cc] = 0;
- }
-
if ( this->MemoryTesterStyle == cmCTestMemCheckHandler::VALGRIND )
{
return this->ProcessMemCheckValgrindOutput(str, log, results);
@@ -601,6 +766,17 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
return this->ProcessMemCheckPurifyOutput(str, log, results);
}
else if ( this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::ADDRESS_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::THREAD_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::MEMORY_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::UB_SANITIZER)
+ {
+ return this->ProcessMemCheckSanitizerOutput(str, log, results);
+ }
+ else if ( this->MemoryTesterStyle ==
cmCTestMemCheckHandler::BOUNDS_CHECKER )
{
return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
@@ -611,15 +787,94 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
log.append("None that I know");
log = str;
}
-
-
return true;
}
+std::vector<int>::size_type cmCTestMemCheckHandler::FindOrAddWarning(
+ const std::string& warning)
+{
+ for(std::vector<std::string>::size_type i =0;
+ i < this->ResultStrings.size(); ++i)
+ {
+ if(this->ResultStrings[i] == warning)
+ {
+ return i;
+ }
+ }
+ this->GlobalResults.push_back(0); // this must stay the same size
+ this->ResultStrings.push_back(warning);
+ this->ResultStringsLong.push_back(warning);
+ return this->ResultStrings.size()-1;
+}
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
+ const std::string& str, std::string& log,
+ std::vector<int>& result)
+{
+ std::string regex;
+ switch ( this->MemoryTesterStyle )
+ {
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ regex = "ERROR: AddressSanitizer: (.*) on.*";
+ break;
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)";
+ break;
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ regex = "WARNING: MemorySanitizer: (.*)";
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ regex = "runtime error: (.*)";
+ break;
+ default:
+ break;
+ }
+ cmsys::RegularExpression sanitizerWarning(regex);
+ cmsys::RegularExpression leakWarning("(Direct|Indirect) leak of .*");
+ int defects = 0;
+ std::vector<std::string> lines;
+ cmSystemTools::Split(str.c_str(), lines);
+ cmOStringStream ostr;
+ log = "";
+ for( std::vector<std::string>::iterator i = lines.begin();
+ i != lines.end(); ++i)
+ {
+ std::string resultFound;
+ if(leakWarning.find(*i))
+ {
+ resultFound = leakWarning.match(1)+" leak";
+ }
+ else if (sanitizerWarning.find(*i))
+ {
+ resultFound = sanitizerWarning.match(1);
+ }
+ if(resultFound.size())
+ {
+ std::vector<int>::size_type idx = this->FindOrAddWarning(resultFound);
+ if(result.size() == 0 || idx > result.size()-1)
+ {
+ result.push_back(1);
+ }
+ else
+ {
+ result[idx]++;
+ }
+ defects++;
+ ostr << "<b>" << this->ResultStrings[idx] << "</b> ";
+ }
+ ostr << cmXMLSafe(*i) << std::endl;
+ }
+ log = ostr.str();
+ if(defects)
+ {
+ return false;
+ }
+ return true;
+}
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
std::vector<std::string> lines;
cmSystemTools::Split(str.c_str(), lines);
@@ -633,19 +888,19 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
for( std::vector<std::string>::iterator i = lines.begin();
i != lines.end(); ++i)
{
- int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
+ std::vector<int>::size_type failure = this->ResultStrings.size();
if ( pfW.find(*i) )
{
- int cc;
- for ( cc = 0; cc < cmCTestMemCheckHandler::NO_MEMORY_FAULT; cc ++ )
+ std::vector<int>::size_type cc;
+ for ( cc = 0; cc < this->ResultStrings.size(); cc ++ )
{
- if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
+ if ( pfW.match(1) == this->ResultStrings[cc] )
{
failure = cc;
break;
}
}
- if ( cc == cmCTestMemCheckHandler::NO_MEMORY_FAULT )
+ if ( cc == this->ResultStrings.size() )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown Purify memory fault: "
<< pfW.match(1) << std::endl);
@@ -653,9 +908,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
<< std::endl;
}
}
- if ( failure != NO_MEMORY_FAULT )
+ if ( failure != this->ResultStrings.size() )
{
- ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
results[failure] ++;
defects ++;
}
@@ -673,7 +928,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
std::vector<std::string> lines;
cmSystemTools::Split(str.c_str(), lines);
@@ -728,7 +983,6 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
double sttime = cmSystemTools::GetTime();
cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl);
std::string::size_type totalOutputSize = 0;
- bool outputFull = false;
for ( cc = 0; cc < lines.size(); cc ++ )
{
cmCTestLog(this->CTest, DEBUG, "test line "
@@ -802,7 +1056,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
if ( failure != cmCTestMemCheckHandler::NO_MEMORY_FAULT )
{
- ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
results[failure] ++;
defects ++;
}
@@ -815,32 +1069,30 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
}
}
// Now put all all the non valgrind output into the test output
- if(!outputFull)
+ // This should be last in case it gets truncated by the output
+ // limiting code
+ for(std::vector<std::string::size_type>::iterator i =
+ nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
{
- for(std::vector<std::string::size_type>::iterator i =
- nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
+ totalOutputSize += lines[*i].size();
+ cmCTestLog(this->CTest, DEBUG, "before xml safe "
+ << lines[*i] << std::endl);
+ cmCTestLog(this->CTest, DEBUG, "after xml safe "
+ << cmXMLSafe(lines[*i]) << std::endl);
+ ostr << cmXMLSafe(lines[*i]) << std::endl;
+ if(!unlimitedOutput && totalOutputSize >
+ static_cast<size_t>(this->CustomMaximumFailedTestOutputSize))
{
- totalOutputSize += lines[*i].size();
- cmCTestLog(this->CTest, DEBUG, "before xml safe "
- << lines[*i] << std::endl);
- cmCTestLog(this->CTest, DEBUG, "after xml safe "
- << cmXMLSafe(lines[*i]) << std::endl);
-
- ostr << cmXMLSafe(lines[*i]) << std::endl;
- if(!unlimitedOutput && totalOutputSize >
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize))
- {
- outputFull = true;
- ostr << "....\n";
- ostr << "Test Output for this test has been truncated see testing"
- " machine logs for full output,\n";
- ostr << "or put CTEST_FULL_OUTPUT in the output of "
- "this test program.\n";
- }
+ ostr << "....\n";
+ ostr << "Test Output for this test has been truncated see testing"
+ " machine logs for full output,\n";
+ ostr << "or put CTEST_FULL_OUTPUT in the output of "
+ "this test program.\n";
+ break; // stop the copy of output if we are full
}
}
cmCTestLog(this->CTest, DEBUG, "End test (elapsed: "
- << (cmSystemTools::GetTime() - sttime) << std::endl);
+ << (cmSystemTools::GetTime() - sttime) << std::endl);
log = ostr.str();
if ( defects )
{
@@ -854,7 +1106,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
//----------------------------------------------------------------------
bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
const std::string& str, std::string& log,
- int* results)
+ std::vector<int>& results)
{
log = "";
double sttime = cmSystemTools::GetTime();
@@ -908,6 +1160,32 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
return true;
}
+// PostProcessTest memcheck results
+void
+cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res,
+ int test)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "PostProcessTest memcheck results for : "
+ << res.Name << std::endl);
+ if(this->MemoryTesterStyle
+ == cmCTestMemCheckHandler::BOUNDS_CHECKER)
+ {
+ this->PostProcessBoundsCheckerTest(res, test);
+ }
+ else
+ {
+ std::vector<std::string> files;
+ this->TestOutputFileNames(test, files);
+ for(std::vector<std::string>::iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ this->AppendMemTesterOutput(res, *i);
+ }
+ }
+}
+
+
// This method puts the bounds checker output file into the output
// for the test
void
@@ -917,11 +1195,13 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"PostProcessBoundsCheckerTest for : "
<< res.Name << std::endl);
- std::string ofile = testOutputFileName(test);
- if ( ofile.empty() )
+ std::vector<std::string> files;
+ this->TestOutputFileNames(test, files);
+ if ( files.size() == 0 )
{
return;
}
+ std::string ofile = files[0];
// put a scope around this to close ifs so the file can be removed
{
cmsys::ifstream ifs(ofile.c_str());
@@ -950,35 +1230,15 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
}
void
-cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res,
- int test)
+cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
+ std::string const& ofile)
{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "PostProcessPurifyTest for : "
- << res.Name << std::endl);
- appendMemTesterOutput(res, test);
-}
-
-void
-cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res,
- int test)
-{
- cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
- "PostProcessValgrindTest for : "
- << res.Name << std::endl);
- appendMemTesterOutput(res, test);
-}
-
-void
-cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
- int test)
-{
- std::string ofile = testOutputFileName(test);
-
if ( ofile.empty() )
{
return;
}
+ // put ifs in scope so file can be deleted if needed
+ {
cmsys::ifstream ifs(ofile.c_str());
if ( !ifs )
{
@@ -992,10 +1252,17 @@ cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
res.Output += line;
res.Output += "\n";
}
+ }
+ if(this->LogWithPID)
+ {
+ cmSystemTools::RemoveFile(ofile.c_str());
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "<< ofile <<"\n");
+ }
}
-std::string
-cmCTestMemCheckHandler::testOutputFileName(int test)
+void cmCTestMemCheckHandler::TestOutputFileNames(int test,
+ std::vector<std::string>&
+ files)
{
std::string index;
cmOStringStream stream;
@@ -1004,14 +1271,30 @@ cmCTestMemCheckHandler::testOutputFileName(int test)
std::string ofile = this->MemoryTesterOutputFile;
std::string::size_type pos = ofile.find("??");
ofile.replace(pos, 2, index);
-
- if ( !cmSystemTools::FileExists(ofile.c_str()) )
+ if(this->LogWithPID)
+ {
+ ofile += ".*";
+ cmsys::Glob g;
+ g.FindFiles(ofile);
+ if(g.GetFiles().size() == 0)
+ {
+ std::string log = "Cannot find memory tester output file: "
+ + ofile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ ofile = "";
+ }
+ else
+ {
+ files = g.GetFiles();
+ return;
+ }
+ }
+ else if ( !cmSystemTools::FileExists(ofile.c_str()) )
{
std::string log = "Cannot find memory tester output file: "
+ ofile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
ofile = "";
}
-
- return ofile;
+ files.push_back(ofile);
}
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 0521a48..69fdd9f 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -15,7 +15,10 @@
#include "cmCTestTestHandler.h"
+#include "cmStandardIncludes.h"
#include "cmListFileCache.h"
+#include <vector>
+#include <string>
class cmMakefile;
@@ -45,7 +48,12 @@ private:
UNKNOWN = 0,
VALGRIND,
PURIFY,
- BOUNDS_CHECKER
+ BOUNDS_CHECKER,
+ // checkers after here do not use the standard error list
+ ADDRESS_SANITIZER,
+ THREAD_SANITIZER,
+ MEMORY_SANITIZER,
+ UB_SANITIZER
};
public:
enum { // Memory faults
@@ -93,7 +101,17 @@ private:
std::vector<std::string> MemoryTesterOptions;
int MemoryTesterStyle;
std::string MemoryTesterOutputFile;
- int MemoryTesterGlobalResults[NO_MEMORY_FAULT];
+ std::string MemoryTesterEnvironmentVariable;
+ // these are used to store the types of errors that can show up
+ std::vector<std::string> ResultStrings;
+ std::vector<std::string> ResultStringsLong;
+ std::vector<int> GlobalResults;
+ bool LogWithPID; // does log file add pid
+
+ std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
+ // initialize the ResultStrings and ResultStringsLong for
+ // this type of checker
+ void InitializeResultsVectors();
///! Initialize memory checking subsystem.
bool InitializeMemoryChecking();
@@ -110,24 +128,29 @@ private:
//string. After running, log holds the output and results hold the
//different memmory errors.
bool ProcessMemCheckOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log, std::vector<int>& results);
bool ProcessMemCheckValgrindOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckPurifyOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
+ bool ProcessMemCheckSanitizerOutput(const std::string& str,
+ std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
- std::string& log, int* results);
+ std::string& log,
+ std::vector<int>& results);
- void PostProcessPurifyTest(cmCTestTestResult& res, int test);
+ void PostProcessTest(cmCTestTestResult& res, int test);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
- void PostProcessValgrindTest(cmCTestTestResult& res, int test);
///! append MemoryTesterOutputFile to the test log
- void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
- int test);
+ void AppendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
+ std::string const& filename);
///! generate the output filename for the given test index
- std::string testOutputFileName(int test);
+ void TestOutputFileNames(int test, std::vector<std::string>& files);
};
#endif
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index b9e6721..7ba434c 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -319,8 +319,8 @@ void cmCTestMultiProcessHandler::UpdateCostData()
{
std::string fname = this->CTest->GetCostDataFile();
std::string tmpout = fname + ".tmp";
- std::fstream fout;
- fout.open(tmpout.c_str(), std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(tmpout.c_str());
PropertiesMap temp = this->Properties;
@@ -610,8 +610,8 @@ void cmCTestMultiProcessHandler::WriteCheckpoint(int index)
{
std::string fname = this->CTest->GetBinaryDir()
+ "/Testing/Temporary/CTestCheckpoint.txt";
- std::fstream fout;
- fout.open(fname.c_str(), std::ios::app | std::ios::out);
+ cmsys::ofstream fout;
+ fout.open(fname.c_str(), std::ios::app);
fout << index << "\n";
fout.close();
}
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 385388d..bdd8c02 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -392,20 +392,7 @@ void cmCTestRunTest::MemCheckPostProcess()
<< this->TestResult.Name << std::endl);
cmCTestMemCheckHandler * handler = static_cast<cmCTestMemCheckHandler*>
(this->TestHandler);
- switch ( handler->MemoryTesterStyle )
- {
- case cmCTestMemCheckHandler::VALGRIND:
- handler->PostProcessValgrindTest(this->TestResult, this->Index);
- break;
- case cmCTestMemCheckHandler::PURIFY:
- handler->PostProcessPurifyTest(this->TestResult, this->Index);
- break;
- case cmCTestMemCheckHandler::BOUNDS_CHECKER:
- handler->PostProcessBoundsCheckerTest(this->TestResult, this->Index);
- break;
- default:
- break;
- }
+ handler->PostProcessTest(this->TestResult, this->Index);
}
//----------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 567acfc..f050148 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -317,6 +317,15 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
return retVal;
}
+static void ctestScriptProgressCallback(const char *m, float, void* cd)
+{
+ cmCTest* ctest = static_cast<cmCTest*>(cd);
+ if(m && *m)
+ {
+ cmCTestLog(ctest, HANDLER_OUTPUT, "-- " << m << std::endl);
+ }
+}
+
void cmCTestScriptHandler::CreateCMake()
{
// create a cmake instance to read the configuration script
@@ -334,6 +343,8 @@ void cmCTestScriptHandler::CreateCMake()
this->LocalGenerator = this->GlobalGenerator->CreateLocalGenerator();
this->Makefile = this->LocalGenerator->GetMakefile();
+ this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest);
+
// Set CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR.
// Also, some commands need Makefile->GetCurrentDirectory().
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 7c72cba..06fcb75 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -225,8 +225,8 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix,
std::string upload_as
= url + "/" + remoteprefix + cmSystemTools::GetFilenameName(*file);
- struct stat st;
- if ( ::stat(local_file.c_str(), &st) )
+
+ if ( !cmSystemTools::FileExists(local_file.c_str()) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
<< local_file << std::endl);
@@ -234,6 +234,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix,
::curl_global_cleanup();
return false;
}
+ unsigned long filelen = cmSystemTools::FileLength(local_file.c_str());
ftpfile = cmsys::SystemTools::Fopen(local_file.c_str(), "rb");
*this->LogFile << "\tUpload file: " << local_file << " to "
@@ -252,7 +253,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix,
// and give the size of the upload (optional)
::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
- static_cast<long>(st.st_size));
+ static_cast<long>(filelen));
// and give curl the buffer for errors
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
@@ -466,8 +467,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
upload_as += md5;
}
- struct stat st;
- if ( ::stat(local_file.c_str(), &st) )
+ if( !cmSystemTools::FileExists(local_file.c_str()) )
{
cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
<< local_file << std::endl);
@@ -475,11 +475,12 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
::curl_global_cleanup();
return false;
}
+ unsigned long filelen = cmSystemTools::FileLength(local_file.c_str());
ftpfile = cmsys::SystemTools::Fopen(local_file.c_str(), "rb");
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: "
<< local_file << " to "
- << upload_as << " Size: " << st.st_size << std::endl);
+ << upload_as << " Size: " << filelen << std::endl);
// specify target
::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
@@ -489,7 +490,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix,
// and give the size of the upload (optional)
::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
- static_cast<long>(st.st_size));
+ static_cast<long>(filelen));
// and give curl the buffer for errors
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
@@ -1478,8 +1479,10 @@ int cmCTestSubmitHandler::ProcessHandler()
//----------------------------------------------------------------------------
std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
{
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
std::string name = this->CTest->GetCTestConfiguration("Site") +
- "___" + this->CTest->GetCTestConfiguration("BuildName") +
+ "___" + buildname +
"___" + this->CTest->GetCurrentTag() + "-" +
this->CTest->GetTestModelString() + "___XML___";
return name;
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 5408a8a..f87466d 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -56,6 +56,8 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"HGCommand", "CTEST_HG_COMMAND");
this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
"HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS");
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index fda61ea..68f5fe1 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -258,12 +258,13 @@ int cmCTestUpdateHandler::ProcessHandler()
double elapsed_time_start = cmSystemTools::GetTime();
bool updated = vc->Update();
-
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<Update mode=\"Client\" Generator=\"ctest-"
<< cmVersion::GetCMakeVersion() << "\">\n"
<< "\t<Site>" << this->CTest->GetCTestConfiguration("Site") << "</Site>\n"
- << "\t<BuildName>" << this->CTest->GetCTestConfiguration("BuildName")
+ << "\t<BuildName>" << buildname
<< "</BuildName>\n"
<< "\t<BuildStamp>" << this->CTest->GetCurrentTag() << "-"
<< this->CTest->GetTestModelString() << "</BuildStamp>" << std::endl;
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
index 4c3f81b..e33c387 100644
--- a/Source/CTest/cmCTestUploadHandler.cxx
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -44,14 +44,15 @@ int cmCTestUploadHandler::ProcessHandler()
"Cannot open Upload.xml file" << std::endl);
return -1;
}
-
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->CTest->GetCTestConfiguration("BuildName"));
cmCTest::SetOfStrings::const_iterator it;
ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<?xml-stylesheet type=\"text/xsl\" "
"href=\"Dart/Source/Server/XSL/Build.xsl "
"<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
<< "<Site BuildName=\""
- << this->CTest->GetCTestConfiguration("BuildName")
+ << buildname
<< "\" BuildStamp=\""
<< this->CTest->GetCurrentTag() << "-"
<< this->CTest->GetTestModelString() << "\" Name=\""
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index f89fa2b..15f796f 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -166,10 +166,17 @@ void cmCTestVC::CleanupImpl()
//----------------------------------------------------------------------------
bool cmCTestVC::Update()
{
- this->NoteOldRevision();
- this->Log << "--- Begin Update ---\n";
- bool result = this->UpdateImpl();
- this->Log << "--- End Update ---\n";
+ bool result = true;
+ // if update version only is on then do not actually update,
+ // just note the current version and finish
+ if(!cmSystemTools::IsOn(
+ this->CTest->GetCTestConfiguration("UpdateVersionOnly").c_str()))
+ {
+ this->NoteOldRevision();
+ this->Log << "--- Begin Update ---\n";
+ result = this->UpdateImpl();
+ this->Log << "--- End Update ---\n";
+ }
this->NoteNewRevision();
return result;
}
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 6b98056..0742be1 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -71,6 +71,7 @@ protected:
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: "
<< atts[tagCount+1]<< std::endl);
std::string filename = atts[tagCount+1];
+ this->CurFileName = "";
for(size_t i=0;i < FilePaths.size();i++)
{
finalpath = FilePaths[i] + "/" + filename;
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
new file mode 100644
index 0000000..f270adb
--- /dev/null
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -0,0 +1,170 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParseJacocoCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/FStream.hxx>
+
+
+class cmParseJacocoCoverage::XMLParser: public cmXMLParser
+{
+ public:
+ XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+ : CTest(ctest), Coverage(cont)
+ {
+ this->PackageName = "";
+ this->ModuleName = "";
+ this->FileName = "";
+ this->CurFileName = "";
+ this->FilePaths.push_back(this->Coverage.SourceDir);
+ }
+
+ virtual ~XMLParser()
+ {
+ }
+
+ protected:
+
+ virtual void EndElement(const std::string&)
+ {
+ }
+
+ virtual void StartElement(const std::string& name,
+ const char** atts)
+ {
+ if(name == "package")
+ {
+ this->PackageName = atts[1];
+ std::string FilePath = this->Coverage.SourceDir +
+ "/" + this->ModuleName + "/src/main/java/" +
+ this->PackageName;
+ this->FilePaths.push_back(FilePath);
+ FilePath = this->Coverage.SourceDir +
+ "/src/main/java/" + this->PackageName;
+ this->FilePaths.push_back(FilePath);
+ }
+ else if(name == "sourcefile")
+ {
+ this->FileName = atts[1];
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: "
+ << this->FileName << std::endl);
+ for(size_t i=0;i < FilePaths.size();i++)
+ {
+ std::string finalpath = FilePaths[i] + "/" + this->FileName;
+ if(cmSystemTools::FileExists(finalpath.c_str()))
+ {
+ this->CurFileName = finalpath;
+ break;
+ }
+ }
+ cmsys::ifstream fin(this->CurFileName.c_str());
+ if(this->CurFileName == "" || !fin )
+ {
+ this->CurFileName = this->Coverage.BinaryDir + "/" +
+ this->FileName;
+ fin.open(this->CurFileName.c_str());
+ if (!fin)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Jacoco Coverage: Error opening " << this->CurFileName
+ << std::endl);
+ this->Coverage.Error++;
+ }
+ }
+ std::string line;
+ FileLinesType& curFileLines =
+ this->Coverage.TotalCoverage[this->CurFileName];
+ curFileLines.push_back(-1);
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ curFileLines.push_back(-1);
+ }
+ }
+ else if(name == "report")
+ {
+ this->ModuleName=atts[1];
+ }
+ else if(name == "line")
+ {
+ int tagCount = 0;
+ int nr = -1;
+ int ci = -1;
+ while(true)
+ {
+ if(strcmp(atts[tagCount],"ci") == 0)
+ {
+ ci = atoi(atts[tagCount+1]);
+ }
+ else if (strcmp(atts[tagCount],"nr") == 0)
+ {
+ nr = atoi(atts[tagCount+1]);
+ }
+ if (ci > -1 && nr > 0)
+ {
+ FileLinesType& curFileLines=
+ this->Coverage.TotalCoverage[this->CurFileName];
+ if(curFileLines.size() > 0)
+ {
+ curFileLines[nr-1] = ci;
+ }
+ break;
+ }
+ ++tagCount;
+ }
+ }
+ }
+
+ private:
+ std::string PackageName;
+ std::string FileName;
+ std::string ModuleName;
+ std::string CurFileName;
+ std::vector<std::string> FilePaths;
+ typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+ FileLinesType;
+ cmCTest* CTest;
+ cmCTestCoverageHandlerContainer& Coverage;
+};
+
+cmParseJacocoCoverage::cmParseJacocoCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+ {
+ }
+
+bool cmParseJacocoCoverage::LoadCoverageData(
+ const std::vector<std::string> files)
+{
+ // load all the jacoco.xml files in the source directory
+ cmsys::Directory dir;
+ size_t i;
+ std::string path;
+ size_t numf = files.size();
+ for (i = 0; i < numf; i++)
+ {
+ path = files[i];
+
+ cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
+ "Reading XML File " << path << std::endl);
+ if(cmSystemTools::GetFilenameLastExtension(path) == ".xml")
+ {
+ if(!this->ReadJacocoXML(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool cmParseJacocoCoverage::ReadJacocoXML(const char* file)
+{
+ cmParseJacocoCoverage::XMLParser
+ parser(this->CTest, this->Coverage);
+ parser.ParseFile(file);
+ return true;
+}
diff --git a/Source/CTest/cmParseJacocoCoverage.h b/Source/CTest/cmParseJacocoCoverage.h
new file mode 100644
index 0000000..dad05a3
--- /dev/null
+++ b/Source/CTest/cmParseJacocoCoverage.h
@@ -0,0 +1,59 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseJacocoCoverage_h
+#define cmParseJacocoCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+
+/** \class cmParseJacocoCoverage
+ * \brief Parse JaCoCO coverage information
+ *
+ * This class is used to parse coverage information for
+ * java using the JaCoCo tool:
+ *
+ * http://www.eclemma.org/jacoco/trunk/index.html
+ */
+class cmParseJacocoCoverage
+{
+public:
+ cmParseJacocoCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ bool LoadCoverageData(const std::vector<std::string> files);
+
+ std::string PackageName;
+ std::string FileName;
+ std::string ModuleName;
+ std::string CurFileName;
+private:
+ // implement virtual from parent
+ // remove files with no coverage
+ void RemoveUnCoveredFiles();
+ // Read a single mcov file
+ bool ReadJacocoXML(const char* f);
+ // split a string based on ,
+ bool SplitString(std::vector<std::string>& args,
+ std::string const& line);
+ bool FindJavaFile(std::string const& routine,
+ std::string& filepath);
+ void InitializeJavaFile(std::string& file);
+ bool LoadSource(std::string d);
+
+ class XMLParser;
+ std::map<std::string, std::string> RoutineToDirectory;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+};
+
+#endif
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index 6236211..225e704 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -96,11 +96,13 @@ void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
}
if(found)
{
- // (2) If the first character found above is whitespace then continue the
- // search for the first following non-whitespace character.
+ // (2) If the first character found above is whitespace or a period
+ // then continue the search for the first following non-whitespace
+ // character.
if(line[i] == ' ' || line[i] == '\t')
{
- while(i < line.size() && (line[i] == ' ' || line[i] == '\t'))
+ while(i < line.size() && (line[i] == ' ' || line[i] == '\t'
+ || line[i] == '.'))
{
i++;
}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index a9d4d98..28f3d9b 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -38,6 +38,18 @@ static const char * cmDocumentationUsage[][2] =
{0,
" ccmake <path-to-source>\n"
" ccmake <path-to-existing-build>"},
+ {0,
+ "Specify a source directory to (re-)generate a build system for "
+ "it in the current working directory. Specify an existing build "
+ "directory to re-generate its build system."},
+ {0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsageNote[][2] =
+{
+ {0,
+ "Run 'ccmake --help' for more information."},
{0,0}
};
@@ -83,7 +95,7 @@ void CMakeMessageHandler(const char* message, const char* title, bool&,
int main(int argc, char const* const* argv)
{
- setlocale(LC_ALL, "");
+ setlocale(LC_CTYPE, "");
cmsys::Encoding::CommandLineArguments encoding_args =
cmsys::Encoding::CommandLineArguments::Main(argc, argv);
@@ -102,6 +114,10 @@ int main(int argc, char const* const* argv)
doc.SetName("ccmake");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
+ if ( argc == 1 )
+ {
+ doc.AppendSection("Usage",cmDocumentationUsageNote);
+ }
doc.SetSection("Generators",generators);
doc.PrependSection("Options",cmDocumentationOptions);
return doc.PrintRequestedDocumentation(std::cout)? 0:1;
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 8da88c1..03c2fb4 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -35,6 +35,32 @@ if (Qt5Widgets_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+ # We need to install Cocoa platform plugin and add qt.conf for Qt5 on Mac.
+ # FIXME: This should be part of Qt5 CMake scripts, but unfortunatelly
+ # Qt5 Mac support is missing there.
+ if(APPLE)
+ macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+ get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ if(EXISTS "${_qt_plugin_path}")
+ get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+ get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+ set(_qt_plugin_dest "${CMAKE_INSTALL_PREFIX}/PlugIns/${_qt_plugin_type}")
+ install(FILES "${_qt_plugin_path}"
+ DESTINATION "${_qt_plugin_dest}")
+ set(${_qt_plugins_var}
+ "${${_qt_plugins_var}};${_qt_plugin_dest}/${_qt_plugin_file}")
+ else()
+ message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+ endif()
+ endmacro()
+ install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = PlugIns\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources")
+ endif()
+
if(WIN32 AND TARGET Qt5::Core)
get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
@@ -168,7 +194,7 @@ if(APPLE OR WIN32)
install(CODE "
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
- fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+ fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
")
endif()
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 8a37797..0574681 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -756,6 +756,9 @@ bool CMakeSetupDialog::setupFirstConfigure()
QString systemName = dialog.getSystemName();
m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME",
tr("CMake System Name"), systemName, false);
+ QString systemVersion = dialog.getSystemVersion();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION",
+ tr("CMake System Version"), systemVersion, false);
QString cxxCompiler = dialog.getCXXCompiler();
m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
tr("CXX compiler."), cxxCompiler, false);
diff --git a/Source/QtIFW/cmake.org.html b/Source/QtIFW/cmake.org.html
new file mode 100644
index 0000000..cf5649d
--- /dev/null
+++ b/Source/QtIFW/cmake.org.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="Refresh" content="0; url=http://cmake.org/" />
+</head>
+<body>
+</body>
+</html>
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
new file mode 100644
index 0000000..5491611
--- /dev/null
+++ b/Source/QtIFW/installscript.qs.in
@@ -0,0 +1,24 @@
+function Component()
+{
+ // default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // call default implementation to actually install applications!
+ component.createOperations();
+
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+@_CPACK_IFW_SHORTCUT_OPTIONAL@
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/cmake.org.html",
+ installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/uninstall.exe",
+ installer.value("StartMenuDir") + "/Uninstall.lnk");
+ }
+}
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 58f7573..a2aecac 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -25,6 +25,28 @@ static std::string cm_archive_error_string(struct archive* a)
}
//----------------------------------------------------------------------------
+static void cm_archive_entry_copy_pathname(struct archive_entry* e,
+ const std::string& dest)
+{
+#if cmsys_STL_HAS_WSTRING
+ archive_entry_copy_pathname_w(e, cmsys::Encoding::ToWide(dest).c_str());
+#else
+ archive_entry_copy_pathname(e, dest.c_str());
+#endif
+}
+
+//----------------------------------------------------------------------------
+static void cm_archive_entry_copy_sourcepath(struct archive_entry* e,
+ const std::string& file)
+{
+#if cmsys_STL_HAS_WSTRING
+ archive_entry_copy_sourcepath_w(e, cmsys::Encoding::ToWide(file).c_str());
+#else
+ archive_entry_copy_sourcepath(e, file.c_str());
+#endif
+}
+
+//----------------------------------------------------------------------------
class cmArchiveWrite::Entry
{
struct archive_entry* Object;
@@ -137,7 +159,15 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
this->Error += cm_archive_error_string(this->Archive);
return;
}
- break;
+ break;
+ case Type7Zip:
+ if(archive_write_set_format_7zip(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_format_7zip: ";
+ this->Error += cm_archive_error_string(this->Archive);
+ return;
+ }
+ break;
}
// do not pad the last block!!
@@ -237,8 +267,8 @@ bool cmArchiveWrite::AddFile(const char* file,
std::cout << dest << "\n";
}
Entry e;
- archive_entry_copy_sourcepath(e, file);
- archive_entry_set_pathname(e, dest.c_str());
+ cm_archive_entry_copy_sourcepath(e, file);
+ cm_archive_entry_copy_pathname(e, dest);
if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK)
{
this->Error = "archive_read_disk_entry_from_file: ";
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 3e3b2f0..a6dcc0e 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -42,7 +42,8 @@ public:
enum Type
{
TypeTAR,
- TypeZIP
+ TypeZIP,
+ Type7Zip
};
/** Construct with output stream to which to write archive. */
diff --git a/Source/cmBootstrapCommands2.cxx b/Source/cmBootstrapCommands2.cxx
index be72526..5675295 100644
--- a/Source/cmBootstrapCommands2.cxx
+++ b/Source/cmBootstrapCommands2.cxx
@@ -14,6 +14,8 @@
// This is sort of a boot strapping approach since you would
// like to have CMake to build CMake.
#include "cmCommands.h"
+#include "cmConditionEvaluator.cxx"
+#include "cmExpandedCommandArgument.cxx"
#include "cmGeneratorExpressionEvaluationFile.cxx"
#include "cmGetCMakePropertyCommand.cxx"
#include "cmGetDirectoryPropertyCommand.cxx"
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index d797d3b..a7905a4 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -488,9 +488,11 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
{
cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
cmCTestLog(this, OUTPUT,
- " Site: " << this->GetCTestConfiguration("Site") << std::endl
- << " Build name: " << this->GetCTestConfiguration("BuildName")
- << std::endl);
+ " Site: " << this->GetCTestConfiguration("Site") << std::endl
+ << " Build name: "
+ << cmCTest::SafeBuildIdField(
+ this->GetCTestConfiguration("BuildName"))
+ << std::endl);
cmCTestLog(this, DEBUG, "Produce XML is on" << std::endl);
if ( this->TestModel == cmCTest::NIGHTLY &&
this->GetCTestConfiguration("NightlyStartTime").empty() )
@@ -1147,7 +1149,7 @@ int cmCTest::GetTestModelFromString(const char* str)
//######################################################################
//----------------------------------------------------------------------
-int cmCTest::RunMakeCommand(const char* command, std::string* output,
+int cmCTest::RunMakeCommand(const char* command, std::string& output,
int* retVal, const char* dir, int timeout, std::ostream& ofs)
{
// First generate the command and arguments
@@ -1166,11 +1168,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
}
argv.push_back(0);
- if ( output )
- {
- *output = "";
- }
-
+ output = "";
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:");
std::vector<const char*>::iterator ait;
for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait )
@@ -1199,27 +1197,25 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
<< " " << std::flush);
while(cmsysProcess_WaitForData(cp, &data, &length, 0))
{
- if ( output )
+ for(int cc =0; cc < length; ++cc)
{
- for(int cc =0; cc < length; ++cc)
+ if(data[cc] == 0)
{
- if(data[cc] == 0)
- {
- data[cc] = '\n';
- }
+ data[cc] = '\n';
}
-
- output->append(data, length);
- while ( output->size() > (tick * tick_len) )
+ }
+ output.append(data, length);
+ while ( output.size() > (tick * tick_len) )
+ {
+ tick ++;
+ cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush);
+ if ( tick % tick_line_len == 0 && tick > 0 )
{
- tick ++;
- cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush);
- if ( tick % tick_line_len == 0 && tick > 0 )
- {
- cmCTestLog(this, HANDLER_OUTPUT, " Size: "
- << int((double(output->size()) / 1024.0) + 1) << "K" << std::endl
- << " " << std::flush);
- }
+ cmCTestLog(this, HANDLER_OUTPUT,
+ " Size: "
+ << int((double(output.size()) / 1024.0) + 1)
+ << "K" << std::endl
+ << " " << std::flush);
}
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, cmCTestLogWrite(data, length));
@@ -1229,7 +1225,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
}
}
cmCTestLog(this, OUTPUT, " Size of output: "
- << int(double(output->size()) / 1024.0) << "K" << std::endl);
+ << int(double(output.size()) / 1024.0) << "K" << std::endl);
cmsysProcess_WaitForExit(cp, 0);
@@ -1253,9 +1249,9 @@ int cmCTest::RunMakeCommand(const char* command, std::string* output,
}
else if(result == cmsysProcess_State_Error)
{
- *output += "\n*** ERROR executing: ";
- *output += cmsysProcess_GetErrorString(cp);
- *output += "\n***The build process failed.";
+ output += "\n*** ERROR executing: ";
+ output += cmsysProcess_GetErrorString(cp);
+ output += "\n***The build process failed.";
cmCTestLog(this, ERROR_MESSAGE, "There was an error: "
<< cmsysProcess_GetErrorString(cp) << std::endl);
}
@@ -1447,7 +1443,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
// Disallow non-filename and non-space whitespace characters.
// If they occur, replace them with ""
//
- const char *disallowed = "\\/:*?\"<>|\n\r\t\f\v";
+ const char *disallowed = "\\:*?\"<>|\n\r\t\f\v";
if (safevalue.find_first_of(disallowed) != value.npos)
{
@@ -1588,12 +1584,14 @@ void cmCTest::EndXML(std::ostream& ostr)
int cmCTest::GenerateCTestNotesOutput(std::ostream& os,
const cmCTest::VectorOfStrings& files)
{
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->GetCTestConfiguration("BuildName"));
cmCTest::VectorOfStrings::const_iterator it;
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<?xml-stylesheet type=\"text/xsl\" "
"href=\"Dart/Source/Server/XSL/Build.xsl "
"<file:///Dart/Source/Server/XSL/Build.xsl> \"?>\n"
- << "<Site BuildName=\"" << this->GetCTestConfiguration("BuildName")
+ << "<Site BuildName=\"" << buildname
<< "\" BuildStamp=\""
<< this->CurrentTag << "-" << this->GetTestModelString() << "\" Name=\""
<< this->GetCTestConfiguration("Site") << "\" Generator=\"ctest"
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 246294f..e19d32c 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -271,7 +271,7 @@ public:
//! Run command specialized for make and configure. Returns process status
// and retVal is return value or exception.
- int RunMakeCommand(const char* command, std::string* output,
+ int RunMakeCommand(const char* command, std::string& output,
int* retVal, const char* dir, int timeout,
std::ostream& ofs);
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 995f191..b13a125 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -166,18 +166,17 @@ guaranteed to be acyclic.
The final list of items produced by this procedure consists of the
original user link line followed by minimal additional items needed to
-satisfy dependencies.
+satisfy dependencies. The final list is then filtered to de-duplicate
+items that we know the linker will re-use automatically (shared libs).
*/
//----------------------------------------------------------------------------
cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget const* target, const std::string& config,
- cmTarget const* head)
+::cmComputeLinkDepends(cmTarget const* target, const std::string& config)
{
// Store context information.
this->Target = target;
- this->HeadTarget = head;
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = this->Makefile->GetLocalGenerator();
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -264,10 +263,20 @@ cmComputeLinkDepends::Compute()
this->OrderLinkEntires();
// Compute the final set of link entries.
+ std::set<int> emmitted;
for(std::vector<int>::const_iterator li = this->FinalLinkOrder.begin();
li != this->FinalLinkOrder.end(); ++li)
{
- this->FinalLinkEntries.push_back(this->EntryList[*li]);
+ int i = *li;
+ LinkEntry const& e = this->EntryList[i];
+ cmTarget const* t = e.Target;
+ // Entries that we know the linker will re-use for symbols
+ // needed by later entries do not need to be repeated.
+ bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY;
+ if(!uniquify || emmitted.insert(i).second)
+ {
+ this->FinalLinkEntries.push_back(e);
+ }
}
// Display the final set.
@@ -294,8 +303,7 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
}
//----------------------------------------------------------------------------
-int cmComputeLinkDepends::AddLinkEntry(int depender_index,
- std::string const& item)
+int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
{
// Check if the item entry has already been added.
std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item);
@@ -312,7 +320,7 @@ int cmComputeLinkDepends::AddLinkEntry(int depender_index,
int index = lei->second;
LinkEntry& entry = this->EntryList[index];
entry.Item = item;
- entry.Target = this->FindTargetToLink(depender_index, entry.Item);
+ entry.Target = item.Target;
entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
item.substr(0, 10) != "-framework");
@@ -356,7 +364,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
{
// Follow the target dependencies.
if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+ entry.Target->GetLinkInterface(this->Config, this->Target))
{
const bool isIface =
entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -372,11 +380,11 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
this->FollowSharedDeps(depender_index, iface);
// Support for CMP0003.
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
oi = iface->WrongConfigLibraries.begin();
oi != iface->WrongConfigLibraries.end(); ++oi)
{
- this->CheckWrongConfigItem(depender_index, *oi);
+ this->CheckWrongConfigItem(*oi);
}
}
}
@@ -408,9 +416,9 @@ cmComputeLinkDepends
void
cmComputeLinkDepends
::QueueSharedDependencies(int depender_index,
- std::vector<std::string> const& deps)
+ std::vector<cmLinkItem> const& deps)
{
- for(std::vector<std::string>::const_iterator li = deps.begin();
+ for(std::vector<cmLinkItem>::const_iterator li = deps.begin();
li != deps.end(); ++li)
{
SharedDepEntry qe;
@@ -434,8 +442,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Initialize the item entry.
LinkEntry& entry = this->EntryList[lei->second];
entry.Item = dep.Item;
- entry.Target = this->FindTargetToLink(dep.DependerIndex,
- dep.Item);
+ entry.Target = dep.Item.Target;
// This item was added specifically because it is a dependent
// shared library. It may get special treatment
@@ -455,7 +462,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
if(entry.Target)
{
if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+ entry.Target->GetLinkInterface(this->Config, this->Target))
{
// Follow public and private dependencies transitively.
this->FollowSharedDeps(index, iface, true);
@@ -474,7 +481,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
cmSystemTools::ExpandListArgument(value, deplist);
// Look for entries meant for this configuration.
- std::vector<std::string> actual_libs;
+ std::vector<cmLinkItem> actual_libs;
cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
bool haveLLT = false;
for(std::vector<std::string>::const_iterator di = deplist.begin();
@@ -522,11 +529,13 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
// If the library is meant for this link type then use it.
if(llt == cmTarget::GENERAL || llt == this->LinkType)
{
- actual_libs.push_back(*di);
+ cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+ actual_libs.push_back(item);
}
else if(this->OldLinkDirMode)
{
- this->CheckWrongConfigItem(depender_index, *di);
+ cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+ this->CheckWrongConfigItem(item);
}
// Reset the link type until another explicit type is given.
@@ -544,38 +553,39 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
cmTarget::LinkImplementation const* impl =
- this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
+ this->Target->GetLinkImplementation(this->Config);
this->AddLinkEntries(-1, impl->Libraries);
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
wi = impl->WrongConfigLibraries.begin();
wi != impl->WrongConfigLibraries.end(); ++wi)
{
- this->CheckWrongConfigItem(-1, *wi);
+ this->CheckWrongConfigItem(*wi);
}
}
//----------------------------------------------------------------------------
+template <typename T>
void
-cmComputeLinkDepends::AddLinkEntries(int depender_index,
- std::vector<std::string> const& libs)
+cmComputeLinkDepends::AddLinkEntries(
+ int depender_index, std::vector<T> const& libs)
{
// Track inferred dependency sets implied by this list.
std::map<int, DependSet> dependSets;
// Loop over the libraries linked directly by the depender.
- for(std::vector<std::string>::const_iterator li = libs.begin();
+ for(typename std::vector<T>::const_iterator li = libs.begin();
li != libs.end(); ++li)
{
// Skip entries that will resolve to the target getting linked or
// are empty.
- std::string item = this->Target->CheckCMP0004(*li);
+ cmLinkItem const& item = *li;
if(item == this->Target->GetName() || item.empty())
{
continue;
}
// Add a link entry for this item.
- int dependee_index = this->AddLinkEntry(depender_index, item);
+ int dependee_index = this->AddLinkEntry(*li);
// The dependee must come after the depender.
if(depender_index >= 0)
@@ -625,40 +635,15 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
const std::string& name)
{
// Look for a target in the scope of the depender.
- cmMakefile* mf = this->Makefile;
+ cmTarget const* from = this->Target;
if(depender_index >= 0)
{
if(cmTarget const* depender = this->EntryList[depender_index].Target)
{
- mf = depender->GetMakefile();
+ from = depender;
}
}
- cmTarget const* tgt = mf->FindTargetToUse(name);
-
- // Skip targets that will not really be linked. This is probably a
- // name conflict between an external library and an executable
- // within the project.
- if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
- !tgt->IsExecutableWithExports())
- {
- tgt = 0;
- }
-
- if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
- {
- cmOStringStream e;
- e << "Target \"" << this->Target->GetName() << "\" links to "
- "OBJECT library \"" << tgt->GetName() << "\" but this is not "
- "allowed. "
- "One may link only to STATIC or SHARED libraries, or to executables "
- "with the ENABLE_EXPORTS property set.";
- this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- tgt = 0;
- }
-
- // Return the target found, if any.
- return tgt;
+ return from->FindTargetToLink(name);
}
//----------------------------------------------------------------------------
@@ -955,7 +940,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
if(cmTarget const* target = this->EntryList[*ni].Target)
{
if(cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config, this->HeadTarget))
+ target->GetLinkInterface(this->Config, this->Target))
{
if(iface->Multiplicity > count)
{
@@ -988,8 +973,7 @@ void cmComputeLinkDepends::DisplayFinalEntries()
}
//----------------------------------------------------------------------------
-void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
- std::string const& item)
+void cmComputeLinkDepends::CheckWrongConfigItem(cmLinkItem const& item)
{
if(!this->OldLinkDirMode)
{
@@ -999,12 +983,8 @@ void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
// For CMake 2.4 bug-compatibility we need to consider the output
// directories of targets linked in another configuration as link
// directories.
- if(cmTarget const* tgt
- = this->FindTargetToLink(depender_index, item))
+ if(item.Target && !item.Target->IsImported())
{
- if(!tgt->IsImported())
- {
- this->OldWrongConfigItems.insert(tgt);
- }
+ this->OldWrongConfigItems.insert(item.Target);
}
}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 13fc993..a931726 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -32,8 +32,7 @@ class cmake;
class cmComputeLinkDepends
{
public:
- cmComputeLinkDepends(cmTarget const* target, const std::string& config,
- cmTarget const* head);
+ cmComputeLinkDepends(cmTarget const* target, const std::string& config);
~cmComputeLinkDepends();
// Basic information about each link item.
@@ -60,7 +59,6 @@ private:
// Context information.
cmTarget const* Target;
- cmTarget const* HeadTarget;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator const* GlobalGenerator;
@@ -79,11 +77,11 @@ private:
std::map<std::string, int>::iterator
AllocateLinkEntry(std::string const& item);
- int AddLinkEntry(int depender_index, std::string const& item);
+ int AddLinkEntry(cmLinkItem const& item);
void AddVarLinkEntries(int depender_index, const char* value);
void AddDirectLinkEntries();
- void AddLinkEntries(int depender_index,
- std::vector<std::string> const& libs);
+ template <typename T>
+ void AddLinkEntries(int depender_index, std::vector<T> const& libs);
cmTarget const* FindTargetToLink(int depender_index,
const std::string& name);
@@ -105,7 +103,7 @@ private:
// of the interface.
struct SharedDepEntry
{
- std::string Item;
+ cmLinkItem Item;
int DependerIndex;
};
std::queue<SharedDepEntry> SharedDepQueue;
@@ -114,7 +112,7 @@ private:
cmTarget::LinkInterface const* iface,
bool follow_interface = false);
void QueueSharedDependencies(int depender_index,
- std::vector<std::string> const& deps);
+ std::vector<cmLinkItem> const& deps);
void HandleSharedDependency(SharedDepEntry const& dep);
// Dependency inferral for each link item.
@@ -165,7 +163,7 @@ private:
// Compatibility help.
bool OldLinkDirMode;
- void CheckWrongConfigItem(int depender_index, std::string const& item);
+ void CheckWrongConfigItem(cmLinkItem const& item);
std::set<cmTarget const*> OldWrongConfigItems;
};
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index ea8536f..e1852a3 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -239,12 +239,10 @@ because this need be done only for shared libraries without soname-s.
//----------------------------------------------------------------------------
cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget const* target, const std::string& config,
- cmTarget const* headTarget)
+::cmComputeLinkInformation(cmTarget const* target, const std::string& config)
{
// Store context information.
this->Target = target;
- this->HeadTarget = headTarget;
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = this->Makefile->GetLocalGenerator();
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -267,7 +265,7 @@ cmComputeLinkInformation
this->OrderDependentRPath = 0;
// Get the language used for linking this target.
- this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
+ this->LinkLanguage = this->Target->GetLinkerLanguage(config);
if(this->LinkLanguage.empty())
{
// The Compute method will do nothing, so skip the rest of the
@@ -505,8 +503,7 @@ bool cmComputeLinkInformation::Compute()
}
// Compute the ordered link line items.
- cmComputeLinkDepends cld(this->Target, this->Config,
- this->HeadTarget);
+ cmComputeLinkDepends cld(this->Target, this->Config);
cld.SetOldLinkDirMode(this->OldLinkDirMode);
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
@@ -572,8 +569,7 @@ bool cmComputeLinkInformation::Compute()
void cmComputeLinkInformation::AddImplicitLinkInfo()
{
// The link closure lists all languages whose implicit info is needed.
- cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
- this->HeadTarget);
+ cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
@@ -1811,7 +1807,7 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
}
}
- is_shared_library = this->ExtractSharedLibraryName.find(file.c_str());
+ is_shared_library = this->ExtractSharedLibraryName.find(file);
if(!is_shared_library)
{
@@ -1831,8 +1827,8 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
{
if(fullPath.find(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(fullPath) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
@@ -1972,7 +1968,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// present. This is done even when skipping rpath support.
{
cmTarget::LinkClosure const* lc =
- this->Target->GetLinkClosure(this->Config, this->HeadTarget);
+ this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e345fe2..e5d674a 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -29,8 +29,7 @@ class cmOrderDirectories;
class cmComputeLinkInformation
{
public:
- cmComputeLinkInformation(cmTarget const* target, const std::string& config,
- cmTarget const* headTarget);
+ cmComputeLinkInformation(cmTarget const* target, const std::string& config);
~cmComputeLinkInformation();
bool Compute();
@@ -75,7 +74,6 @@ private:
// Context information.
cmTarget const* Target;
- cmTarget const* HeadTarget;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index f28217f..75d3967 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -249,20 +249,21 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
const_cast<cmTarget*>(depender)->AddUtility(objLib);
}
}
- std::vector<std::string> tlibs;
- depender->GetDirectLinkLibraries(*it, tlibs, depender);
+
+ cmTarget::LinkImplementation const* impl =
+ depender->GetLinkImplementation(*it);
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(std::vector<std::string>::const_iterator lib = tlibs.begin();
- lib != tlibs.end(); ++lib)
+ for(std::vector<cmLinkImplItem>::const_iterator
+ lib = impl->Libraries.begin();
+ lib != impl->Libraries.end(); ++lib)
{
// Don't emit the same library twice for this target.
if(emitted.insert(*lib).second)
{
this->AddTargetDepend(depender_index, *lib, true);
- this->AddInterfaceDepends(depender_index, *lib,
- true, emitted);
+ this->AddInterfaceDepends(depender_index, *lib, emitted);
}
}
}
@@ -270,11 +271,11 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Loop over all utility dependencies.
{
- std::set<std::string> const& tutils = depender->GetUtilities();
+ std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
std::set<std::string> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(std::set<std::string>::const_iterator util = tutils.begin();
+ for(std::set<cmLinkItem>::const_iterator util = tutils.begin();
util != tutils.end(); ++util)
{
// Don't emit the same utility twice for this target.
@@ -296,7 +297,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
if(cmTarget::LinkInterface const* iface =
dependee->GetLinkInterface(config, depender))
{
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
lib = iface->Libraries.begin();
lib != iface->Libraries.end(); ++lib)
{
@@ -304,8 +305,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
if(emitted.insert(*lib).second)
{
this->AddTargetDepend(depender_index, *lib, true);
- this->AddInterfaceDepends(depender_index, *lib,
- true, emitted);
+ this->AddInterfaceDepends(depender_index, *lib, emitted);
}
}
}
@@ -313,17 +313,15 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
- const std::string& dependee_name,
- bool linking,
+ cmLinkItem const& dependee_name,
std::set<std::string> &emitted)
{
cmTarget const* depender = this->Targets[depender_index];
- cmTarget const* dependee =
- depender->GetMakefile()->FindTargetToUse(dependee_name);
+ cmTarget const* dependee = dependee_name.Target;
// Skip targets that will not really be linked. This is probably a
// name conflict between an external library and an executable
// within the project.
- if(linking && dependee &&
+ if(dependee &&
dependee->GetType() == cmTarget::EXECUTABLE &&
!dependee->IsExecutableWithExports())
{
@@ -347,16 +345,15 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
}
//----------------------------------------------------------------------------
-void cmComputeTargetDepends::AddTargetDepend(int depender_index,
- const std::string& dependee_name,
- bool linking)
+void cmComputeTargetDepends::AddTargetDepend(
+ int depender_index, cmLinkItem const& dependee_name,
+ bool linking)
{
// Get the depender.
cmTarget const* depender = this->Targets[depender_index];
// Check the target's makefile first.
- cmTarget const* dependee =
- depender->GetMakefile()->FindTargetToUse(dependee_name);
+ cmTarget const* dependee = dependee_name.Target;
if(!dependee && !linking &&
(depender->GetType() != cmTarget::GLOBAL_TARGET))
@@ -424,12 +421,11 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
if(dependee->IsImported())
{
// Skip imported targets but follow their utility dependencies.
- std::set<std::string> const& utils = dependee->GetUtilities();
- for(std::set<std::string>::const_iterator i = utils.begin();
+ std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
+ for(std::set<cmLinkItem>::const_iterator i = utils.begin();
i != utils.end(); ++i)
{
- if(cmTarget const* transitive_dependee =
- dependee->GetMakefile()->FindTargetToUse(*i))
+ if(cmTarget const* transitive_dependee = i->Target)
{
this->AddTargetDepend(depender_index, transitive_dependee, false);
}
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 7553816..902f342 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -20,6 +20,7 @@
class cmComputeComponentGraph;
class cmGlobalGenerator;
+class cmLinkItem;
class cmTarget;
class cmTargetDependSet;
@@ -46,14 +47,14 @@ private:
void CollectDepends();
void CollectTargetDepends(int depender_index);
void AddTargetDepend(int depender_index,
- const std::string& dependee_name,
+ cmLinkItem const& dependee_name,
bool linking);
void AddTargetDepend(int depender_index, cmTarget const* dependee,
bool linking);
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
void AddInterfaceDepends(int depender_index,
- const std::string& dependee_name,
- bool linking, std::set<std::string> &emitted);
+ cmLinkItem const& dependee_name,
+ std::set<std::string> &emitted);
void AddInterfaceDepends(int depender_index, cmTarget const* dependee,
const std::string& config,
std::set<std::string> &emitted);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
new file mode 100644
index 0000000..aba26de
--- /dev/null
+++ b/Source/cmConditionEvaluator.cxx
@@ -0,0 +1,770 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmConditionEvaluator.h"
+
+cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
+ Makefile(makefile),
+ Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
+ Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054))
+{
+
+}
+
+//=========================================================================
+// order of operations,
+// 1. ( ) -- parenthetical groups
+// 2. IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
+// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
+// 4. NOT
+// 5. AND OR
+//
+// There is an issue on whether the arguments should be values of references,
+// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
+// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
+// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
+// take numeric values or variable names. STRLESS and STRGREATER take
+// variable names but if the variable name is not found it will use the name
+// directly. AND OR take variables or the values 0 or 1.
+
+bool cmConditionEvaluator::IsTrue(
+ const std::vector<cmExpandedCommandArgument> &args,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ errorString = "";
+
+ // handle empty invocation
+ if (args.size() < 1)
+ {
+ return false;
+ }
+
+ // store the reduced args in this vector
+ cmArgumentList newArgs;
+
+ // copy to the list structure
+ for(unsigned int i = 0; i < args.size(); ++i)
+ {
+ newArgs.push_back(args[i]);
+ }
+
+ // now loop through the arguments and see if we can reduce any of them
+ // we do this multiple times. Once for each level of precedence
+ // parens
+ if (!this->HandleLevel0(newArgs, errorString, status))
+ {
+ return false;
+ }
+ //predicates
+ if (!this->HandleLevel1(newArgs, errorString, status))
+ {
+ return false;
+ }
+ // binary ops
+ if (!this->HandleLevel2(newArgs, errorString, status))
+ {
+ return false;
+ }
+
+ // NOT
+ if (!this->HandleLevel3(newArgs, errorString, status))
+ {
+ return false;
+ }
+ // AND OR
+ if (!this->HandleLevel4(newArgs, errorString, status))
+ {
+ return false;
+ }
+
+ // now at the end there should only be one argument left
+ if (newArgs.size() != 1)
+ {
+ errorString = "Unknown arguments specified";
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+
+ return this->GetBooleanValueWithAutoDereference(*(newArgs.begin()),
+ errorString, status, true);
+}
+
+//=========================================================================
+const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
+ cmExpandedCommandArgument const& argument) const
+{
+ if((this->Policy54Status != cmPolicies::WARN &&
+ this->Policy54Status != cmPolicies::OLD) &&
+ argument.WasQuoted())
+ {
+ return 0;
+ }
+
+ const char* def = this->Makefile.GetDefinition(argument.GetValue());
+
+ if(def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN)
+ {
+ bool hasBeenReported = this->Makefile.HasCMP0054AlreadyBeenReported(
+ this->Makefile.GetBacktrace()[0]);
+
+ if(!hasBeenReported)
+ {
+ cmOStringStream e;
+ e << (this->Makefile.GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0054)) << "\n";
+ e << "Quoted variables like \"" << argument.GetValue() <<
+ "\" will no longer be dereferenced "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ }
+
+ return def;
+}
+
+//=========================================================================
+const char* cmConditionEvaluator::GetVariableOrString(
+ const cmExpandedCommandArgument& argument) const
+{
+ const char* def = this->GetDefinitionIfUnquoted(argument);
+
+ if(!def)
+ {
+ def = argument.c_str();
+ }
+
+ return def;
+}
+
+//=========================================================================
+bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
+ cmExpandedCommandArgument& argument) const
+{
+ if((this->Policy54Status != cmPolicies::WARN &&
+ this->Policy54Status != cmPolicies::OLD) &&
+ argument.WasQuoted())
+ {
+ return false;
+ }
+
+ bool isKeyword = argument.GetValue() == keyword;
+
+ if(isKeyword && argument.WasQuoted() &&
+ this->Policy54Status == cmPolicies::WARN)
+ {
+ bool hasBeenReported = this->Makefile.HasCMP0054AlreadyBeenReported(
+ this->Makefile.GetBacktrace()[0]);
+
+ if(!hasBeenReported)
+ {
+ cmOStringStream e;
+ e << (this->Makefile.GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0054)) << "\n";
+ e << "Quoted keywords like \"" << argument.GetValue() <<
+ "\" will no longer be interpreted as keywords "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ }
+
+ return isKeyword;
+}
+
+//=========================================================================
+bool cmConditionEvaluator::GetBooleanValue(
+ cmExpandedCommandArgument& arg) const
+{
+ // Check basic constants.
+ if (arg == "0")
+ {
+ return false;
+ }
+ if (arg == "1")
+ {
+ return true;
+ }
+
+ // Check named constants.
+ if (cmSystemTools::IsOn(arg.c_str()))
+ {
+ return true;
+ }
+ if (cmSystemTools::IsOff(arg.c_str()))
+ {
+ return false;
+ }
+
+ // Check for numbers.
+ if(!arg.empty())
+ {
+ char* end;
+ double d = strtod(arg.c_str(), &end);
+ if(*end == '\0')
+ {
+ // The whole string is a number. Use C conversion to bool.
+ return d? true:false;
+ }
+ }
+
+ // Check definition.
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ return !cmSystemTools::IsOff(def);
+}
+
+//=========================================================================
+// Boolean value behavior from CMake 2.6.4 and below.
+bool cmConditionEvaluator::GetBooleanValueOld(
+ cmExpandedCommandArgument const& arg, bool one) const
+{
+ if(one)
+ {
+ // Old IsTrue behavior for single argument.
+ if(arg == "0")
+ { return false; }
+ else if(arg == "1")
+ { return true; }
+ else
+ {
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ return !cmSystemTools::IsOff(def);
+ }
+ }
+ else
+ {
+ // Old GetVariableOrNumber behavior.
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ if(!def && atoi(arg.c_str()))
+ {
+ def = arg.c_str();
+ }
+ return !cmSystemTools::IsOff(def);
+ }
+}
+
+//=========================================================================
+// returns the resulting boolean value
+bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
+ cmExpandedCommandArgument &newArg,
+ std::string &errorString,
+ cmake::MessageType &status,
+ bool oneArg) const
+{
+ // Use the policy if it is set.
+ if (this->Policy12Status == cmPolicies::NEW)
+ {
+ return GetBooleanValue(newArg);
+ }
+ else if (this->Policy12Status == cmPolicies::OLD)
+ {
+ return GetBooleanValueOld(newArg, oneArg);
+ }
+
+ // Check policy only if old and new results differ.
+ bool newResult = this->GetBooleanValue(newArg);
+ bool oldResult = this->GetBooleanValueOld(newArg, oneArg);
+ if(newResult != oldResult)
+ {
+ switch(this->Policy12Status)
+ {
+ case cmPolicies::WARN:
+ {
+ cmPolicies* policies = this->Makefile.GetPolicies();
+ errorString = "An argument named \"" + newArg.GetValue()
+ + "\" appears in a conditional statement. "
+ + policies->GetPolicyWarning(cmPolicies::CMP0012);
+ status = cmake::AUTHOR_WARNING;
+ }
+ case cmPolicies::OLD:
+ return oldResult;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmPolicies* policies = this->Makefile.GetPolicies();
+ errorString = "An argument named \"" + newArg.GetValue()
+ + "\" appears in a conditional statement. "
+ + policies->GetRequiredPolicyError(cmPolicies::CMP0012);
+ status = cmake::FATAL_ERROR;
+ }
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ return newResult;
+}
+
+//=========================================================================
+void cmConditionEvaluator::IncrementArguments(cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const
+{
+ if (argP1 != newArgs.end())
+ {
+ argP1++;
+ argP2 = argP1;
+ if (argP1 != newArgs.end())
+ {
+ argP2++;
+ }
+ }
+}
+
+//=========================================================================
+// helper function to reduce code duplication
+void cmConditionEvaluator::HandlePredicate(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const
+{
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+}
+
+//=========================================================================
+// helper function to reduce code duplication
+void cmConditionEvaluator::HandleBinaryOp(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2)
+{
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP2);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+}
+
+//=========================================================================
+// level 0 processes parenthetical expressions
+bool cmConditionEvaluator::HandleLevel0(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ while (arg != newArgs.end())
+ {
+ if (IsKeyword("(", *arg))
+ {
+ // search for the closing paren for this opening one
+ cmArgumentList::iterator argClose;
+ argClose = arg;
+ argClose++;
+ unsigned int depth = 1;
+ while (argClose != newArgs.end() && depth)
+ {
+ if (this->IsKeyword("(", *argClose))
+ {
+ depth++;
+ }
+ if (this->IsKeyword(")", *argClose))
+ {
+ depth--;
+ }
+ argClose++;
+ }
+ if (depth)
+ {
+ errorString = "mismatched parenthesis in condition";
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+ // store the reduced args in this vector
+ std::vector<cmExpandedCommandArgument> newArgs2;
+
+ // copy to the list structure
+ cmArgumentList::iterator argP1 = arg;
+ argP1++;
+ for(; argP1 != argClose; argP1++)
+ {
+ newArgs2.push_back(*argP1);
+ }
+ newArgs2.pop_back();
+ // now recursively invoke IsTrue to handle the values inside the
+ // parenthetical expression
+ bool value =
+ this->IsTrue(newArgs2, errorString, status);
+ if(value)
+ {
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ argP1 = arg;
+ argP1++;
+ // remove the now evaluated parenthetical expression
+ newArgs.erase(argP1,argClose);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level one handles most predicates except for NOT
+bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
+ std::string &, cmake::MessageType &)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ // does a file exist
+ if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileExists(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a directory with this name exist
+ if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsDirectory(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a symlink with this name exist
+ if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsSymlink(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // is the given path an absolute path ?
+ if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ cmSystemTools::FileIsFullPath(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a command exist
+ if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ this->Makefile.CommandExists(argP1->c_str()),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a policy exist
+ if (this->IsKeyword("POLICY", *arg) && argP1 != newArgs.end())
+ {
+ cmPolicies::PolicyID pid;
+ this->HandlePredicate(
+ this->Makefile.GetPolicies()->GetPolicyID(
+ argP1->c_str(), pid),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // does a target exist
+ if (this->IsKeyword("TARGET", *arg) && argP1 != newArgs.end())
+ {
+ this->HandlePredicate(
+ this->Makefile.FindTargetToUse(argP1->GetValue())?true:false,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ // is a variable defined
+ if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
+ {
+ size_t argP1len = argP1->GetValue().size();
+ bool bdef = false;
+ if(argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+ argP1->GetValue().operator[](argP1len-1) == '}')
+ {
+ std::string env = argP1->GetValue().substr(4, argP1len-5);
+ bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
+ }
+ else
+ {
+ bdef = this->Makefile.IsDefinitionSet(argP1->GetValue());
+ }
+ this->HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level two handles most binary operations except for AND OR
+bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ const char *def;
+ const char *def2;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ IsKeyword("MATCHES", *argP1))
+ {
+ def = this->GetVariableOrString(*arg);
+ const char* rex = argP2->c_str();
+ this->Makefile.ClearMatches();
+ cmsys::RegularExpression regEntry;
+ if ( !regEntry.compile(rex) )
+ {
+ cmOStringStream error;
+ error << "Regular expression \"" << rex << "\" cannot compile";
+ errorString = error.str();
+ status = cmake::FATAL_ERROR;
+ return false;
+ }
+ if (regEntry.find(def))
+ {
+ this->Makefile.StoreMatches(regEntry);
+ *arg = cmExpandedCommandArgument("1", true);
+ }
+ else
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ }
+ newArgs.erase(argP2);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+ }
+
+ if (argP1 != newArgs.end() && this->IsKeyword("MATCHES", *arg))
+ {
+ *arg = cmExpandedCommandArgument("0", true);
+ newArgs.erase(argP1);
+ argP1 = arg;
+ this->IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("LESS", *argP1) ||
+ this->IsKeyword("GREATER", *argP1) ||
+ this->IsKeyword("EQUAL", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ double lhs;
+ double rhs;
+ bool result;
+ if(sscanf(def, "%lg", &lhs) != 1 ||
+ sscanf(def2, "%lg", &rhs) != 1)
+ {
+ result = false;
+ }
+ else if (*(argP1) == "LESS")
+ {
+ result = (lhs < rhs);
+ }
+ else if (*(argP1) == "GREATER")
+ {
+ result = (lhs > rhs);
+ }
+ else
+ {
+ result = (lhs == rhs);
+ }
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("STRLESS", *argP1) ||
+ this->IsKeyword("STREQUAL", *argP1) ||
+ this->IsKeyword("STRGREATER", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ int val = strcmp(def,def2);
+ bool result;
+ if (*(argP1) == "STRLESS")
+ {
+ result = (val < 0);
+ }
+ else if (*(argP1) == "STRGREATER")
+ {
+ result = (val > 0);
+ }
+ else // strequal
+ {
+ result = (val == 0);
+ }
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ (this->IsKeyword("VERSION_LESS", *argP1) ||
+ this->IsKeyword("VERSION_GREATER", *argP1) ||
+ this->IsKeyword("VERSION_EQUAL", *argP1)))
+ {
+ def = this->GetVariableOrString(*arg);
+ def2 = this->GetVariableOrString(*argP2);
+ cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL;
+ if(*argP1 == "VERSION_LESS")
+ {
+ op = cmSystemTools::OP_LESS;
+ }
+ else if(*argP1 == "VERSION_GREATER")
+ {
+ op = cmSystemTools::OP_GREATER;
+ }
+ bool result = cmSystemTools::VersionCompare(op, def, def2);
+ this->HandleBinaryOp(result,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ // is file A newer than file B
+ if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
+ this->IsKeyword("IS_NEWER_THAN", *argP1))
+ {
+ int fileIsNewer=0;
+ bool success=cmSystemTools::FileTimeCompare(arg->GetValue(),
+ (argP2)->GetValue(),
+ &fileIsNewer);
+ this->HandleBinaryOp(
+ (success==false || fileIsNewer==1 || fileIsNewer==0),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level 3 handles NOT
+bool cmConditionEvaluator::HandleLevel3(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && IsKeyword("NOT", *arg))
+ {
+ bool rhs = this->GetBooleanValueWithAutoDereference(*argP1,
+ errorString,
+ status);
+ this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
+
+//=========================================================================
+// level 4 handles AND OR
+bool cmConditionEvaluator::HandleLevel4(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status)
+{
+ int reducible;
+ bool lhs;
+ bool rhs;
+ do
+ {
+ reducible = 0;
+ cmArgumentList::iterator arg = newArgs.begin();
+ cmArgumentList::iterator argP1;
+ cmArgumentList::iterator argP2;
+ while (arg != newArgs.end())
+ {
+ argP1 = arg;
+ IncrementArguments(newArgs,argP1,argP2);
+ if (argP1 != newArgs.end() && IsKeyword("AND", *argP1) &&
+ argP2 != newArgs.end())
+ {
+ lhs = this->GetBooleanValueWithAutoDereference(*arg,
+ errorString,
+ status);
+ rhs = this->GetBooleanValueWithAutoDereference(*argP2,
+ errorString,
+ status);
+ this->HandleBinaryOp((lhs && rhs),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+
+ if (argP1 != newArgs.end() && this->IsKeyword("OR", *argP1) &&
+ argP2 != newArgs.end())
+ {
+ lhs = this->GetBooleanValueWithAutoDereference(*arg,
+ errorString,
+ status);
+ rhs = this->GetBooleanValueWithAutoDereference(*argP2,
+ errorString,
+ status);
+ this->HandleBinaryOp((lhs || rhs),
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ ++arg;
+ }
+ }
+ while (reducible);
+ return true;
+}
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
new file mode 100644
index 0000000..01624f9
--- /dev/null
+++ b/Source/cmConditionEvaluator.h
@@ -0,0 +1,96 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmConditionEvaluator_h
+#define cmConditionEvaluator_h
+
+#include "cmCommand.h"
+#include "cmExpandedCommandArgument.h"
+
+class cmConditionEvaluator
+{
+public:
+ typedef std::list<cmExpandedCommandArgument> cmArgumentList;
+
+ cmConditionEvaluator(cmMakefile& makefile);
+
+ // this is a shared function for both If and Else to determine if the
+ // arguments were valid, and if so, was the response true. If there is
+ // an error, the errorString will be set.
+ bool IsTrue(const std::vector<cmExpandedCommandArgument> &args,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+private:
+ // Filter the given variable definition based on policy CMP0054.
+ const char* GetDefinitionIfUnquoted(
+ const cmExpandedCommandArgument& argument) const;
+
+ const char* GetVariableOrString(
+ const cmExpandedCommandArgument& argument) const;
+
+ bool IsKeyword(std::string const& keyword,
+ cmExpandedCommandArgument& argument) const;
+
+ bool GetBooleanValue(
+ cmExpandedCommandArgument& arg) const;
+
+ bool GetBooleanValueOld(
+ cmExpandedCommandArgument const& arg, bool one) const;
+
+ bool GetBooleanValueWithAutoDereference(
+ cmExpandedCommandArgument &newArg,
+ std::string &errorString,
+ cmake::MessageType &status,
+ bool oneArg = false) const;
+
+ void IncrementArguments(
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const;
+
+ void HandlePredicate(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2) const;
+
+ void HandleBinaryOp(bool value, int &reducible,
+ cmArgumentList::iterator &arg,
+ cmArgumentList &newArgs,
+ cmArgumentList::iterator &argP1,
+ cmArgumentList::iterator &argP2);
+
+ bool HandleLevel0(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel1(cmArgumentList &newArgs,
+ std::string &, cmake::MessageType &);
+
+ bool HandleLevel2(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel3(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ bool HandleLevel4(cmArgumentList &newArgs,
+ std::string &errorString,
+ cmake::MessageType &status);
+
+ cmMakefile& Makefile;
+ cmPolicies::PolicyStatus Policy12Status;
+ cmPolicies::PolicyStatus Policy54Status;
+};
+
+#endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index a3f3277..bc5708d 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -489,7 +489,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
targetName,
this->SrcFileSignature,
&cmakeFlags,
- &output);
+ output);
if ( erroroc )
{
cmSystemTools::SetErrorOccured();
@@ -634,6 +634,10 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName)
searchDirs.push_back(tmp);
}
searchDirs.push_back("/Debug");
+#if defined(__APPLE__)
+ std::string app = "/Debug/" + targetName + ".app";
+ searchDirs.push_back(app);
+#endif
searchDirs.push_back("/Development");
for(std::vector<std::string>::const_iterator it = searchDirs.begin();
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index babf1c4..fe32dd5 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -15,7 +15,8 @@
cmDefinitions::Def cmDefinitions::NoDef;
//----------------------------------------------------------------------------
-cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
+cmDefinitions::cmDefinitions(cmDefinitions* parent)
+ : Up(parent)
{
}
@@ -35,7 +36,7 @@ cmDefinitions::GetInternal(const std::string& key)
{
return i->second;
}
- else if(cmDefinitions* up = this->Up)
+ if(cmDefinitions* up = this->Up)
{
// Query the parent scope and store the result locally.
Def def = up->GetInternal(key);
@@ -51,16 +52,7 @@ cmDefinitions::SetInternal(const std::string& key, Def const& def)
if(this->Up || def.Exists)
{
// In lower scopes we store keys, defined or not.
- MapType::iterator i = this->Map.find(key);
- if(i == this->Map.end())
- {
- i = this->Map.insert(MapType::value_type(key, def)).first;
- }
- else
- {
- i->second = def;
- }
- return i->second;
+ return (this->Map[key] = def);
}
else
{
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index d615fb0..a2f053f 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -13,6 +13,9 @@
#define cmDefinitions_h
#include "cmStandardIncludes.h"
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cmsys/hash_map.hxx"
+#endif
/** \class cmDefinitions
* \brief Store a scope of variable definitions for CMake language.
@@ -69,7 +72,11 @@ private:
cmDefinitions* Up;
// Local definitions, set or unset.
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ typedef cmsys::hash_map<std::string, Def> MapType;
+#else
typedef std::map<std::string, Def> MapType;
+#endif
MapType Map;
// Internal query and update methods.
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 50a395e..134f45b 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -58,12 +58,7 @@ bool cmDepends::Write(std::ostream &makeDepends,
// Get the source and object file.
std::string const& src = *si++;
if(si == pairs.end()) { break; }
- std::string obj = *si++;
-
- // Make sure the object file is relative to the top of the build tree.
- obj = this->LocalGenerator->Convert(obj,
- cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ std::string const& obj = *si++;
dependencies[obj].insert(src);
}
for(std::map<std::string, std::set<std::string> >::const_iterator
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index d26d3a9..a1fc268 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -269,14 +269,20 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- internalDepends << obj << std::endl;
+ std::string obj_i =
+ this->LocalGenerator->Convert(obj, cmLocalGenerator::HOME_OUTPUT);
+ std::string obj_m =
+ this->LocalGenerator->ConvertToOutputFormat(obj_i,
+ cmLocalGenerator::MAKERULE);
+ internalDepends << obj_i << std::endl;
+
for(std::set<std::string>::const_iterator i=dependencies.begin();
i != dependencies.end(); ++i)
{
- makeDepends << obj << ": " <<
+ makeDepends << obj_m << ": " <<
this->LocalGenerator->Convert(*i,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< std::endl;
internalDepends << " " << *i << std::endl;
}
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 79cb560..8fc8347 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -443,15 +443,20 @@ cmDependsFortran
const char* src = info.Source.c_str();
// Write the include dependencies to the output stream.
- internalDepends << obj << std::endl;
+ std::string obj_i =
+ this->LocalGenerator->Convert(obj, cmLocalGenerator::HOME_OUTPUT);
+ std::string obj_m =
+ this->LocalGenerator->ConvertToOutputFormat(obj_i,
+ cmLocalGenerator::MAKERULE);
+ internalDepends << obj_i << std::endl;
internalDepends << " " << src << std::endl;
for(std::set<std::string>::const_iterator i = info.Includes.begin();
i != info.Includes.end(); ++i)
{
- makeDepends << obj << ": " <<
+ makeDepends << obj_m << ": " <<
this->LocalGenerator->Convert(*i,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< std::endl;
internalDepends << " " << *i << std::endl;
}
@@ -482,10 +487,10 @@ cmDependsFortran
proxy += ".mod.proxy";
proxy = this->LocalGenerator->Convert(proxy,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ cmLocalGenerator::MAKERULE);
// since we require some things add them to our list of requirements
- makeDepends << obj << ".requires: " << proxy << std::endl;
+ makeDepends << obj_m << ".requires: " << proxy << std::endl;
}
// The object file should depend on timestamped files for the
@@ -499,8 +504,8 @@ cmDependsFortran
std::string stampFile =
this->LocalGenerator->Convert(required->second,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << obj << ": " << stampFile << "\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << obj_m << ": " << stampFile << "\n";
}
else
{
@@ -512,8 +517,8 @@ cmDependsFortran
module =
this->LocalGenerator->Convert(module,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << obj << ": " << module << "\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << obj_m << ": " << module << "\n";
}
}
}
@@ -528,8 +533,8 @@ cmDependsFortran
proxy += ".mod.proxy";
proxy = this->LocalGenerator->Convert(proxy,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << proxy << ": " << obj << ".provides" << std::endl;
+ cmLocalGenerator::MAKERULE);
+ makeDepends << proxy << ": " << obj_m << ".provides" << std::endl;
}
// If any modules are provided then they must be converted to stamp files.
@@ -537,7 +542,7 @@ cmDependsFortran
{
// Create a target to copy the module after the object file
// changes.
- makeDepends << obj << ".provides.build:\n";
+ makeDepends << obj_m << ".provides.build:\n";
for(std::set<std::string>::const_iterator i = info.Provides.begin();
i != info.Provides.end(); ++i)
{
@@ -575,7 +580,7 @@ cmDependsFortran
}
// After copying the modules update the timestamp file so that
// copying will not be done again until the source rebuilds.
- makeDepends << "\t$(CMAKE_COMMAND) -E touch " << obj
+ makeDepends << "\t$(CMAKE_COMMAND) -E touch " << obj_m
<< ".provides.build\n";
// Make sure the module timestamp rule is evaluated by the time
@@ -584,8 +589,8 @@ cmDependsFortran
driver += "/build";
driver = this->LocalGenerator->Convert(driver,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
- makeDepends << driver << ": " << obj << ".provides.build\n";
+ cmLocalGenerator::MAKERULE);
+ makeDepends << driver << ": " << obj_m << ".provides.build\n";
}
return true;
@@ -765,7 +770,11 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char* compilerId)
{
/*
- gnu:
+ gnu >= 4.9:
+ A mod file is an ascii file compressed with gzip.
+ Compiling twice produces identical modules.
+
+ gnu < 4.9:
A mod file is an ascii file.
<bar.mod>
FORTRAN module created from /path/to/foo.f90 on Sun Dec 30 22:47:58 2007
@@ -821,21 +830,30 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
*/
if (strcmp(compilerId, "GNU") == 0 )
{
- const char seq[1] = {'\n'};
- const int seqlen = 1;
-
- if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ // GNU Fortran 4.9 and later compress .mod files with gzip
+ // but also do not include a date so we can fall through to
+ // compare them without skipping any prefix.
+ unsigned char hdr[2];
+ bool okay = finModFile.read(reinterpret_cast<char*>(hdr), 2)? true:false;
+ finModFile.seekg(0);
+ if(!(okay && hdr[0] == 0x1f && hdr[1] == 0x8b))
{
- // The module is of unexpected format. Assume it is different.
- std::cerr << compilerId << " fortran module " << modFile
- << " has unexpected format." << std::endl;
- return true;
- }
+ const char seq[1] = {'\n'};
+ const int seqlen = 1;
- if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
- {
- // The stamp must differ if the sequence is not contained.
- return true;
+ if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ {
+ // The module is of unexpected format. Assume it is different.
+ std::cerr << compilerId << " fortran module " << modFile
+ << " has unexpected format." << std::endl;
+ return true;
+ }
+
+ if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ {
+ // The stamp must differ if the sequence is not contained.
+ return true;
+ }
}
}
else if(strcmp(compilerId, "Intel") == 0)
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 8d035af..3ff1017 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -113,7 +113,9 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
switch (ht)
{
case cmDocumentation::Usage:
- return this->PrintDocumentationUsage(os);
+ return this->PrintUsage(os);
+ case cmDocumentation::Help:
+ return this->PrintHelp(os);
case cmDocumentation::Full:
return this->PrintHelpFull(os);
case cmDocumentation::OneManual:
@@ -300,7 +302,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
(strcmp(argv[i], "-h") == 0) ||
(strcmp(argv[i], "-H") == 0))
{
- help.HelpType = cmDocumentation::Usage;
+ help.HelpType = cmDocumentation::Help;
GET_OPT_ARGUMENT(help.Argument);
help.Argument = cmSystemTools::LowerCase(help.Argument);
// special case for single command
@@ -841,7 +843,19 @@ bool cmDocumentation::PrintHelpListVariables(std::ostream& os)
}
//----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
+bool cmDocumentation::PrintUsage(std::ostream& os)
+{
+ std::map<std::string,cmDocumentationSection*>::iterator si;
+ si = this->AllSections.find("Usage");
+ if(si != this->AllSections.end())
+ {
+ this->Formatter.PrintSection(os, *si->second);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintHelp(std::ostream& os)
{
std::map<std::string,cmDocumentationSection*>::iterator si;
si = this->AllSections.find("Usage");
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index c98e48e..b72b5fe 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -102,6 +102,8 @@ private:
bool PrintFiles(std::ostream& os, std::string const& pattern);
bool PrintVersion(std::ostream& os);
+ bool PrintUsage(std::ostream& os);
+ bool PrintHelp(std::ostream& os);
bool PrintHelpFull(std::ostream& os);
bool PrintHelpOneManual(std::ostream& os);
bool PrintHelpOneCommand(std::ostream& os);
@@ -115,7 +117,6 @@ private:
bool PrintHelpListProperties(std::ostream& os);
bool PrintHelpListVariables(std::ostream& os);
bool PrintHelpListPolicies(std::ostream& os);
- bool PrintDocumentationUsage(std::ostream& os);
bool PrintOldCustomModules(std::ostream& os);
const char* GetNameString() const;
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index 61766b9..59513cc 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -26,7 +26,7 @@ public:
/** Types of help provided. */
enum Type
{
- None, Version, Usage, Full, ListManuals,
+ None, Version, Usage, Help, Full, ListManuals,
ListCommands, ListModules, ListProperties, ListVariables, ListPolicies,
OneManual, OneCommand, OneModule, OneProperty, OneVariable, OnePolicy,
OldCustomModules
diff --git a/Source/cmExpandedCommandArgument.cxx b/Source/cmExpandedCommandArgument.cxx
new file mode 100644
index 0000000..4477cf5
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.cxx
@@ -0,0 +1,51 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmExpandedCommandArgument.h"
+
+cmExpandedCommandArgument::cmExpandedCommandArgument():
+ Quoted(false)
+{
+
+}
+
+cmExpandedCommandArgument::cmExpandedCommandArgument(
+ std::string const& value, bool quoted):
+ Value(value), Quoted(quoted)
+{
+
+}
+
+std::string const& cmExpandedCommandArgument::GetValue() const
+{
+ return this->Value;
+}
+
+bool cmExpandedCommandArgument::WasQuoted() const
+{
+ return this->Quoted;
+}
+
+bool cmExpandedCommandArgument::operator== (std::string const& value) const
+{
+ return this->Value == value;
+}
+
+bool cmExpandedCommandArgument::empty() const
+{
+ return this->Value.empty();
+}
+
+const char* cmExpandedCommandArgument::c_str() const
+{
+ return this->Value.c_str();
+}
diff --git a/Source/cmExpandedCommandArgument.h b/Source/cmExpandedCommandArgument.h
new file mode 100644
index 0000000..f4e1517
--- /dev/null
+++ b/Source/cmExpandedCommandArgument.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExpandedCommandArgument_h
+#define cmExpandedCommandArgument_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmExpandedCommandArgument
+ * \brief Represents an expanded command argument
+ *
+ * cmCommandArgument stores a string representing an expanded
+ * command argument and context information.
+ */
+
+class cmExpandedCommandArgument
+{
+public:
+ cmExpandedCommandArgument();
+ cmExpandedCommandArgument(std::string const& value, bool quoted);
+
+ std::string const& GetValue() const;
+
+ bool WasQuoted() const;
+
+ bool operator== (std::string const& value) const;
+
+ bool empty() const;
+
+ const char* c_str() const;
+
+private:
+ std::string Value;
+ bool Quoted;
+};
+
+#endif
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 9f5eee5..1f39d7a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -865,15 +865,16 @@ cmExportFileGenerator
}
//----------------------------------------------------------------------------
+template <typename T>
void
cmExportFileGenerator
::SetImportLinkProperty(std::string const& suffix,
cmTarget* target,
const std::string& propName,
- std::vector<std::string> const& entries,
+ std::vector<T> const& entries,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets
- )
+ )
{
// Skip the property if there are no entries.
if(entries.empty())
@@ -884,7 +885,7 @@ cmExportFileGenerator
// Construct the property value.
std::string link_entries;
const char* sep = "";
- for(std::vector<std::string>::const_iterator li = entries.begin();
+ for(typename std::vector<T>::const_iterator li = entries.begin();
li != entries.end(); ++li)
{
// Separate this from the previous entry.
@@ -902,7 +903,6 @@ cmExportFileGenerator
properties[prop] = link_entries;
}
-
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
const std::string& config)
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index abd8ad5..919924e 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -95,9 +95,11 @@ protected:
std::string const& suffix, cmTarget* target,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
+
+ template <typename T>
void SetImportLinkProperty(std::string const& suffix,
cmTarget* target, const std::string& propName,
- std::vector<std::string> const& entries,
+ std::vector<T> const& entries,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 688d2eb..cb150a7 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -108,14 +108,12 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
std::string targetEntry = target.GetName();
targetEntry += "_LIB_DEPENDS";
- // Construct the dependency variable value. It is safe to use
- // the target GetLinkLibraries method here because this code is
- // called at the end of configure but before generate so library
- // dependencies have yet to be analyzed. Therefore the value
- // will be the direct link dependencies.
+ // Construct the dependency variable value with the direct link
+ // dependencies.
std::string valueOld;
std::string valueNew;
- cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
+ cmTarget::LinkLibraryVectorType const& libs =
+ target.GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
li != libs.end(); ++li)
{
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 6f76dc4..56a6edb 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -574,7 +574,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
}
}
- const char* buildType = makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string buildType = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::string location;
if ( target->GetType()==cmTarget::OBJECT_LIBRARY)
{
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index e23551e..1beb3fd 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -968,7 +968,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
continue;
}
std::vector<std::string> includeDirs;
- const char *config = mf->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
(*it)->GetIncludeDirectories(includeDirs, l->second, "C", config);
this->AppendIncludeDirectories(fout, includeDirs, emmited);
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 655f3ba..1325cec 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -428,7 +428,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
arg_length_minimum,
arg_length_maximum,
arg__maximum,
- arg_regex };
+ arg_regex,
+ arg_encoding };
unsigned int minlen = 0;
unsigned int maxlen = 0;
int limit_input = -1;
@@ -438,6 +439,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
bool have_regex = false;
bool newline_consume = false;
bool hex_conversion_enabled = true;
+ bool utf8_encoding = false;
int arg_mode = arg_none;
for(unsigned int i=3; i < args.size(); ++i)
{
@@ -475,6 +477,10 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
hex_conversion_enabled = false;
arg_mode = arg_none;
}
+ else if(args[i] == "ENCODING")
+ {
+ arg_mode = arg_encoding;
+ }
else if(arg_mode == arg_limit_input)
{
if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
@@ -556,6 +562,22 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
have_regex = true;
arg_mode = arg_none;
}
+ else if(arg_mode == arg_encoding)
+ {
+ if(args[i] == "UTF-8")
+ {
+ utf8_encoding = true;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "STRINGS option ENCODING \""
+ << args[i] << "\" not recognized.";
+ this->SetError(e.str());
+ return false;
+ }
+ arg_mode = arg_none;
+ }
else
{
cmOStringStream e;
@@ -596,11 +618,75 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
int output_size = 0;
std::vector<std::string> strings;
std::string s;
- int c;
while((!limit_count || strings.size() < limit_count) &&
(limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
- (c = fin.get(), fin))
+ fin)
{
+ std::string current_str;
+
+ int c = fin.get();
+
+ if(c == '\r')
+ {
+ // Ignore CR character to make output always have UNIX newlines.
+ continue;
+ }
+
+ else if((c >= 0x20 && c < 0x7F) || c == '\t' ||
+ (c == '\n' && newline_consume))
+ {
+ // This is an ASCII character that may be part of a string.
+ // Cast added to avoid compiler warning. Cast is ok because
+ // c is guaranteed to fit in char by the above if...
+ current_str += static_cast<char>(c);
+ }
+ else if(utf8_encoding)
+ {
+ // Check for UTF-8 encoded string (up to 4 octets)
+ static const unsigned char utf8_check_table[3][2] =
+ {
+ {0xE0, 0xC0},
+ {0xF0, 0xE0},
+ {0xF8, 0xF0},
+ };
+
+ // how many octets are there?
+ unsigned int num_utf8_bytes = 0;
+ for(unsigned int j=0; num_utf8_bytes == 0 && j<3; j++)
+ {
+ if((c & utf8_check_table[j][0]) == utf8_check_table[j][1])
+ num_utf8_bytes = j+2;
+ }
+
+ // get subsequent octets and check that they are valid
+ for(unsigned int j=0; j<num_utf8_bytes; j++)
+ {
+ if(j != 0)
+ {
+ c = fin.get();
+ if(!fin || (c & 0xC0) != 0x80)
+ {
+ fin.putback(static_cast<char>(c));
+ break;
+ }
+ }
+ current_str += static_cast<char>(c);
+ }
+
+ // if this was an invalid utf8 sequence, discard the data, and put
+ // back subsequent characters
+ if((current_str.length() != num_utf8_bytes))
+ {
+ for(unsigned int j=0; j<current_str.size()-1; j++)
+ {
+ c = current_str[current_str.size() - 1 - j];
+ fin.putback(static_cast<char>(c));
+ }
+ current_str = "";
+ }
+ }
+
+
if(c == '\n' && !newline_consume)
{
// The current line has been terminated. Check if the current
@@ -621,26 +707,13 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// Reset the string to empty.
s = "";
}
- else if(c == '\r')
- {
- // Ignore CR character to make output always have UNIX newlines.
- }
- else if((c >= 0x20 && c < 0x7F) || c == '\t' ||
- (c == '\n' && newline_consume))
- {
- // This is an ASCII character that may be part of a string.
- // Cast added to avoid compiler warning. Cast is ok because
- // c is guaranteed to fit in char by the above if...
- s += static_cast<char>(c);
- }
- else
+ else if(current_str.empty())
{
- // TODO: Support ENCODING option. See issue #10519.
// A non-string character has been found. Check if the current
// string matches the requirements. We require that the length
// be at least one no matter what the user specified.
if(s.length() >= minlen && s.length() >= 1 &&
- (!have_regex || regex.find(s.c_str())))
+ (!have_regex || regex.find(s.c_str())))
{
output_size += static_cast<int>(s.size()) + 1;
if(limit_output >= 0 && output_size >= limit_output)
@@ -654,10 +727,15 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// Reset the string to empty.
s = "";
}
+ else
+ {
+ s += current_str;
+ }
+
- // Terminate a string if the maximum length is reached.
if(maxlen > 0 && s.size() == maxlen)
{
+ // Terminate a string if the maximum length is reached.
if(s.length() >= minlen &&
(!have_regex || regex.find(s.c_str())))
{
@@ -1613,7 +1691,8 @@ bool cmFileCopier::InstallDirectory(const char* source,
MatchProperties const& match_properties)
{
// Inform the user about this directory installation.
- this->ReportCopy(destination, TypeDir, true);
+ this->ReportCopy(destination, TypeDir,
+ !cmSystemTools::FileIsDirectory(destination));
// Make sure the destination directory exists.
if(!cmSystemTools::MakeDirectory(destination))
@@ -1704,6 +1783,9 @@ struct cmFileInstaller: public cmFileCopier
cmFileCopier(command, "INSTALL"),
InstallType(cmInstallType_FILES),
Optional(false),
+ MessageAlways(false),
+ MessageLazy(false),
+ MessageNever(false),
DestDirLength(0)
{
// Installation does not use source permissions by default.
@@ -1725,6 +1807,9 @@ struct cmFileInstaller: public cmFileCopier
protected:
cmInstallType InstallType;
bool Optional;
+ bool MessageAlways;
+ bool MessageLazy;
+ bool MessageNever;
int DestDirLength;
std::string Rename;
@@ -1740,9 +1825,12 @@ protected:
virtual void ReportCopy(const char* toFile, Type type, bool copy)
{
- std::string message = (copy? "Installing: " : "Up-to-date: ");
- message += toFile;
- this->Makefile->DisplayStatus(message.c_str(), -1);
+ if(!this->MessageNever && (copy || !this->MessageLazy))
+ {
+ std::string message = (copy? "Installing: " : "Up-to-date: ");
+ message += toFile;
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
if(type != TypeDir)
{
// Add the file to the manifest.
@@ -1828,6 +1916,16 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
return false;
}
+ if(((this->MessageAlways?1:0) +
+ (this->MessageLazy?1:0) +
+ (this->MessageNever?1:0)) > 1)
+ {
+ this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
+ "MESSAGE_LAZY, and MESSAGE_NEVER "
+ "are mutually exclusive.");
+ return false;
+ }
+
return true;
}
@@ -1879,6 +1977,42 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
this->Optional = true;
}
}
+ else if(arg == "MESSAGE_ALWAYS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageAlways = true;
+ }
+ }
+ else if(arg == "MESSAGE_LAZY")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageLazy = true;
+ }
+ }
+ else if(arg == "MESSAGE_NEVER")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MessageNever = true;
+ }
+ }
else if(arg == "PERMISSIONS")
{
if(this->CurrentMatchRule)
@@ -2057,23 +2191,26 @@ bool cmFileInstaller::HandleInstallDestination()
this->DestDirLength = int(sdestdir.size());
}
- if ( !cmSystemTools::FileExists(destination.c_str()) )
+ if(this->InstallType != cmInstallType_DIRECTORY)
{
- if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
+ if ( !cmSystemTools::FileExists(destination.c_str()) )
{
- std::string errstring = "cannot create directory: " + destination +
+ if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
+ {
+ std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges.";
+ this->FileCommand->SetError(errstring);
+ return false;
+ }
+ }
+ if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
+ {
+ std::string errstring = "INSTALL destination: " + destination +
+ " is not a directory.";
this->FileCommand->SetError(errstring);
return false;
}
}
- if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
- {
- std::string errstring = "INSTALL destination: " + destination +
- " is not a directory.";
- this->FileCommand->SetError(errstring);
- return false;
- }
return true;
}
@@ -3113,15 +3250,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
return false;
}
- struct stat st;
- if(::stat(filename.c_str(), &st))
- {
- std::string errStr = "UPLOAD cannot stat file '";
- errStr += filename + "'.";
- this->SetError(errStr);
- fclose(fin);
- return false;
- }
+ unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str());
::CURL *curl;
::curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -3211,7 +3340,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
// and give the size of the upload (optional)
res = ::curl_easy_setopt(curl,
- CURLOPT_INFILESIZE, static_cast<long>(st.st_size));
+ CURLOPT_INFILESIZE, static_cast<long>(file_size));
check_curl_result(res, "UPLOAD cannot set input file size: ");
res = ::curl_easy_perform(curl);
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 028d229..7fc1464 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -97,6 +97,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
context.Quiet = quiet;
context.HadError = false;
context.HadContextSensitiveCondition = false;
+ context.HadHeadSensitiveCondition = false;
context.HeadTarget = headTarget;
context.EvaluateForBuildsystem = this->EvaluateForBuildsystem;
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
@@ -124,6 +125,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
if (!context.HadError)
{
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
+ this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
}
this->DependTargets = context.DependTargets;
@@ -137,6 +139,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
const std::string& input)
: Backtrace(backtrace), Input(input),
HadContextSensitiveCondition(false),
+ HadHeadSensitiveCondition(false),
EvaluateForBuildsystem(false)
{
cmGeneratorExpressionLexer l;
@@ -469,12 +472,11 @@ std::string::size_type cmGeneratorExpression::Find(const std::string &input)
//----------------------------------------------------------------------------
bool cmGeneratorExpression::IsValidTargetName(const std::string &input)
{
- cmsys::RegularExpression targetNameValidator;
// The ':' is supported to allow use with IMPORTED targets. At least
// Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter.
- targetNameValidator.compile("^[A-Za-z0-9_.:+-]+$");
+ static cmsys::RegularExpression targetNameValidator("^[A-Za-z0-9_.:+-]+$");
- return targetNameValidator.find(input.c_str());
+ return targetNameValidator.find(input);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 324d23c..b952520 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -111,6 +111,10 @@ public:
{
return this->HadContextSensitiveCondition;
}
+ bool GetHadHeadSensitiveCondition() const
+ {
+ return this->HadHeadSensitiveCondition;
+ }
void SetEvaluateForBuildsystem(bool eval)
{
@@ -141,6 +145,7 @@ private:
MaxLanguageStandard;
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
+ mutable bool HadHeadSensitiveCondition;
bool EvaluateForBuildsystem;
};
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index c54922d..c1478df 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -394,16 +394,14 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
cmGeneratorExpressionDAGChecker *,
const std::string &lang) const
{
- const char *compilerId = context->Makefile ?
- context->Makefile->GetSafeDefinition(
- "CMAKE_" + lang + "_COMPILER_ID") : "";
+ const char *compilerId =
+ context->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
if (parameters.size() == 0)
{
return compilerId ? compilerId : "";
}
- cmsys::RegularExpression compilerIdValidator;
- compilerIdValidator.compile("^[A-Za-z0-9_]*$");
- if (!compilerIdValidator.find(parameters.begin()->c_str()))
+ static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");
+ if (!compilerIdValidator.find(*parameters.begin()))
{
reportError(context, content->GetOriginalExpression(),
"Expression syntax not recognized.");
@@ -501,17 +499,15 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
cmGeneratorExpressionDAGChecker *,
const std::string &lang) const
{
- const char *compilerVersion = context->Makefile ?
- context->Makefile->GetSafeDefinition(
- "CMAKE_" + lang + "_COMPILER_VERSION") : "";
+ const char *compilerVersion = context->Makefile->GetSafeDefinition(
+ "CMAKE_" + lang + "_COMPILER_VERSION");
if (parameters.size() == 0)
{
return compilerVersion ? compilerVersion : "";
}
- cmsys::RegularExpression compilerIdValidator;
- compilerIdValidator.compile("^[0-9\\.]*$");
- if (!compilerIdValidator.find(parameters.begin()->c_str()))
+ static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$");
+ if (!compilerIdValidator.find(*parameters.begin()))
{
reportError(context, content->GetOriginalExpression(),
"Expression syntax not recognized.");
@@ -585,9 +581,8 @@ struct PlatformIdNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent *,
cmGeneratorExpressionDAGChecker *) const
{
- const char *platformId = context->Makefile ?
- context->Makefile->GetSafeDefinition(
- "CMAKE_SYSTEM_NAME") : "";
+ const char *platformId =
+ context->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME");
if (parameters.size() == 0)
{
return platformId ? platformId : "";
@@ -711,9 +706,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
{
return configurationNode.Evaluate(parameters, context, content, 0);
}
- cmsys::RegularExpression configValidator;
- configValidator.compile("^[A-Za-z0-9_]*$");
- if (!configValidator.find(parameters.begin()->c_str()))
+ static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
+ if (!configValidator.find(*parameters.begin()))
{
reportError(context, content->GetOriginalExpression(),
"Expression syntax not recognized.");
@@ -802,66 +796,55 @@ static const char* targetPropertyTransitiveWhitelist[] = {
#undef TRANSITIVE_PROPERTY_NAME
-std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
- cmTarget const* target,
- cmTarget const* headTarget,
- cmGeneratorExpressionContext *context,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string &interfacePropertyName)
+template <typename T>
+std::string
+getLinkedTargetsContent(
+ std::vector<T> const &libraries,
+ cmTarget const* target,
+ cmTarget const* headTarget,
+ cmGeneratorExpressionContext *context,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string &interfacePropertyName)
{
- cmGeneratorExpression ge(&context->Backtrace);
-
+ std::string linkedTargetsContent;
std::string sep;
std::string depString;
- for (std::vector<cmTarget*>::const_iterator
- it = targets.begin();
- it != targets.end(); ++it)
+ for (typename std::vector<T>::const_iterator it = libraries.begin();
+ it != libraries.end(); ++it)
{
- if (*it == target)
- {
- // Broken code can have a target in its own link interface.
- // Don't follow such link interface entries so as not to create a
- // self-referencing loop.
- continue;
+ // Broken code can have a target in its own link interface.
+ // Don't follow such link interface entries so as not to create a
+ // self-referencing loop.
+ if (it->Target && it->Target != target)
+ {
+ depString +=
+ sep + "$<TARGET_PROPERTY:" +
+ it->Target->GetName() + "," + interfacePropertyName + ">";
+ sep = ";";
}
- depString +=
- sep + "$<TARGET_PROPERTY:" +
- (*it)->GetName() + "," + interfacePropertyName + ">";
- sep = ";";
}
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
- std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
- context->Config,
- context->Quiet,
- headTarget,
- target,
- dagChecker);
- if (cge->GetHadContextSensitiveCondition())
+ if(!depString.empty())
{
- context->HadContextSensitiveCondition = true;
- }
- return linkedTargetsContent;
-}
-
-std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
- cmTarget const* target,
- cmTarget const* headTarget,
- cmGeneratorExpressionContext *context,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string &interfacePropertyName)
-{
- std::vector<cmTarget*> tgts;
- for (std::vector<std::string>::const_iterator
- it = libraries.begin();
- it != libraries.end(); ++it)
- {
- if (cmTarget *tgt = context->Makefile->FindTargetToUse(*it))
+ cmGeneratorExpression ge(&context->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
+ linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
+ context->Config,
+ context->Quiet,
+ headTarget,
+ target,
+ dagChecker);
+ if (cge->GetHadContextSensitiveCondition())
{
- tgts.push_back(tgt);
+ context->HadContextSensitiveCondition = true;
+ }
+ if (cge->GetHadHeadSensitiveCondition())
+ {
+ context->HadHeadSensitiveCondition = true;
}
}
- return getLinkedTargetsContent(tgts, target, headTarget, context,
- dagChecker, interfacePropertyName);
+ linkedTargetsContent =
+ cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
+ return linkedTargetsContent;
}
//----------------------------------------------------------------------------
@@ -884,12 +867,15 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
return std::string();
}
- cmsys::RegularExpression propertyNameValidator;
- propertyNameValidator.compile("^[A-Za-z0-9_]+$");
+ static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
cmTarget const* target = context->HeadTarget;
std::string propertyName = *parameters.begin();
+ if (parameters.size() == 1)
+ {
+ context->HadHeadSensitiveCondition = true;
+ }
if (!target && parameters.size() == 1)
{
reportError(context, content->GetOriginalExpression(),
@@ -973,7 +959,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return std::string();
}
- if (!propertyNameValidator.find(propertyName.c_str()))
+ if (!propertyNameValidator.find(propertyName))
{
::reportError(context, content->GetOriginalExpression(),
"Property name not supported.");
@@ -1031,6 +1017,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
if (dagCheckerParent->EvaluatingLinkLibraries())
{
+#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
+ (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
+ if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE)
+ false)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:...> expression in link libraries "
+ "evaluation depends on target property which is transitive "
+ "over the link libraries, creating a recursion.");
+ return std::string();
+ }
+#undef TRANSITIVE_PROPERTY_COMPARE
+
if(!prop)
{
return std::string();
@@ -1045,19 +1044,25 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
ASSERT_TRANSITIVE_PROPERTY_METHOD)
false);
- }
#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
+ }
}
std::string linkedTargetsContent;
std::string interfacePropertyName;
+ bool isInterfaceProperty = false;
#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
- if (propertyName == #prop || propertyName == "INTERFACE_" #prop) \
+ if (propertyName == #prop) \
{ \
interfacePropertyName = "INTERFACE_" #prop; \
} \
+ else if (propertyName == "INTERFACE_" #prop) \
+ { \
+ interfacePropertyName = "INTERFACE_" #prop; \
+ isInterfaceProperty = true; \
+ } \
else
CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
@@ -1073,50 +1078,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
}
#undef POPULATE_INTERFACE_PROPERTY_NAME
-
- cmTarget const* headTarget = context->HeadTarget
+ cmTarget const* headTarget = context->HeadTarget && isInterfaceProperty
? context->HeadTarget : target;
- const char * const *transBegin =
- cmArrayBegin(targetPropertyTransitiveWhitelist) + 1;
- const char * const *transEnd =
- cmArrayEnd(targetPropertyTransitiveWhitelist);
-
- if (std::find_if(transBegin, transEnd,
- cmStrCmp(propertyName)) != transEnd)
+ if(isInterfaceProperty)
{
-
- std::vector<cmTarget*> tgts;
- target->GetTransitivePropertyTargets(context->Config,
- headTarget, tgts);
- if (!tgts.empty())
+ if(cmTarget::LinkInterfaceLibraries const* iface =
+ target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
{
linkedTargetsContent =
- getLinkedTargetsContent(tgts, target,
- headTarget,
- context, &dagChecker,
- interfacePropertyName);
+ getLinkedTargetsContent(iface->Libraries, target,
+ headTarget,
+ context, &dagChecker,
+ interfacePropertyName);
}
}
- else if (std::find_if(transBegin, transEnd,
- cmStrCmp(interfacePropertyName)) != transEnd)
+ else if(!interfacePropertyName.empty())
{
- const cmTarget::LinkImplementation *impl
- = target->GetLinkImplementationLibraries(context->Config,
- headTarget);
- if(impl)
+ if(cmTarget::LinkImplementationLibraries const* impl =
+ target->GetLinkImplementationLibraries(context->Config))
{
linkedTargetsContent =
- getLinkedTargetsContent(impl->Libraries, target,
- headTarget,
- context, &dagChecker,
- interfacePropertyName);
+ getLinkedTargetsContent(impl->Libraries, target,
+ target,
+ context, &dagChecker,
+ interfacePropertyName);
}
}
- linkedTargetsContent =
- cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
-
if (!prop)
{
if (target->IsImported()
@@ -1190,31 +1179,31 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return propContent ? propContent : "";
}
}
- for (size_t i = 1;
- i < cmArraySize(targetPropertyTransitiveWhitelist);
- ++i)
+ if(!interfacePropertyName.empty())
{
- if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName)
- {
- cmGeneratorExpression ge(&context->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
- std::string result = cge->Evaluate(context->Makefile,
+ cmGeneratorExpression ge(&context->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+ cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
+ std::string result = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
headTarget,
target,
&dagChecker);
- if (cge->GetHadContextSensitiveCondition())
- {
- context->HadContextSensitiveCondition = true;
- }
- if (!linkedTargetsContent.empty())
- {
- result += (result.empty() ? "" : ";") + linkedTargetsContent;
- }
- return result;
+ if (cge->GetHadContextSensitiveCondition())
+ {
+ context->HadContextSensitiveCondition = true;
+ }
+ if (cge->GetHadHeadSensitiveCondition())
+ {
+ context->HadHeadSensitiveCondition = true;
+ }
+ if (!linkedTargetsContent.empty())
+ {
+ result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
+ return result;
}
return prop;
}
@@ -1333,6 +1322,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
"not be used with add_custom_command or add_custom_target.");
return std::string();
}
+ context->HadHeadSensitiveCondition = true;
typedef std::map<std::string, std::vector<std::string> > LangMap;
static LangMap availableFeatures;
@@ -1466,6 +1456,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
}
context->HadContextSensitiveCondition = true;
+ context->HadHeadSensitiveCondition = true;
for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i)
{
@@ -1529,7 +1520,17 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
} installPrefixNode;
//----------------------------------------------------------------------------
-template<bool linker, bool soname>
+class ArtifactNameTag;
+class ArtifactLinkerTag;
+class ArtifactSonameTag;
+class ArtifactPdbTag;
+
+class ArtifactPathTag;
+class ArtifactDirTag;
+class ArtifactNameTag;
+
+//----------------------------------------------------------------------------
+template<typename ArtifactT>
struct TargetFilesystemArtifactResultCreator
{
static std::string Create(cmTarget* target,
@@ -1539,7 +1540,7 @@ struct TargetFilesystemArtifactResultCreator
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultCreator<false, true>
+struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
{
static std::string Create(cmTarget* target,
cmGeneratorExpressionContext *context,
@@ -1569,7 +1570,45 @@ struct TargetFilesystemArtifactResultCreator<false, true>
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultCreator<true, false>
+struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
+{
+ static std::string Create(cmTarget* target,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content)
+ {
+ std::string language = target->GetLinkerLanguage(context->Config);
+
+ std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
+
+ if(!context->Makefile->IsOn(pdbSupportVar))
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE is not supported by the target linker.");
+ return std::string();
+ }
+
+ cmTarget::TargetType targetType = target->GetType();
+
+ if(targetType != cmTarget::SHARED_LIBRARY &&
+ targetType != cmTarget::MODULE_LIBRARY &&
+ targetType != cmTarget::EXECUTABLE)
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE is allowed only for "
+ "targets with linker created artifacts.");
+ return std::string();
+ }
+
+ std::string result = target->GetPDBDirectory(context->Config);
+ result += "/";
+ result += target->GetPDBName(context->Config);
+ return result;
+ }
+};
+
+//----------------------------------------------------------------------------
+template<>
+struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
{
static std::string Create(cmTarget* target,
cmGeneratorExpressionContext *context,
@@ -1590,7 +1629,7 @@ struct TargetFilesystemArtifactResultCreator<true, false>
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultCreator<false, false>
+struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
{
static std::string Create(cmTarget* target,
cmGeneratorExpressionContext *context,
@@ -1602,7 +1641,7 @@ struct TargetFilesystemArtifactResultCreator<false, false>
//----------------------------------------------------------------------------
-template<bool dirQual, bool nameQual>
+template<typename ArtifactT>
struct TargetFilesystemArtifactResultGetter
{
static std::string Get(const std::string &result);
@@ -1610,7 +1649,7 @@ struct TargetFilesystemArtifactResultGetter
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultGetter<false, true>
+struct TargetFilesystemArtifactResultGetter<ArtifactNameTag>
{
static std::string Get(const std::string &result)
{ return cmSystemTools::GetFilenameName(result); }
@@ -1618,7 +1657,7 @@ struct TargetFilesystemArtifactResultGetter<false, true>
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultGetter<true, false>
+struct TargetFilesystemArtifactResultGetter<ArtifactDirTag>
{
static std::string Get(const std::string &result)
{ return cmSystemTools::GetFilenamePath(result); }
@@ -1626,14 +1665,14 @@ struct TargetFilesystemArtifactResultGetter<true, false>
//----------------------------------------------------------------------------
template<>
-struct TargetFilesystemArtifactResultGetter<false, false>
+struct TargetFilesystemArtifactResultGetter<ArtifactPathTag>
{
static std::string Get(const std::string &result)
{ return result; }
};
//----------------------------------------------------------------------------
-template<bool linker, bool soname, bool dirQual, bool nameQual>
+template<typename ArtifactT, typename ComponentT>
struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
{
TargetFilesystemArtifact() {}
@@ -1681,7 +1720,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
context->AllTargets.insert(target);
std::string result =
- TargetFilesystemArtifactResultCreator<linker, soname>::Create(
+ TargetFilesystemArtifactResultCreator<ArtifactT>::Create(
target,
context,
content);
@@ -1690,29 +1729,35 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
return std::string();
}
return
- TargetFilesystemArtifactResultGetter<dirQual, nameQual>::Get(result);
+ TargetFilesystemArtifactResultGetter<ComponentT>::Get(result);
}
};
//----------------------------------------------------------------------------
+template<typename ArtifactT>
+struct TargetFilesystemArtifactNodeGroup
+{
+ TargetFilesystemArtifactNodeGroup()
+ {
+ }
+
+ TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File;
+ TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName;
+ TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir;
+};
+
+//----------------------------------------------------------------------------
static const
-TargetFilesystemArtifact<false, false, false, false> targetFileNode;
-static const
-TargetFilesystemArtifact<true, false, false, false> targetLinkerFileNode;
-static const
-TargetFilesystemArtifact<false, true, false, false> targetSoNameFileNode;
-static const
-TargetFilesystemArtifact<false, false, false, true> targetFileNameNode;
-static const
-TargetFilesystemArtifact<true, false, false, true> targetLinkerFileNameNode;
-static const
-TargetFilesystemArtifact<false, true, false, true> targetSoNameFileNameNode;
+TargetFilesystemArtifactNodeGroup<ArtifactNameTag> targetNodeGroup;
+
static const
-TargetFilesystemArtifact<false, false, true, false> targetFileDirNode;
+TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup;
+
static const
-TargetFilesystemArtifact<true, false, true, false> targetLinkerFileDirNode;
+TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup;
+
static const
-TargetFilesystemArtifact<false, true, true, false> targetSoNameFileDirNode;
+TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
//----------------------------------------------------------------------------
static const
@@ -1738,15 +1783,18 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode;
nodeMap["CONFIGURATION"] = &configurationNode;
nodeMap["CONFIG"] = &configurationTestNode;
- nodeMap["TARGET_FILE"] = &targetFileNode;
- nodeMap["TARGET_LINKER_FILE"] = &targetLinkerFileNode;
- nodeMap["TARGET_SONAME_FILE"] = &targetSoNameFileNode;
- nodeMap["TARGET_FILE_NAME"] = &targetFileNameNode;
- nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerFileNameNode;
- nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameFileNameNode;
- nodeMap["TARGET_FILE_DIR"] = &targetFileDirNode;
- nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerFileDirNode;
- nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameFileDirNode;
+ nodeMap["TARGET_FILE"] = &targetNodeGroup.File;
+ nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File;
+ nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File;
+ nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File;
+ nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName;
+ nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName;
+ nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName;
+ nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName;
+ nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir;
+ nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir;
+ nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir;
+ nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir;
nodeMap["STREQUAL"] = &strEqualNode;
nodeMap["EQUAL"] = &equalNode;
nodeMap["LOWER_CASE"] = &lowerCaseNode;
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 0ffb860..8a529e8 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -41,6 +41,7 @@ struct cmGeneratorExpressionContext
bool Quiet;
bool HadError;
bool HadContextSensitiveCondition;
+ bool HadHeadSensitiveCondition;
bool EvaluateForBuildsystem;
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a7576ed..14b5a92 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -38,7 +38,8 @@ void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
{
e << " " << (*i)->GetLocation().GetName() << "\n";
}
- e << "but may contain only headers and sources that compile.";
+ e << "but may contain only sources that compile, header files, and "
+ "other files that would not affect linking of a normal library.";
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
target->GetBacktrace());
}
@@ -52,6 +53,8 @@ struct ExternalObjectsTag {};
struct IDLSourcesTag {};
struct ResxTag {};
struct ModuleDefinitionFileTag {};
+struct AppManifestTag{};
+struct CertificatesTag{};
#if !defined(_MSC_VER) || _MSC_VER >= 1310
template<typename Tag, typename OtherTag>
@@ -194,6 +197,14 @@ struct TagVisitor
{
DoAccept<IsSameTag<Tag, ResxTag>::Result>::Do(this->Data, sf);
}
+ else if (ext == "appxmanifest")
+ {
+ DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf);
+ }
+ else if (ext == "pfx")
+ {
+ DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
+ }
else if(this->Header.find(sf->GetFullPath().c_str()))
{
DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
@@ -205,10 +216,6 @@ struct TagVisitor
else
{
DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
- if(this->IsObjLib && ext != "txt")
- {
- this->BadObjLibFiles.push_back(sf);
- }
}
}
};
@@ -252,7 +259,7 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
return 0;
}
-static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
+static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
const std::string& config,
cmTarget *headTarget,
cmGeneratorExpressionDAGChecker *dagChecker,
@@ -432,6 +439,24 @@ void cmGeneratorTarget
}
//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetAppManifest(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(AppManifest);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
+::GetCertificates(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(Certificates);
+}
+
+//----------------------------------------------------------------------------
bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const
{
@@ -448,13 +473,6 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
if (iter == this->SystemIncludesCache.end())
{
- cmTarget::LinkImplementation const* impl
- = this->Target->GetLinkImplementation(config, this->Target);
- if(!impl)
- {
- return false;
- }
-
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(),
"SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
@@ -474,35 +492,15 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
&dagChecker), result);
}
- std::set<cmTarget*> uniqueDeps;
- for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
- li != impl->Libraries.end(); ++li)
+ std::vector<cmTarget const*> const& deps =
+ this->Target->GetLinkImplementationClosure(config);
+ for(std::vector<cmTarget const*>::const_iterator
+ li = deps.begin(), le = deps.end(); li != le; ++li)
{
- cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
- if (!tgt)
- {
- continue;
- }
-
- if (uniqueDeps.insert(tgt).second)
- {
- handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
- &dagChecker, result, excludeImported);
-
- std::vector<cmTarget*> deps;
- tgt->GetTransitivePropertyTargets(config, this->Target, deps);
-
- for(std::vector<cmTarget*>::const_iterator di = deps.begin();
- di != deps.end(); ++di)
- {
- if (uniqueDeps.insert(*di).second)
- {
- handleSystemIncludesDep(this->Makefile, *di, config, this->Target,
- &dagChecker, result, excludeImported);
- }
- }
- }
+ handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
+ &dagChecker, result, excludeImported);
}
+
std::set<std::string> unique;
for(std::vector<std::string>::iterator li = result.begin();
li != result.end(); ++li)
@@ -521,9 +519,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
iter = this->SystemIncludesCache.insert(entry).first;
}
- std::string dirString = dir;
- return std::binary_search(iter->second.begin(), iter->second.end(),
- dirString);
+ return std::binary_search(iter->second.begin(), iter->second.end(), dir);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 29aa410..2083b88 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -54,6 +54,10 @@ public:
const std::string& config) const;
void GetExpectedResxHeaders(std::set<std::string>&,
const std::string& config) const;
+ void GetAppManifest(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
+ void GetCertificates(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
void ComputeObjectMapping();
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 8a96289..7667a85 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -29,7 +29,7 @@ bool cmGetSourceFilePropertyCommand
// for the location we must create a source file first
if (!sf && args[2] == "LOCATION")
{
- sf = this->Makefile->GetOrCreateSource(file);
+ sf = this->Makefile->CreateSource(file);
}
if(sf)
{
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 470dea4..120d2f8 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -39,7 +39,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 6c8be72..ae0e807 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -76,18 +76,46 @@ cmGlobalGenerator::~cmGlobalGenerator()
}
}
+bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(p.empty())
+ {
+ return true;
+ }
+ else
+ {
+ cmOStringStream e;
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support platform specification, but platform\n"
+ " " << p << "\n"
+ "was specified.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+}
+
bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
{
- cmOStringStream e;
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "does not support toolset specification, but toolset\n"
- " " << ts << "\n"
- "was specified.";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
+ if(ts.empty())
+ {
+ return true;
+ }
+ else
+ {
+ cmOStringStream e;
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support toolset specification, but toolset\n"
+ " " << ts << "\n"
+ "was specified.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
}
std::string cmGlobalGenerator::SelectMakeProgram(
@@ -148,8 +176,6 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
{
return;
}
- std::string doc = lang;
- doc += " compiler.";
const char* cname = this->GetCMakeInstance()->
GetCacheManager()->GetCacheValue(langComp);
std::string changeVars;
@@ -186,8 +212,6 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
changeVars.c_str());
}
}
- mf->AddCacheDefinition(langComp, path.c_str(),
- doc.c_str(), cmCacheManager::FILEPATH);
}
void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
@@ -294,7 +318,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
// will run xcodebuild and if it sees the error text file busy
// it will stop forwarding output, and let the build finish.
// Then it will retry the build. It will continue this
- // untill no text file busy errors occur.
+ // until no text file busy errors occur.
std::string cmakexbuild =
this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
@@ -414,7 +438,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// try and load the CMakeSystem.cmake if it is there
std::string fpath = rootBin;
- if(!mf->GetDefinition("CMAKE_SYSTEM_LOADED"))
+ bool const readCMakeSystem = !mf->GetDefinition("CMAKE_SYSTEM_LOADED");
+ if(readCMakeSystem)
{
fpath += "/CMakeSystem.cmake";
if(cmSystemTools::FileExists(fpath.c_str()))
@@ -448,13 +473,31 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
mf->ReadListFile(0,fpath.c_str());
}
- // Tell the generator about the toolset, if any.
- std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
- if(!toolset.empty() &&
- !this->SetGeneratorToolset(toolset, mf))
+ if(readCMakeSystem)
{
- cmSystemTools::SetFatalErrorOccured();
- return;
+ // Tell the generator about the target system.
+ std::string system = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ if(!this->SetSystemName(system, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
+ // Tell the generator about the platform, if any.
+ std::string platform = mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM");
+ if(!this->SetGeneratorPlatform(platform, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
+ // Tell the generator about the toolset, if any.
+ std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
+ if(!this->SetGeneratorToolset(toolset, mf))
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
}
// **** Load the system specific initialization if not yet loaded
@@ -463,8 +506,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
fpath = mf->GetModulesFile("CMakeSystemSpecificInitialize.cmake");
if(!mf->ReadListFile(0,fpath.c_str()))
{
- cmSystemTools::Error("Could not find cmake module file: ",
- fpath.c_str());
+ cmSystemTools::Error("Could not find cmake module file: "
+ "CMakeSystemSpecificInitialize.cmake");
}
}
@@ -532,7 +575,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
if(!mf->ReadListFile(0,determineFile.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
- determineFile.c_str());
+ determineCompiler.c_str());
}
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
@@ -584,8 +627,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
if(!mf->ReadListFile(0,fpath.c_str()))
{
- cmSystemTools::Error("Could not find cmake module file: ",
- fpath.c_str());
+ cmSystemTools::Error("Could not find cmake module file: "
+ "CMakeSystemSpecificInformation.cmake");
}
}
// loop over languages again loading CMake(LANG)Information.cmake
@@ -616,7 +659,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
"No " << compilerName << " could be found.\n"
;
}
- else if(strcmp(lang, "RC") != 0)
+ else if(strcmp(lang, "RC") != 0 &&
+ strcmp(lang, "ASM_MASM") != 0)
{
if(!cmSystemTools::FileIsFullPath(compilerFile))
{
@@ -700,7 +744,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
if(!mf->ReadListFile(0,ifpath.c_str()))
{
cmSystemTools::Error("Could not find cmake module file: ",
- ifpath.c_str());
+ testLang.c_str());
}
std::string compilerWorks = "CMAKE_";
compilerWorks += lang;
@@ -840,6 +884,14 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf,
case cmPolicies::OLD:
// OLD behavior is to convert QCC to GNU.
mf->AddDefinition(compilerIdVar, "GNU");
+ if(lang == "C")
+ {
+ mf->AddDefinition("CMAKE_COMPILER_IS_GNUCC", "1");
+ }
+ else if(lang == "CXX")
+ {
+ mf->AddDefinition("CMAKE_COMPILER_IS_GNUCXX", "1");
+ }
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
@@ -956,9 +1008,9 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
if (sscanf(linkerPref, "%d", &preference)!=1)
{
// backward compatibility: before 2.6 LINKER_PREFERENCE
- // was either "None" or "Prefered", and only the first character was
+ // was either "None" or "Preferred", and only the first character was
// tested. So if there is a custom language out there and it is
- // "Prefered", set its preference high
+ // "Preferred", set its preference high
if (linkerPref[0]=='P')
{
preference = 100;
@@ -1045,36 +1097,6 @@ void cmGlobalGenerator::ClearEnabledLanguages()
this->LanguageEnabled.clear();
}
-bool cmGlobalGenerator::IsDependedOn(const std::string& project,
- cmTarget const* targetIn)
-{
- // Get all local gens for this project
- std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator it =
- this->ProjectMap.find(project);
- if (it == this->ProjectMap.end())
- {
- return false;
- }
-
- // loop over local gens and get the targets for each one
- for(std::vector<cmLocalGenerator*>::const_iterator geIt = it->second.begin();
- geIt != it->second.end(); ++geIt)
- {
- cmTargets const& targets = (*geIt)->GetMakefile()->GetTargets();
- for (cmTargets::const_iterator l = targets.begin();
- l != targets.end(); l++)
- {
- cmTarget const& target = l->second;
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
- if(tgtdeps.count(targetIn))
- {
- return true;
- }
- }
- }
- return false;
-}
-
void cmGlobalGenerator::Configure()
{
this->FirstTimeProgress = 0.0f;
@@ -1175,7 +1197,7 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
return false;
}
-void cmGlobalGenerator::Generate()
+void cmGlobalGenerator::DoGenerate()
{
// Some generators track files replaced during the Generate.
// Start with an empty vector:
@@ -1184,6 +1206,11 @@ void cmGlobalGenerator::Generate()
// clear targets to issue warning CMP0042 for
this->CMP0042WarnTargets.clear();
+ this->Generate();
+}
+
+void cmGlobalGenerator::Generate()
+{
// Check whether this generator is allowed to run.
if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
{
@@ -1637,7 +1664,7 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir,
const std::string& bindir,
const std::string& projectName,
const std::string& target, bool fast,
- std::string *output, cmMakefile *mf)
+ std::string& output, cmMakefile *mf)
{
// if this is not set, then this is a first time configure
// and there is a good chance that the try compile stuff will
@@ -1696,7 +1723,7 @@ void cmGlobalGenerator::GenerateBuildCommand(
int cmGlobalGenerator::Build(
const std::string&, const std::string& bindir,
const std::string& projectName, const std::string& target,
- std::string *output,
+ std::string& output,
const std::string& makeCommandCSTR,
const std::string& config,
bool clean, bool fast,
@@ -1709,22 +1736,15 @@ int cmGlobalGenerator::Build(
*/
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(bindir.c_str());
- if(output)
- {
- *output += "Change Dir: ";
- *output += bindir;
- *output += "\n";
- }
+ output += "Change Dir: ";
+ output += bindir;
+ output += "\n";
int retVal;
bool hideconsole = cmSystemTools::GetRunCommandHideConsole();
cmSystemTools::SetRunCommandHideConsole(true);
std::string outputBuffer;
- std::string* outputPtr = 0;
- if(output)
- {
- outputPtr = &outputBuffer;
- }
+ std::string* outputPtr = &outputBuffer;
// should we do a clean first?
if (clean)
@@ -1732,32 +1752,23 @@ int cmGlobalGenerator::Build(
std::vector<std::string> cleanCommand;
this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName,
bindir, "clean", config, fast);
- if(output)
- {
- *output += "\nRun Clean Command:";
- *output += cmSystemTools::PrintSingleCommand(cleanCommand);
- *output += "\n";
- }
+ output += "\nRun Clean Command:";
+ output += cmSystemTools::PrintSingleCommand(cleanCommand);
+ output += "\n";
if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr,
&retVal, 0, outputflag, timeout))
{
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
- if (output)
- {
- *output += *outputPtr;
- *output += "\nGenerator: execution of make clean failed.\n";
- }
+ output += *outputPtr;
+ output += "\nGenerator: execution of make clean failed.\n";
// return to the original directory
cmSystemTools::ChangeDirectory(cwd.c_str());
return 1;
}
- if (output)
- {
- *output += *outputPtr;
- }
+ output += *outputPtr;
}
// now build
@@ -1765,12 +1776,9 @@ int cmGlobalGenerator::Build(
this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName,
bindir, target, config, fast, nativeOptions);
std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand);
- if(output)
- {
- *output += "\nRun Build Command:";
- *output += makeCommandStr;
- *output += "\n";
- }
+ output += "\nRun Build Command:";
+ output += makeCommandStr;
+ output += "\n";
if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr,
&retVal, 0, outputflag, timeout))
@@ -1779,27 +1787,21 @@ int cmGlobalGenerator::Build(
cmSystemTools::Error
("Generator: execution of make failed. Make command was: ",
makeCommandStr.c_str());
- if (output)
- {
- *output += *outputPtr;
- *output += "\nGenerator: execution of make failed. Make command was: "
+ output += *outputPtr;
+ output += "\nGenerator: execution of make failed. Make command was: "
+ makeCommandStr + "\n";
- }
// return to the original directory
cmSystemTools::ChangeDirectory(cwd.c_str());
return 1;
}
- if (output)
- {
- *output += *outputPtr;
- }
+ output += *outputPtr;
cmSystemTools::SetRunCommandHideConsole(hideconsole);
// The SGI MipsPro 7.3 compiler does not return an error code when
// the source has a #error in it! This is a work-around for such
// compilers.
- if((retVal == 0) && (output->find("#error") != std::string::npos))
+ if((retVal == 0) && (output.find("#error") != std::string::npos))
{
retVal = 1;
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 67bd378..ddd7e91 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -39,7 +39,7 @@ class cmExportBuildFileGenerator;
class cmQtAutoGenerators;
/** \class cmGlobalGenerator
- * \brief Responable for overseeing the generation process for the entire tree
+ * \brief Responsible for overseeing the generation process for the entire tree
*
* Subclasses of this class generate makefiles for various
* platforms.
@@ -61,6 +61,14 @@ public:
virtual bool MatchesGeneratorName(const std::string& name) const
{ return this->GetName() == name; }
+ /** Tell the generator about the target system. */
+ virtual bool SetSystemName(std::string const&, cmMakefile*)
+ { return true; }
+
+ /** Set the generator-specific platform name. Returns true if platform
+ is supported and false otherwise. */
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
@@ -76,7 +84,7 @@ public:
* basically creates a series of LocalGenerators for each directory and
* requests that they Generate.
*/
- virtual void Generate();
+ void DoGenerate();
/**
* Set/Get and Clear the enabled languages.
@@ -86,7 +94,7 @@ public:
void ClearEnabledLanguages();
void GetEnabledLanguages(std::vector<std::string>& lang) const;
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -100,7 +108,7 @@ public:
bool optional) const;
/**
- * Try to determine system infomation, get it from another generator
+ * Try to determine system information, get it from another generator
*/
virtual void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
cmMakefile* mf);
@@ -112,7 +120,7 @@ public:
virtual int TryCompile(const std::string& srcdir, const std::string& bindir,
const std::string& projectName,
const std::string& targetName,
- bool fast, std::string *output, cmMakefile* mf);
+ bool fast, std::string& output, cmMakefile* mf);
/**
@@ -123,7 +131,7 @@ public:
*/
int Build(const std::string& srcdir, const std::string& bindir,
const std::string& projectName, const std::string& targetName,
- std::string *output,
+ std::string& output,
const std::string& makeProgram, const std::string& config,
bool clean, bool fast,
double timeout,
@@ -190,7 +198,7 @@ public:
std::string GetLanguageFromExtension(const char* ext) const;
///! is an extension to be ignored
bool IgnoreFile(const char* ext) const;
- ///! What is the preference for linkers and this language (None or Prefered)
+ ///! What is the preference for linkers and this language (None or Preferred)
int GetLinkerPreference(const std::string& lang) const;
///! What is the object file extension for a given source file?
std::string GetLanguageOutputExtension(cmSourceFile const&) const;
@@ -214,6 +222,11 @@ public:
*/
virtual void FindMakeProgram(cmMakefile*);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /** Is this the Visual Studio 6 generator? */
+ virtual bool IsForVS6() const { return false; }
+#endif
+
///! Find a target by name by searching the local generators.
cmTarget* FindTarget(const std::string& name,
bool excludeAliases = false) const;
@@ -225,9 +238,6 @@ public:
that is a framework. */
bool NameResolvesToFramework(const std::string& libname) const;
- /** If check to see if the target is linked to by any other
- target in the project */
- bool IsDependedOn(const std::string& project, cmTarget const* target);
///! Find a local generator by its startdirectory
cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const;
@@ -332,6 +342,8 @@ public:
bool GenerateCPackPropertiesFile();
protected:
+ virtual void Generate();
+
typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend
// information, and also collect all the targets
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 344e013..fbb35f3 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -40,7 +40,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h
index c4825bd..baecde7 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.h
+++ b/Source/cmGlobalMSYSMakefileGenerator.h
@@ -39,7 +39,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h
index 4289422..fa8d9f2 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.h
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -38,7 +38,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 2ff44e3..e7b03dd 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -38,7 +38,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index a0caf0e..6e7b06b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -151,11 +151,6 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
++i)
{
arguments += " " + EncodeIdent(EncodePath(*i), os);
-
- //we need to track every dependency that comes in, since we are trying
- //to find dependencies that are side effects of build commands
- //
- this->CombinedBuildExplicitDependencies.insert( EncodePath(*i) );
}
// Write implicit dependencies.
@@ -210,7 +205,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
&& args.size() + buildstr.size() + assignments.size()
> (size_t) cmdLineLimit) {
buildstr += "_RSP_FILE";
- variable_assignments.clear();
+ variable_assignments.str(std::string());
cmGlobalNinjaGenerator::WriteVariable(variable_assignments,
"RSP_FILE", rspfile, "", 1);
assignments += variable_assignments.str();
@@ -280,6 +275,13 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
cmNinjaDeps(),
orderOnly,
vars);
+
+ //we need to track every dependency that comes in, since we are trying
+ //to find dependencies that are side effects of build commands
+ for(cmNinjaDeps::const_iterator i = deps.begin(); i != deps.end(); ++i)
+ {
+ this->CombinedCustomCommandExplicitDependencies.insert( EncodePath(*i) );
+ }
}
void
@@ -538,6 +540,15 @@ void cmGlobalNinjaGenerator
cmSystemTools::Error("The Ninja generator does not support Fortran yet.");
}
this->cmGlobalGenerator::EnableLanguage(langs, makefile, optional);
+ for(std::vector<std::string>::const_iterator l = langs.begin();
+ l != langs.end(); ++l)
+ {
+ if(*l == "NONE")
+ {
+ continue;
+ }
+ this->ResolveLanguageCompiler(*l, makefile, optional);
+ }
}
bool cmGlobalNinjaGenerator::UsingMinGW = false;
@@ -961,7 +972,16 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
{
knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
}
+ //get list files which are implicit dependencies as well and will be phony
+ //for rebuild manifest
+ std::vector<std::string> const& lf = (*i)->GetMakefile()->GetListFiles();
+ typedef std::vector<std::string>::const_iterator vect_it;
+ for(vect_it j = lf.begin(); j != lf.end(); ++j)
+ {
+ knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
+ }
}
+ knownDependencies.insert( "CMakeCache.txt" );
for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
li = this->EvaluationFiles.begin();
@@ -1006,17 +1026,17 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
//to keep this data around
this->CombinedBuildOutputs.clear();
- //now we difference with CombinedBuildExplicitDependencies to find
+ //now we difference with CombinedCustomCommandExplicitDependencies to find
//the list of items we know nothing about.
- //We have encoded all the paths in CombinedBuildExplicitDependencies
+ //We have encoded all the paths in CombinedCustomCommandExplicitDependencies
//and knownDependencies so no matter if unix or windows paths they
//should all match now.
std::vector<std::string> unkownExplicitDepends;
- this->CombinedBuildExplicitDependencies.erase("all");
+ this->CombinedCustomCommandExplicitDependencies.erase("all");
- std::set_difference(this->CombinedBuildExplicitDependencies.begin(),
- this->CombinedBuildExplicitDependencies.end(),
+ std::set_difference(this->CombinedCustomCommandExplicitDependencies.begin(),
+ this->CombinedCustomCommandExplicitDependencies.end(),
knownDependencies.begin(),
knownDependencies.end(),
std::back_inserter(unkownExplicitDepends));
@@ -1118,6 +1138,16 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
implicitDeps.end());
+ cmNinjaVars variables;
+ // Use 'console' pool to get non buffered output of the CMake re-run call
+ // Available since Ninja 1.5
+ if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ ninjaVersion().c_str(),
+ "1.5") == false)
+ {
+ variables["pool"] = "console";
+ }
+
this->WriteBuild(os,
"Re-run CMake if any of its inputs changed.",
"RERUN_CMAKE",
@@ -1125,7 +1155,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
/*explicitDeps=*/ cmNinjaDeps(),
implicitDeps,
/*orderOnlyDeps=*/ cmNinjaDeps(),
- /*variables=*/ cmNinjaVars());
+ variables);
this->WritePhonyBuild(os,
"A missing CMake input file is not an error.",
@@ -1144,6 +1174,17 @@ std::string cmGlobalNinjaGenerator::ninjaCmd() const
return "ninja";
}
+std::string cmGlobalNinjaGenerator::ninjaVersion() const
+{
+ std::string version;
+ std::string command = ninjaCmd() + " --version";
+ cmSystemTools::RunSingleCommand(command.c_str(),
+ &version, 0, 0,
+ cmSystemTools::OUTPUT_NONE);
+
+ return version;
+}
+
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
WriteRule(*this->RulesFileStream,
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index f2643af..f666ee3 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -182,9 +182,6 @@ public:
/// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
static void GetDocumentation(cmDocumentationEntry& entry);
- /// Overloaded methods. @see cmGlobalGenerator::Generate()
- virtual void Generate();
-
/// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile* mf,
@@ -300,8 +297,13 @@ public:
void AddTargetAlias(const std::string& alias, cmTarget* target);
virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+ std::string ninjaVersion() const;
protected:
+ /// Overloaded methods. @see cmGlobalGenerator::Generate()
+ virtual void Generate();
+
/// Overloaded methods.
/// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const { return true; }
@@ -335,8 +337,7 @@ private:
std::string ninjaCmd() const;
-
- /// The file containing the build statement. (the relation ship of the
+ /// The file containing the build statement. (the relationship of the
/// compilation DAG).
cmGeneratedFileStream* BuildFileStream;
/// The file containing the rule statements. (The action attached to each
@@ -363,10 +364,11 @@ private:
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
- //The combined explicit dependencies of all build commands that the global
- //generator has issued. When combined with CombinedBuildOutputs it allows
- //us to detect the set of explicit dependencies that have
- std::set<std::string> CombinedBuildExplicitDependencies;
+ /// The combined explicit dependencies of custom build commands
+ std::set<std::string> CombinedCustomCommandExplicitDependencies;
+
+ /// When combined with CombinedCustomCommandExplicitDependencies it allows
+ /// us to detect the set of explicit dependencies that have
std::set<std::string> CombinedBuildOutputs;
/// The mapping from source file to assumed dependencies.
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 8dae81b..3478534 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -530,7 +530,7 @@ cmGlobalUnixMakefileGenerator3
// Begin the directory-level rules section.
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir, cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE);
+ cmLocalGenerator::MAKERULE);
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Directory level rules for directory "
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index f44dd12..c61c36e 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -71,7 +71,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 86d0de3..d70d2af 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -48,20 +48,22 @@ public:
const char* p = cmVS10GenName(name, genName);
if(!p)
{ return 0; }
- if(strcmp(p, "") == 0)
+ if(!*p)
{
return new cmGlobalVisualStudio10Generator(
- genName, "", "");
+ genName, "");
}
- if(strcmp(p, " Win64") == 0)
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
return new cmGlobalVisualStudio10Generator(
- genName, "x64", "CMAKE_FORCE_WIN64");
+ genName, "x64");
}
- if(strcmp(p, " IA64") == 0)
+ if(strcmp(p, "IA64") == 0)
{
return new cmGlobalVisualStudio10Generator(
- genName, "Itanium", "CMAKE_FORCE_IA64");
+ genName, "Itanium");
}
return 0;
}
@@ -88,16 +90,16 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
- const std::string& name, const std::string& platformName,
- const std::string& additionalPlatformDefinition)
- : cmGlobalVisualStudio8Generator(name, platformName,
- additionalPlatformDefinition)
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio8Generator(name, platformName)
{
std::string vc10Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0\\Setup\\VC;"
"ProductDir", vc10Express, cmSystemTools::KeyWOW64_32);
- this->MasmEnabled = false;
+ this->SystemIsWindowsCE = false;
+ this->SystemIsWindowsPhone = false;
+ this->SystemIsWindowsStore = false;
this->MSBuildCommandInitialized = false;
}
@@ -115,30 +117,158 @@ cmGlobalVisualStudio10Generator::MatchesGeneratorName(
}
//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
+{
+ this->SystemName = s;
+ this->SystemVersion = mf->GetSafeDefinition("CMAKE_SYSTEM_VERSION");
+ if(!this->InitializeSystem(mf))
+ {
+ return false;
+ }
+ return this->cmGlobalVisualStudio8Generator::SetSystemName(s, mf);
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(!this->cmGlobalVisualStudio8Generator::SetGeneratorPlatform(p, mf))
+ {
+ return false;
+ }
+ if(this->GetPlatformName() == "Itanium" || this->GetPlatformName() == "x64")
+ {
+ if(this->IsExpressEdition() && !this->Find64BitTools(mf))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
bool
cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
{
+ if (this->SystemIsWindowsCE && ts.empty() &&
+ this->DefaultPlatformToolset.empty())
+ {
+ cmOStringStream e;
+ e << this->GetName() << " Windows CE version '" << this->SystemVersion
+ << "' requires CMAKE_GENERATOR_TOOLSET to be set.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
this->GeneratorToolset = ts;
- this->AddVSPlatformToolsetDefinition(mf);
+ if(const char* toolset = this->GetPlatformToolset())
+ {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
+{
+ if (this->SystemName == "WindowsCE")
+ {
+ this->SystemIsWindowsCE = true;
+ if (!this->InitializeWindowsCE(mf))
+ {
+ return false;
+ }
+ }
+ else if(this->SystemName == "WindowsPhone")
+ {
+ this->SystemIsWindowsPhone = true;
+ if(!this->InitializeWindowsPhone(mf))
+ {
+ return false;
+ }
+ }
+ else if(this->SystemName == "WindowsStore")
+ {
+ this->SystemIsWindowsStore = true;
+ if(!this->InitializeWindowsStore(mf))
+ {
+ return false;
+ }
+ }
+ else if(this->SystemName == "Android")
+ {
+ if(this->DefaultPlatformName != "Win32")
+ {
+ cmOStringStream e;
+ e << "CMAKE_SYSTEM_NAME is 'Android' but CMAKE_GENERATOR "
+ << "specifies a platform too: '" << this->GetName() << "'";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ std::string v = this->GetInstalledNsightTegraVersion();
+ if(v.empty())
+ {
+ mf->IssueMessage(cmake::FATAL_ERROR,
+ "CMAKE_SYSTEM_NAME is 'Android' but "
+ "'NVIDIA Nsight Tegra Visual Studio Edition' "
+ "is not installed.");
+ return false;
+ }
+ this->DefaultPlatformName = "Tegra-Android";
+ this->DefaultPlatformToolset = "Default";
+ this->NsightTegraVersion = v;
+ mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v.c_str());
+ }
+
return true;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
+bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf)
{
- cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
- this->AddVSPlatformToolsetDefinition(mf);
+ if (this->DefaultPlatformName != "Win32")
+ {
+ cmOStringStream e;
+ e << "CMAKE_SYSTEM_NAME is 'WindowsCE' but CMAKE_GENERATOR "
+ << "specifies a platform too: '" << this->GetName() << "'";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ this->DefaultPlatformToolset = this->SelectWindowsCEToolset();
+
+ return true;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator
-::AddVSPlatformToolsetDefinition(cmMakefile* mf) const
+bool cmGlobalVisualStudio10Generator::InitializeWindowsPhone(cmMakefile* mf)
{
- if(const char* toolset = this->GetPlatformToolset())
+ cmOStringStream e;
+ e << this->GetName() << " does not support Windows Phone.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ cmOStringStream e;
+ e << this->GetName() << " does not support Windows Store.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
+{
+ if (this->SystemVersion == "8.0")
{
- mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
+ return "CE800";
}
+ return "";
}
//----------------------------------------------------------------------------
@@ -160,7 +290,6 @@ cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
{
cmLocalVisualStudio10Generator* lg =
new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS10);
- lg->SetPlatformName(this->GetPlatformName());
lg->SetGlobalGenerator(this);
return lg;
}
@@ -202,23 +331,6 @@ void cmGlobalVisualStudio10Generator
::EnableLanguage(std::vector<std::string>const & lang,
cmMakefile *mf, bool optional)
{
- if(this->PlatformName == "Itanium" || this->PlatformName == "x64")
- {
- if(this->IsExpressEdition() && !this->Find64BitTools(mf))
- {
- return;
- }
- }
-
- for(std::vector<std::string>::const_iterator it = lang.begin();
- it != lang.end(); ++it)
- {
- if(*it == "ASM_MASM")
- {
- this->MasmEnabled = true;
- }
- }
-
cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
}
@@ -436,7 +548,7 @@ bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
// This edition does not come with 64-bit tools. Look for them.
//
// TODO: Detect available tools? x64\v100 exists but does not work?
- // KHLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\4.0;VCTargetsPath
+ // HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\4.0;VCTargetsPath
// c:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/Platforms/
// {Itanium,Win32,x64}/PlatformToolsets/{v100,v90,Windows7.1SDK}
std::string winSDK_7_1;
@@ -500,3 +612,25 @@ bool cmGlobalVisualStudio10Generator::UseFolderProperty()
{
return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty();
}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::IsNsightTegra() const
+{
+ return !this->NsightTegraVersion.empty();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetNsightTegraVersion() const
+{
+ return this->NsightTegraVersion;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion()
+{
+ std::string version;
+ cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Nsight Tegra;"
+ "Version", version, cmSystemTools::KeyWOW64_32);
+ return version;
+}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index b4dcc7e..686dcdf 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -25,12 +25,13 @@ class cmGlobalVisualStudio10Generator :
{
public:
cmGlobalVisualStudio10Generator(const std::string& name,
- const std::string& platformName,
- const std::string& additionalPlatformDefinition);
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
virtual bool MatchesGeneratorName(const std::string& name) const;
+ virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
virtual void GenerateBuildCommand(
@@ -44,15 +45,11 @@ public:
std::vector<std::string> const& makeOptions = std::vector<std::string>()
);
- virtual void AddPlatformDefinitions(cmMakefile* mf);
-
///! create the correct local generator
virtual cmLocalGenerator *CreateLocalGenerator();
- virtual void Generate();
-
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -62,12 +59,31 @@ public:
/** Is the installed VS an Express edition? */
bool IsExpressEdition() const { return this->ExpressEdition; }
- /** Is the Microsoft Assembler enabled? */
- bool IsMasmEnabled() const { return this->MasmEnabled; }
+ /** Generating for Nsight Tegra VS plugin? */
+ bool IsNsightTegra() const;
+ std::string GetNsightTegraVersion() const;
/** The toolset name for the target platform. */
const char* GetPlatformToolset() const;
+ /** Return the CMAKE_SYSTEM_NAME. */
+ std::string const& GetSystemName() const { return this->SystemName; }
+
+ /** Return the CMAKE_SYSTEM_VERSION. */
+ std::string const& GetSystemVersion() const { return this->SystemVersion; }
+
+ /** Return true if building for WindowsCE */
+ bool TargetsWindowsCE() const
+ { return this->SystemIsWindowsCE; }
+
+ /** Return true if building for WindowsPhone */
+ bool TargetsWindowsPhone() const
+ { return this->SystemIsWindowsPhone; }
+
+ /** Return true if building for WindowsStore */
+ bool TargetsWindowsStore() const
+ { return this->SystemIsWindowsStore; }
+
/**
* Where does this version of Visual Studio look for macros for the
* current user? Returns the empty string if this version of Visual
@@ -94,15 +110,31 @@ public:
virtual void FindMakeProgram(cmMakefile*);
+ static std::string GetInstalledNsightTegraVersion();
+
protected:
+ virtual void Generate();
+ virtual bool InitializeSystem(cmMakefile* mf);
+ virtual bool InitializeWindowsCE(cmMakefile* mf);
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual std::string SelectWindowsCEToolset() const;
+ virtual std::string SelectWindowsPhoneToolset() const { return ""; }
+ virtual std::string SelectWindowsStoreToolset() const { return ""; }
+
virtual const char* GetIDEVersion() { return "10.0"; }
std::string const& GetMSBuildCommand();
std::string GeneratorToolset;
std::string DefaultPlatformToolset;
+ std::string SystemName;
+ std::string SystemVersion;
+ std::string NsightTegraVersion;
+ bool SystemIsWindowsCE;
+ bool SystemIsWindowsPhone;
+ bool SystemIsWindowsStore;
bool ExpressEdition;
- bool MasmEnabled;
bool UseFolderProperty();
@@ -123,6 +155,5 @@ private:
virtual std::string FindMSBuildCommand();
virtual std::string FindDevEnvCommand();
virtual std::string GetVSMakeProgram() { return this->GetMSBuildCommand(); }
- void AddVSPlatformToolsetDefinition(cmMakefile* mf) const;
};
#endif
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 7033f2a..39bbdc0 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -43,25 +43,22 @@ public:
const char* p = cmVS11GenName(name, genName);
if(!p)
{ return 0; }
- if(strcmp(p, "") == 0)
+ if(!*p)
{
return new cmGlobalVisualStudio11Generator(
- genName, "", "");
+ genName, "");
}
- if(strcmp(p, " Win64") == 0)
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
return new cmGlobalVisualStudio11Generator(
- genName, "x64", "CMAKE_FORCE_WIN64");
+ genName, "x64");
}
- if(strcmp(p, " ARM") == 0)
+ if(strcmp(p, "ARM") == 0)
{
return new cmGlobalVisualStudio11Generator(
- genName, "ARM", "");
- }
-
- if(*p++ != ' ')
- {
- return 0;
+ genName, "ARM");
}
std::set<std::string> installedSDKs =
@@ -73,7 +70,7 @@ public:
}
cmGlobalVisualStudio11Generator* ret =
- new cmGlobalVisualStudio11Generator(name, p, NULL);
+ new cmGlobalVisualStudio11Generator(name, p);
ret->WindowsCEVersion = "8.00";
return ret;
}
@@ -108,10 +105,8 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
- const std::string& name, const std::string& platformName,
- const std::string& additionalPlatformDefinition)
- : cmGlobalVisualStudio10Generator(name, platformName,
- additionalPlatformDefinition)
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio10Generator(name, platformName)
{
std::string vc11Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
@@ -134,6 +129,56 @@ cmGlobalVisualStudio11Generator::MatchesGeneratorName(
}
//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf)
+{
+ this->DefaultPlatformToolset = this->SelectWindowsPhoneToolset();
+ if(this->DefaultPlatformToolset.empty())
+ {
+ cmOStringStream e;
+ e << this->GetName() << " supports Windows Phone '8.0', but not '"
+ << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ this->DefaultPlatformToolset = this->SelectWindowsStoreToolset();
+ if(this->DefaultPlatformToolset.empty())
+ {
+ cmOStringStream e;
+ e << this->GetName() << " supports Windows Store '8.0', but not '"
+ << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset() const
+{
+ if(this->SystemVersion == "8.0")
+ {
+ return "v110_wp80";
+ }
+ return this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset() const
+{
+ if(this->SystemVersion == "8.0")
+ {
+ return "v110";
+ }
+ return this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset();
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
{
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
@@ -152,7 +197,6 @@ cmLocalGenerator *cmGlobalVisualStudio11Generator::CreateLocalGenerator()
{
cmLocalVisualStudio10Generator* lg =
new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS11);
- lg->SetPlatformName(this->GetPlatformName());
lg->SetGlobalGenerator(this);
return lg;
}
@@ -198,3 +242,17 @@ cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs()
return ret;
}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::NeedsDeploy(cmTarget::TargetType type) const
+{
+ if((type == cmTarget::EXECUTABLE ||
+ type == cmTarget::SHARED_LIBRARY) &&
+ (this->SystemIsWindowsPhone ||
+ this->SystemIsWindowsStore))
+ {
+ return true;
+ }
+ return cmGlobalVisualStudio10Generator::NeedsDeploy(type);
+}
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 48ea489..bbd935c 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -21,8 +21,7 @@ class cmGlobalVisualStudio11Generator:
{
public:
cmGlobalVisualStudio11Generator(const std::string& name,
- const std::string& platformName,
- const std::string& additionalPlatformDefinition);
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
virtual bool MatchesGeneratorName(const std::string& name) const;
@@ -35,9 +34,16 @@ public:
/** TODO: VS 11 user macro support. */
virtual std::string GetUserMacrosDirectory() { return ""; }
protected:
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual std::string SelectWindowsPhoneToolset() const;
+ virtual std::string SelectWindowsStoreToolset() const;
virtual const char* GetIDEVersion() { return "11.0"; }
bool UseFolderProperty();
static std::set<std::string> GetInstalledWindowsCESDKs();
+
+ /** Return true if the configuration needs to be deployed */
+ virtual bool NeedsDeploy(cmTarget::TargetType type) const;
private:
class Factory;
friend class Factory;
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 40f8b05..29ecfe0 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -43,20 +43,22 @@ public:
const char* p = cmVS12GenName(name, genName);
if(!p)
{ return 0; }
- if(strcmp(p, "") == 0)
+ if(!*p)
{
return new cmGlobalVisualStudio12Generator(
- genName, "", "");
+ genName, "");
}
- if(strcmp(p, " Win64") == 0)
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
{
return new cmGlobalVisualStudio12Generator(
- genName, "x64", "CMAKE_FORCE_WIN64");
+ genName, "x64");
}
- if(strcmp(p, " ARM") == 0)
+ if(strcmp(p, "ARM") == 0)
{
return new cmGlobalVisualStudio12Generator(
- genName, "ARM", "");
+ genName, "ARM");
}
return 0;
}
@@ -83,10 +85,8 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
- const std::string& name, const std::string& platformName,
- const std::string& additionalPlatformDefinition)
- : cmGlobalVisualStudio11Generator(name, platformName,
- additionalPlatformDefinition)
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio11Generator(name, platformName)
{
std::string vc12Express;
this->ExpressEdition = cmSystemTools::ReadRegistryValue(
@@ -109,6 +109,56 @@ cmGlobalVisualStudio12Generator::MatchesGeneratorName(
}
//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
+{
+ this->DefaultPlatformToolset = this->SelectWindowsPhoneToolset();
+ if(this->DefaultPlatformToolset.empty())
+ {
+ cmOStringStream e;
+ e << this->GetName() << " supports Windows Phone '8.0' and '8.1', "
+ "but not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf)
+{
+ this->DefaultPlatformToolset = this->SelectWindowsStoreToolset();
+ if(this->DefaultPlatformToolset.empty())
+ {
+ cmOStringStream e;
+ e << this->GetName() << " supports Windows Store '8.0' and '8.1', "
+ "but not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset() const
+{
+ if(this->SystemVersion == "8.1")
+ {
+ return "v120_wp81";
+ }
+ return this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset() const
+{
+ if(this->SystemVersion == "8.1")
+ {
+ return "v120";
+ }
+ return this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset();
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout)
{
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
@@ -127,7 +177,6 @@ cmLocalGenerator *cmGlobalVisualStudio12Generator::CreateLocalGenerator()
{
cmLocalVisualStudio10Generator* lg =
new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS12);
- lg->SetPlatformName(this->GetPlatformName());
lg->SetGlobalGenerator(this);
return lg;
}
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 4557f28..ec85f10 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -21,8 +21,7 @@ class cmGlobalVisualStudio12Generator:
{
public:
cmGlobalVisualStudio12Generator(const std::string& name,
- const std::string& platformName,
- const std::string& additionalPlatformDefinition);
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
virtual bool MatchesGeneratorName(const std::string& name) const;
@@ -40,6 +39,10 @@ public:
//version number
virtual const char* GetToolsVersion() { return "12.0"; }
protected:
+ virtual bool InitializeWindowsPhone(cmMakefile* mf);
+ virtual bool InitializeWindowsStore(cmMakefile* mf);
+ virtual std::string SelectWindowsPhoneToolset() const;
+ virtual std::string SelectWindowsStoreToolset() const;
virtual const char* GetIDEVersion() { return "12.0"; }
private:
class Factory;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
new file mode 100644
index 0000000..d001f93
--- /dev/null
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -0,0 +1,113 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGlobalVisualStudio14Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
+#include "cmMakefile.h"
+
+static const char vs14generatorName[] = "Visual Studio 14";
+
+class cmGlobalVisualStudio14Generator::Factory
+ : public cmGlobalGeneratorFactory
+{
+public:
+ virtual cmGlobalGenerator* CreateGlobalGenerator(
+ const std::string& genName) const
+ {
+ if(strncmp(genName.c_str(), vs14generatorName,
+ sizeof(vs14generatorName) - 1) != 0)
+ {
+ return 0;
+ }
+ const char* p = genName.c_str() + sizeof(vs14generatorName) - 1;
+ if(!*p)
+ {
+ return new cmGlobalVisualStudio14Generator(
+ genName, "");
+ }
+ if(*p++ != ' ')
+ { return 0; }
+ if(strcmp(p, "Win64") == 0)
+ {
+ return new cmGlobalVisualStudio14Generator(
+ genName, "x64");
+ }
+ if(strcmp(p, "ARM") == 0)
+ {
+ return new cmGlobalVisualStudio14Generator(
+ genName, "ARM");
+ }
+ return 0;
+ }
+
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = vs14generatorName;
+ entry.Brief = "Generates Visual Studio 14 project files.";
+ }
+
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs14generatorName);
+ names.push_back(vs14generatorName + std::string(" ARM"));
+ names.push_back(vs14generatorName + std::string(" Win64"));
+ }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
+{
+ return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio12Generator(name, platformName)
+{
+ std::string vc14Express;
+ this->ExpressEdition = cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\14.0\\Setup\\VC;"
+ "ProductDir", vc14Express, cmSystemTools::KeyWOW64_32);
+ this->DefaultPlatformToolset = "v140";
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio14Generator::MatchesGeneratorName(
+ const std::string& name) const
+{
+ return name == this->GetName();
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
+{
+ // Visual Studio 14 writes .sln format 12.00
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ if (this->ExpressEdition)
+ {
+ fout << "# Visual Studio Express 14 for Windows Desktop\n";
+ }
+ else
+ {
+ fout << "# Visual Studio 14\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+cmLocalGenerator *cmGlobalVisualStudio14Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio10Generator* lg =
+ new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS14);
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
new file mode 100644
index 0000000..3fd60a0
--- /dev/null
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -0,0 +1,43 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmGlobalVisualStudio14Generator_h
+#define cmGlobalVisualStudio14Generator_h
+
+#include "cmGlobalVisualStudio12Generator.h"
+
+
+/** \class cmGlobalVisualStudio14Generator */
+class cmGlobalVisualStudio14Generator:
+ public cmGlobalVisualStudio12Generator
+{
+public:
+ cmGlobalVisualStudio14Generator(const std::string& name,
+ const std::string& platformName);
+ static cmGlobalGeneratorFactory* NewFactory();
+
+ virtual bool MatchesGeneratorName(const std::string& name) const;
+
+ virtual void WriteSLNHeader(std::ostream& fout);
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /** TODO: VS 14 user macro support. */
+ virtual std::string GetUserMacrosDirectory() { return ""; }
+
+ virtual const char* GetToolsVersion() { return "14.0"; }
+protected:
+ virtual const char* GetIDEVersion() { return "14.0"; }
+private:
+ class Factory;
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 7397bbb..455a7a2 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -41,7 +41,6 @@ void cmGlobalVisualStudio6Generator
cmMakefile *mf,
bool optional)
{
- cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
this->GenerateConfigurations(mf);
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 2797e11..58efb25 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -42,7 +42,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -64,13 +64,6 @@ public:
);
/**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
-
- /**
* Generate the DSW workspace file.
*/
virtual void OutputDSWFile();
@@ -91,7 +84,10 @@ public:
virtual void FindMakeProgram(cmMakefile*);
+ virtual bool IsForVS6() const { return true; }
+
protected:
+ virtual void Generate();
virtual const char* GetIDEVersion() { return "6.0"; }
private:
virtual std::string GetVSMakeProgram() { return this->GetMSDevCommand(); }
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 4bea5ac..a67a649 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -118,7 +118,7 @@ void cmGlobalVisualStudio71Generator
fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
<< ") = postSolution\n";
// Write out the configurations for all the targets in the project
- this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ this->WriteTargetConfigurations(fout, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
if (useFolderProperty)
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index b581147..401e475 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -23,14 +23,15 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
{
this->IntelProjectVersion = 0;
this->DevEnvCommandInitialized = false;
+ this->MasmEnabled = false;
if (platformName.empty())
{
- this->PlatformName = "Win32";
+ this->DefaultPlatformName = "Win32";
}
else
{
- this->PlatformName = platformName;
+ this->DefaultPlatformName = platformName;
}
}
@@ -80,7 +81,6 @@ void cmGlobalVisualStudio7Generator
{
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
- this->AddPlatformDefinitions(mf);
if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
mf->AddCacheDefinition(
@@ -260,12 +260,38 @@ cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf)
+std::string const& cmGlobalVisualStudio7Generator::GetPlatformName() const
+{
+ if(!this->GeneratorPlatform.empty())
+ {
+ return this->GeneratorPlatform;
+ }
+ return this->DefaultPlatformName;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
{
- cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
- mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
this->GetIntelProjectVersion());
+ return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio7Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(this->GetPlatformName() == "x64")
+ {
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
+ }
+ else if(this->GetPlatformName() == "Itanium")
+ {
+ mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
+ }
+ mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
+ return this->cmGlobalVisualStudioGenerator::SetGeneratorPlatform(p, mf);
}
void cmGlobalVisualStudio7Generator::GenerateConfigurations(cmMakefile* mf)
@@ -366,7 +392,6 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile()
void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
std::ostream& fout,
- cmLocalGenerator* root,
OrderedTargetDependSet const& projectTargets)
{
// loop over again and write out configurations for each target
@@ -392,8 +417,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
else
{
const std::set<std::string>& configsPartOfDefaultBuild =
- this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(),
- target);
+ this->IsPartOfDefaultBuild(projectTargets, target);
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName)
@@ -579,7 +603,7 @@ void cmGlobalVisualStudio7Generator
// Write out the configurations for all the targets in the project
fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
- this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ this->WriteTargetConfigurations(fout, orderedProjectTargets);
fout << "\tEndGlobalSection\n";
// Write out global sections
@@ -767,7 +791,6 @@ void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
const char* typeGuid,
const std::set<std::string>&)
{
- std::string d = cmSystemTools::ConvertToOutputPath(location);
fout << "Project("
<< "\"{"
<< (typeGuid ? typeGuid : this->ExternalProjectType(location))
@@ -981,8 +1004,7 @@ cmGlobalVisualStudio7Generator
std::set<std::string>
cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
- const std::string& project,
- cmTarget const* target)
+ OrderedTargetDependSet const& projectTargets, cmTarget const* target)
{
std::set<std::string> activeConfigs;
// if it is a utilitiy target then only make it part of the
@@ -992,7 +1014,7 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
{
return activeConfigs;
}
- if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target))
+ if(type == cmTarget::UTILITY && !this->IsDependedOn(projectTargets, target))
{
return activeConfigs;
}
@@ -1010,6 +1032,24 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
return activeConfigs;
}
+bool
+cmGlobalVisualStudio7Generator
+::IsDependedOn(OrderedTargetDependSet const& projectTargets,
+ cmTarget const* targetIn)
+{
+ for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
+ l != projectTargets.end(); ++l)
+ {
+ cmTarget const& target = **l;
+ TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
+ if(tgtdeps.count(targetIn))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
//----------------------------------------------------------------------------
static cmVS7FlagTable cmVS7ExtraFlagTable[] =
{
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 1dc709d..201a6a6 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -39,18 +39,20 @@ public:
static std::string GetActualName() {return "Visual Studio 7";}
///! Get the name for the platform.
- const std::string& GetPlatformName() const { return this->PlatformName; }
+ std::string const& GetPlatformName() const;
///! Create a local generator appropriate to this Global Generator
virtual cmLocalGenerator *CreateLocalGenerator();
- virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
+
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -72,13 +74,6 @@ public:
);
/**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
-
- /**
* Generate the DSW workspace file.
*/
virtual void OutputSLNFile();
@@ -109,10 +104,14 @@ public:
virtual void FindMakeProgram(cmMakefile*);
+ /** Is the Microsoft Assembler enabled? */
+ bool IsMasmEnabled() const { return this->MasmEnabled; }
+
// Encoding for Visual Studio files
virtual std::string Encoding();
protected:
+ virtual void Generate();
virtual const char* GetIDEVersion() { return "7.0"; }
std::string const& GetDevEnvCommand();
@@ -150,7 +149,6 @@ protected:
OrderedTargetDependSet const& projectTargets);
virtual void WriteTargetConfigurations(
std::ostream& fout,
- cmLocalGenerator* root,
OrderedTargetDependSet const& projectTargets);
void GenerateConfigurations(cmMakefile* mf);
@@ -164,8 +162,11 @@ protected:
std::string ConvertToSolutionPath(const char* path);
- std::set<std::string> IsPartOfDefaultBuild(const std::string& project,
- cmTarget const* target);
+ std::set<std::string>
+ IsPartOfDefaultBuild(OrderedTargetDependSet const& projectTargets,
+ cmTarget const* target);
+ bool IsDependedOn(OrderedTargetDependSet const& projectTargets,
+ cmTarget const* target);
std::vector<std::string> Configurations;
std::map<std::string, std::string> GUIDMap;
@@ -176,7 +177,9 @@ protected:
// Set during OutputSLNFile with the name of the current project.
// There is one SLN file per project.
std::string CurrentProject;
- std::string PlatformName;
+ std::string GeneratorPlatform;
+ std::string DefaultPlatformName;
+ bool MasmEnabled;
private:
char* IntelProjectVersion;
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index e6672a8..745515b 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -36,7 +36,7 @@ public:
if(p[0] == '\0')
{
return new cmGlobalVisualStudio8Generator(
- name, "", "");
+ name, "");
}
if(p[0] != ' ')
@@ -49,7 +49,7 @@ public:
if(!strcmp(p, "Win64"))
{
return new cmGlobalVisualStudio8Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ name, "x64");
}
cmVisualStudioWCEPlatformParser parser(p);
@@ -60,7 +60,7 @@ public:
}
cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator(
- name, p, "");
+ name, p);
ret->WindowsCEVersion = parser.GetOSVersion();
return ret;
}
@@ -93,17 +93,11 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio8Generator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(
- const std::string& name, const std::string& platformName,
- const std::string& additionalPlatformDefinition)
+ const std::string& name, const std::string& platformName)
: cmGlobalVisualStudio71Generator(platformName)
{
this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms";
this->Name = name;
-
- if (!additionalPlatformDefinition.empty())
- {
- this->AdditionalPlatformDefinition = additionalPlatformDefinition;
- }
}
//----------------------------------------------------------------------------
@@ -132,17 +126,31 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator()
{
cmLocalVisualStudio7Generator *lg =
new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8);
- lg->SetPlatformName(this->GetPlatformName());
lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
lg->SetGlobalGenerator(this);
return lg;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
+void cmGlobalVisualStudio8Generator
+::EnableLanguage(std::vector<std::string>const & lang,
+ cmMakefile *mf, bool optional)
{
- cmGlobalVisualStudio71Generator::AddPlatformDefinitions(mf);
+ for(std::vector<std::string>::const_iterator it = lang.begin();
+ it != lang.end(); ++it)
+ {
+ if(*it == "ASM_MASM")
+ {
+ this->MasmEnabled = true;
+ }
+ }
+ this->AddPlatformDefinitions(mf);
+ cmGlobalVisualStudio7Generator::EnableLanguage(lang, mf, optional);
+}
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
if(this->TargetsWindowsCE())
{
mf->AddDefinition("CMAKE_VS_WINCE_VERSION",
@@ -151,6 +159,21 @@ void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
}
//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p,
+ cmMakefile* mf)
+{
+ if(this->DefaultPlatformName == "Win32")
+ {
+ this->GeneratorPlatform = p;
+ return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf);
+ }
+ else
+ {
+ return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform(p, mf);
+ }
+}
+
+//----------------------------------------------------------------------------
// ouput standard header for dsw file
void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
{
@@ -398,9 +421,7 @@ cmGlobalVisualStudio8Generator
platformMapping : this->GetPlatformName())
<< "\n";
}
- bool needsDeploy = (type == cmTarget::EXECUTABLE ||
- type == cmTarget::SHARED_LIBRARY);
- if(this->TargetsWindowsCE() && needsDeploy)
+ if(this->NeedsDeploy(type))
{
fout << "\t\t{" << guid << "}." << *i
<< "|" << this->GetPlatformName() << ".Deploy.0 = " << *i << "|"
@@ -412,6 +433,15 @@ cmGlobalVisualStudio8Generator
}
//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio8Generator::NeedsDeploy(cmTarget::TargetType type) const
+{
+ bool needsDeploy = (type == cmTarget::EXECUTABLE ||
+ type == cmTarget::SHARED_LIBRARY);
+ return this->TargetsWindowsCE() && needsDeploy;
+}
+
+//----------------------------------------------------------------------------
bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
{
// Skip over the cmGlobalVisualStudioGenerator implementation!
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 2459c05..4b41ed7 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -24,8 +24,7 @@ class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator
{
public:
cmGlobalVisualStudio8Generator(const std::string& name,
- const std::string& platformName,
- const std::string& additionalPlatformDefinition);
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
///! Get the name for the generator.
@@ -37,14 +36,17 @@ public:
///! Create a local generator appropriate to this Global Generator
virtual cmLocalGenerator *CreateLocalGenerator();
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+
/**
* Override Configure and Generate to add the build-system check
* target.
*/
virtual void Configure();
- virtual void Generate();
/**
* Where does this version of Visual Studio look for macros for the
@@ -68,6 +70,7 @@ public:
return !this->WindowsCEVersion.empty(); }
protected:
+ virtual void Generate();
virtual const char* GetIDEVersion() { return "8.0"; }
virtual std::string FindDevEnvCommand();
@@ -76,6 +79,9 @@ protected:
bool AddCheckTarget();
+ /** Return true if the configuration needs to be deployed */
+ virtual bool NeedsDeploy(cmTarget::TargetType type) const;
+
static cmIDEFlagTable const* GetExtraFlagTableVS8();
virtual void WriteSLNHeader(std::ostream& fout);
virtual void WriteSolutionConfigurations(std::ostream& fout);
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index c0051c7..1d73b5c 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -34,7 +34,7 @@ public:
if(p[0] == '\0')
{
return new cmGlobalVisualStudio9Generator(
- name, "", "");
+ name, "");
}
if(p[0] != ' ')
@@ -47,13 +47,13 @@ public:
if(!strcmp(p, "IA64"))
{
return new cmGlobalVisualStudio9Generator(
- name, "Itanium", "CMAKE_FORCE_IA64");
+ name, "Itanium");
}
if(!strcmp(p, "Win64"))
{
return new cmGlobalVisualStudio9Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ name, "x64");
}
cmVisualStudioWCEPlatformParser parser(p);
@@ -64,7 +64,7 @@ public:
}
cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator(
- name, p, NULL);
+ name, p);
ret->WindowsCEVersion = parser.GetOSVersion();
return ret;
}
@@ -98,10 +98,8 @@ cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
//----------------------------------------------------------------------------
cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
- const std::string& name, const std::string& platformName,
- const std::string& additionalPlatformDefinition)
- : cmGlobalVisualStudio8Generator(name, platformName,
- additionalPlatformDefinition)
+ const std::string& name, const std::string& platformName)
+ : cmGlobalVisualStudio8Generator(name, platformName)
{
}
@@ -117,21 +115,12 @@ cmLocalGenerator *cmGlobalVisualStudio9Generator::CreateLocalGenerator()
{
cmLocalVisualStudio7Generator *lg
= new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9);
- lg->SetPlatformName(this->GetPlatformName());
lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
lg->SetGlobalGenerator(this);
return lg;
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9Generator
-::EnableLanguage(std::vector<std::string>const & lang,
- cmMakefile *mf, bool optional)
-{
- cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
-}
-
-//----------------------------------------------------------------------------
std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
{
std::string base;
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
index fb87bbe..0a191cd 100644
--- a/Source/cmGlobalVisualStudio9Generator.h
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -25,19 +25,16 @@ class cmGlobalVisualStudio9Generator :
{
public:
cmGlobalVisualStudio9Generator(const std::string& name,
- const std::string& platformName,
- const std::string& additionalPlatformDefinition);
+ const std::string& platformName);
static cmGlobalGeneratorFactory* NewFactory();
///! create the correct local generator
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
- virtual void EnableLanguage(std::vector<std::string>const& languages,
- cmMakefile *, bool optional);
virtual void WriteSLNHeader(std::ostream& fout);
/**
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index c5a0e29..2dab23c 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -23,7 +23,6 @@
//----------------------------------------------------------------------------
cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
{
- this->AdditionalPlatformDefinition = "";
}
//----------------------------------------------------------------------------
@@ -478,15 +477,6 @@ void cmGlobalVisualStudioGenerator::FindMakeProgram(cmMakefile* mf)
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf)
-{
- if(!this->AdditionalPlatformDefinition.empty())
- {
- mf->AddDefinition(this->AdditionalPlatformDefinition, "TRUE");
- }
-}
-
-//----------------------------------------------------------------------------
std::string
cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget const* target)
{
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 1ab8990..356f4d4 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -27,11 +27,6 @@ public:
virtual ~cmGlobalVisualStudioGenerator();
/**
- * Basic generate implementation for all VS generators.
- */
- virtual void Generate();
-
- /**
* Configure CMake's Visual Studio macros file into the user's Visual
* Studio macros directory.
*/
@@ -90,6 +85,8 @@ public:
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
protected:
+ virtual void Generate();
+
// Does this VS version link targets to each other if there are
// dependencies in the SLN file? This was done for VS versions
// below 8.
@@ -97,8 +94,6 @@ protected:
virtual const char* GetIDEVersion() = 0;
- virtual void AddPlatformDefinitions(cmMakefile* mf);
-
virtual bool ComputeTargetDepends();
class VSDependSet: public std::set<std::string> {};
class VSDependMap: public std::map<cmTarget const*, VSDependSet> {};
@@ -111,7 +106,6 @@ protected:
std::string GetUtilityDepend(cmTarget const* target);
typedef std::map<cmTarget const*, std::string> UtilityDependsMap;
UtilityDependsMap UtilityDepends;
- std::string AdditionalPlatformDefinition;
private:
virtual std::string GetVSMakeProgram() = 0;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 2057a42..0e577b5 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -38,7 +38,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 29a5955..13e6988 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -208,8 +208,11 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
if(this->XcodeVersion >= 30)
{
this->GeneratorToolset = ts;
- mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
- this->GeneratorToolset.c_str());
+ if(!this->GeneratorToolset.empty())
+ {
+ mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
+ this->GeneratorToolset.c_str());
+ }
return true;
}
else
@@ -830,16 +833,14 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
const std::string &lang,
cmSourceFile* sf)
{
- std::string fname = fullpath;
- cmXCodeObject* fileRef = this->FileRefs[fname];
+ std::string key = GetGroupMapKeyFromPath(cmtarget, fullpath);
+ cmXCodeObject* fileRef = this->FileRefs[key];
if(!fileRef)
{
fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
- std::string comment = fname;
- fileRef->SetComment(fname.c_str());
- this->FileRefs[fname] = fileRef;
+ fileRef->SetComment(fullpath);
+ this->FileRefs[key] = fileRef;
}
- std::string key = GetGroupMapKeyFromPath(cmtarget, fullpath);
cmXCodeObject* group = this->GroupMap[key];
cmXCodeObject* children = group->GetObject("children");
if (!children->HasObject(fileRef))
@@ -864,24 +865,24 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
}
if(fileType.empty())
{
+ // Compute the extension without leading '.'.
+ std::string ext = cmSystemTools::GetFilenameLastExtension(fullpath);
+ if(!ext.empty())
+ {
+ ext = ext.substr(1);
+ }
+
// If fullpath references a directory, then we need to specify
// lastKnownFileType as folder in order for Xcode to be able to
// open the contents of the folder.
// (Xcode 4.6 does not like explicitFileType=folder).
if(cmSystemTools::FileIsDirectory(fullpath.c_str()))
{
- fileType = "folder";
+ fileType = (ext == "xcassets"? "folder.assetcatalog" : "folder");
useLastKnownFileType = true;
}
else
{
- // Compute the extension without leading '.'.
- std::string ext = cmSystemTools::GetFilenameLastExtension(fullpath);
- if(!ext.empty())
- {
- ext = ext.substr(1);
- }
-
fileType = GetSourcecodeValueFromFileExtension(
ext, lang, useLastKnownFileType);
}
@@ -1255,7 +1256,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
// If the language is compiled as a source trust Xcode to link with it.
cmTarget::LinkImplementation const* impl =
- cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
+ cmtarget.GetLinkImplementation("NOCONFIG");
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
@@ -2299,7 +2300,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
}
- buildSettings->AddAttribute("OTHER_LDFLAGS",
+ buildSettings->AddAttribute(this->GetTargetLinkFlagsVar(target),
this->CreateString(extraLinkOptions.c_str()));
buildSettings->AddAttribute("OTHER_REZFLAGS",
this->CreateString(""));
@@ -2527,6 +2528,22 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
}
//----------------------------------------------------------------------------
+const char*
+cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(cmTarget const& cmtarget) const
+{
+ if(this->XcodeVersion >= 60 &&
+ (cmtarget.GetType() == cmTarget::STATIC_LIBRARY ||
+ cmtarget.GetType() == cmTarget::OBJECT_LIBRARY))
+ {
+ return "OTHER_LIBTOOLFLAGS";
+ }
+ else
+ {
+ return "OTHER_LDFLAGS";
+ }
+}
+
+//----------------------------------------------------------------------------
const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
{
switch(cmtarget.GetType())
@@ -2835,8 +2852,9 @@ void cmGlobalXCodeGenerator
sep = " ";
linkObjs += this->XCodeEscapePath(oi->c_str());
}
- this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
- linkObjs.c_str(), configName);
+ this->AppendBuildSettingAttribute(
+ target, this->GetTargetLinkFlagsVar(*cmtarget),
+ linkObjs.c_str(), configName);
}
// Skip link information for object libraries.
@@ -2914,8 +2932,9 @@ void cmGlobalXCodeGenerator
target->AddDependTarget(configName, li->Target->GetName());
}
}
- this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
- linkLibs.c_str(), configName);
+ this->AppendBuildSettingAttribute(
+ target, this->GetTargetLinkFlagsVar(*cmtarget),
+ linkLibs.c_str(), configName);
}
}
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index ae23e3b..9d7b784 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -44,7 +44,7 @@ public:
virtual cmLocalGenerator *CreateLocalGenerator();
/**
- * Try to determine system infomation such as shared library
+ * Try to determine system information such as shared library
* extension, pthreads, byte order etc.
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
@@ -64,13 +64,6 @@ public:
std::vector<std::string> const& makeOptions = std::vector<std::string>()
);
- /**
- * Generate the all required files for building this project/tree. This
- * basically creates a series of LocalGenerators for each directory and
- * requests that they Generate.
- */
- virtual void Generate();
-
/** Append the subdirectory for the given configuration. */
virtual void AppendDirectoryForConfig(const std::string& prefix,
const std::string& config,
@@ -91,6 +84,8 @@ public:
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
void AppendFlag(std::string& flags, std::string const& flag);
+protected:
+ virtual void Generate();
private:
cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
cmSourceGroup* sg);
@@ -139,6 +134,7 @@ private:
cmXCodeObject* buildPhases);
void ForceLinkerLanguages();
void ForceLinkerLanguage(cmTarget& cmtarget);
+ const char* GetTargetLinkFlagsVar(cmTarget const& cmtarget) const;
const char* GetTargetFileType(cmTarget& cmtarget);
const char* GetTargetProductType(cmTarget& cmtarget);
std::string AddConfigurations(cmXCodeObject* target, cmTarget& cmtarget);
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 1f3c066..0eb903d 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -152,18 +152,7 @@ void cmIDEOptions::FlagMapUpdate(cmIDEFlagTable const* entry,
}
else if(entry->special & cmIDEFlagTable::SemicolonAppendable)
{
- std::map<std::string,std::string>::iterator itr;
- itr = this->FlagMap.find(entry->IDEName);
- if(itr != this->FlagMap.end())
- {
- // Append to old value (if present) with semicolons;
- itr->second += ";";
- itr->second += new_value;
- }
- else
- {
- this->FlagMap[entry->IDEName] = new_value;
- }
+ this->FlagMap[entry->IDEName].push_back(new_value);
}
else
{
@@ -200,18 +189,47 @@ void cmIDEOptions::AddFlag(const char* flag, const char* value)
}
//----------------------------------------------------------------------------
+void cmIDEOptions::AddFlag(const char* flag,
+ std::vector<std::string> const& value)
+{
+ this->FlagMap[flag] = value;
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AppendFlag(std::string const& flag,
+ std::string const& value)
+{
+ this->FlagMap[flag].push_back(value);
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AppendFlag(std::string const& flag,
+ std::vector<std::string> const& value)
+{
+ FlagValue& fv = this->FlagMap[flag];
+ std::copy(value.begin(), value.end(), std::back_inserter(fv));
+}
+
+//----------------------------------------------------------------------------
void cmIDEOptions::RemoveFlag(const char* flag)
{
this->FlagMap.erase(flag);
}
//----------------------------------------------------------------------------
+bool cmIDEOptions::HasFlag(std::string const& flag) const
+{
+ return this->FlagMap.find(flag) != this->FlagMap.end();
+}
+
+//----------------------------------------------------------------------------
const char* cmIDEOptions::GetFlag(const char* flag)
{
- std::map<std::string, std::string>::iterator i = this->FlagMap.find(flag);
- if(i != this->FlagMap.end())
+ // This method works only for single-valued flags!
+ std::map<std::string, FlagValue>::iterator i = this->FlagMap.find(flag);
+ if(i != this->FlagMap.end() && i->second.size() == 1)
{
- return i->second.c_str();
+ return i->second[0].c_str();
}
return 0;
}
diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h
index e7749ec..7386016 100644
--- a/Source/cmIDEOptions.h
+++ b/Source/cmIDEOptions.h
@@ -29,7 +29,12 @@ public:
void AddDefines(const char* defines);
void AddDefines(const std::vector<std::string> &defines);
void AddFlag(const char* flag, const char* value);
+ void AddFlag(const char* flag, std::vector<std::string> const& value);
+ void AppendFlag(std::string const& flag, std::string const& value);
+ void AppendFlag(std::string const& flag,
+ std::vector<std::string> const& value);
void RemoveFlag(const char* flag);
+ bool HasFlag(std::string const& flag) const;
const char* GetFlag(const char* flag);
protected:
@@ -40,7 +45,23 @@ protected:
// Then parse the command line flags specified in CMAKE_CXX_FLAGS
// and CMAKE_C_FLAGS
// and overwrite or add new values to this map
- std::map<std::string, std::string> FlagMap;
+ class FlagValue: public std::vector<std::string>
+ {
+ typedef std::vector<std::string> derived;
+ public:
+ FlagValue& operator=(std::string const& r)
+ {
+ this->resize(1);
+ this->operator[](0) = r;
+ return *this;
+ }
+ FlagValue& operator=(std::vector<std::string> const& r)
+ {
+ this->derived::operator=(r);
+ return *this;
+ }
+ };
+ std::map<std::string, FlagValue > FlagMap;
// Preprocessor definitions.
std::vector<std::string> Defines;
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 1141b01..f728c15 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -12,21 +12,23 @@
#include "cmIfCommand.h"
#include "cmStringCommand.h"
+#include "cmConditionEvaluator.h"
+
#include <stdlib.h> // required for atof
#include <list>
#include <cmsys/RegularExpression.hxx>
static std::string cmIfCommandError(
- cmMakefile* mf, std::vector<std::string> const& args)
+ cmMakefile* mf, std::vector<cmExpandedCommandArgument> const& args)
{
cmLocalGenerator* lg = mf->GetLocalGenerator();
std::string err = "given arguments:\n ";
- for(std::vector<std::string>::const_iterator i = args.begin();
+ for(std::vector<cmExpandedCommandArgument>::const_iterator i = args.begin();
i != args.end(); ++i)
{
err += " ";
- err += lg->EscapeForCMake(*i);
+ err += lg->EscapeForCMake(i->GetValue());
}
err += "\n";
return err;
@@ -103,14 +105,16 @@ IsFunctionBlocked(const cmListFileFunction& lff,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Functions[c].Arguments,
expandedArguments);
cmake::MessageType messType;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments, errorString,
- &mf, messType);
+
+ cmConditionEvaluator conditionEvaluator(mf);
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messType);
if (errorString.size())
{
@@ -185,13 +189,15 @@ bool cmIfCommand
{
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
this->Makefile->ExpandArguments(args, expandedArguments);
cmake::MessageType status;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- this->Makefile, status);
+
+ cmConditionEvaluator conditionEvaluator(*(this->Makefile));
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, status);
if (errorString.size())
{
@@ -222,698 +228,3 @@ bool cmIfCommand
return true;
}
-
-namespace
-{
- //=========================================================================
- bool GetBooleanValue(std::string& arg, cmMakefile* mf)
- {
- // Check basic constants.
- if (arg == "0")
- {
- return false;
- }
- if (arg == "1")
- {
- return true;
- }
-
- // Check named constants.
- if (cmSystemTools::IsOn(arg.c_str()))
- {
- return true;
- }
- if (cmSystemTools::IsOff(arg.c_str()))
- {
- return false;
- }
-
- // Check for numbers.
- if(!arg.empty())
- {
- char* end;
- double d = strtod(arg.c_str(), &end);
- if(*end == '\0')
- {
- // The whole string is a number. Use C conversion to bool.
- return d? true:false;
- }
- }
-
- // Check definition.
- const char* def = mf->GetDefinition(arg);
- return !cmSystemTools::IsOff(def);
- }
-
- //=========================================================================
- // Boolean value behavior from CMake 2.6.4 and below.
- bool GetBooleanValueOld(std::string const& arg, cmMakefile* mf, bool one)
- {
- if(one)
- {
- // Old IsTrue behavior for single argument.
- if(arg == "0")
- { return false; }
- else if(arg == "1")
- { return true; }
- else
- { return !cmSystemTools::IsOff(mf->GetDefinition(arg)); }
- }
- else
- {
- // Old GetVariableOrNumber behavior.
- const char* def = mf->GetDefinition(arg);
- if(!def && atoi(arg.c_str()))
- {
- def = arg.c_str();
- }
- return !cmSystemTools::IsOff(def);
- }
- }
-
- //=========================================================================
- // returns the resulting boolean value
- bool GetBooleanValueWithAutoDereference(
- std::string &newArg,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status,
- bool oneArg = false)
- {
- // Use the policy if it is set.
- if (Policy12Status == cmPolicies::NEW)
- {
- return GetBooleanValue(newArg, makefile);
- }
- else if (Policy12Status == cmPolicies::OLD)
- {
- return GetBooleanValueOld(newArg, makefile, oneArg);
- }
-
- // Check policy only if old and new results differ.
- bool newResult = GetBooleanValue(newArg, makefile);
- bool oldResult = GetBooleanValueOld(newArg, makefile, oneArg);
- if(newResult != oldResult)
- {
- switch(Policy12Status)
- {
- case cmPolicies::WARN:
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
- + "\" appears in a conditional statement. "
- + policies->GetPolicyWarning(cmPolicies::CMP0012);
- status = cmake::AUTHOR_WARNING;
- }
- case cmPolicies::OLD:
- return oldResult;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- {
- cmPolicies* policies = makefile->GetPolicies();
- errorString = "An argument named \"" + newArg
- + "\" appears in a conditional statement. "
- + policies->GetRequiredPolicyError(cmPolicies::CMP0012);
- status = cmake::FATAL_ERROR;
- }
- case cmPolicies::NEW:
- break;
- }
- }
- return newResult;
- }
-
- //=========================================================================
- void IncrementArguments(std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if (argP1 != newArgs.end())
- {
- argP1++;
- argP2 = argP1;
- if (argP1 != newArgs.end())
- {
- argP2++;
- }
- }
- }
-
- //=========================================================================
- // helper function to reduce code duplication
- void HandlePredicate(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- //=========================================================================
- // helper function to reduce code duplication
- void HandleBinaryOp(bool value, int &reducible,
- std::list<std::string>::iterator &arg,
- std::list<std::string> &newArgs,
- std::list<std::string>::iterator &argP1,
- std::list<std::string>::iterator &argP2)
- {
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- //=========================================================================
- // level 0 processes parenthetical expressions
- bool HandleLevel0(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmake::MessageType &status)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- while (arg != newArgs.end())
- {
- if (*arg == "(")
- {
- // search for the closing paren for this opening one
- std::list<std::string>::iterator argClose;
- argClose = arg;
- argClose++;
- unsigned int depth = 1;
- while (argClose != newArgs.end() && depth)
- {
- if (*argClose == "(")
- {
- depth++;
- }
- if (*argClose == ")")
- {
- depth--;
- }
- argClose++;
- }
- if (depth)
- {
- errorString = "mismatched parenthesis in condition";
- status = cmake::FATAL_ERROR;
- return false;
- }
- // store the reduced args in this vector
- std::vector<std::string> newArgs2;
-
- // copy to the list structure
- std::list<std::string>::iterator argP1 = arg;
- argP1++;
- for(; argP1 != argClose; argP1++)
- {
- newArgs2.push_back(*argP1);
- }
- newArgs2.pop_back();
- // now recursively invoke IsTrue to handle the values inside the
- // parenthetical expression
- bool value =
- cmIfCommand::IsTrue(newArgs2, errorString, makefile, status);
- if(value)
- {
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- argP1 = arg;
- argP1++;
- // remove the now evaluated parenthetical expression
- newArgs.erase(argP1,argClose);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level one handles most predicates except for NOT
- bool HandleLevel1(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &, cmake::MessageType &)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- // does a file exist
- if (*arg == "EXISTS" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileExists((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a directory with this name exist
- if (*arg == "IS_DIRECTORY" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsDirectory((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a symlink with this name exist
- if (*arg == "IS_SYMLINK" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsSymlink((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // is the given path an absolute path ?
- if (*arg == "IS_ABSOLUTE" && argP1 != newArgs.end())
- {
- HandlePredicate(
- cmSystemTools::FileIsFullPath((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a command exist
- if (*arg == "COMMAND" && argP1 != newArgs.end())
- {
- HandlePredicate(
- makefile->CommandExists((argP1)->c_str()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a policy exist
- if (*arg == "POLICY" && argP1 != newArgs.end())
- {
- cmPolicies::PolicyID pid;
- HandlePredicate(
- makefile->GetPolicies()->GetPolicyID((argP1)->c_str(), pid),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a target exist
- if (*arg == "TARGET" && argP1 != newArgs.end())
- {
- HandlePredicate(
- makefile->FindTargetToUse(*argP1)?true:false,
- reducible, arg, newArgs, argP1, argP2);
- }
- // is a variable defined
- if (*arg == "DEFINED" && argP1 != newArgs.end())
- {
- size_t argP1len = argP1->size();
- bool bdef = false;
- if(argP1len > 4 && argP1->substr(0, 4) == "ENV{" &&
- argP1->operator[](argP1len-1) == '}')
- {
- std::string env = argP1->substr(4, argP1len-5);
- bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
- }
- else
- {
- bdef = makefile->IsDefinitionSet(*(argP1));
- }
- HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level two handles most binary operations except for AND OR
- bool HandleLevel2(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmake::MessageType &status)
- {
- int reducible;
- const char *def;
- const char *def2;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- *(argP1) == "MATCHES")
- {
- def = cmIfCommand::GetVariableOrString(*arg, makefile);
- const char* rex = (argP2)->c_str();
- makefile->ClearMatches();
- cmsys::RegularExpression regEntry;
- if ( !regEntry.compile(rex) )
- {
- cmOStringStream error;
- error << "Regular expression \"" << rex << "\" cannot compile";
- errorString = error.str();
- status = cmake::FATAL_ERROR;
- return false;
- }
- if (regEntry.find(def))
- {
- makefile->StoreMatches(regEntry);
- *arg = "1";
- }
- else
- {
- *arg = "0";
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- if (argP1 != newArgs.end() && *arg == "MATCHES")
- {
- *arg = "0";
- newArgs.erase(argP1);
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- reducible = 1;
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "LESS" || *(argP1) == "GREATER" ||
- *(argP1) == "EQUAL"))
- {
- def = cmIfCommand::GetVariableOrString(*arg, makefile);
- def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
- double lhs;
- double rhs;
- bool result;
- if(sscanf(def, "%lg", &lhs) != 1 ||
- sscanf(def2, "%lg", &rhs) != 1)
- {
- result = false;
- }
- else if (*(argP1) == "LESS")
- {
- result = (lhs < rhs);
- }
- else if (*(argP1) == "GREATER")
- {
- result = (lhs > rhs);
- }
- else
- {
- result = (lhs == rhs);
- }
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "STRLESS" ||
- *(argP1) == "STREQUAL" ||
- *(argP1) == "STRGREATER"))
- {
- def = cmIfCommand::GetVariableOrString(*arg, makefile);
- def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
- int val = strcmp(def,def2);
- bool result;
- if (*(argP1) == "STRLESS")
- {
- result = (val < 0);
- }
- else if (*(argP1) == "STRGREATER")
- {
- result = (val > 0);
- }
- else // strequal
- {
- result = (val == 0);
- }
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (*(argP1) == "VERSION_LESS" || *(argP1) == "VERSION_GREATER" ||
- *(argP1) == "VERSION_EQUAL"))
- {
- def = cmIfCommand::GetVariableOrString(*arg, makefile);
- def2 = cmIfCommand::GetVariableOrString(*argP2, makefile);
- cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL;
- if(*argP1 == "VERSION_LESS")
- {
- op = cmSystemTools::OP_LESS;
- }
- else if(*argP1 == "VERSION_GREATER")
- {
- op = cmSystemTools::OP_GREATER;
- }
- bool result = cmSystemTools::VersionCompare(op, def, def2);
- HandleBinaryOp(result,
- reducible, arg, newArgs, argP1, argP2);
- }
-
- // is file A newer than file B
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- *(argP1) == "IS_NEWER_THAN")
- {
- int fileIsNewer=0;
- bool success=cmSystemTools::FileTimeCompare(arg->c_str(),
- (argP2)->c_str(),
- &fileIsNewer);
- HandleBinaryOp(
- (success==false || fileIsNewer==1 || fileIsNewer==0),
- reducible, arg, newArgs, argP1, argP2);
- }
-
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level 3 handles NOT
- bool HandleLevel3(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
- {
- int reducible;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && *arg == "NOT")
- {
- bool rhs = GetBooleanValueWithAutoDereference(*argP1, makefile,
- errorString,
- Policy12Status,
- status);
- HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-
- //=========================================================================
- // level 4 handles AND OR
- bool HandleLevel4(std::list<std::string> &newArgs,
- cmMakefile *makefile,
- std::string &errorString,
- cmPolicies::PolicyStatus Policy12Status,
- cmake::MessageType &status)
- {
- int reducible;
- bool lhs;
- bool rhs;
- do
- {
- reducible = 0;
- std::list<std::string>::iterator arg = newArgs.begin();
- std::list<std::string>::iterator argP1;
- std::list<std::string>::iterator argP2;
- while (arg != newArgs.end())
- {
- argP1 = arg;
- IncrementArguments(newArgs,argP1,argP2);
- if (argP1 != newArgs.end() && *(argP1) == "AND" &&
- argP2 != newArgs.end())
- {
- lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
- errorString,
- Policy12Status,
- status);
- rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
- errorString,
- Policy12Status,
- status);
- HandleBinaryOp((lhs && rhs),
- reducible, arg, newArgs, argP1, argP2);
- }
-
- if (argP1 != newArgs.end() && *(argP1) == "OR" &&
- argP2 != newArgs.end())
- {
- lhs = GetBooleanValueWithAutoDereference(*arg, makefile,
- errorString,
- Policy12Status,
- status);
- rhs = GetBooleanValueWithAutoDereference(*argP2, makefile,
- errorString,
- Policy12Status,
- status);
- HandleBinaryOp((lhs || rhs),
- reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
- }
- }
- while (reducible);
- return true;
- }
-}
-
-
-//=========================================================================
-// order of operations,
-// 1. ( ) -- parenthetical groups
-// 2. IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
-// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
-// 4. NOT
-// 5. AND OR
-//
-// There is an issue on whether the arguments should be values of references,
-// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
-// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
-// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
-// take numeric values or variable names. STRLESS and STRGREATER take
-// variable names but if the variable name is not found it will use the name
-// directly. AND OR take variables or the values 0 or 1.
-
-
-bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
- std::string &errorString, cmMakefile *makefile,
- cmake::MessageType &status)
-{
- errorString = "";
-
- // handle empty invocation
- if (args.size() < 1)
- {
- return false;
- }
-
- // store the reduced args in this vector
- std::list<std::string> newArgs;
-
- // copy to the list structure
- for(unsigned int i = 0; i < args.size(); ++i)
- {
- newArgs.push_back(args[i]);
- }
-
- // now loop through the arguments and see if we can reduce any of them
- // we do this multiple times. Once for each level of precedence
- // parens
- if (!HandleLevel0(newArgs, makefile, errorString, status))
- {
- return false;
- }
- //predicates
- if (!HandleLevel1(newArgs, makefile, errorString, status))
- {
- return false;
- }
- // binary ops
- if (!HandleLevel2(newArgs, makefile, errorString, status))
- {
- return false;
- }
-
- // used to store the value of policy CMP0012 for performance
- cmPolicies::PolicyStatus Policy12Status =
- makefile->GetPolicyStatus(cmPolicies::CMP0012);
-
- // NOT
- if (!HandleLevel3(newArgs, makefile, errorString,
- Policy12Status, status))
- {
- return false;
- }
- // AND OR
- if (!HandleLevel4(newArgs, makefile, errorString,
- Policy12Status, status))
- {
- return false;
- }
-
- // now at the end there should only be one argument left
- if (newArgs.size() != 1)
- {
- errorString = "Unknown arguments specified";
- status = cmake::FATAL_ERROR;
- return false;
- }
-
- return GetBooleanValueWithAutoDereference(*(newArgs.begin()),
- makefile,
- errorString,
- Policy12Status,
- status, true);
-}
-
-//=========================================================================
-const char* cmIfCommand::GetVariableOrString(const std::string& str,
- const cmMakefile* mf)
-{
- const char* def = mf->GetDefinition(str);
- if(!def)
- {
- def = str.c_str();
- }
- return def;
-}
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index 814c052..689efce 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -70,17 +70,9 @@ public:
*/
virtual bool IsScriptable() const { return true; }
- // this is a shared function for both If and Else to determine if the
- // arguments were valid, and if so, was the response true. If there is
- // an error, the errorString will be set.
- static bool IsTrue(const std::vector<std::string> &args,
- std::string &errorString, cmMakefile *mf,
- cmake::MessageType &status);
-
- // Get a definition from the makefile. If it doesn't exist,
- // return the original string.
- static const char* GetVariableOrString(const std::string& str,
- const cmMakefile* mf);
+ // Filter the given variable definition based on policy CMP0054.
+ static const char* GetDefinitionIfUnquoted(
+ const cmMakefile* mf, cmExpandedCommandArgument const& argument);
cmTypeMacro(cmIfCommand, cmCommand);
};
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 0041122..ec500d9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -25,9 +25,12 @@
static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
{
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
impLib, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
+ message,
args.GetOptional() || forceOpt);
}
@@ -36,10 +39,13 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs)
{
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(mf);
return new cmInstallFilesGenerator(mf,
absFiles, args.GetDestination().c_str(),
programs, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
+ message,
args.GetRename().c_str(), args.GetOptional());
}
@@ -911,6 +917,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
Doing doing = DoingDirs;
bool in_match_mode = false;
bool optional = false;
+ bool message_never = false;
std::vector<std::string> dirs;
const char* destination = 0;
std::string permissions_file;
@@ -949,6 +956,21 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
optional = true;
doing = DoingNone;
}
+ else if(args[i] == "MESSAGE_NEVER")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Mark the rule as quiet.
+ message_never = true;
+ doing = DoingNone;
+ }
else if(args[i] == "PATTERN")
{
// Switch to a new pattern match rule.
@@ -1208,6 +1230,9 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
return false;
}
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never);
+
// Create the directory install generator.
this->Makefile->AddInstallGenerator(
new cmInstallDirectoryGenerator(dirs, destination,
@@ -1215,6 +1240,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
permissions_dir.c_str(),
configurations,
component.c_str(),
+ message,
literal_args.c_str(),
optional));
@@ -1333,13 +1359,16 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
}
}
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
+
// Create the export install generator.
cmInstallExportGenerator* exportGenerator =
new cmInstallExportGenerator(
exportSet,
ica.GetDestination().c_str(),
ica.GetPermissions().c_str(), ica.GetConfigurations(),
- ica.GetComponent().c_str(), fname.c_str(),
+ ica.GetComponent().c_str(), message, fname.c_str(),
name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
this->Makefile->AddInstallGenerator(exportGenerator);
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index ddf7d08..8c13bab 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -21,9 +21,11 @@ cmInstallDirectoryGenerator
const char* dir_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* literal_args,
bool optional):
- cmInstallGenerator(dest, configurations, component), Directories(dirs),
+ cmInstallGenerator(dest, configurations, component, message),
+ Directories(dirs),
FilePermissions(file_permissions), DirPermissions(dir_permissions),
LiteralArguments(literal_args), Optional(optional)
{
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index d76ef3c..165ab91 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -26,6 +26,7 @@ public:
const char* dir_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* literal_args,
bool optional = false);
virtual ~cmInstallDirectoryGenerator();
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 9a17052..ddfd6c5 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -32,10 +32,11 @@ cmInstallExportGenerator::cmInstallExportGenerator(
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* filename, const char* name_space,
bool exportOld,
cmMakefile* mf)
- :cmInstallGenerator(destination, configurations, component)
+ :cmInstallGenerator(destination, configurations, component, message)
,ExportSet(exportSet)
,FilePermissions(file_permissions)
,FileName(filename)
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 37b5593..eb8c28b 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -30,6 +30,7 @@ public:
const char* dest, const char* file_permissions,
const std::vector<std::string>& configurations,
const char* component,
+ MessageLevel message,
const char* filename, const char* name_space,
bool exportOld, cmMakefile* mf);
~cmInstallExportGenerator();
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 7eabbef..f106e1a 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -132,11 +132,13 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
std::string no_component = this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
new cmInstallFilesGenerator(this->Makefile, this->Files,
destination.c_str(), false,
no_permissions, no_configurations,
- no_component.c_str(), no_rename));
+ no_component.c_str(), message, no_rename));
}
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index b2be82e..91b102a 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -23,9 +23,10 @@ cmInstallFilesGenerator
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* rename,
bool optional):
- cmInstallGenerator(dest, configurations, component),
+ cmInstallGenerator(dest, configurations, component, message),
Makefile(mf),
Files(files), Programs(programs),
FilePermissions(file_permissions),
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 23bf935..0dbd712 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -28,6 +28,7 @@ public:
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
+ MessageLevel message,
const char* rename,
bool optional = false);
virtual ~cmInstallFilesGenerator();
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 9370e48..b261cbf 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -11,16 +11,19 @@
============================================================================*/
#include "cmInstallGenerator.h"
+#include "cmMakefile.h"
#include "cmSystemTools.h"
//----------------------------------------------------------------------------
cmInstallGenerator
::cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations,
- const char* component):
+ const char* component,
+ MessageLevel message):
cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations),
Destination(destination? destination:""),
- Component(component? component:"")
+ Component(component? component:""),
+ Message(message)
{
}
@@ -96,6 +99,13 @@ void cmInstallGenerator
{
os << " OPTIONAL";
}
+ switch(this->Message)
+ {
+ case MessageDefault: break;
+ case MessageAlways: os << " MESSAGE_ALWAYS"; break;
+ case MessageLazy: os << " MESSAGE_LAZY"; break;
+ case MessageNever: os << " MESSAGE_NEVER"; break;
+ }
if(permissions_file && *permissions_file)
{
os << " PERMISSIONS" << permissions_file;
@@ -180,3 +190,27 @@ std::string cmInstallGenerator::GetInstallDestination() const
result += this->Destination;
return result;
}
+
+//----------------------------------------------------------------------------
+cmInstallGenerator::MessageLevel
+cmInstallGenerator::SelectMessageLevel(cmMakefile* mf, bool never)
+{
+ if(never)
+ {
+ return MessageNever;
+ }
+ std::string m = mf->GetSafeDefinition("CMAKE_INSTALL_MESSAGE");
+ if(m == "ALWAYS")
+ {
+ return MessageAlways;
+ }
+ if(m == "LAZY")
+ {
+ return MessageLazy;
+ }
+ if(m == "NEVER")
+ {
+ return MessageNever;
+ }
+ return MessageDefault;
+}
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index c72e9e9..38aac91 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -16,6 +16,7 @@
#include "cmScriptGenerator.h"
class cmLocalGenerator;
+class cmMakefile;
/** \class cmInstallGenerator
* \brief Support class for generating install scripts.
@@ -24,9 +25,18 @@ class cmLocalGenerator;
class cmInstallGenerator: public cmScriptGenerator
{
public:
+ enum MessageLevel
+ {
+ MessageDefault,
+ MessageAlways,
+ MessageLazy,
+ MessageNever
+ };
+
cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations,
- const char* component);
+ const char* component,
+ MessageLevel message);
virtual ~cmInstallGenerator();
void AddInstallRule(
@@ -50,6 +60,9 @@ public:
/** Test if this generator installs something for a given configuration. */
bool InstallsForConfig(const std::string& config);
+ /** Select message level from CMAKE_INSTALL_MESSAGE or 'never'. */
+ static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
+
protected:
virtual void GenerateScript(std::ostream& os);
@@ -58,6 +71,7 @@ protected:
// Information shared by most generator types.
std::string Destination;
std::string Component;
+ MessageLevel Message;
};
#endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 597f7ee..0405769 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -93,11 +93,13 @@ void cmInstallProgramsCommand::FinalPass()
std::string no_component = this->Makefile->GetSafeDefinition(
"CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
new cmInstallFilesGenerator(this->Makefile, this->Files,
destination.c_str(), true,
no_permissions, no_configurations,
- no_component.c_str(), no_rename));
+ no_component.c_str(), message, no_rename));
}
/**
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index 1ecf021..933aa07 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -15,7 +15,7 @@
cmInstallScriptGenerator
::cmInstallScriptGenerator(const char* script, bool code,
const char* component) :
- cmInstallGenerator(0, std::vector<std::string>(), component),
+ cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault),
Script(script), Code(code)
{
}
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index ec2b518..d689c89 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -24,8 +24,10 @@ cmInstallTargetGenerator
::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
const char* file_permissions,
std::vector<std::string> const& configurations,
- const char* component, bool optional):
- cmInstallGenerator(dest, configurations, component), Target(&t),
+ const char* component,
+ MessageLevel message,
+ bool optional):
+ cmInstallGenerator(dest, configurations, component, message), Target(&t),
ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
{
this->ActionsPerConfig = true;
@@ -213,6 +215,20 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
filesFrom.push_back(from1);
filesTo.push_back(to1);
}
+ else if(this->Target->IsCFBundleOnApple())
+ {
+ // Install the whole app bundle directory.
+ type = cmInstallType_DIRECTORY;
+ literal_args += " USE_SOURCE_PERMISSIONS";
+
+ std::string targetNameBase = targetName.substr(0, targetName.find('/'));
+
+ std::string from1 = fromDirConfig + targetNameBase;
+ std::string to1 = toDir + targetName;
+
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ }
else
{
bool haveNamelink = false;
@@ -661,46 +677,72 @@ cmInstallTargetGenerator
return;
}
- if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ cmMakefile* mf = this->Target->GetMakefile();
+
+ if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
// If using install_name_tool, set up the rules to modify the rpaths.
std::string installNameTool =
- this->Target->GetMakefile()->
- GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+ mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
cli->GetRPath(oldRuntimeDirs, false);
cli->GetRPath(newRuntimeDirs, true);
- // Note: These paths are kept unique to avoid install_name_tool corruption.
- std::set<std::string> runpaths;
- for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
- i != oldRuntimeDirs.end(); ++i)
- {
- std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()->
- GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
+ std::string darwin_major_version_s =
+ mf->GetSafeDefinition("DARWIN_MAJOR_VERSION");
- if(runpaths.find(runpath) == runpaths.end())
- {
- runpaths.insert(runpath);
- os << indent << "execute_process(COMMAND " << installNameTool << "\n";
- os << indent << " -delete_rpath \"" << runpath << "\"\n";
- os << indent << " \"" << toDestDirPath << "\")\n";
- }
+ std::stringstream ss(darwin_major_version_s);
+ int darwin_major_version;
+ ss >> darwin_major_version;
+ if(!ss.fail() && darwin_major_version <= 9 &&
+ (!oldRuntimeDirs.empty() || !newRuntimeDirs.empty())
+ )
+ {
+ cmOStringStream msg;
+ msg << "WARNING: Target \"" << this->Target->GetName()
+ << "\" has runtime paths which cannot be changed during install. "
+ << "To change runtime paths, OS X version 10.6 or newer is required. "
+ << "Therefore, runtime paths will not be changed when installing. "
+ << "CMAKE_BUILD_WITH_INSTALL_RPATH may be used to work around"
+ " this limitation.";
+ mf->IssueMessage(cmake::WARNING, msg.str());
}
-
- runpaths.clear();
- for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
- i != newRuntimeDirs.end(); ++i)
+ else
{
- std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()->
- GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
+ // Note: These paths are kept unique to avoid
+ // install_name_tool corruption.
+ std::set<std::string> runpaths;
+ for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
+ i != oldRuntimeDirs.end(); ++i)
+ {
+ std::string runpath =
+ mf->GetLocalGenerator()->
+ GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
- if(runpaths.find(runpath) == runpaths.end())
+ if(runpaths.find(runpath) == runpaths.end())
+ {
+ runpaths.insert(runpath);
+ os << indent << "execute_process(COMMAND " << installNameTool <<"\n";
+ os << indent << " -delete_rpath \"" << runpath << "\"\n";
+ os << indent << " \"" << toDestDirPath << "\")\n";
+ }
+ }
+
+ runpaths.clear();
+ for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
+ i != newRuntimeDirs.end(); ++i)
{
- os << indent << "execute_process(COMMAND " << installNameTool << "\n";
- os << indent << " -add_rpath \"" << runpath << "\"\n";
- os << indent << " \"" << toDestDirPath << "\")\n";
+ std::string runpath =
+ mf->GetLocalGenerator()->
+ GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
+
+ if(runpaths.find(runpath) == runpaths.end())
+ {
+ os << indent << "execute_process(COMMAND " << installNameTool <<"\n";
+ os << indent << " -add_rpath \"" << runpath << "\"\n";
+ os << indent << " \"" << toDestDirPath << "\")\n";
+ }
}
}
}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 0f21da7..7e5cc71 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -24,11 +24,11 @@ class cmInstallTargetGenerator: public cmInstallGenerator
public:
cmInstallTargetGenerator(
cmTarget& t, const char* dest, bool implib,
- const char* file_permissions = "",
- std::vector<std::string> const& configurations
- = std::vector<std::string>(),
- const char* component = "Unspecified",
- bool optional = false
+ const char* file_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ MessageLevel message,
+ bool optional
);
virtual ~cmInstallTargetGenerator();
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 7813fcc..4b53752 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -77,6 +77,13 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
}
//----------------------------------------------------------------------------
+bool cmInstalledFile::HasProperty(
+ const std::string& prop) const
+{
+ return this->Properties.find(prop) != this->Properties.end();
+}
+
+//----------------------------------------------------------------------------
bool cmInstalledFile::GetProperty(
const std::string& prop, std::string& value) const
{
@@ -111,3 +118,14 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
bool isSet = this->GetProperty(prop, value);
return isSet && cmSystemTools::IsOn(value.c_str());
}
+
+//----------------------------------------------------------------------------
+void cmInstalledFile::GetPropertyAsList(const std::string& prop,
+ std::vector<std::string>& list) const
+{
+ std::string value;
+ this->GetProperty(prop, value);
+
+ list.clear();
+ cmSystemTools::ExpandListArgument(value, list);
+}
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index df28221..7134a4e 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -62,10 +62,15 @@ public:
void AppendProperty(cmMakefile const* mf,
const std::string& prop, const char* value,bool asString=false);
+ bool HasProperty(const std::string& prop) const;
+
bool GetProperty(const std::string& prop, std::string& value) const;
bool GetPropertyAsBool(const std::string& prop) const;
+ void GetPropertyAsList(const std::string& prop,
+ std::vector<std::string>& list) const;
+
void SetName(cmMakefile* mf, const std::string& name);
std::string const& GetName() const;
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 705666d..3fc5b69 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -142,7 +142,8 @@ bool cmListFile::ParseFile(const char* filename,
bool topLevel,
cmMakefile *mf)
{
- if(!cmSystemTools::FileExists(filename))
+ if(!cmSystemTools::FileExists(filename) ||
+ cmSystemTools::FileIsDirectory(filename))
{
return false;
}
diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c
index bfa388e..af4fc3d 100644
--- a/Source/cmListFileLexer.c
+++ b/Source/cmListFileLexer.c
@@ -369,8 +369,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 23
-#define YY_END_OF_BUFFER 24
+#define YY_NUM_RULES 24
+#define YY_END_OF_BUFFER 25
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -381,10 +381,10 @@ struct yy_trans_info
static yyconst flex_int16_t yy_accept[77] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 4, 4,
- 24, 13, 21, 1, 15, 3, 13, 5, 6, 7,
- 22, 22, 16, 18, 19, 20, 10, 11, 8, 12,
- 9, 4, 13, 0, 13, 0, 21, 0, 0, 7,
- 13, 0, 13, 0, 2, 0, 13, 16, 0, 17,
+ 25, 13, 22, 1, 16, 3, 13, 5, 6, 7,
+ 15, 23, 17, 19, 20, 21, 10, 11, 8, 12,
+ 9, 4, 13, 0, 13, 0, 22, 0, 0, 7,
+ 13, 0, 13, 0, 2, 0, 13, 17, 0, 18,
10, 8, 4, 0, 14, 0, 0, 0, 0, 14,
0, 0, 14, 0, 0, 0, 2, 14, 0, 0,
0, 0, 0, 0, 0, 0
@@ -523,10 +523,10 @@ static yyconst flex_int16_t yy_chk[253] =
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[24] =
+static yyconst flex_int32_t yy_rule_can_match_eol[25] =
{ 0,
-1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
- 0, 0, 0, 0, };
+1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@@ -615,7 +615,7 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer);
-#line 621 "cmListFileLexer.c"
+#line 628 "cmListFileLexer.c"
#define INITIAL 0
#define STRING 1
@@ -850,7 +850,7 @@ YY_DECL
#line 91 "cmListFileLexer.in.l"
-#line 858 "cmListFileLexer.c"
+#line 865 "cmListFileLexer.c"
if ( !yyg->yy_init )
{
@@ -1111,75 +1111,84 @@ case 15:
YY_RULE_SETUP
#line 215 "cmListFileLexer.in.l"
{
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 16:
+YY_RULE_SETUP
+#line 222 "cmListFileLexer.in.l"
+{
lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
cmListFileLexerSetToken(lexer, "", 0);
lexer->column += yyleng;
BEGIN(STRING);
}
YY_BREAK
-case 16:
+case 17:
YY_RULE_SETUP
-#line 222 "cmListFileLexer.in.l"
+#line 229 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
-case 17:
-/* rule 17 can match eol */
+case 18:
+/* rule 18 can match eol */
YY_RULE_SETUP
-#line 227 "cmListFileLexer.in.l"
+#line 234 "cmListFileLexer.in.l"
{
/* Continuation: text is not part of string */
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 18:
-/* rule 18 can match eol */
+case 19:
+/* rule 19 can match eol */
YY_RULE_SETUP
-#line 233 "cmListFileLexer.in.l"
+#line 240 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
++lexer->line;
lexer->column = 1;
}
YY_BREAK
-case 19:
+case 20:
YY_RULE_SETUP
-#line 239 "cmListFileLexer.in.l"
+#line 246 "cmListFileLexer.in.l"
{
lexer->column += yyleng;
BEGIN(INITIAL);
return 1;
}
-case 20:
+case 21:
YY_RULE_SETUP
-#line 245 "cmListFileLexer.in.l"
+#line 252 "cmListFileLexer.in.l"
{
cmListFileLexerAppend(lexer, yytext, yyleng);
lexer->column += yyleng;
}
YY_BREAK
case YY_STATE_EOF(STRING):
-#line 250 "cmListFileLexer.in.l"
+#line 257 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadString;
BEGIN(INITIAL);
return 1;
}
-case 21:
+case 22:
YY_RULE_SETUP
-#line 256 "cmListFileLexer.in.l"
+#line 263 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_Space;
cmListFileLexerSetToken(lexer, yytext, yyleng);
lexer->column += yyleng;
return 1;
}
-case 22:
+case 23:
YY_RULE_SETUP
-#line 263 "cmListFileLexer.in.l"
+#line 270 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_BadCharacter;
cmListFileLexerSetToken(lexer, yytext, yyleng);
@@ -1188,18 +1197,18 @@ YY_RULE_SETUP
}
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(COMMENT):
-#line 270 "cmListFileLexer.in.l"
+#line 277 "cmListFileLexer.in.l"
{
lexer->token.type = cmListFileLexer_Token_None;
cmListFileLexerSetToken(lexer, 0, 0);
return 0;
}
-case 23:
+case 24:
YY_RULE_SETUP
-#line 276 "cmListFileLexer.in.l"
+#line 283 "cmListFileLexer.in.l"
ECHO;
YY_BREAK
-#line 1220 "cmListFileLexer.c"
+#line 1238 "cmListFileLexer.c"
case YY_END_OF_BUFFER:
{
@@ -2320,7 +2329,7 @@ void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 276 "cmListFileLexer.in.l"
+#line 282 "cmListFileLexer.in.l"
diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l
index ed4bf6b..a520c72 100644
--- a/Source/cmListFileLexer.in.l
+++ b/Source/cmListFileLexer.in.l
@@ -212,6 +212,13 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\"
return 1;
}
+\[ {
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
\" {
lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
cmListFileLexerSetToken(lexer, "", 0);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c8c8c79..50e279b 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -681,7 +681,7 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
objVector.push_back(ofname);
this->AddCustomCommandToCreateObject(ofname.c_str(),
llang, *(*i), target);
- objs += this->Convert(ofname,START_OUTPUT,MAKEFILE);
+ objs += this->Convert(ofname,START_OUTPUT,SHELL);
objs += " ";
}
}
@@ -1287,9 +1287,11 @@ cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
//----------------------------------------------------------------------------
std::string
cmLocalGenerator::ConvertToIncludeReference(std::string const& path,
- OutputFormat format)
+ OutputFormat format,
+ bool forceFullPaths)
{
- return this->ConvertToOutputForExisting(path, START_OUTPUT, format);
+ return this->ConvertToOutputForExisting(
+ path, forceFullPaths? FULL : START_OUTPUT, format);
}
//----------------------------------------------------------------------------
@@ -1297,6 +1299,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
const std::vector<std::string> &includes,
cmGeneratorTarget* target,
const std::string& lang,
+ bool forceFullPaths,
bool forResponseFile,
const std::string& config)
{
@@ -1401,7 +1404,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
flagUsed = true;
}
std::string includePath =
- this->ConvertToIncludeReference(*i, shellFormat);
+ this->ConvertToIncludeReference(*i, shellFormat, forceFullPaths);
if(quotePaths && includePath.size() && includePath[0] != '\"')
{
includeFlags << "\"";
@@ -1861,7 +1864,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
((useWatcomQuote) ? WATCOMQUOTE : SHELL);
bool escapeAllowMakeVars = !forResponseFile;
cmOStringStream fout;
- const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config);
if(!pcli)
{
@@ -2229,7 +2232,10 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
"does not know the compile flags to use to enable it.";
this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
}
- this->AppendFlags(flags, opt);
+ else
+ {
+ this->AppendFlagEscape(flags, opt);
+ }
return;
}
@@ -2275,7 +2281,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
if (const char *opt = target->GetMakefile()->GetDefinition(option_flag))
{
- this->AppendFlags(flags, opt);
+ this->AppendFlagEscape(flags, opt);
return;
}
}
@@ -2752,7 +2758,7 @@ std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source,
{
std::string result = source;
// Convert it to an output path.
- if (output == MAKEFILE)
+ if (output == MAKERULE)
{
result = cmSystemTools::ConvertToOutputPath(result.c_str());
}
@@ -2995,6 +3001,17 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
}
//----------------------------------------------------------------------------
+class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
+{
+public:
+ cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
+ cmInstallTargetGenerator(
+ t, dest, implib, "", std::vector<std::string>(), "Unspecified",
+ cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
+ false) {}
+};
+
+//----------------------------------------------------------------------------
void
cmLocalGenerator
::GenerateTargetInstallRules(
@@ -3039,7 +3056,8 @@ cmLocalGenerator
case cmTarget::MODULE_LIBRARY:
{
// Use a target install generator.
- cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g(l->second, destination.c_str(), false);
g.Generate(os, config, configurationTypes);
}
break;
@@ -3049,16 +3067,19 @@ cmLocalGenerator
// Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime
// destination.
- cmInstallTargetGenerator g1(l->second, destination.c_str(), true);
+ cmInstallTargetGeneratorLocal
+ g1(l->second, destination.c_str(), true);
g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user.
destination = l->second.GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
- cmInstallTargetGenerator g2(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g2(l->second, destination.c_str(), false);
g2.Generate(os, config, configurationTypes);
#else
// Use a target install generator.
- cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ cmInstallTargetGeneratorLocal
+ g(l->second, destination.c_str(), false);
g.Generate(os, config, configurationTypes);
#endif
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index ad73073..3a9d5be 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -106,7 +106,7 @@ public:
* path setting
*/
enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
- enum OutputFormat { UNCHANGED, MAKEFILE, SHELL, WATCOMQUOTE, RESPONSE };
+ enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
std::string ConvertToOutputFormat(const std::string& source,
OutputFormat output);
std::string Convert(const std::string& remote, RelativeRoot local,
@@ -160,6 +160,7 @@ public:
std::string GetIncludeFlags(const std::vector<std::string> &includes,
cmGeneratorTarget* target,
const std::string& lang,
+ bool forceFullPaths = false,
bool forResponseFile = false,
const std::string& config = "");
@@ -215,7 +216,8 @@ public:
OutputFormat format = SHELL);
virtual std::string ConvertToIncludeReference(std::string const& path,
- OutputFormat format = SHELL);
+ OutputFormat format = SHELL,
+ bool forceFullPaths = false);
/** Called from command-line hook to clear dependencies. */
virtual void ClearDependencies(cmMakefile* /* mf */,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 2ac8363..398b55a 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -151,9 +151,10 @@ cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib,
std::string
cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path,
- OutputFormat format)
+ OutputFormat format,
+ bool forceFullPaths)
{
- return this->Convert(path, HOME_OUTPUT, format);
+ return this->Convert(path, forceFullPaths? FULL : HOME_OUTPUT, format);
}
//----------------------------------------------------------------------------
@@ -189,6 +190,7 @@ void cmLocalNinjaGenerator::WriteBuildFileTop()
{
// For the build file.
this->WriteProjectHeader(this->GetBuildFileStream());
+ this->WriteNinjaRequiredVersion(this->GetBuildFileStream());
this->WriteNinjaFilesInclusion(this->GetBuildFileStream());
// For the rule file.
@@ -205,6 +207,30 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
}
+void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
+{
+ // Default required version
+ // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
+ std::string requiredVersion = "1.3";
+
+ // Ninja generator uses the 'console' pool if available (>= 1.5)
+ std::string usedVersion = this->GetGlobalNinjaGenerator()->ninjaVersion();
+ if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ usedVersion.c_str(),
+ "1.5") == false)
+ {
+ requiredVersion = "1.5";
+ }
+
+ cmGlobalNinjaGenerator::WriteComment(os,
+ "Minimal version of Ninja required by this file");
+ os
+ << "ninja_required_version = "
+ << requiredVersion
+ << std::endl << std::endl
+ ;
+}
+
void cmLocalNinjaGenerator::WritePools(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 11321b8..1d27224 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -108,7 +108,8 @@ public:
protected:
virtual std::string ConvertToIncludeReference(std::string const& path,
- OutputFormat format = SHELL);
+ OutputFormat format = SHELL,
+ bool forceFullPaths = false);
private:
@@ -117,6 +118,7 @@ private:
void WriteBuildFileTop();
void WriteProjectHeader(std::ostream& os);
+ void WriteNinjaRequiredVersion(std::ostream& os);
void WriteNinjaFilesInclusion(std::ostream& os);
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 94e45e5..23513fa 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -630,7 +630,7 @@ cmLocalUnixMakefileGenerator3
// Construct the left hand side of the rule.
replace = target;
- std::string tgt = this->Convert(replace,HOME_OUTPUT,MAKEFILE);
+ std::string tgt = this->Convert(replace,HOME_OUTPUT,MAKERULE);
const char* space = "";
if(tgt.size() == 1)
{
@@ -663,7 +663,7 @@ cmLocalUnixMakefileGenerator3
dep != depends.end(); ++dep)
{
replace = *dep;
- replace = this->Convert(replace,HOME_OUTPUT,MAKEFILE);
+ replace = this->Convert(replace,HOME_OUTPUT,MAKERULE);
os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
}
}
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 5db735f..c14fb2b 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1101,7 +1101,8 @@ void cmLocalVisualStudio6Generator
}
}
// find link libraries
- const cmTarget::LinkLibraryVectorType& libs = target.GetLinkLibraries();
+ const cmTarget::LinkLibraryVectorType& libs =
+ target.GetLinkLibrariesForVS6();
cmTarget::LinkLibraryVectorType::const_iterator j;
for(j = libs.begin(); j != libs.end(); ++j)
{
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index a6c6e8d..eb45423 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -44,11 +44,20 @@ private:
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
+static void cmConvertToWindowsSlash(std::string& s)
+{
+ std::string::size_type pos = 0;
+ while((pos = s.find('/', pos)) != std::string::npos)
+ {
+ s[pos] = '\\';
+ pos++;
+ }
+}
+
//----------------------------------------------------------------------------
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(VSVersion v):
cmLocalVisualStudioGenerator(v)
{
- this->PlatformName = "Win32";
this->ExtraFlagTable = 0;
this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
}
@@ -647,8 +656,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
{
mfcFlag = "0";
}
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
fout << "\t\t<Configuration\n"
- << "\t\t\tName=\"" << configName << "|" << this->PlatformName << "\"\n"
+ << "\t\t\tName=\"" << configName
+ << "|" << gg->GetPlatformName() << "\"\n"
<< "\t\t\tOutputDirectory=\"" << configName << "\"\n";
// This is an internal type to Visual Studio, it seems that:
// 4 == static library
@@ -784,6 +796,20 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
<< "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
<< "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n";
+ if (this->FortranProject)
+ {
+ // Intel Fortran >= 15.0 uses TargetName property.
+ std::string targetNameFull = target.GetFullName(configName);
+ std::string targetName =
+ cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
+ std::string targetExt =
+ cmSystemTools::GetFilenameLastExtension(targetNameFull);
+ fout <<
+ "\t\t\tTargetName=\"" << this->EscapeForXML(targetName) << "\"\n"
+ "\t\t\tTargetExt=\"" << this->EscapeForXML(targetExt) << "\"\n"
+ ;
+ }
+
// If unicode is enabled change the character set to unicode, if not
// then default to MBCS.
if(targetOptions.UsingUnicode())
@@ -860,6 +886,31 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
}
}
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
+ if(gg->IsMasmEnabled() && !this->FortranProject)
+ {
+ Options masmOptions(this, Options::MasmCompiler, 0, 0);
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"MASM\"\n"
+ "\t\t\t\tIncludePaths=\""
+ ;
+ const char* sep = "";
+ for(i = includes.begin(); i != includes.end(); ++i)
+ {
+ std::string inc = *i;
+ cmConvertToWindowsSlash(inc);
+ fout << sep << this->EscapeForXML(inc);
+ sep = ";";
+ }
+ fout << "\"\n";
+ // Use same preprocessor definitions as VCCLCompilerTool.
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+ "ASM_MASM");
+ masmOptions.OutputFlagMap(fout, "\t\t\t\t");
+ fout <<
+ "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
+ "\t\t\t/>\n";
+ }
tool = "VCCustomBuildTool";
if(this->FortranProject)
{
@@ -896,11 +947,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
}
fout << "\"\n";
fout << "\t\t\t\tMkTypLibCompatible=\"false\"\n";
- if( this->PlatformName == "x64" )
+ if( gg->GetPlatformName() == "x64" )
{
fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
}
- else if( this->PlatformName == "ia64" )
+ else if( gg->GetPlatformName() == "ia64" )
{
fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
}
@@ -1011,7 +1062,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
if(!this->ModuleDefinitionFile.empty())
{
std::string defFile =
- this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str());
+ this->ConvertToOptionallyRelativeOutputPath(this->ModuleDefinitionFile);
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
switch(target.GetType())
@@ -1640,6 +1691,8 @@ bool cmLocalVisualStudio7Generator
std::ostream &fout, const std::string& libName,
std::vector<std::string> *configs)
{
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
const std::vector<const cmSourceFile *> &sourceFiles =
sg->GetSourceFiles();
std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
@@ -1691,11 +1744,12 @@ bool cmLocalVisualStudio7Generator
else if(!fcinfo.FileConfigMap.empty())
{
const char* aCompilerTool = "VCCLCompilerTool";
- const char* lang = "CXX";
+ const char* ppLang = "CXX";
if(this->FortranProject)
{
aCompilerTool = "VFFortranCompilerTool";
}
+ std::string const& lang = (*sf)->GetLanguage();
std::string ext = (*sf)->GetExtension();
ext = cmSystemTools::LowerCase(ext);
if(ext == "idl")
@@ -1709,7 +1763,7 @@ bool cmLocalVisualStudio7Generator
if(ext == "rc")
{
aCompilerTool = "VCResourceCompilerTool";
- lang = "RC";
+ ppLang = "RC";
if(this->FortranProject)
{
aCompilerTool = "VFResourceCompilerTool";
@@ -1723,6 +1777,11 @@ bool cmLocalVisualStudio7Generator
aCompilerTool = "VFCustomBuildTool";
}
}
+ if (gg->IsMasmEnabled() && !this->FortranProject &&
+ lang == "ASM_MASM")
+ {
+ aCompilerTool = "MASM";
+ }
for(std::map<std::string, cmLVS7GFileConfig>::const_iterator
fci = fcinfo.FileConfigMap.begin();
fci != fcinfo.FileConfigMap.end(); ++fci)
@@ -1730,7 +1789,7 @@ bool cmLocalVisualStudio7Generator
cmLVS7GFileConfig const& fc = fci->second;
fout << "\t\t\t\t<FileConfiguration\n"
<< "\t\t\t\t\tName=\"" << fci->first
- << "|" << this->PlatformName << "\"";
+ << "|" << gg->GetPlatformName() << "\"";
if(fc.ExcludedFromBuild)
{
fout << " ExcludedFromBuild=\"true\"";
@@ -1759,7 +1818,7 @@ bool cmLocalVisualStudio7Generator
fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
fileOptions.OutputPreprocessorDefinitions(fout,
"\t\t\t\t\t", "\n",
- lang);
+ ppLang);
}
if(!fc.AdditionalDeps.empty())
{
@@ -1800,6 +1859,9 @@ WriteCustomRule(std::ostream& fout,
const cmCustomCommand& command,
FCInfo& fcinfo)
{
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
+
// Write the rule for each configuration.
std::vector<std::string>::iterator i;
std::vector<std::string> *configs =
@@ -1820,7 +1882,8 @@ WriteCustomRule(std::ostream& fout,
cmCustomCommandGenerator ccg(command, *i, this->Makefile);
cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
fout << "\t\t\t\t<FileConfiguration\n";
- fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
+ fout << "\t\t\t\t\tName=\"" << *i << "|"
+ << gg->GetPlatformName() << "\">\n";
if(!fc.CompileFlags.empty())
{
fout << "\t\t\t\t\t<Tool\n"
@@ -2030,7 +2093,7 @@ cmLocalVisualStudio7Generator
fout<< "\tKeyword=\"" << keyword << "\">\n"
<< "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\">\n"
<< "\t<Platforms>\n"
- << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
}
@@ -2085,8 +2148,18 @@ cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
}
fout << "\tKeyword=\"" << keyword << "\">\n"
<< "\t<Platforms>\n"
- << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
+ if(gg->IsMasmEnabled())
+ {
+ fout <<
+ "\t<ToolFiles>\n"
+ "\t\t<DefaultToolFile\n"
+ "\t\t\tFileName=\"masm.rules\"\n"
+ "\t\t/>\n"
+ "\t</ToolFiles>\n"
+ ;
+ }
}
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 6c04559..c2caa26 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -53,8 +53,6 @@ public:
*/
void SetBuildType(BuildType,const std::string& name);
- void SetPlatformName(const std::string& n) { this->PlatformName = n;}
-
void SetExtraFlagTable(cmVS7FlagTable const* table)
{ this->ExtraFlagTable = table; }
virtual std::string GetTargetDirectory(cmTarget const&) const;
@@ -124,7 +122,6 @@ private:
std::string ModuleDefinitionFile;
bool FortranProject;
bool WindowsCEProject;
- std::string PlatformName; // Win32 or x64
cmLocalVisualStudio7GeneratorInternals* Internal;
};
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index 3bf4f43..d26c2ea 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -40,7 +40,9 @@ public:
VS9 = 90,
VS10 = 100,
VS11 = 110,
- VS12 = 120
+ VS12 = 120,
+ /* VS13 = 130 was skipped */
+ VS14 = 140
};
cmLocalVisualStudioGenerator(VSVersion v);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 630957f..0bd1624 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -989,7 +989,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
// Choose a source file on which to store the custom command.
cmSourceFile* file = 0;
- if(!main_dependency.empty())
+ if(!commandLines.empty() && !main_dependency.empty())
{
// The main dependency was specified. Use it unless a different
// custom command already used it.
@@ -1010,11 +1010,9 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
file = 0;
}
}
- else
+ else if (!file)
{
- // The main dependency does not have a custom command or we are
- // allowed to replace it. Use it to store the command.
- file = this->GetOrCreateSource(main_dependency);
+ file = this->CreateSource(main_dependency);
}
}
@@ -1041,7 +1039,10 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
}
// Create a cmSourceFile for the rule file.
- file = this->GetOrCreateSource(outName, true);
+ if (!file)
+ {
+ file = this->CreateSource(outName, true);
+ }
file->SetProperty("__CMAKE_RULE", "1");
}
@@ -1055,16 +1056,16 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
}
}
- // Construct a complete list of dependencies.
- std::vector<std::string> depends2(depends);
- if(!main_dependency.empty())
- {
- depends2.push_back(main_dependency);
- }
-
// Attach the custom command to the file.
if(file)
{
+ // Construct a complete list of dependencies.
+ std::vector<std::string> depends2(depends);
+ if(!main_dependency.empty())
+ {
+ depends2.push_back(main_dependency);
+ }
+
cmCustomCommand* cc =
new cmCustomCommand(this, outputs, depends2, commandLines,
comment, workingDir);
@@ -1256,28 +1257,31 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
}
// Store the custom command in the target.
- std::string force = this->GetStartOutputDirectory();
- force += cmake::GetCMakeFilesDirectory();
- force += "/";
- force += utilityName;
- std::string no_main_dependency = "";
- bool no_replace = false;
- this->AddCustomCommandToOutput(force, depends,
- no_main_dependency,
- commandLines, comment,
- workingDirectory, no_replace,
- escapeOldStyle);
- cmSourceFile* sf = target->AddSourceCMP0049(force);
-
- // The output is not actually created so mark it symbolic.
- if(sf)
- {
- sf->SetProperty("SYMBOLIC", "1");
- }
- else
- {
- cmSystemTools::Error("Could not get source file entry for ",
- force.c_str());
+ if (!commandLines.empty() || !depends.empty())
+ {
+ std::string force = this->GetStartOutputDirectory();
+ force += cmake::GetCMakeFilesDirectory();
+ force += "/";
+ force += utilityName;
+ std::string no_main_dependency = "";
+ bool no_replace = false;
+ this->AddCustomCommandToOutput(force, depends,
+ no_main_dependency,
+ commandLines, comment,
+ workingDirectory, no_replace,
+ escapeOldStyle);
+ cmSourceFile* sf = target->AddSourceCMP0049(force);
+
+ // The output is not actually created so mark it symbolic.
+ if(sf)
+ {
+ sf->SetProperty("SYMBOLIC", "1");
+ }
+ else
+ {
+ cmSystemTools::Error("Could not get source file entry for ",
+ force.c_str());
+ }
}
return target;
}
@@ -3288,6 +3292,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
this->FunctionBlockerBarriers.pop_back();
}
+//----------------------------------------------------------------------------
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
std::vector<std::string>& outArgs) const
@@ -3324,6 +3329,47 @@ bool cmMakefile::ExpandArguments(
}
//----------------------------------------------------------------------------
+bool cmMakefile::ExpandArguments(
+ std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs) const
+{
+ std::vector<cmListFileArgument>::const_iterator i;
+ std::string value;
+ outArgs.reserve(inArgs.size());
+ for(i = inArgs.begin(); i != inArgs.end(); ++i)
+ {
+ // No expansion in a bracket argument.
+ if(i->Delim == cmListFileArgument::Bracket)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(i->Value, true));
+ continue;
+ }
+ // Expand the variables in the argument.
+ value = i->Value;
+ this->ExpandVariablesInString(value, false, false, false,
+ i->FilePath, i->Line,
+ false, false);
+
+ // If the argument is quoted, it should be one argument.
+ // Otherwise, it may be a list of arguments.
+ if(i->Delim == cmListFileArgument::Quoted)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(value, true));
+ }
+ else
+ {
+ std::vector<std::string> stringArgs;
+ cmSystemTools::ExpandListArgument(value, stringArgs);
+ for(size_t j = 0; j < stringArgs.size(); ++j)
+ {
+ outArgs.push_back(cmExpandedCommandArgument(stringArgs[j], false));
+ }
+ }
+ }
+ return !cmSystemTools::GetFatalErrorOccured();
+}
+
+//----------------------------------------------------------------------------
void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
{
if(!this->CallStack.empty())
@@ -3451,6 +3497,19 @@ cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const
}
//----------------------------------------------------------------------------
+cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
+ bool generated)
+{
+ cmSourceFile* sf = new cmSourceFile(this, sourceName);
+ if(generated)
+ {
+ sf->SetProperty("GENERATED", "1");
+ }
+ this->SourceFiles.push_back(sf);
+ return sf;
+}
+
+//----------------------------------------------------------------------------
cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
bool generated)
{
@@ -3460,13 +3519,7 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
}
else
{
- cmSourceFile* sf = new cmSourceFile(this, sourceName);
- if(generated)
- {
- sf->SetProperty("GENERATED", "1");
- }
- this->SourceFiles.push_back(sf);
- return sf;
+ return this->CreateSource(sourceName, generated);
}
}
@@ -3499,7 +3552,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
const std::string& targetName,
bool fast,
const std::vector<std::string> *cmakeArgs,
- std::string *output)
+ std::string& output)
{
this->Internal->IsSourceFileTryCompile = fast;
// does the binary directory exist ? If not create it...
@@ -3537,6 +3590,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cm.SetHomeOutputDirectory(bindir);
cm.SetStartDirectory(srcdir);
cm.SetStartOutputDirectory(bindir);
+ cm.SetGeneratorPlatform(this->GetCMakeInstance()->GetGeneratorPlatform());
cm.SetGeneratorToolset(this->GetCMakeInstance()->GetGeneratorToolset());
cm.LoadCache();
if(!gg->IsMultiConfig())
@@ -4927,12 +4981,14 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
this->PolicyBarriers.pop_back();
}
+//----------------------------------------------------------------------------
bool cmMakefile::SetPolicyVersion(const char *version)
{
return this->GetCMakeInstance()->GetPolicies()->
ApplyPolicyVersion(this,version);
}
+//----------------------------------------------------------------------------
cmPolicies *cmMakefile::GetPolicies() const
{
if (!this->GetCMakeInstance())
@@ -4943,6 +4999,23 @@ cmPolicies *cmMakefile::GetPolicies() const
}
//----------------------------------------------------------------------------
+bool cmMakefile::HasCMP0054AlreadyBeenReported(
+ cmListFileContext context) const
+{
+ cmCMP0054Id id(context);
+
+ bool alreadyReported =
+ this->CMP0054ReportedIds.find(id) != this->CMP0054ReportedIds.end();
+
+ if(!alreadyReported)
+ {
+ this->CMP0054ReportedIds.insert(id);
+ }
+
+ return alreadyReported;
+}
+
+//----------------------------------------------------------------------------
void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
{
/* Record the setting of every policy. */
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d5ffd98..164290a 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -21,6 +21,7 @@
#include "cmTarget.h"
#include "cmNewLineStyle.h"
#include "cmGeneratorTarget.h"
+#include "cmExpandedCommandArgument.h"
#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -130,7 +131,7 @@ public:
const std::string& projectName, const std::string& targetName,
bool fast,
const std::vector<std::string> *cmakeArgs,
- std::string *output);
+ std::string& output);
bool GetIsSourceFileTryCompile() const;
@@ -375,7 +376,35 @@ public:
/**
* Get the Policies Instance
*/
- cmPolicies *GetPolicies() const;
+ cmPolicies *GetPolicies() const;
+
+ struct cmCMP0054Id
+ {
+ cmCMP0054Id(cmListFileContext const& context):
+ Context(context)
+ {
+
+ }
+
+ bool operator< (cmCMP0054Id const& id) const
+ {
+ if(this->Context.FilePath != id.Context.FilePath)
+ return this->Context.FilePath < id.Context.FilePath;
+
+ return this->Context.Line < id.Context.Line;
+ }
+
+ cmListFileContext Context;
+ };
+
+ mutable std::set<cmCMP0054Id> CMP0054ReportedIds;
+
+ /**
+ * Determine if the given context, name pair has already been reported
+ * in context of CMP0054.
+ */
+ bool HasCMP0054AlreadyBeenReported(
+ cmListFileContext context) const;
/**
* Add an auxiliary directory to the build.
@@ -560,6 +589,13 @@ public:
*/
cmSourceFile* GetSource(const std::string& sourceName) const;
+ /** Create the source file and return it. generated
+ * indicates if it is a generated file, this is used in determining
+ * how to create the source file instance e.g. name
+ */
+ cmSourceFile* CreateSource(const std::string& sourceName,
+ bool generated = false);
+
/** Get a cmSourceFile pointer for a given source name, if the name is
* not found, then create the source file and return it. generated
* indicates if it is a generated file, this is used in determining
@@ -763,6 +799,10 @@ public:
*/
bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
std::vector<std::string>& outArgs) const;
+
+ bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
+ std::vector<cmExpandedCommandArgument>& outArgs) const;
+
/**
* Get the instance
*/
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 403f6e6..1f8f686 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -218,7 +218,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->LocalGenerator->IncludeDirective << " " << root
<< this->Convert(dependFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
if(!this->NoRuleMessages)
@@ -229,7 +229,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->LocalGenerator->IncludeDirective << " " << root
<< this->Convert(this->ProgressFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
@@ -262,7 +262,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->LocalGenerator->IncludeDirective << " " << root
<< this->Convert(this->FlagFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
@@ -361,9 +361,13 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
- *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
- *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
- "\n\n";
+ std::string flags = this->GetFlags(*l);
+ std::string defines = this->GetDefines(*l);
+ // Escape comment characters so they do not terminate assignment.
+ cmSystemTools::ReplaceString(flags, "#", "\\#");
+ cmSystemTools::ReplaceString(defines, "#", "\\#");
+ *this->FlagFileStream << *l << "_FLAGS = " << flags << "\n\n";
+ *this->FlagFileStream << *l << "_DEFINES = " << defines << "\n\n";
}
}
@@ -1958,7 +1962,7 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
std::string includeFlags =
this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
- lang, useResponseFile);
+ lang, false, useResponseFile);
if(includeFlags.empty())
{
return;
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 6b039bb..617214f 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -54,7 +54,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
<< this->LocalGenerator->IncludeDirective << " " << root
<< this->Convert(this->ProgressFileNameFull,
cmLocalGenerator::HOME_OUTPUT,
- cmLocalGenerator::MAKEFILE)
+ cmLocalGenerator::MAKERULE)
<< "\n\n";
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index cfcf9f4..e344df4 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -187,12 +187,7 @@ cmNinjaNormalTargetGenerator
responseFlag += rspfile;
// build response file content
- std::string linkOptionVar = cmakeVarLang;
- linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_";
- linkOptionVar += cmTarget::GetTargetTypeName(targetType);
- const std::string linkOption =
- GetMakefile()->GetSafeDefinition(linkOptionVar);
- rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
+ rspcontent = "$in_newline $LINK_PATH $LINK_LIBRARIES";
vars.Objects = responseFlag.c_str();
vars.LinkLibraries = "";
}
@@ -608,6 +603,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string(cmake::GetCMakeFilesDirectoryPostSlash())
+ target.GetName() + ".rsp";
+ // Gather order-only dependencies.
+ cmNinjaDeps orderOnlyDeps;
+ this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(),
+ orderOnlyDeps);
+
// Write the build statement for this target.
globalGen.WriteBuild(this->GetBuildFileStream(),
comment.str(),
@@ -615,7 +615,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
outputs,
explicitDeps,
implicitDeps,
- emptyDeps,
+ orderOnlyDeps,
vars,
rspfile,
commandLineLengthLimit);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 24689fb..816e6d8 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -542,22 +542,24 @@ cmNinjaTargetGenerator
std::back_inserter(orderOnlyDeps), MapToNinjaPath());
}
- cmNinjaDeps orderOnlyTarget;
- orderOnlyTarget.push_back(this->OrderDependsTargetForTarget());
- this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
- "Order-only phony target for "
- + this->GetTargetName(),
- orderOnlyTarget,
- cmNinjaDeps(),
- cmNinjaDeps(),
- orderOnlyDeps);
-
+ if (!orderOnlyDeps.empty())
+ {
+ cmNinjaDeps orderOnlyTarget;
+ orderOnlyTarget.push_back(this->OrderDependsTargetForTarget());
+ this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(),
+ "Order-only phony target for "
+ + this->GetTargetName(),
+ orderOnlyTarget,
+ cmNinjaDeps(),
+ cmNinjaDeps(),
+ orderOnlyDeps);
+ }
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources, config);
for(std::vector<cmSourceFile const*>::const_iterator
si = objectSources.begin(); si != objectSources.end(); ++si)
{
- this->WriteObjectBuildStatement(*si);
+ this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
}
std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config);
if(!def.empty())
@@ -570,7 +572,8 @@ cmNinjaTargetGenerator
void
cmNinjaTargetGenerator
-::WriteObjectBuildStatement(cmSourceFile const* source)
+::WriteObjectBuildStatement(
+ cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
{
std::string comment;
const std::string language = source->GetLanguage();
@@ -599,7 +602,10 @@ cmNinjaTargetGenerator
}
cmNinjaDeps orderOnlyDeps;
- orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
+ if (writeOrderDependsTargetForTarget)
+ {
+ orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
+ }
// If the source file is GENERATED and does not have a custom command
// (either attached to this source file or another one), assume that one of
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 94c420f..40a15a3 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -114,7 +114,8 @@ protected:
void WriteLanguageRules(const std::string& language);
void WriteCompileRule(const std::string& language);
void WriteObjectBuildStatements();
- void WriteObjectBuildStatement(cmSourceFile const* source);
+ void WriteObjectBuildStatement(cmSourceFile const* source,
+ bool writeOrderDependsTargetForTarget);
void WriteCustomCommandBuildStatement(cmCustomCommand *cc);
cmNinjaDeps GetObjects() const
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index ec671fc..007364c 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -39,8 +39,8 @@ public:
if(file.rfind(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(file) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
@@ -72,7 +72,10 @@ public:
{
// Check if this directory conflicts with the entry.
std::string const& dir = this->OD->OriginalDirectories[i];
- if(dir != this->Directory && this->FindConflict(dir))
+ if(dir != this->Directory &&
+ cmSystemTools::GetRealPath(dir) !=
+ cmSystemTools::GetRealPath(this->Directory) &&
+ this->FindConflict(dir))
{
// The library will be found in this directory but this is not
// the directory named for it. Add an entry to make sure the
@@ -90,7 +93,10 @@ public:
{
// Check if this directory conflicts with the entry.
std::string const& dir = this->OD->OriginalDirectories[i];
- if(dir != this->Directory && this->FindConflict(dir))
+ if(dir != this->Directory &&
+ cmSystemTools::GetRealPath(dir) !=
+ cmSystemTools::GetRealPath(this->Directory) &&
+ this->FindConflict(dir))
{
// The library will be found in this directory but it is
// supposed to be found in an implicit search directory.
@@ -326,8 +332,8 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
if(fullPath.rfind(".framework") != std::string::npos)
{
- cmsys::RegularExpression splitFramework;
- splitFramework.compile("^(.*)/(.*).framework/(.*)$");
+ static cmsys::RegularExpression
+ splitFramework("^(.*)/(.*).framework/(.*)$");
if(splitFramework.find(fullPath) &&
(std::string::npos !=
splitFramework.match(3).find(splitFramework.match(2))))
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 693945d..a420f59 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -359,6 +359,11 @@ cmPolicies::cmPolicies()
CMP0053, "CMP0053",
"Simplify variable reference and escape sequence evaluation.",
3,1,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0054, "CMP0054",
+ "Only interpret if() arguments as variables or keywords when unquoted.",
+ 3,1,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5d69d14..7c73da8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -109,6 +109,8 @@ public:
/// INTERFACE_INCLUDE_DIRECTORIES
CMP0053, ///< Simplify variable reference and escape sequence evaluation
+ CMP0054, ///< Only interpret if() arguments as variables
+ /// or keywords when unquoted.
/** \brief Always the last entry.
*
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index cc6932d..93ebde6 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -392,7 +392,8 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
std::map<std::string, std::string> configUicOptions;
if (target->GetPropertyAsBool("AUTOMOC")
- || target->GetPropertyAsBool("AUTOUIC"))
+ || target->GetPropertyAsBool("AUTOUIC")
+ || target->GetPropertyAsBool("AUTORCC"))
{
this->SetupSourceFiles(target);
}
@@ -1000,6 +1001,7 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
this->WriteOldMocDefinitionsFile(targetDirectory);
+ delete gg->GetCurrentLocalGenerator();
delete gg;
gg = NULL;
makefile = NULL;
@@ -1178,9 +1180,9 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile(
cmSystemTools::ConvertToUnixSlashes(filename);
filename += "/AutomocOldMocDefinitions.cmake";
- std::fstream outfile;
+ cmsys::ofstream outfile;
outfile.open(filename.c_str(),
- std::ios::out | std::ios::trunc);
+ std::ios::trunc);
outfile << "set(AM_OLD_COMPILE_SETTINGS "
<< cmLocalGenerator::EscapeForCMake(
this->CurrentCompileSettingsStr) << ")\n";
@@ -1303,8 +1305,8 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
const std::vector<std::string>& headerExtensions =
makefile->GetHeaderExtensions();
- std::map<std::string, std::string> includedUis;
- std::map<std::string, std::string> skippedUis;
+ std::map<std::string, std::vector<std::string> > includedUis;
+ std::map<std::string, std::vector<std::string> > skippedUis;
std::vector<std::string> uicSkipped;
cmSystemTools::ExpandListArgument(this->SkipUic, uicSkipped);
@@ -1314,7 +1316,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
{
const bool skipUic = std::find(uicSkipped.begin(), uicSkipped.end(), *it)
!= uicSkipped.end();
- std::map<std::string, std::string>& uiFiles
+ std::map<std::string, std::vector<std::string> >& uiFiles
= skipUic ? skippedUis : includedUis;
const std::string &absFilename = *it;
if (this->Verbose)
@@ -1375,12 +1377,17 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
{
this->GenerateMoc(it->first, it->second);
}
- for(std::map<std::string, std::string>::const_iterator
+ for(std::map<std::string, std::vector<std::string> >::const_iterator
it = includedUis.begin();
it != includedUis.end();
++it)
{
- this->GenerateUi(it->first, it->second);
+ for (std::vector<std::string>::const_iterator nit = it->second.begin();
+ nit != it->second.end();
+ ++nit)
+ {
+ this->GenerateUi(it->first, *nit);
+ }
}
if(!this->RccExecutable.empty())
@@ -1444,9 +1451,9 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
}
// source file that includes all remaining moc files (_automoc.cpp file)
- std::fstream outfile;
+ cmsys::ofstream outfile;
outfile.open(this->OutMocCppFilename.c_str(),
- std::ios::out | std::ios::trunc);
+ std::ios::trunc);
outfile << automocSource;
outfile.close();
@@ -1455,9 +1462,9 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string> &includedUis)
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> > &includedUis)
{
cmsys::RegularExpression mocIncludeRegExp(
"[\n][ \t]*#[ \t]*include[ \t]+"
@@ -1643,9 +1650,9 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename,
void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& includedUis)
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis)
{
cmsys::RegularExpression mocIncludeRegExp(
"[\n][ \t]*#[ \t]*include[ \t]+"
@@ -1763,7 +1770,7 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename,
void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
- std::map<std::string, std::string>& includedUis)
+ std::map<std::string, std::vector<std::string> >& includedUis)
{
if (this->UicExecutable.empty())
{
@@ -1781,8 +1788,8 @@ void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
- const std::string& contentsString,
- std::map<std::string, std::string>& includedUis)
+ const std::string& contentsString,
+ std::map<std::string, std::vector<std::string> >& includedUis)
{
if (this->UicExecutable.empty())
{
@@ -1812,7 +1819,7 @@ void cmQtAutoGenerators::ParseForUic(const std::string& absFilename,
// finding the correct header, so we need to remove the ui_ part
basename = basename.substr(3);
- includedUis[realName] = basename;
+ includedUis[realName].push_back(basename);
matchOffset += uiIncludeRegExp.end();
} while(uiIncludeRegExp.find(contentsString.c_str() + matchOffset));
@@ -1858,9 +1865,9 @@ cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename,
void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders,
- const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs,
- std::map<std::string, std::string>& includedUis)
+ const std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis)
{
for(std::set<std::string>::const_iterator hIt=absHeaders.begin();
hIt!=absHeaders.end();
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 501e13a..c298f5d 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -51,28 +51,28 @@ private:
bool GenerateUi(const std::string& realName, const std::string& uiFileName);
bool GenerateQrc();
void ParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& includedUis);
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
void StrictParseCppFile(const std::string& absFilename,
- const std::vector<std::string>& headerExtensions,
- std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& includedUis);
+ const std::vector<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
void SearchHeadersForCppFile(const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
std::set<std::string>& absHeaders);
void ParseHeaders(const std::set<std::string>& absHeaders,
- const std::map<std::string, std::string>& includedMocs,
- std::map<std::string, std::string>& notIncludedMocs,
- std::map<std::string, std::string>& includedUis);
+ const std::map<std::string, std::string>& includedMocs,
+ std::map<std::string, std::string>& notIncludedMocs,
+ std::map<std::string, std::vector<std::string> >& includedUis);
void ParseForUic(const std::string& fileName,
- const std::string& contentsString,
- std::map<std::string, std::string>& includedUis);
+ const std::string& contentsString,
+ std::map<std::string, std::vector<std::string> >& includedUis);
void ParseForUic(const std::string& fileName,
- std::map<std::string, std::string>& includedUis);
+ std::map<std::string, std::vector<std::string> >& includedUis);
void Init();
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index 3731502..8baf7b3 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -462,12 +462,6 @@ struct cmStrCmp {
return strcmp(input, m_test.c_str()) == 0;
}
- // For use with binary_search
- bool operator()(const char *str1, const char *str2) const
- {
- return strcmp(str1, str2) < 0;
- }
-
private:
const std::string m_test;
};
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 65912da..90a8f85 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -20,6 +20,7 @@
#include <time.h>
#include <cmTimestamp.h>
+#include <cmUuid.h>
//----------------------------------------------------------------------------
bool cmStringCommand
@@ -105,6 +106,10 @@ bool cmStringCommand
{
return this->HandleGenexStripCommand(args);
}
+ else if(subCommand == "UUID")
+ {
+ return this->HandleUuidCommand(args);
+ }
std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e);
@@ -981,3 +986,114 @@ bool cmStringCommand
return true;
}
+
+bool cmStringCommand
+::HandleUuidCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ unsigned int argsIndex = 1;
+
+ if(args.size() < 2)
+ {
+ this->SetError("UUID sub-command requires an output variable.");
+ return false;
+ }
+
+ const std::string &outputVariable = args[argsIndex++];
+
+ std::string uuidNamespaceString;
+ std::string uuidName;
+ std::string uuidType;
+ bool uuidUpperCase = false;
+
+ while(args.size() > argsIndex)
+ {
+ if(args[argsIndex] == "NAMESPACE")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, NAMESPACE requires a value.");
+ return false;
+ }
+ uuidNamespaceString = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "NAME")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, NAME requires a value.");
+ return false;
+ }
+ uuidName = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "TYPE")
+ {
+ ++argsIndex;
+ if(argsIndex >= args.size())
+ {
+ this->SetError("UUID sub-command, TYPE requires a value.");
+ return false;
+ }
+ uuidType = args[argsIndex++];
+ }
+ else if(args[argsIndex] == "UPPER")
+ {
+ ++argsIndex;
+ uuidUpperCase = true;
+ }
+ else
+ {
+ std::string e = "UUID sub-command does not recognize option " +
+ args[argsIndex] + ".";
+ this->SetError(e);
+ return false;
+ }
+ }
+
+ std::string uuid;
+ cmUuid uuidGenerator;
+
+ std::vector<unsigned char> uuidNamespace;
+ if(!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace))
+ {
+ this->SetError("UUID sub-command, malformed NAMESPACE UUID.");
+ return false;
+ }
+
+ if(uuidType == "MD5")
+ {
+ uuid = uuidGenerator.FromMd5(uuidNamespace, uuidName);
+ }
+ else if(uuidType == "SHA1")
+ {
+ uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName);
+ }
+ else
+ {
+ std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'.";
+ this->SetError(e);
+ return false;
+ }
+
+ if(uuid.empty())
+ {
+ this->SetError("UUID sub-command, generation failed.");
+ return false;
+ }
+
+ if(uuidUpperCase)
+ {
+ uuid = cmSystemTools::UpperCase(uuid);
+ }
+
+ this->Makefile->AddDefinition(outputVariable, uuid.c_str());
+ return true;
+#else
+ cmOStringStream e;
+ e << args[0] << " not available during bootstrap";
+ this->SetError(e.str().c_str());
+ return false;
+#endif
+}
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 8292e64..9c75095 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -74,6 +74,7 @@ protected:
bool HandleTimestampCommand(std::vector<std::string> const& args);
bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
bool HandleGenexStripCommand(std::vector<std::string> const& args);
+ bool HandleUuidCommand(std::vector<std::string> const& args);
class RegexReplacement
{
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 2e417cb..fbb4416 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -91,6 +91,31 @@ extern char** environ;
# endif
#endif
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+static std::string
+cm_archive_entry_pathname(struct archive_entry *entry)
+{
+#if cmsys_STL_HAS_WSTRING
+ return cmsys::Encoding::ToNarrow(
+ archive_entry_pathname_w(entry)).c_str();
+#else
+ return archive_entry_pathname(entry);
+#endif
+}
+
+static int cm_archive_read_open_file(struct archive* a,
+ const char* file,
+ int block_size)
+{
+#if cmsys_STL_HAS_WSTRING
+ std::wstring wfile = cmsys::Encoding::ToWide(file);
+ return archive_read_open_filename_w(a, wfile.c_str(), block_size);
+#else
+ return archive_read_open_filename(a, file, block_size);
+#endif
+}
+#endif
+
#ifdef _WIN32
class cmSystemToolsWindowsHandle
{
@@ -359,14 +384,28 @@ bool cmSystemTools::IsOn(const char* val)
{
return false;
}
- std::basic_string<char> v = val;
+ size_t len = strlen(val);
+ if (len > 4)
+ {
+ return false;
+ }
+ std::basic_string<char> v(val, len);
+ static std::set<std::string> onValues;
+ if(onValues.empty())
+ {
+ onValues.insert("ON");
+ onValues.insert("1");
+ onValues.insert("YES");
+ onValues.insert("TRUE");
+ onValues.insert("Y");
+ }
for(std::basic_string<char>::iterator c = v.begin();
c != v.end(); c++)
{
*c = static_cast<char>(toupper(*c));
}
- return (v == "ON" || v == "1" || v == "YES" || v == "TRUE" || v == "Y");
+ return (onValues.count(v) > 0);
}
bool cmSystemTools::IsNOTFOUND(const char* val)
@@ -381,19 +420,35 @@ bool cmSystemTools::IsNOTFOUND(const char* val)
bool cmSystemTools::IsOff(const char* val)
{
- if (!val || strlen(val) == 0)
+ if (!val || !*val)
{
return true;
}
- std::basic_string<char> v = val;
+ size_t len = strlen(val);
+ // Try and avoid toupper() for large strings.
+ if (len > 6)
+ {
+ return cmSystemTools::IsNOTFOUND(val);
+ }
+ static std::set<std::string> offValues;
+ if(offValues.empty())
+ {
+ offValues.insert("OFF");
+ offValues.insert("0");
+ offValues.insert("NO");
+ offValues.insert("FALSE");
+ offValues.insert("N");
+ offValues.insert("IGNORE");
+ }
+ // Try and avoid toupper().
+ std::basic_string<char> v(val, len);
for(std::basic_string<char>::iterator c = v.begin();
c != v.end(); c++)
{
*c = static_cast<char>(toupper(*c));
}
- return (v == "OFF" || v == "0" || v == "NO" || v == "FALSE" ||
- v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE");
+ return (offValues.count(v) > 0);
}
//----------------------------------------------------------------------------
@@ -439,7 +494,7 @@ void cmSystemTools::ParseWindowsCommandLine(const char* command,
{
arg.append(backslashes, '\\');
backslashes = 0;
- if(isspace(*c))
+ if(((*c & 0x80) == 0 ) && isspace(*c))
{
if(in_quotes)
{
@@ -1581,7 +1636,7 @@ namespace{
}
strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
fprintf(out, " %s ", tmp);
- fprintf(out, "%s", archive_entry_pathname(entry));
+ fprintf(out, "%s", cm_archive_entry_pathname(entry).c_str());
/* Extra information for links. */
if (archive_entry_hardlink(entry)) /* Hard link */
@@ -1641,11 +1696,13 @@ bool extract_tar(const char* outFileName, bool verbose,
archive_read_support_compression_all(a);
archive_read_support_format_all(a);
struct archive_entry *entry;
- int r = archive_read_open_file(a, outFileName, 10240);
+ int r = cm_archive_read_open_file(a, outFileName, 10240);
if(r)
{
cmSystemTools::Error("Problem with archive_read_open_file(): ",
archive_error_string(a));
+ archive_write_free(ext);
+ archive_read_close(a);
return false;
}
for (;;)
@@ -1666,7 +1723,7 @@ bool extract_tar(const char* outFileName, bool verbose,
if(extract)
{
cmSystemTools::Stdout("x ");
- cmSystemTools::Stdout(archive_entry_pathname(entry));
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
}
else
{
@@ -1676,7 +1733,7 @@ bool extract_tar(const char* outFileName, bool verbose,
}
else if(!extract)
{
- cmSystemTools::Stdout(archive_entry_pathname(entry));
+ cmSystemTools::Stdout(cm_archive_entry_pathname(entry).c_str());
cmSystemTools::Stdout("\n");
}
if(extract)
@@ -1706,7 +1763,8 @@ bool extract_tar(const char* outFileName, bool verbose,
else if(const char* linktext = archive_entry_symlink(entry))
{
std::cerr << "cmake -E tar: warning: skipping symbolic link \""
- << archive_entry_pathname(entry) << "\" -> \""
+ << cm_archive_entry_pathname(entry)
+ << "\" -> \""
<< linktext << "\"." << std::endl;
}
#endif
@@ -1715,11 +1773,12 @@ bool extract_tar(const char* outFileName, bool verbose,
cmSystemTools::Error("Problem with archive_write_header(): ",
archive_error_string(ext));
cmSystemTools::Error("Current file: ",
- archive_entry_pathname(entry));
+ cm_archive_entry_pathname(entry).c_str());
break;
}
}
}
+ archive_write_free(ext);
archive_read_close(a);
archive_read_finish(a);
return r == ARCHIVE_EOF || r == ARCHIVE_OK;
@@ -2129,6 +2188,11 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
cmSystemToolsCMakeCommand = exe_dir;
cmSystemToolsCMakeCommand += "/cmake";
cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension();
+#ifndef CMAKE_BUILD_WITH_CMAKE
+ // The bootstrap cmake does not provide the other tools,
+ // so use the directory where they are about to be built.
+ exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
+#endif
cmSystemToolsCTestCommand = exe_dir;
cmSystemToolsCTestCommand += "/ctest";
cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension();
@@ -2181,7 +2245,7 @@ void cmSystemTools::FindCMakeResources(const char* argv0)
}
#else
// Bootstrap build knows its source.
- cmSystemToolsCMakeRoot = CMAKE_ROOT_DIR;
+ cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR;
#endif
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 59cc14c..b476a27 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -25,6 +25,12 @@
#include <stdlib.h> // required for atof
#include <assert.h>
#include <errno.h>
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_set.hxx>
+#define UNORDERED_SET cmsys::hash_set
+#else
+#define UNORDERED_SET std::set
+#endif
const char* cmTarget::GetTargetTypeName(TargetType targetType)
{
@@ -64,11 +70,16 @@ struct cmTarget::OutputInfo
//----------------------------------------------------------------------------
struct cmTarget::ImportInfo
{
+ ImportInfo(): NoSOName(false), Multiplicity(0) {}
bool NoSOName;
+ int Multiplicity;
std::string Location;
std::string SOName;
std::string ImportLibrary;
- cmTarget::LinkInterface LinkInterface;
+ std::string Languages;
+ std::string Libraries;
+ std::string LibrariesProp;
+ std::string SharedDeps;
};
//----------------------------------------------------------------------------
@@ -77,11 +88,6 @@ struct cmTarget::CompileInfo
std::string CompilePdbDir;
};
-struct TargetConfigPair : public std::pair<cmTarget const* , std::string> {
- TargetConfigPair(cmTarget const* tgt, const std::string &config)
- : std::pair<cmTarget const* , std::string>(tgt, config) {}
-};
-
//----------------------------------------------------------------------------
class cmTargetInternals
{
@@ -90,11 +96,13 @@ public:
: Backtrace(NULL)
{
this->PolicyWarnedCMP0022 = false;
+ this->UtilityItemsDone = false;
}
cmTargetInternals(cmTargetInternals const&)
: Backtrace(NULL)
{
this->PolicyWarnedCMP0022 = false;
+ this->UtilityItemsDone = false;
}
~cmTargetInternals();
@@ -105,53 +113,100 @@ public:
struct OptionalLinkInterface: public cmTarget::LinkInterface
{
OptionalLinkInterface():
- Exists(false), Complete(false), ExplicitLibraries(0) {}
+ LibrariesDone(false), AllDone(false),
+ Exists(false), HadHeadSensitiveCondition(false),
+ ExplicitLibraries(0) {}
+ bool LibrariesDone;
+ bool AllDone;
bool Exists;
- bool Complete;
+ bool HadHeadSensitiveCondition;
const char* ExplicitLibraries;
};
void ComputeLinkInterface(cmTarget const* thisTarget,
const std::string& config,
OptionalLinkInterface& iface,
- cmTarget const* head,
- const char *explicitLibraries) const;
+ cmTarget const* head) const;
+ void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkInterface& iface,
+ cmTarget const* head,
+ bool usage_requirements_only);
- typedef std::map<TargetConfigPair, OptionalLinkInterface>
+ struct HeadToLinkInterfaceMap:
+ public std::map<cmTarget const*, OptionalLinkInterface> {};
+ typedef std::map<std::string, HeadToLinkInterfaceMap>
LinkInterfaceMapType;
LinkInterfaceMapType LinkInterfaceMap;
+ LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
bool PolicyWarnedCMP0022;
typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
OutputInfoMapType OutputInfoMap;
- typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
- ImportInfoMapType;
+ typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap;
typedef std::map<std::string, cmTarget::CompileInfo> CompileInfoMapType;
CompileInfoMapType CompileInfoMap;
// Cache link implementation computation from each configuration.
- typedef std::map<TargetConfigPair,
- cmTarget::LinkImplementation> LinkImplMapType;
+ struct OptionalLinkImplementation: public cmTarget::LinkImplementation
+ {
+ OptionalLinkImplementation():
+ LibrariesDone(false), LanguagesDone(false),
+ HadHeadSensitiveCondition(false) {}
+ bool LibrariesDone;
+ bool LanguagesDone;
+ bool HadHeadSensitiveCondition;
+ };
+ void ComputeLinkImplementationLibraries(cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkImplementation& impl,
+ cmTarget const* head) const;
+ void ComputeLinkImplementationLanguages(cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkImplementation& impl
+ ) const;
+
+ struct HeadToLinkImplementationMap:
+ public std::map<cmTarget const*, OptionalLinkImplementation> {};
+ typedef std::map<std::string,
+ HeadToLinkImplementationMap> LinkImplMapType;
LinkImplMapType LinkImplMap;
- typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
- LinkClosureMapType;
+ typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType;
LinkClosureMapType LinkClosureMap;
- typedef std::map<TargetConfigPair, std::vector<cmSourceFile*> >
- SourceFilesMapType;
+ struct LinkImplClosure: public std::vector<cmTarget const*>
+ {
+ LinkImplClosure(): Done(false) {}
+ bool Done;
+ };
+ std::map<std::string, LinkImplClosure> LinkImplClosureMap;
+
+ struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces
+ {
+ CompatibleInterfaces(): Done(false) {}
+ bool Done;
+ };
+ std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
+
+ typedef std::map<std::string, std::vector<cmSourceFile*> >
+ SourceFilesMapType;
SourceFilesMapType SourceFilesMap;
- struct TargetPropertyEntry {
+ std::set<cmLinkItem> UtilityItems;
+ bool UtilityItemsDone;
+
+ class TargetPropertyEntry {
+ static cmLinkImplItem NoLinkImplItem;
+ public:
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
- const std::string &targetName = std::string())
- : ge(cge), TargetName(targetName)
+ cmLinkImplItem const& item = NoLinkImplItem)
+ : ge(cge), LinkImplItem(item)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
- std::vector<std::string> CachedEntries;
- const std::string TargetName;
+ cmLinkImplItem const& LinkImplItem;
};
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
@@ -160,26 +215,15 @@ public:
std::vector<TargetPropertyEntry*> SourceEntries;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
- mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceIncludeDirectoriesEntries;
- mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceCompileOptionsEntries;
- mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceCompileDefinitionsEntries;
- mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceSourcesEntries;
- mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
- CachedLinkInterfaceCompileFeaturesEntries;
-
- mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
- mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
- mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
- mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
- mutable std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone;
+ void AddInterfaceEntries(
+ cmTarget const* thisTarget, std::string const& config,
+ std::string const& prop, std::vector<TargetPropertyEntry*>& entries);
};
+cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
+
//----------------------------------------------------------------------------
-void deleteAndClear(
+static void deleteAndClear(
std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
{
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
@@ -193,26 +237,8 @@ void deleteAndClear(
}
//----------------------------------------------------------------------------
-void deleteAndClear(
- std::map<std::string,
- std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries)
-{
- for (std::map<std::string,
- std::vector<cmTargetInternals::TargetPropertyEntry*> >::iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
- {
- deleteAndClear(it->second);
- }
-}
-
-//----------------------------------------------------------------------------
cmTargetInternals::~cmTargetInternals()
{
- deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
- deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
- deleteAndClear(this->CachedLinkInterfaceCompileFeaturesEntries);
- deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
- deleteAndClear(this->CachedLinkInterfaceSourcesEntries);
}
//----------------------------------------------------------------------------
@@ -226,9 +252,12 @@ cmTarget::cmTarget()
#undef INITIALIZE_TARGET_POLICY_MEMBER
this->Makefile = 0;
- this->LinkLibrariesAnalyzed = false;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LinkLibrariesForVS6Analyzed = false;
+#endif
this->HaveInstallRule = false;
this->DLLPlatform = false;
+ this->IsAndroid = false;
this->IsApple = false;
this->IsImportedTarget = false;
this->BuildInterfaceIncludesAppended = false;
@@ -284,12 +313,18 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"));
+ // Check whether we are targeting an Android platform.
+ this->IsAndroid =
+ strcmp(this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"),
+ "Android") == 0;
+
// Check whether we are targeting an Apple platform.
this->IsApple = this->Makefile->IsOn("APPLE");
// Setup default property values.
- if (this->GetType() != INTERFACE_LIBRARY)
+ if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
{
+ this->SetPropertyDefault("ANDROID_API", 0);
this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
@@ -329,41 +364,44 @@ void cmTarget::SetMakefile(cmMakefile* mf)
mf->GetConfigurations(configNames);
// Setup per-configuration property default values.
- const char* configProps[] = {
- "ARCHIVE_OUTPUT_DIRECTORY_",
- "LIBRARY_OUTPUT_DIRECTORY_",
- "RUNTIME_OUTPUT_DIRECTORY_",
- "PDB_OUTPUT_DIRECTORY_",
- "COMPILE_PDB_OUTPUT_DIRECTORY_",
- "MAP_IMPORTED_CONFIG_",
- 0};
- for(std::vector<std::string>::iterator ci = configNames.begin();
- ci != configNames.end(); ++ci)
- {
- std::string configUpper = cmSystemTools::UpperCase(*ci);
- for(const char** p = configProps; *p; ++p)
- {
- if (this->TargetTypeValue == INTERFACE_LIBRARY
- && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
+ if (this->GetType() != UTILITY)
+ {
+ const char* configProps[] = {
+ "ARCHIVE_OUTPUT_DIRECTORY_",
+ "LIBRARY_OUTPUT_DIRECTORY_",
+ "RUNTIME_OUTPUT_DIRECTORY_",
+ "PDB_OUTPUT_DIRECTORY_",
+ "COMPILE_PDB_OUTPUT_DIRECTORY_",
+ "MAP_IMPORTED_CONFIG_",
+ 0};
+ for(std::vector<std::string>::iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ std::string configUpper = cmSystemTools::UpperCase(*ci);
+ for(const char** p = configProps; *p; ++p)
{
- continue;
+ if (this->TargetTypeValue == INTERFACE_LIBRARY
+ && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
+ {
+ continue;
+ }
+ std::string property = *p;
+ property += configUpper;
+ this->SetPropertyDefault(property, 0);
}
- std::string property = *p;
- property += configUpper;
- this->SetPropertyDefault(property, 0);
- }
- // Initialize per-configuration name postfix property from the
- // variable only for non-executable targets. This preserves
- // compatibility with previous CMake versions in which executables
- // did not support this variable. Projects may still specify the
- // property directly.
- if(this->TargetTypeValue != cmTarget::EXECUTABLE
- && this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY)
- {
- std::string property = cmSystemTools::UpperCase(*ci);
- property += "_POSTFIX";
- this->SetPropertyDefault(property, 0);
+ // Initialize per-configuration name postfix property from the
+ // variable only for non-executable targets. This preserves
+ // compatibility with previous CMake versions in which executables
+ // did not support this variable. Projects may still specify the
+ // property directly.
+ if(this->TargetTypeValue != cmTarget::EXECUTABLE
+ && this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY)
+ {
+ std::string property = cmSystemTools::UpperCase(*ci);
+ property += "_POSTFIX";
+ this->SetPropertyDefault(property, 0);
+ }
}
}
@@ -402,19 +440,23 @@ void cmTarget::SetMakefile(cmMakefile* mf)
}
}
- if (this->GetType() != INTERFACE_LIBRARY)
+ if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
{
this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
}
+ if(this->TargetTypeValue == cmTarget::EXECUTABLE)
+ {
+ this->SetPropertyDefault("ANDROID_GUI", 0);
+ }
if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
|| this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
{
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
}
- if (this->GetType() != INTERFACE_LIBRARY)
+ if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
{
this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
}
@@ -436,8 +478,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->PolicyStatusCMP0022 = cmPolicies::NEW;
}
- this->SetPropertyDefault("JOB_POOL_COMPILE", 0);
- this->SetPropertyDefault("JOB_POOL_LINK", 0);
+ if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
+ {
+ this->SetPropertyDefault("JOB_POOL_COMPILE", 0);
+ this->SetPropertyDefault("JOB_POOL_LINK", 0);
+ }
}
//----------------------------------------------------------------------------
@@ -461,6 +506,22 @@ cmListFileBacktrace const* cmTarget::GetUtilityBacktrace(
}
//----------------------------------------------------------------------------
+std::set<cmLinkItem> const& cmTarget::GetUtilityItems() const
+{
+ if(!this->Internal->UtilityItemsDone)
+ {
+ this->Internal->UtilityItemsDone = true;
+ for(std::set<std::string>::const_iterator i = this->Utilities.begin();
+ i != this->Utilities.end(); ++i)
+ {
+ this->Internal->UtilityItems.insert(
+ cmLinkItem(*i, this->Makefile->FindTargetToUse(*i)));
+ }
+ }
+ return this->Internal->UtilityItems;
+}
+
+//----------------------------------------------------------------------------
void cmTarget::FinishConfigure()
{
// Erase any cached link information that might have been comptued
@@ -469,8 +530,13 @@ void cmTarget::FinishConfigure()
// invalidation code in this source file is buggy.
this->ClearLinkMaps();
- // Do old-style link dependency analysis.
- this->AnalyzeLibDependencies(*this->Makefile);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
+ if(this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->IsForVS6())
+ {
+ this->AnalyzeLibDependenciesForVS6(*this->Makefile);
+ }
+#endif
}
//----------------------------------------------------------------------------
@@ -479,6 +545,7 @@ void cmTarget::ClearLinkMaps()
this->LinkImplementationLanguageIsContextDependent = true;
this->Internal->LinkImplMap.clear();
this->Internal->LinkInterfaceMap.clear();
+ this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear();
this->Internal->LinkClosureMap.clear();
for (cmTargetLinkInformationMap::const_iterator it
= this->LinkInformation.begin();
@@ -571,9 +638,8 @@ bool cmTarget::IsBundleOnApple() const
static bool processSources(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &srcs,
- std::set<std::string> &uniqueSrcs,
+ UNORDERED_SET<std::string> &uniqueSrcs,
cmGeneratorExpressionDAGChecker *dagChecker,
- cmTarget const* head,
std::string const& config, bool debugSources)
{
cmMakefile *mf = tgt->GetMakefile();
@@ -583,49 +649,37 @@ static bool processSources(cmTarget const* tgt,
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
- bool cacheSources = false;
- std::vector<std::string> entrySources = (*it)->CachedEntries;
- if(entrySources.empty())
+ std::vector<std::string> entrySources;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ config,
+ false,
+ tgt,
+ tgt,
+ dagChecker),
+ entrySources);
+
+ if ((*it)->ge->GetHadContextSensitiveCondition())
{
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- head ? head : tgt,
- tgt,
- dagChecker),
- entrySources);
+ contextDependent = true;
+ }
- if ((*it)->ge->GetHadContextSensitiveCondition())
- {
- contextDependent = true;
- }
- else if (mf->IsGeneratingBuildSystem())
- {
- cacheSources = true;
- }
+ for(std::vector<std::string>::iterator i = entrySources.begin();
+ i != entrySources.end(); ++i)
+ {
+ std::string& src = *i;
- for(std::vector<std::string>::iterator i = entrySources.begin();
- i != entrySources.end(); ++i)
+ cmSourceFile* sf = mf->GetOrCreateSource(src);
+ std::string e;
+ src = sf->GetFullPath(&e);
+ if(src.empty())
{
- std::string& src = *i;
-
- cmSourceFile* sf = mf->GetOrCreateSource(src);
- std::string e;
- src = sf->GetFullPath(&e);
- if(src.empty())
+ if(!e.empty())
{
- if(!e.empty())
- {
- cmake* cm = mf->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, e,
- tgt->GetBacktrace());
- }
- return contextDependent;
+ cmake* cm = mf->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e,
+ tgt->GetBacktrace());
}
- }
- if (cacheSources)
- {
- (*it)->CachedEntries = entrySources;
+ return contextDependent;
}
}
std::string usedSources;
@@ -656,8 +710,7 @@ static bool processSources(cmTarget const* tgt,
//----------------------------------------------------------------------------
void cmTarget::GetSourceFiles(std::vector<std::string> &files,
- const std::string& config,
- cmTarget const* head) const
+ const std::string& config) const
{
assert(this->GetType() != INTERFACE_LIBRARY);
@@ -715,66 +768,28 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"SOURCES", 0, 0);
- std::set<std::string> uniqueSrcs;
+ UNORDERED_SET<std::string> uniqueSrcs;
bool contextDependentDirectSources = processSources(this,
this->Internal->SourceEntries,
files,
uniqueSrcs,
&dagChecker,
- head,
config,
debugSources);
- if (!this->Internal->CacheLinkInterfaceSourcesDone[config])
- {
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
- {
- if (!cmGeneratorExpression::IsValidTargetName(it->Value)
- && cmGeneratorExpression::Find(it->Value) == std::string::npos)
- {
- continue;
- }
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, &dagChecker);
- if (!this->Makefile->FindTargetToUse(targetResult))
- {
- continue;
- }
- }
- std::string sourceGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_SOURCES>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- sourceGenex = "$<$<BOOL:" + it->Value + ">:" + sourceGenex + ">";
- }
- cmGeneratorExpression ge(&it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- sourceGenex);
+ std::vector<cmTargetInternals::TargetPropertyEntry*>
+ linkInterfaceSourcesEntries;
- this->Internal
- ->CachedLinkInterfaceSourcesEntries[config].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
- }
+ this->Internal->AddInterfaceEntries(
+ this, config, "INTERFACE_SOURCES",
+ linkInterfaceSourcesEntries);
- std::vector<std::string>::size_type numFilesBefore = files.size();
- bool contextDependentInterfaceSources = processSources(this,
- this->Internal->CachedLinkInterfaceSourcesEntries[config],
+ std::vector<std::string>::size_type numFilesBefore = files.size();
+ bool contextDependentInterfaceSources = processSources(this,
+ linkInterfaceSourcesEntries,
files,
uniqueSrcs,
&dagChecker,
- head,
config,
debugSources);
@@ -784,14 +799,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
this->LinkImplementationLanguageIsContextDependent = false;
}
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal->CachedLinkInterfaceSourcesEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceSourcesDone[config] = true;
- }
+ deleteAndClear(linkInterfaceSourcesEntries);
}
//----------------------------------------------------------------------------
@@ -853,12 +861,11 @@ cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
//----------------------------------------------------------------------------
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
- const std::string& config,
- cmTarget const* head) const
+ const std::string& config) const
{
// Lookup any existing link implementation for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ std::string key = cmSystemTools::UpperCase(config);
if(!this->LinkImplementationLanguageIsContextDependent)
{
@@ -875,7 +882,7 @@ void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
else
{
std::vector<std::string> srcs;
- this->GetSourceFiles(srcs, config, head);
+ this->GetSourceFiles(srcs, config);
std::set<cmSourceFile*> emitted;
@@ -931,10 +938,13 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
if(!(src[0] == '$' && src[1] == '<'))
{
- filename = this->ProcessSourceItemCMP0049(filename);
- if (cmSystemTools::GetErrorOccuredFlag())
+ if(!filename.empty())
{
- return;
+ filename = this->ProcessSourceItemCMP0049(filename);
+ if(filename.empty())
+ {
+ return;
+ }
}
this->Makefile->GetOrCreateSource(filename);
}
@@ -1002,8 +1012,7 @@ std::string cmTarget::ProcessSourceItemCMP0049(const std::string& s)
cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
{
std::string src = this->ProcessSourceItemCMP0049(s);
-
- if (cmSystemTools::GetErrorOccuredFlag())
+ if(!s.empty() && src.empty())
{
return 0;
}
@@ -1195,63 +1204,6 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) const
}
//----------------------------------------------------------------------------
-void cmTarget::GetDirectLinkLibraries(const std::string& config,
- std::vector<std::string> &libs,
- cmTarget const* head) const
-{
- const char *prop = this->GetProperty("LINK_LIBRARIES");
- if (prop)
- {
- cmGeneratorExpression ge;
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
-
- cmGeneratorExpressionDAGChecker dagChecker(
- this->GetName(),
- "LINK_LIBRARIES", 0, 0);
- cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
- config,
- false,
- head,
- &dagChecker),
- libs);
-
- std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
- for (std::set<std::string>::const_iterator it = seenProps.begin();
- it != seenProps.end(); ++it)
- {
- if (!this->GetProperty(*it))
- {
- this->LinkImplicitNullProperties.insert(*it);
- }
- }
- cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetInterfaceLinkLibraries(const std::string& config,
- std::vector<std::string> &libs,
- cmTarget const* head) const
-{
- const char *prop = this->GetProperty("INTERFACE_LINK_LIBRARIES");
- if (prop)
- {
- cmGeneratorExpression ge;
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
-
- cmGeneratorExpressionDAGChecker dagChecker(
- this->GetName(),
- "INTERFACE_LINK_LIBRARIES", 0, 0);
- cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
- config,
- false,
- head,
- &dagChecker),
- libs);
- }
-}
-
-//----------------------------------------------------------------------------
std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
cmTarget::LinkLibraryType llt) const
{
@@ -1325,7 +1277,7 @@ void cmTarget::GetTllSignatureTraces(cmOStringStream &s,
= (sig == cmTarget::KeywordTLLSignature ? "keyword"
: "plain");
s << "The uses of the " << sigString << " signature are here:\n";
- std::set<std::string> emitted;
+ UNORDERED_SET<std::string> emitted;
for(std::vector<cmListFileBacktrace>::iterator it = sigs.begin();
it != sigs.end(); ++it)
{
@@ -1374,7 +1326,9 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
cmTarget::LibraryID tmp;
tmp.first = lib;
tmp.second = llt;
- this->LinkLibraries.push_back( tmp );
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LinkLibrariesForVS6.push_back( tmp );
+#endif
this->OriginalLinkLibraries.push_back(tmp);
this->ClearLinkMaps();
@@ -1440,9 +1394,10 @@ cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
}
}
+#if defined(_WIN32) && !defined(__CYGWIN__)
//----------------------------------------------------------------------------
void
-cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
+cmTarget::AnalyzeLibDependenciesForVS6( const cmMakefile& mf )
{
// There are two key parts of the dependency analysis: (1)
// determining the libraries in the link line, and (2) constructing
@@ -1519,8 +1474,8 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// eventually be removed. This code was moved here from the end of
// old source list processing code which was called just before this
// method.
- for(LinkLibraryVectorType::iterator p = this->LinkLibraries.begin();
- p != this->LinkLibraries.end(); ++p)
+ for(LinkLibraryVectorType::iterator p = this->LinkLibrariesForVS6.begin();
+ p != this->LinkLibrariesForVS6.end(); ++p)
{
this->Makefile->ExpandVariablesInString(p->first, true, true);
}
@@ -1532,22 +1487,22 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// 1. Build the dependency graph
//
for(LinkLibraryVectorType::reverse_iterator lib
- = this->LinkLibraries.rbegin();
- lib != this->LinkLibraries.rend(); ++lib)
+ = this->LinkLibrariesForVS6.rbegin();
+ lib != this->LinkLibrariesForVS6.rend(); ++lib)
{
- this->GatherDependencies( mf, *lib, dep_map);
+ this->GatherDependenciesForVS6( mf, *lib, dep_map);
}
// 2. Remove any dependencies that are already satisfied in the original
// link line.
//
- for(LinkLibraryVectorType::iterator lib = this->LinkLibraries.begin();
- lib != this->LinkLibraries.end(); ++lib)
+ for(LinkLibraryVectorType::iterator lib = this->LinkLibrariesForVS6.begin();
+ lib != this->LinkLibrariesForVS6.end(); ++lib)
{
for( LinkLibraryVectorType::iterator lib2 = lib;
- lib2 != this->LinkLibraries.end(); ++lib2)
+ lib2 != this->LinkLibrariesForVS6.end(); ++lib2)
{
- this->DeleteDependency( dep_map, *lib, *lib2);
+ this->DeleteDependencyForVS6( dep_map, *lib, *lib2);
}
}
@@ -1556,43 +1511,43 @@ cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
// missing. Start from the back and keep adding.
//
std::set<DependencyMap::key_type> done, visited;
- std::vector<DependencyMap::key_type> newLinkLibraries;
+ std::vector<DependencyMap::key_type> newLinkLibrariesForVS6;
for(LinkLibraryVectorType::reverse_iterator lib =
- this->LinkLibraries.rbegin();
- lib != this->LinkLibraries.rend(); ++lib)
+ this->LinkLibrariesForVS6.rbegin();
+ lib != this->LinkLibrariesForVS6.rend(); ++lib)
{
// skip zero size library entries, this may happen
// if a variable expands to nothing.
if (lib->first.size() != 0)
{
- this->Emit( *lib, dep_map, done, visited, newLinkLibraries );
+ this->EmitForVS6( *lib, dep_map, done, visited, newLinkLibrariesForVS6 );
}
}
// 4. Add the new libraries to the link line.
//
for( std::vector<DependencyMap::key_type>::reverse_iterator k =
- newLinkLibraries.rbegin();
- k != newLinkLibraries.rend(); ++k )
+ newLinkLibrariesForVS6.rbegin();
+ k != newLinkLibrariesForVS6.rend(); ++k )
{
// get the llt from the dep_map
- this->LinkLibraries.push_back( std::make_pair(k->first,k->second) );
+ this->LinkLibrariesForVS6.push_back( std::make_pair(k->first,k->second) );
}
- this->LinkLibrariesAnalyzed = true;
+ this->LinkLibrariesForVS6Analyzed = true;
}
//----------------------------------------------------------------------------
-void cmTarget::InsertDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep)
+void cmTarget::InsertDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep)
{
depMap[lib].push_back(dep);
}
//----------------------------------------------------------------------------
-void cmTarget::DeleteDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep)
+void cmTarget::DeleteDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep)
{
// Make sure there is an entry in the map for lib. If so, delete all
// dependencies to dep. There may be repeated entries because of
@@ -1611,11 +1566,11 @@ void cmTarget::DeleteDependency( DependencyMap& depMap,
}
//----------------------------------------------------------------------------
-void cmTarget::Emit(const LibraryID lib,
- const DependencyMap& dep_map,
- std::set<LibraryID>& emitted,
- std::set<LibraryID>& visited,
- DependencyList& link_line )
+void cmTarget::EmitForVS6(const LibraryID lib,
+ const DependencyMap& dep_map,
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line )
{
// It's already been emitted
if( emitted.find(lib) != emitted.end() )
@@ -1661,7 +1616,7 @@ void cmTarget::Emit(const LibraryID lib,
if( emitted.find(*i) == emitted.end() )
{
// emit dependencies
- Emit( *i, dep_map, emitted, visited, link_line );
+ this->EmitForVS6( *i, dep_map, emitted, visited, link_line );
// emit self
emitted.insert(*i);
emitted_here.insert(*i);
@@ -1674,9 +1629,9 @@ void cmTarget::Emit(const LibraryID lib,
}
//----------------------------------------------------------------------------
-void cmTarget::GatherDependencies( const cmMakefile& mf,
- const LibraryID& lib,
- DependencyMap& dep_map)
+void cmTarget::GatherDependenciesForVS6( const cmMakefile& mf,
+ const LibraryID& lib,
+ DependencyMap& dep_map)
{
// If the library is already in the dependency map, then it has
// already been fully processed.
@@ -1720,8 +1675,8 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
else
{
LibraryID lib2(l,llt);
- this->InsertDependency( dep_map, lib, lib2);
- this->GatherDependencies( mf, lib2, dep_map);
+ this->InsertDependencyForVS6( dep_map, lib, lib2);
+ this->GatherDependenciesForVS6( mf, lib2, dep_map);
llt = cmTarget::GENERAL;
}
}
@@ -1729,9 +1684,10 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
end = depline.find( ";", start );
}
// cannot depend on itself
- this->DeleteDependency( dep_map, lib, lib);
+ this->DeleteDependencyForVS6( dep_map, lib, lib);
}
}
+#endif
//----------------------------------------------------------------------------
static bool whiteListedInterfaceProperty(const std::string& prop)
@@ -1740,22 +1696,20 @@ static bool whiteListedInterfaceProperty(const std::string& prop)
{
return true;
}
- static const char* builtIns[] = {
- // ###: This must remain sorted. It is processed with a binary search.
- "COMPATIBLE_INTERFACE_BOOL",
- "COMPATIBLE_INTERFACE_NUMBER_MAX",
- "COMPATIBLE_INTERFACE_NUMBER_MIN",
- "COMPATIBLE_INTERFACE_STRING",
- "EXPORT_NAME",
- "IMPORTED",
- "NAME",
- "TYPE"
- };
+ static UNORDERED_SET<std::string> builtIns;
+ if (builtIns.empty())
+ {
+ builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
+ builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
+ builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
+ builtIns.insert("COMPATIBLE_INTERFACE_STRING");
+ builtIns.insert("EXPORT_NAME");
+ builtIns.insert("IMPORTED");
+ builtIns.insert("NAME");
+ builtIns.insert("TYPE");
+ }
- if (std::binary_search(cmArrayBegin(builtIns),
- cmArrayEnd(builtIns),
- prop.c_str(),
- cmStrCmp(prop)))
+ if (builtIns.count(prop))
{
return true;
}
@@ -1780,15 +1734,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
-
- if (prop == "NAME")
+ else if (prop == "NAME")
{
cmOStringStream e;
e << "NAME property is read-only\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if(prop == "INCLUDE_DIRECTORIES")
+ else if(prop == "INCLUDE_DIRECTORIES")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
@@ -1796,9 +1749,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- if(prop == "COMPILE_OPTIONS")
+ else if(prop == "COMPILE_OPTIONS")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
@@ -1806,9 +1758,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileOptionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- if(prop == "COMPILE_FEATURES")
+ else if(prop == "COMPILE_FEATURES")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
@@ -1816,9 +1767,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileFeaturesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- if(prop == "COMPILE_DEFINITIONS")
+ else if(prop == "COMPILE_DEFINITIONS")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
@@ -1826,25 +1776,22 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->CompileDefinitionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- if(prop == "EXPORT_NAME" && this->IsImported())
+ else if(prop == "EXPORT_NAME" && this->IsImported())
{
cmOStringStream e;
e << "EXPORT_NAME property can't be set on imported targets (\""
<< this->Name << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
}
- if (prop == "LINK_LIBRARIES")
+ else if (prop == "LINK_LIBRARIES")
{
this->Internal->LinkImplementationPropertyEntries.clear();
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt);
this->Internal->LinkImplementationPropertyEntries.push_back(entry);
- return;
}
- if (prop == "SOURCES")
+ else if (prop == "SOURCES")
{
if(this->IsImported())
{
@@ -1861,10 +1808,12 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->SourceEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- this->Properties.SetProperty(prop, value, cmProperty::TARGET);
- this->MaybeInvalidatePropertyCache(prop);
+ else
+ {
+ this->Properties.SetProperty(prop, value, cmProperty::TARGET);
+ this->MaybeInvalidatePropertyCache(prop);
+ }
}
//----------------------------------------------------------------------------
@@ -1880,61 +1829,55 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if (prop == "NAME")
+ else if (prop == "NAME")
{
cmOStringStream e;
e << "NAME property is read-only\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if(prop == "INCLUDE_DIRECTORIES")
+ else if(prop == "INCLUDE_DIRECTORIES")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
this->Internal->IncludeDirectoriesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
}
- if(prop == "COMPILE_OPTIONS")
+ else if(prop == "COMPILE_OPTIONS")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
this->Internal->CompileOptionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
}
- if(prop == "COMPILE_FEATURES")
+ else if(prop == "COMPILE_FEATURES")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
this->Internal->CompileFeaturesEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
}
- if(prop == "COMPILE_DEFINITIONS")
+ else if(prop == "COMPILE_DEFINITIONS")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(&lfbt);
this->Internal->CompileDefinitionsEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
- return;
}
- if(prop == "EXPORT_NAME" && this->IsImported())
+ else if(prop == "EXPORT_NAME" && this->IsImported())
{
cmOStringStream e;
e << "EXPORT_NAME property can't be set on imported targets (\""
<< this->Name << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
}
- if (prop == "LINK_LIBRARIES")
+ else if (prop == "LINK_LIBRARIES")
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt);
this->Internal->LinkImplementationPropertyEntries.push_back(entry);
- return;
}
- if (prop == "SOURCES")
+ else if (prop == "SOURCES")
{
if(this->IsImported())
{
@@ -1950,10 +1893,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->SourceEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge));
- return;
}
- this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
- this->MaybeInvalidatePropertyCache(prop);
+ else
+ {
+ this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
+ this->MaybeInvalidatePropertyCache(prop);
+ }
}
//----------------------------------------------------------------------------
@@ -2049,7 +1994,7 @@ void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry)
static void processIncludeDirectories(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &includes,
- std::set<std::string> &uniqueIncludes,
+ UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugIncludes)
{
@@ -2058,61 +2003,28 @@ static void processIncludeDirectories(cmTarget const* tgt,
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
- bool testIsOff = true;
- bool cacheIncludes = false;
- std::vector<std::string>& entryIncludes = (*it)->CachedEntries;
- if(!entryIncludes.empty())
- {
- testIsOff = false;
- }
- else
- {
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker),
- entryIncludes);
- if (mf->IsGeneratingBuildSystem()
- && !(*it)->ge->GetHadContextSensitiveCondition())
- {
- cacheIncludes = true;
- }
- }
+ cmLinkImplItem const& item = (*it)->LinkImplItem;
+ std::string const& targetName = item;
+ bool const fromImported = item.Target && item.Target->IsImported();
+ bool const checkCMP0027 = item.FromGenex;
+ std::vector<std::string> entryIncludes;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ config,
+ false,
+ tgt,
+ dagChecker),
+ entryIncludes);
+
std::string usedIncludes;
for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
- std::string targetName = (*it)->TargetName;
- std::string evaluatedTargetName;
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(targetName);
- evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0);
- }
-
- cmTarget *dependentTarget = mf->FindTargetToUse(targetName);
-
- const bool fromImported = dependentTarget
- && dependentTarget->IsImported();
-
- cmTarget *evaluatedDependentTarget =
- (targetName != evaluatedTargetName)
- ? mf->FindTargetToUse(evaluatedTargetName)
- : 0;
-
- targetName = evaluatedTargetName;
-
- const bool fromEvaluatedImported = evaluatedDependentTarget
- && evaluatedDependentTarget->IsImported();
-
- if ((fromImported || fromEvaluatedImported)
+ if (fromImported
&& !cmSystemTools::FileExists(li->c_str()))
{
cmOStringStream e;
cmake::MessageType messageType = cmake::FATAL_ERROR;
- if (fromEvaluatedImported)
+ if (checkCMP0027)
{
switch(tgt->GetPolicyStatusCMP0027())
{
@@ -2184,7 +2096,7 @@ static void processIncludeDirectories(cmTarget const* tgt,
}
}
- if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
+ if (!cmSystemTools::IsOff(li->c_str()))
{
cmSystemTools::ConvertToUnixSlashes(*li);
}
@@ -2199,10 +2111,6 @@ static void processIncludeDirectories(cmTarget const* tgt,
}
}
}
- if (cacheIncludes)
- {
- (*it)->CachedEntries = entryIncludes;
- }
if (!usedIncludes.empty())
{
mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
@@ -2218,7 +2126,7 @@ std::vector<std::string>
cmTarget::GetIncludeDirectories(const std::string& config) const
{
std::vector<std::string> includes;
- std::set<std::string> uniqueIncludes;
+ UNORDERED_SET<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"INCLUDE_DIRECTORIES", 0, 0);
@@ -2250,95 +2158,47 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
config,
debugIncludes);
- if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config])
+ std::vector<cmTargetInternals::TargetPropertyEntry*>
+ linkInterfaceIncludeDirectoriesEntries;
+ this->Internal->AddInterfaceEntries(
+ this, config, "INTERFACE_INCLUDE_DIRECTORIES",
+ linkInterfaceIncludeDirectoriesEntries);
+
+ if(this->Makefile->IsOn("APPLE"))
{
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
- {
- if (!cmGeneratorExpression::IsValidTargetName(it->Value)
- && cmGeneratorExpression::Find(it->Value) == std::string::npos)
- {
- continue;
- }
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
{
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string result = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(result))
+ std::string libDir = cmSystemTools::CollapseFullPath(it->c_str());
+
+ static cmsys::RegularExpression
+ frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+ if(!frameworkCheck.find(libDir))
{
continue;
}
- }
- std::string includeGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
- }
- cmGeneratorExpression ge(&it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- includeGenex);
-
- this->Internal
- ->CachedLinkInterfaceIncludeDirectoriesEntries[config].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
-
- if(this->Makefile->IsOn("APPLE"))
- {
- LinkImplementation const* impl = this->GetLinkImplementation(config,
- this);
- for(std::vector<std::string>::const_iterator
- it = impl->Libraries.begin();
- it != impl->Libraries.end(); ++it)
- {
- std::string libDir = cmSystemTools::CollapseFullPath(it->c_str());
-
- static cmsys::RegularExpression
- frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
- if(!frameworkCheck.find(libDir))
- {
- continue;
- }
- libDir = frameworkCheck.match(1);
+ libDir = frameworkCheck.match(1);
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(libDir.c_str());
- this->Internal
- ->CachedLinkInterfaceIncludeDirectoriesEntries[config]
- .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
- }
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(libDir.c_str());
+ linkInterfaceIncludeDirectoriesEntries
+ .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
}
}
processIncludeDirectories(this,
- this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[config],
+ linkInterfaceIncludeDirectoriesEntries,
includes,
uniqueIncludes,
&dagChecker,
config,
debugIncludes);
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(
- this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[config]
- = true;
- }
+ deleteAndClear(linkInterfaceIncludeDirectoriesEntries);
return includes;
}
@@ -2347,7 +2207,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
static void processCompileOptionsInternal(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions, const char *logName)
{
@@ -2356,27 +2216,18 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
- bool cacheOptions = false;
- std::vector<std::string> entryOptions = (*it)->CachedEntries;
- if(entryOptions.empty())
- {
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker),
- entryOptions);
- if (mf->IsGeneratingBuildSystem()
- && !(*it)->ge->GetHadContextSensitiveCondition())
- {
- cacheOptions = true;
- }
- }
+ std::vector<std::string> entryOptions;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ config,
+ false,
+ tgt,
+ dagChecker),
+ entryOptions);
std::string usedOptions;
for(std::vector<std::string>::iterator
li = entryOptions.begin(); li != entryOptions.end(); ++li)
{
- std::string opt = *li;
+ std::string const& opt = *li;
if(uniqueOptions.insert(opt).second)
{
@@ -2387,10 +2238,6 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
}
}
}
- if (cacheOptions)
- {
- (*it)->CachedEntries = entryOptions;
- }
if (!usedOptions.empty())
{
mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
@@ -2406,7 +2253,7 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
static void processCompileOptions(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions)
{
@@ -2443,7 +2290,7 @@ void cmTarget::GetAutoUicOptions(std::vector<std::string> &result,
void cmTarget::GetCompileOptions(std::vector<std::string> &result,
const std::string& config) const
{
- std::set<std::string> uniqueOptions;
+ UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_OPTIONS", 0, 0);
@@ -2475,72 +2322,29 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
config,
debugOptions);
- if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[config])
- {
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
- {
- if (!cmGeneratorExpression::IsValidTargetName(it->Value)
- && cmGeneratorExpression::Find(it->Value) == std::string::npos)
- {
- continue;
- }
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetResult))
- {
- continue;
- }
- }
- std::string optionGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_COMPILE_OPTIONS>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- optionGenex = "$<$<BOOL:" + it->Value + ">:" + optionGenex + ">";
- }
- cmGeneratorExpression ge(&it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- optionGenex);
+ std::vector<cmTargetInternals::TargetPropertyEntry*>
+ linkInterfaceCompileOptionsEntries;
- this->Internal
- ->CachedLinkInterfaceCompileOptionsEntries[config].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
- }
+ this->Internal->AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_OPTIONS",
+ linkInterfaceCompileOptionsEntries);
processCompileOptions(this,
- this->Internal->CachedLinkInterfaceCompileOptionsEntries[config],
+ linkInterfaceCompileOptionsEntries,
result,
uniqueOptions,
&dagChecker,
config,
debugOptions);
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal->CachedLinkInterfaceCompileOptionsEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceCompileOptionsDone[config] = true;
- }
+ deleteAndClear(linkInterfaceCompileOptionsEntries);
}
//----------------------------------------------------------------------------
static void processCompileDefinitions(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions)
{
@@ -2553,7 +2357,7 @@ static void processCompileDefinitions(cmTarget const* tgt,
void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
const std::string& config) const
{
- std::set<std::string> uniqueOptions;
+ UNORDERED_SET<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_DEFINITIONS", 0, 0);
@@ -2585,109 +2389,61 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
config,
debugDefines);
- if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config])
+ std::vector<cmTargetInternals::TargetPropertyEntry*>
+ linkInterfaceCompileDefinitionsEntries;
+ this->Internal->AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_DEFINITIONS",
+ linkInterfaceCompileDefinitionsEntries);
+ if (!config.empty())
{
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
- {
- if (!cmGeneratorExpression::IsValidTargetName(it->Value)
- && cmGeneratorExpression::Find(it->Value) == std::string::npos)
- {
- continue;
- }
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetResult))
- {
- continue;
- }
- }
- std::string defsGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_COMPILE_DEFINITIONS>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- defsGenex = "$<$<BOOL:" + it->Value + ">:" + defsGenex + ">";
- }
- cmGeneratorExpression ge(&it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- defsGenex);
-
- this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries[config].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
- if (!config.empty())
+ std::string configPropName = "COMPILE_DEFINITIONS_"
+ + cmSystemTools::UpperCase(config);
+ const char *configProp = this->GetProperty(configPropName);
+ if (configProp)
{
- std::string configPropName = "COMPILE_DEFINITIONS_"
- + cmSystemTools::UpperCase(config);
- const char *configProp = this->GetProperty(configPropName);
- if (configProp)
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
{
- switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
+ case cmPolicies::WARN:
{
- case cmPolicies::WARN:
- {
- cmOStringStream e;
- e << this->Makefile->GetCMakeInstance()->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0043);
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
- e.str());
- }
- case cmPolicies::OLD:
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(configProp);
- this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries[config]
- .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
- }
- break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- break;
+ cmOStringStream e;
+ e << this->Makefile->GetCMakeInstance()->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0043);
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ e.str());
+ }
+ case cmPolicies::OLD:
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(configProp);
+ linkInterfaceCompileDefinitionsEntries
+ .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
}
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
}
}
-
}
processCompileDefinitions(this,
- this->Internal->CachedLinkInterfaceCompileDefinitionsEntries[config],
+ linkInterfaceCompileDefinitionsEntries,
list,
uniqueOptions,
&dagChecker,
config,
debugDefines);
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal
- ->CachedLinkInterfaceCompileDefinitionsEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceCompileDefinitionsDone[config]
- = true;
- }
+ deleteAndClear(linkInterfaceCompileDefinitionsEntries);
}
//----------------------------------------------------------------------------
static void processCompileFeatures(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &options,
- std::set<std::string> &uniqueOptions,
+ UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string& config, bool debugOptions)
{
@@ -2699,7 +2455,7 @@ static void processCompileFeatures(cmTarget const* tgt,
void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
const std::string& config) const
{
- std::set<std::string> uniqueFeatures;
+ UNORDERED_SET<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
"COMPILE_FEATURES",
@@ -2732,65 +2488,21 @@ void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
config,
debugFeatures);
- if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config])
- {
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
- {
- if (!cmGeneratorExpression::IsValidTargetName(it->Value)
- && cmGeneratorExpression::Find(it->Value) == std::string::npos)
- {
- continue;
- }
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(it->Value);
- std::string targetResult = cge->Evaluate(this->Makefile, config,
- false, this, 0, 0);
- if (!this->Makefile->FindTargetToUse(targetResult))
- {
- continue;
- }
- }
- std::string featureGenex = "$<TARGET_PROPERTY:" +
- it->Value + ",INTERFACE_COMPILE_FEATURES>";
- if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
- {
- // Because it->Value is a generator expression, ensure that it
- // evaluates to the non-empty string before being used in the
- // TARGET_PROPERTY expression.
- featureGenex = "$<$<BOOL:" + it->Value + ">:" + featureGenex + ">";
- }
- cmGeneratorExpression ge(&it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
- featureGenex);
-
- this->Internal
- ->CachedLinkInterfaceCompileFeaturesEntries[config].push_back(
- new cmTargetInternals::TargetPropertyEntry(cge,
- it->Value));
- }
- }
+ std::vector<cmTargetInternals::TargetPropertyEntry*>
+ linkInterfaceCompileFeaturesEntries;
+ this->Internal->AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_FEATURES",
+ linkInterfaceCompileFeaturesEntries);
processCompileFeatures(this,
- this->Internal->CachedLinkInterfaceCompileFeaturesEntries[config],
+ linkInterfaceCompileFeaturesEntries,
result,
uniqueFeatures,
&dagChecker,
config,
debugFeatures);
- if (!this->Makefile->IsGeneratingBuildSystem())
- {
- deleteAndClear(this->Internal->CachedLinkInterfaceCompileFeaturesEntries);
- }
- else
- {
- this->Internal->CacheLinkInterfaceCompileFeaturesDone[config] = true;
- }
+ deleteAndClear(linkInterfaceCompileFeaturesEntries);
}
//----------------------------------------------------------------------------
@@ -3068,16 +2780,11 @@ const char* cmTarget::GetLocationForBuild() const
// Now handle the deprecated build-time configuration location.
location = this->GetDirectory();
- if(!location.empty())
- {
- location += "/";
- }
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
if(cfgid && strcmp(cfgid, ".") != 0)
{
location += "/";
location += cfgid;
- location += "/";
}
if(this->IsAppBundleOnApple())
@@ -3198,6 +2905,22 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
}
//----------------------------------------------------------------------------
+static void MakePropertyList(std::string& output,
+ std::vector<cmTargetInternals::TargetPropertyEntry*> const& values)
+{
+ output = "";
+ std::string sep;
+ for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+ it = values.begin(), end = values.end();
+ it != end; ++it)
+ {
+ output += sep;
+ output += (*it)->ge->GetInput();
+ sep = ";";
+ }
+}
+
+//----------------------------------------------------------------------------
const char *cmTarget::GetProperty(const std::string& prop) const
{
return this->GetProperty(prop, this->Makefile);
@@ -3217,11 +2940,6 @@ const char *cmTarget::GetProperty(const std::string& prop,
return 0;
}
- if (prop == "NAME")
- {
- return this->GetName().c_str();
- }
-
// Watch for special "computed" properties that are dependent on
// other properties or variables. Always recompute them.
if(this->GetType() == cmTarget::EXECUTABLE ||
@@ -3230,7 +2948,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
this->GetType() == cmTarget::MODULE_LIBRARY ||
this->GetType() == cmTarget::UNKNOWN_LIBRARY)
{
- if(prop == "LOCATION")
+ static const std::string propLOCATION = "LOCATION";
+ if(prop == propLOCATION)
{
if (!this->HandleLocationPropertyPolicy(context))
{
@@ -3246,12 +2965,12 @@ const char *cmTarget::GetProperty(const std::string& prop,
// cannot take into account the per-configuration name of the
// target because the configuration type may not be known at
// CMake time.
- this->Properties.SetProperty("LOCATION", this->GetLocationForBuild(),
+ this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(),
cmProperty::TARGET);
}
// Support "LOCATION_<CONFIG>".
- if(cmHasLiteralPrefix(prop, "LOCATION_"))
+ else if(cmHasLiteralPrefix(prop, "LOCATION_"))
{
if (!this->HandleLocationPropertyPolicy(context))
{
@@ -3263,7 +2982,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
cmProperty::TARGET);
}
// Support "<CONFIG>_LOCATION".
- if(cmHasLiteralSuffix(prop, "_LOCATION"))
+ else if(cmHasLiteralSuffix(prop, "_LOCATION"))
{
std::string configName(prop.c_str(), prop.size() - 9);
if(configName != "IMPORTED")
@@ -3278,198 +2997,210 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
}
}
- if(prop == "INCLUDE_DIRECTORIES")
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->IncludeDirectoriesEntries.begin(),
- end = this->Internal->IncludeDirectoriesEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ static UNORDERED_SET<std::string> specialProps;
+#define MAKE_STATIC_PROP(PROP) \
+ static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(LINK_LIBRARIES);
+ MAKE_STATIC_PROP(TYPE);
+ MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
+ MAKE_STATIC_PROP(COMPILE_FEATURES);
+ MAKE_STATIC_PROP(COMPILE_OPTIONS);
+ MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
+ MAKE_STATIC_PROP(IMPORTED);
+ MAKE_STATIC_PROP(NAME);
+ MAKE_STATIC_PROP(SOURCES);
+#undef MAKE_STATIC_PROP
+ if(specialProps.empty())
+ {
+ specialProps.insert(propLINK_LIBRARIES);
+ specialProps.insert(propTYPE);
+ specialProps.insert(propINCLUDE_DIRECTORIES);
+ specialProps.insert(propCOMPILE_FEATURES);
+ specialProps.insert(propCOMPILE_OPTIONS);
+ specialProps.insert(propCOMPILE_DEFINITIONS);
+ specialProps.insert(propIMPORTED);
+ specialProps.insert(propNAME);
+ specialProps.insert(propSOURCES);
+ }
+ if(specialProps.count(prop))
+ {
+ if(prop == propLINK_LIBRARIES)
+ {
+ if (this->Internal->LinkImplementationPropertyEntries.empty())
+ {
+ return 0;
+ }
+
+ static std::string output;
+ output = "";
+ std::string sep;
+ for (std::vector<cmValueWithOrigin>::const_iterator
+ it = this->Internal->LinkImplementationPropertyEntries.begin(),
+ end = this->Internal->LinkImplementationPropertyEntries.end();
+ it != end; ++it)
+ {
+ output += sep;
+ output += it->Value;
+ sep = ";";
+ }
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "COMPILE_OPTIONS")
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->CompileOptionsEntries.begin(),
- end = this->Internal->CompileOptionsEntries.end();
- it != end; ++it)
+ // the type property returns what type the target is
+ else if (prop == propTYPE)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ return cmTarget::GetTargetTypeName(this->GetType());
}
- return output.c_str();
- }
- if(prop == "COMPILE_FEATURES")
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->CompileFeaturesEntries.begin(),
- end = this->Internal->CompileFeaturesEntries.end();
- it != end; ++it)
+ else if(prop == propINCLUDE_DIRECTORIES)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ if (this->Internal->IncludeDirectoriesEntries.empty())
+ {
+ return 0;
+ }
+
+ static std::string output;
+ MakePropertyList(output, this->Internal->IncludeDirectoriesEntries);
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "COMPILE_DEFINITIONS")
- {
- static std::string output;
- output = "";
- std::string sep;
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for (std::vector<TargetPropertyEntry*>::const_iterator
- it = this->Internal->CompileDefinitionsEntries.begin(),
- end = this->Internal->CompileDefinitionsEntries.end();
- it != end; ++it)
+ else if(prop == propCOMPILE_FEATURES)
{
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
+ if (this->Internal->CompileFeaturesEntries.empty())
+ {
+ return 0;
+ }
+
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileFeaturesEntries);
+ return output.c_str();
}
- return output.c_str();
- }
- if(prop == "LINK_LIBRARIES")
- {
- static std::string output;
- output = "";
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->Internal->LinkImplementationPropertyEntries.begin(),
- end = this->Internal->LinkImplementationPropertyEntries.end();
- it != end; ++it)
+ else if(prop == propCOMPILE_OPTIONS)
{
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
+ if (this->Internal->CompileOptionsEntries.empty())
+ {
+ return 0;
+ }
- if (prop == "IMPORTED")
- {
- return this->IsImported()?"TRUE":"FALSE";
- }
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileOptionsEntries);
+ return output.c_str();
+ }
+ else if(prop == propCOMPILE_DEFINITIONS)
+ {
+ if (this->Internal->CompileDefinitionsEntries.empty())
+ {
+ return 0;
+ }
- if(prop == "SOURCES")
- {
- cmOStringStream ss;
- const char* sep = "";
- typedef cmTargetInternals::TargetPropertyEntry
- TargetPropertyEntry;
- for(std::vector<TargetPropertyEntry*>::const_iterator
- i = this->Internal->SourceEntries.begin();
- i != this->Internal->SourceEntries.end(); ++i)
+ static std::string output;
+ MakePropertyList(output, this->Internal->CompileDefinitionsEntries);
+ return output.c_str();
+ }
+ else if (prop == propIMPORTED)
{
- std::string entry = (*i)->ge->GetInput();
+ return this->IsImported()?"TRUE":"FALSE";
+ }
+ else if (prop == propNAME)
+ {
+ return this->GetName().c_str();
+ }
+ else if(prop == propSOURCES)
+ {
+ if (this->Internal->SourceEntries.empty())
+ {
+ return 0;
+ }
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
- for (std::vector<std::string>::const_iterator
- li = files.begin(); li != files.end(); ++li)
+ cmOStringStream ss;
+ const char* sep = "";
+ typedef cmTargetInternals::TargetPropertyEntry
+ TargetPropertyEntry;
+ for(std::vector<TargetPropertyEntry*>::const_iterator
+ i = this->Internal->SourceEntries.begin();
+ i != this->Internal->SourceEntries.end(); ++i)
{
- if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
- (*li)[li->size() - 1] == '>')
- {
- std::string objLibName = li->substr(17, li->size()-18);
+ std::string entry = (*i)->ge->GetInput();
- if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
{
- ss << sep;
- sep = ";";
- ss << *li;
- continue;
- }
+ std::string objLibName = li->substr(17, li->size()-18);
- bool addContent = false;
- bool noMessage = true;
- cmOStringStream e;
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- switch(context->GetPolicyStatus(cmPolicies::CMP0051))
- {
- case cmPolicies::WARN:
- e << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n";
- noMessage = false;
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- addContent = true;
- }
- if (!noMessage)
- {
- e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> "
- "generator expression in its sources list. This content was not "
- "previously part of the SOURCES property when that property was "
- "read at configure time. Code reading that property needs to be "
- "adapted to ignore the generator expression using the "
- "string(GENEX_STRIP) command.";
- context->IssueMessage(messageType, e.str());
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ continue;
+ }
+
+ bool addContent = false;
+ bool noMessage = true;
+ cmOStringStream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(context->GetPolicyStatus(cmPolicies::CMP0051))
+ {
+ case cmPolicies::WARN:
+ e << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n";
+ noMessage = false;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ addContent = true;
+ }
+ if (!noMessage)
+ {
+ e << "Target \"" << this->Name << "\" contains "
+ "$<TARGET_OBJECTS> generator expression in its sources list. "
+ "This content was not previously part of the SOURCES property "
+ "when that property was read at configure time. Code reading "
+ "that property needs to be adapted to ignore the generator "
+ "expression using the string(GENEX_STRIP) command.";
+ context->IssueMessage(messageType, e.str());
+ }
+ if (addContent)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
}
- if (addContent)
+ else if (cmGeneratorExpression::Find(*li) == std::string::npos)
{
ss << sep;
sep = ";";
ss << *li;
}
- }
- else if (cmGeneratorExpression::Find(*li) == std::string::npos)
- {
- ss << sep;
- sep = ";";
- ss << *li;
- }
- else
- {
- cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
- // Construct what is known about this source file location.
- cmSourceFileLocation const& location = sf->GetLocation();
- std::string sname = location.GetDirectory();
- if(!sname.empty())
+ else
{
- sname += "/";
- }
- sname += location.GetName();
+ cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
+ // Construct what is known about this source file location.
+ cmSourceFileLocation const& location = sf->GetLocation();
+ std::string sname = location.GetDirectory();
+ if(!sname.empty())
+ {
+ sname += "/";
+ }
+ sname += location.GetName();
- ss << sep;
- sep = ";";
- // Append this list entry.
- ss << sname;
+ ss << sep;
+ sep = ";";
+ // Append this list entry.
+ ss << sname;
+ }
}
}
+ this->Properties.SetProperty("SOURCES", ss.str().c_str(),
+ cmProperty::TARGET);
}
- this->Properties.SetProperty("SOURCES", ss.str().c_str(),
- cmProperty::TARGET);
}
- // the type property returns what type the target is
- if (prop == "TYPE")
- {
- return cmTarget::GetTargetTypeName(this->GetType());
- }
bool chain = false;
const char *retVal =
this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain);
@@ -3492,19 +3223,17 @@ class cmTargetCollectLinkLanguages
public:
cmTargetCollectLinkLanguages(cmTarget const* target,
const std::string& config,
- std::set<std::string>& languages,
+ UNORDERED_SET<std::string>& languages,
cmTarget const* head):
Config(config), Languages(languages), HeadTarget(head),
Makefile(target->GetMakefile()), Target(target)
{ this->Visited.insert(target); }
- void Visit(const std::string& name)
+ void Visit(cmLinkItem const& item)
{
- cmTarget *target = this->Makefile->FindTargetToUse(name);
-
- if(!target)
+ if(!item.Target)
{
- if(name.find("::") != std::string::npos)
+ if(item.find("::") != std::string::npos)
{
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
@@ -3530,7 +3259,7 @@ public:
if(!noMessage)
{
e << "Target \"" << this->Target->GetName()
- << "\" links to target \"" << name
+ << "\" links to target \"" << item
<< "\" but the target was not found. Perhaps a find_package() "
"call is missing for an IMPORTED target, or an ALIAS target is "
"missing?";
@@ -3541,13 +3270,13 @@ public:
}
return;
}
- if(!this->Visited.insert(target).second)
+ if(!this->Visited.insert(item.Target).second)
{
return;
}
cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config, this->HeadTarget);
+ item.Target->GetLinkInterface(this->Config, this->HeadTarget);
if(!iface) { return; }
for(std::vector<std::string>::const_iterator
@@ -3556,7 +3285,7 @@ public:
this->Languages.insert(*li);
}
- for(std::vector<std::string>::const_iterator
+ for(std::vector<cmLinkItem>::const_iterator
li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
{
this->Visit(*li);
@@ -3564,7 +3293,7 @@ public:
}
private:
std::string Config;
- std::set<std::string>& Languages;
+ UNORDERED_SET<std::string>& Languages;
cmTarget const* HeadTarget;
cmMakefile* Makefile;
const cmTarget* Target;
@@ -3572,25 +3301,22 @@ private:
};
//----------------------------------------------------------------------------
-std::string cmTarget::GetLinkerLanguage(const std::string& config,
- cmTarget const* head) const
+std::string cmTarget::GetLinkerLanguage(const std::string& config) const
{
- cmTarget const* headTarget = head ? head : this;
- return this->GetLinkClosure(config, headTarget)->LinkerLanguage;
+ return this->GetLinkClosure(config)->LinkerLanguage;
}
//----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(
- const std::string& config,
- cmTarget const* head) const
+cmTarget::LinkClosure const*
+cmTarget::GetLinkClosure(const std::string& config) const
{
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ std::string key(cmSystemTools::UpperCase(config));
cmTargetInternals::LinkClosureMapType::iterator
i = this->Internal->LinkClosureMap.find(key);
if(i == this->Internal->LinkClosureMap.end())
{
LinkClosure lc;
- this->ComputeLinkClosure(config, lc, head);
+ this->ComputeLinkClosure(config, lc);
cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
i = this->Internal->LinkClosureMap.insert(entry).first;
}
@@ -3604,7 +3330,7 @@ class cmTargetSelectLinker
cmTarget const* Target;
cmMakefile* Makefile;
cmGlobalGenerator* GG;
- std::set<std::string> Preferred;
+ UNORDERED_SET<std::string> Preferred;
public:
cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target)
{
@@ -3636,7 +3362,7 @@ public:
e << "Target " << this->Target->GetName()
<< " contains multiple languages with the highest linker preference"
<< " (" << this->Preference << "):\n";
- for(std::set<std::string>::const_iterator
+ for(UNORDERED_SET<std::string>::const_iterator
li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
{
e << " " << *li << "\n";
@@ -3651,12 +3377,12 @@ public:
};
//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
- cmTarget const* head) const
+void cmTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
{
// Get languages built in this target.
- std::set<std::string> languages;
- LinkImplementation const* impl = this->GetLinkImplementation(config, head);
+ UNORDERED_SET<std::string> languages;
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
@@ -3664,15 +3390,16 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
}
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, head);
- for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
+ cmTargetCollectLinkLanguages cll(this, config, languages, this);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li)
{
cll.Visit(*li);
}
// Store the transitive closure of languages.
- for(std::set<std::string>::const_iterator li = languages.begin();
+ for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
li != languages.end(); ++li)
{
lc.Languages.push_back(*li);
@@ -3700,7 +3427,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
}
// Now consider languages that propagate from linked targets.
- for(std::set<std::string>::const_iterator sit = languages.begin();
+ for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
sit != languages.end(); ++sit)
{
std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
@@ -3715,6 +3442,51 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
}
//----------------------------------------------------------------------------
+void cmTarget::ExpandLinkItems(std::string const& prop,
+ std::string const& value,
+ std::string const& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const
+{
+ cmGeneratorExpression ge;
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+ // The $<LINK_ONLY> expression may be in a link interface to specify private
+ // link dependencies that are otherwise excluded from usage requirements.
+ if(usage_requirements_only)
+ {
+ dagChecker.SetTransitivePropertiesOnly();
+ }
+ std::vector<std::string> libs;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->Makefile,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker), libs);
+ this->LookupLinkItems(libs, items);
+ hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const
+{
+ for(std::vector<std::string>::const_iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ std::string name = this->CheckCMP0004(*i);
+ if(name == this->GetName() || name.empty())
+ {
+ continue;
+ }
+ items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
+ }
+}
+
+//----------------------------------------------------------------------------
const char* cmTarget::GetSuffixVariableInternal(bool implib) const
{
switch(this->GetType())
@@ -3732,7 +3504,10 @@ const char* cmTarget::GetSuffixVariableInternal(bool implib) const
case cmTarget::EXECUTABLE:
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
- : "CMAKE_EXECUTABLE_SUFFIX");
+ // Android GUI application packages store the native
+ // binary as a shared library.
+ : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
+ "CMAKE_SHARED_LIBRARY_SUFFIX" : "CMAKE_EXECUTABLE_SUFFIX"));
default:
break;
}
@@ -3756,7 +3531,12 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const
? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_MODULE_PREFIX");
case cmTarget::EXECUTABLE:
- return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_PREFIX"
+ // Android GUI application packages store the native
+ // binary as a shared library.
+ : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
+ "CMAKE_SHARED_LIBRARY_PREFIX" : ""));
default:
break;
}
@@ -3845,8 +3625,7 @@ bool cmTarget::HasSOName(const std::string& config) const
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
this->GetType() == cmTarget::MODULE_LIBRARY) &&
!this->GetPropertyAsBool("NO_SONAME") &&
- this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
- this)));
+ this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
}
//----------------------------------------------------------------------------
@@ -3855,7 +3634,7 @@ std::string cmTarget::GetSOName(const std::string& config) const
if(this->IsImported())
{
// Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
{
if(info->NoSOName)
{
@@ -3923,7 +3702,7 @@ bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
else
{
// Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
{
if(!info->NoSOName && !info->SOName.empty())
{
@@ -4009,7 +3788,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(
{
if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
{
return info->NoSOName;
}
@@ -4133,7 +3912,7 @@ std::string
cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
{
std::string result;
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
{
result = implib? info->ImportLibrary : info->Location;
}
@@ -4219,7 +3998,7 @@ void cmTarget::GetFullNameInternal(const std::string& config,
const char* suffixVar = this->GetSuffixVariableInternal(implib);
// Check for language-specific default prefix and suffix.
- std::string ll = this->GetLinkerLanguage(config, this);
+ std::string ll = this->GetLinkerLanguage(config);
if(!ll.empty())
{
if(!targetSuffix && suffixVar && *suffixVar)
@@ -4320,6 +4099,7 @@ void cmTarget::GetLibraryNames(std::string& name,
const char* version = this->GetProperty("VERSION");
const char* soversion = this->GetProperty("SOVERSION");
if(!this->HasSOName(config) ||
+ this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
this->IsFrameworkOnApple())
{
// Versioning is supported only for shared libraries and modules,
@@ -4506,9 +4286,12 @@ bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
{
return false;
}
- std::vector<std::string> libs;
- this->GetDirectLinkLibraries(config, libs, this);
- return !libs.empty();
+ if(LinkImplementationLibraries const* impl =
+ this->GetLinkImplementationLibraries(config))
+ {
+ return !impl->Libraries.empty();
+ }
+ return false;
}
//----------------------------------------------------------------------------
@@ -4557,7 +4340,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const std::string& config) const
}
// Check for rpath support on this platform.
- std::string ll = this->GetLinkerLanguage(config, this);
+ std::string ll = this->GetLinkerLanguage(config);
if(!ll.empty())
{
std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
@@ -4949,12 +4732,13 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
//----------------------------------------------------------------------------
template<typename PropertyType>
-PropertyType getTypedProperty(cmTarget const* tgt, const char *prop,
+PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop,
PropertyType *);
//----------------------------------------------------------------------------
template<>
-bool getTypedProperty<bool>(cmTarget const* tgt, const char *prop, bool *)
+bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop,
+ bool *)
{
return tgt->GetPropertyAsBool(prop);
}
@@ -4962,7 +4746,7 @@ bool getTypedProperty<bool>(cmTarget const* tgt, const char *prop, bool *)
//----------------------------------------------------------------------------
template<>
const char *getTypedProperty<const char *>(cmTarget const* tgt,
- const char *prop,
+ const std::string& prop,
const char **)
{
return tgt->GetProperty(prop);
@@ -5201,7 +4985,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
CompatibleType t,
PropertyType *)
{
- PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
+ PropertyType propContent = getTypedProperty<PropertyType>(tgt, p,
0);
const bool explicitlySet = tgt->GetProperties()
.find(p)
@@ -5211,8 +4995,8 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
assert((impliedByUse ^ explicitlySet)
|| (!impliedByUse && !explicitlySet));
- std::vector<cmTarget*> deps;
- tgt->GetTransitiveTargetClosure(config, tgt, deps);
+ std::vector<cmTarget const*> const& deps =
+ tgt->GetLinkImplementationClosure(config);
if(deps.empty())
{
@@ -5237,7 +5021,8 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
report += "\" property not set.\n";
}
- for(std::vector<cmTarget*>::const_iterator li =
+ std::string interfaceProperty = "INTERFACE_" + p;
+ for(std::vector<cmTarget const*>::const_iterator li =
deps.begin();
li != deps.end(); ++li)
{
@@ -5250,11 +5035,11 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
cmTarget const* theTarget = *li;
const bool ifaceIsSet = theTarget->GetProperties()
- .find("INTERFACE_" + p)
+ .find(interfaceProperty)
!= theTarget->GetProperties().end();
PropertyType ifacePropContent =
getTypedProperty<PropertyType>(theTarget,
- ("INTERFACE_" + p).c_str(), 0);
+ interfaceProperty, 0);
std::string reportEntry;
if (ifaceIsSet)
@@ -5423,45 +5208,6 @@ const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty(
}
//----------------------------------------------------------------------------
-bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
- const std::string& interfaceProperty,
- const std::string& config)
-{
- std::vector<cmTarget*> deps;
- tgt->GetTransitiveTargetClosure(config, tgt, deps);
-
- if(deps.empty())
- {
- return false;
- }
-
- for(std::vector<cmTarget*>::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- const char *prop = (*li)->GetProperty(interfaceProperty);
- if (!prop)
- {
- continue;
- }
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
- {
- if (*pi == p)
- {
- return true;
- }
- }
- }
-
- return false;
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
const std::string& config) const
{
@@ -5470,9 +5216,7 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
{
return false;
}
- return (p == "POSITION_INDEPENDENT_CODE") ||
- isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
- config);
+ return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
}
//----------------------------------------------------------------------------
@@ -5484,9 +5228,7 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
{
return false;
}
- return (p == "AUTOUIC_OPTIONS") ||
- isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
- config);
+ return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
}
//----------------------------------------------------------------------------
@@ -5498,8 +5240,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
{
return false;
}
- return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN",
- config);
+ return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
}
//----------------------------------------------------------------------------
@@ -5511,8 +5252,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
{
return false;
}
- return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX",
- config);
+ return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
}
//----------------------------------------------------------------------------
@@ -5558,11 +5298,10 @@ cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<std::string>& languages,
- const std::string& config,
- cmTarget const* head) const
+ const std::string& config) const
{
std::vector<cmSourceFile*> sourceFiles;
- this->GetSourceFiles(sourceFiles, config, head);
+ this->GetSourceFiles(sourceFiles, config);
for(std::vector<cmSourceFile*>::const_iterator
i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
{
@@ -5598,7 +5337,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages,
for(std::vector<cmTarget*>::const_iterator
i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
{
- (*i)->GetLanguages(languages, config, head);
+ (*i)->GetLanguages(languages, config);
}
}
@@ -5646,7 +5385,7 @@ bool cmTarget::IsChrpathUsed(const std::string& config) const
#if defined(CMAKE_USE_ELF_PARSER)
// Enable if the rpath flag uses a separator and the target uses ELF
// binaries.
- std::string ll = this->GetLinkerLanguage(config, this);
+ std::string ll = this->GetLinkerLanguage(config);
if(!ll.empty())
{
std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
@@ -5671,8 +5410,7 @@ bool cmTarget::IsChrpathUsed(const std::string& config) const
//----------------------------------------------------------------------------
cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const std::string& config,
- cmTarget const* headTarget) const
+cmTarget::GetImportInfo(const std::string& config) const
{
// There is no imported information for non-imported targets.
if(!this->IsImported())
@@ -5691,16 +5429,15 @@ cmTarget::GetImportInfo(const std::string& config,
{
config_upper = "NOCONFIG";
}
- TargetConfigPair key(headTarget, config_upper);
typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
ImportInfoMapType::const_iterator i =
- this->Internal->ImportInfoMap.find(key);
+ this->Internal->ImportInfoMap.find(config_upper);
if(i == this->Internal->ImportInfoMap.end())
{
ImportInfo info;
- this->ComputeImportInfo(config_upper, info, headTarget);
- ImportInfoMapType::value_type entry(key, info);
+ this->ComputeImportInfo(config_upper, info);
+ ImportInfoMapType::value_type entry(config_upper, info);
i = this->Internal->ImportInfoMap.insert(entry).first;
}
@@ -5852,8 +5589,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
//----------------------------------------------------------------------------
void cmTarget::ComputeImportInfo(std::string const& desired_config,
- ImportInfo& info,
- cmTarget const* headTarget) const
+ ImportInfo& info) const
{
// This method finds information about an imported target from its
// properties. The "IMPORTED_" namespace is reserved for properties
@@ -5892,19 +5628,8 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
}
if(propertyLibs)
{
- cmGeneratorExpression ge;
-
- cmGeneratorExpressionDAGChecker dagChecker(
- this->GetName(),
- linkProp, 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
- ->Evaluate(this->Makefile,
- desired_config,
- false,
- headTarget,
- this,
- &dagChecker),
- info.LinkInterface.Libraries);
+ info.LibrariesProp = linkProp;
+ info.Libraries = propertyLibs;
}
}
if(this->GetType() == INTERFACE_LIBRARY)
@@ -5990,13 +5715,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
linkProp += suffix;
if(const char* config_libs = this->GetProperty(linkProp))
{
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.SharedDeps);
+ info.SharedDeps = config_libs;
}
else if(const char* libs =
this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
{
- cmSystemTools::ExpandListArgument(libs, info.LinkInterface.SharedDeps);
+ info.SharedDeps = libs;
}
}
@@ -6007,14 +5731,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
linkProp += suffix;
if(const char* config_libs = this->GetProperty(linkProp))
{
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.Languages);
+ info.Languages = config_libs;
}
else if(const char* libs =
this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
{
- cmSystemTools::ExpandListArgument(libs,
- info.LinkInterface.Languages);
+ info.Languages = libs;
}
}
@@ -6025,12 +5747,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
linkProp += suffix;
if(const char* config_reps = this->GetProperty(linkProp))
{
- sscanf(config_reps, "%u", &info.LinkInterface.Multiplicity);
+ sscanf(config_reps, "%u", &info.Multiplicity);
}
else if(const char* reps =
this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
{
- sscanf(reps, "%u", &info.LinkInterface.Multiplicity);
+ sscanf(reps, "%u", &info.Multiplicity);
}
}
}
@@ -6043,11 +5765,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
// Imported targets have their own link interface.
if(this->IsImported())
{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
- {
- return &info->LinkInterface;
- }
- return 0;
+ return this->GetImportLinkInterface(config, head, false);
}
// Link interfaces are not supported for executables that do not
@@ -6059,48 +5777,46 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
}
// Lookup any existing link interface for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmTargetInternals::HeadToLinkInterfaceMap& hm =
+ this->Internal->LinkInterfaceMap[CONFIG];
- cmTargetInternals::LinkInterfaceMapType::iterator
- i = this->Internal->LinkInterfaceMap.find(key);
- if(i == this->Internal->LinkInterfaceMap.end())
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
{
- // Compute the link interface for this configuration.
- cmTargetInternals::OptionalLinkInterface iface;
- iface.ExplicitLibraries =
- this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
- if (iface.Exists)
- {
- this->Internal->ComputeLinkInterface(this, config, iface,
- head, iface.ExplicitLibraries);
- }
+ return &hm.begin()->second;
+ }
- // Store the information for this configuration.
- cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
- i = this->Internal->LinkInterfaceMap.insert(entry).first;
+ cmTargetInternals::OptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->Internal->ComputeLinkInterfaceLibraries(
+ this, config, iface, head, false);
}
- else if(!i->second.Complete && i->second.Exists)
+ if(!iface.AllDone)
{
- this->Internal->ComputeLinkInterface(this, config, i->second, head,
- i->second.ExplicitLibraries);
+ iface.AllDone = true;
+ if(iface.Exists)
+ {
+ this->Internal->ComputeLinkInterface(this, config, iface, head);
+ }
}
- return i->second.Exists ? &i->second : 0;
+ return iface.Exists? &iface : 0;
}
//----------------------------------------------------------------------------
-cmTarget::LinkInterface const*
+cmTarget::LinkInterfaceLibraries const*
cmTarget::GetLinkInterfaceLibraries(const std::string& config,
- cmTarget const* head) const
+ cmTarget const* head,
+ bool usage_requirements_only) const
{
// Imported targets have their own link interface.
if(this->IsImported())
{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
- {
- return &info->LinkInterface;
- }
- return 0;
+ return this->GetImportLinkInterface(config, head, usage_requirements_only);
}
// Link interfaces are not supported for executables that do not
@@ -6112,136 +5828,162 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config,
}
// Lookup any existing link interface for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmTargetInternals::HeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
+ this->Internal->LinkInterfaceMap[CONFIG]);
- cmTargetInternals::LinkInterfaceMapType::iterator
- i = this->Internal->LinkInterfaceMap.find(key);
- if(i == this->Internal->LinkInterfaceMap.end())
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
{
- // Compute the link interface for this configuration.
- cmTargetInternals::OptionalLinkInterface iface;
- iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
- iface,
- head,
- iface.Exists);
+ return &hm.begin()->second;
+ }
- // Store the information for this configuration.
- cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
- i = this->Internal->LinkInterfaceMap.insert(entry).first;
+ cmTargetInternals::OptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->Internal->ComputeLinkInterfaceLibraries(
+ this, config, iface, head, usage_requirements_only);
}
- return i->second.Exists ? &i->second : 0;
+ return iface.Exists? &iface : 0;
}
//----------------------------------------------------------------------------
-void processILibs(const std::string& config,
- cmTarget const* headTarget,
- std::string const& name,
- std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
+cmTarget::LinkInterface const*
+cmTarget::GetImportLinkInterface(const std::string& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only) const
{
- if (cmTarget* tgt = headTarget->GetMakefile()
- ->FindTargetToUse(name))
+ cmTarget::ImportInfo const* info = this->GetImportInfo(config);
+ if(!info)
{
- if (emitted.insert(tgt).second)
- {
- tgts.push_back(tgt);
- std::vector<std::string> ilibs;
- cmTarget::LinkInterface const* iface =
- tgt->GetLinkInterfaceLibraries(config, headTarget);
- if (iface)
- {
- for(std::vector<std::string>::const_iterator
- it = iface->Libraries.begin();
- it != iface->Libraries.end(); ++it)
- {
- processILibs(config, headTarget, *it, tgts, emitted);
- }
- }
- }
+ return 0;
}
-}
-//----------------------------------------------------------------------------
-void cmTarget::GetTransitiveTargetClosure(const std::string& config,
- cmTarget const* headTarget,
- std::vector<cmTarget*> &tgts) const
-{
- std::set<cmTarget*> emitted;
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmTargetInternals::HeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
+ this->Internal->LinkInterfaceMap[CONFIG]);
- cmTarget::LinkImplementation const* impl
- = this->GetLinkImplementationLibraries(config, headTarget);
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
- for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
- it != impl->Libraries.end(); ++it)
+ cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget];
+ if(!iface.AllDone)
{
- processILibs(config, headTarget, *it, tgts, emitted);
+ iface.AllDone = true;
+ iface.Multiplicity = info->Multiplicity;
+ cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+ this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ std::vector<std::string> deps;
+ cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+ this->LookupLinkItems(deps, iface.SharedDeps);
}
+
+ return &iface;
}
//----------------------------------------------------------------------------
-void cmTarget::GetTransitivePropertyTargets(const std::string& config,
- cmTarget const* headTarget,
- std::vector<cmTarget*> &tgts) const
+void processILibs(const std::string& config,
+ cmTarget const* headTarget,
+ cmLinkItem const& item,
+ std::vector<cmTarget const*>& tgts,
+ std::set<cmTarget const*>& emitted)
{
- cmTarget::LinkInterface const* iface
- = this->GetLinkInterfaceLibraries(config, headTarget);
- if (!iface)
+ if (item.Target && emitted.insert(item.Target).second)
{
- return;
- }
- if(this->GetType() != STATIC_LIBRARY
- || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
- || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
- {
- for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
- it != iface->Libraries.end(); ++it)
+ tgts.push_back(item.Target);
+ if(cmTarget::LinkInterfaceLibraries const* iface =
+ item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
{
- if (cmTarget* tgt = headTarget->GetMakefile()
- ->FindTargetToUse(*it))
+ for(std::vector<cmLinkItem>::const_iterator
+ it = iface->Libraries.begin();
+ it != iface->Libraries.end(); ++it)
{
- tgts.push_back(tgt);
+ processILibs(config, headTarget, *it, tgts, emitted);
}
}
- return;
}
+}
- const char* linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- const char* interfaceLibs = this->GetProperty(linkIfaceProp);
-
- if (!interfaceLibs)
+//----------------------------------------------------------------------------
+std::vector<cmTarget const*> const&
+cmTarget::GetLinkImplementationClosure(const std::string& config) const
+{
+ cmTargetInternals::LinkImplClosure& tgts =
+ this->Internal->LinkImplClosureMap[config];
+ if(!tgts.Done)
{
- return;
- }
+ tgts.Done = true;
+ std::set<cmTarget const*> emitted;
- // The interface libraries have been explicitly set.
- cmGeneratorExpression ge;
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- linkIfaceProp, 0, 0);
- dagChecker.SetTransitivePropertiesOnly();
- std::vector<std::string> libs;
- cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), libs);
+ cmTarget::LinkImplementationLibraries const* impl
+ = this->GetLinkImplementationLibraries(config);
+
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
+ {
+ processILibs(config, this, *it, tgts , emitted);
+ }
+ }
+ return tgts;
+}
- for(std::vector<std::string>::const_iterator it = libs.begin();
- it != libs.end(); ++it)
+//----------------------------------------------------------------------------
+cmTarget::CompatibleInterfaces const&
+cmTarget::GetCompatibleInterfaces(std::string const& config) const
+{
+ cmTargetInternals::CompatibleInterfaces& compat =
+ this->Internal->CompatibleInterfacesMap[config];
+ if(!compat.Done)
{
- if (cmTarget* tgt = headTarget->GetMakefile()
- ->FindTargetToUse(*it))
+ compat.Done = true;
+ compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
+ compat.PropsString.insert("AUTOUIC_OPTIONS");
+ std::vector<cmTarget const*> const& deps =
+ this->GetLinkImplementationClosure(config);
+ for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
+ li != deps.end(); ++li)
{
- tgts.push_back(tgt);
+#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
+ if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
+ { \
+ std::vector<std::string> props; \
+ cmSystemTools::ExpandListArgument(prop, props); \
+ std::copy(props.begin(), props.end(), \
+ std::inserter(compat.Props##x, compat.Props##x.begin())); \
+ }
+ CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
+ CM_READ_COMPATIBLE_INTERFACE(STRING, String)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
+#undef CM_READ_COMPATIBLE_INTERFACE
}
}
+ return compat;
}
//----------------------------------------------------------------------------
-const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
- LinkInterface& iface,
- cmTarget const* headTarget,
- bool &exists) const
+void
+cmTargetInternals::ComputeLinkInterfaceLibraries(
+ cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkInterface& iface,
+ cmTarget const* headTarget,
+ bool usage_requirements_only)
{
// Construct the property name suffix for this configuration.
std::string suffix = "_";
@@ -6258,15 +6000,15 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
// libraries and executables that export symbols.
const char* explicitLibraries = 0;
std::string linkIfaceProp;
- if(this->PolicyStatusCMP0022 != cmPolicies::OLD &&
- this->PolicyStatusCMP0022 != cmPolicies::WARN)
+ if(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD &&
+ thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN)
{
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- explicitLibraries = this->GetProperty(linkIfaceProp);
+ explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
}
- else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->IsExecutableWithExports())
+ else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
+ thisTarget->IsExecutableWithExports())
{
// CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
// shared lib or executable.
@@ -6274,31 +6016,32 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
// Lookup the per-configuration property.
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
linkIfaceProp += suffix;
- explicitLibraries = this->GetProperty(linkIfaceProp);
+ explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
// If not set, try the generic property.
if(!explicitLibraries)
{
linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- explicitLibraries = this->GetProperty(linkIfaceProp);
+ explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
}
}
- if(explicitLibraries && this->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->Internal->PolicyWarnedCMP0022)
+ if(explicitLibraries &&
+ thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022)
{
// Compare the explicitly set old link interface properties to the
// preferred new link interface property one and warn if different.
const char* newExplicitLibraries =
- this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
if (newExplicitLibraries
&& strcmp(newExplicitLibraries, explicitLibraries) != 0)
{
cmOStringStream w;
w <<
- (this->Makefile->GetPolicies()
+ (thisTarget->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- "Target \"" << this->GetName() << "\" has an "
+ "Target \"" << thisTarget->GetName() << "\" has an "
"INTERFACE_LINK_LIBRARIES property which differs from its " <<
linkIfaceProp << " properties."
"\n"
@@ -6306,70 +6049,62 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
" " << newExplicitLibraries << "\n" <<
linkIfaceProp << ":\n"
" " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->Internal->PolicyWarnedCMP0022 = true;
+ thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
}
}
// There is no implicit link interface for executables or modules
// so if none was explicitly set then there is no link interface.
if(!explicitLibraries &&
- (this->GetType() == cmTarget::EXECUTABLE ||
- (this->GetType() == cmTarget::MODULE_LIBRARY)))
+ (thisTarget->GetType() == cmTarget::EXECUTABLE ||
+ (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
{
- exists = false;
- return 0;
+ return;
}
- exists = true;
+ iface.Exists = true;
+ iface.ExplicitLibraries = explicitLibraries;
if(explicitLibraries)
{
// The interface libraries have been explicitly set.
- cmGeneratorExpression ge;
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- linkIfaceProp, 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), iface.Libraries);
- }
- else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
- || this->PolicyStatusCMP0022 == cmPolicies::OLD)
+ thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ }
+ else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
+ || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
// cleared the property explicitly and we should not fall back
// to the link implementation.
{
// The link implementation is the default link interface.
- LinkImplementation const* impl =
- this->GetLinkImplementationLibraries(config, headTarget);
- iface.Libraries = impl->Libraries;
- if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->Internal->PolicyWarnedCMP0022)
+ cmTarget::LinkImplementationLibraries const* impl =
+ thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
+ std::copy(impl->Libraries.begin(), impl->Libraries.end(),
+ std::back_inserter(iface.Libraries));
+ if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022 && !usage_requirements_only)
{
// Compare the link implementation fallback link interface to the
// preferred new link interface property and warn if different.
- cmGeneratorExpression ge;
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- "INTERFACE_LINK_LIBRARIES", 0, 0);
- std::vector<std::string> ifaceLibs;
- const char* newExplicitLibraries =
- this->GetProperty("INTERFACE_LINK_LIBRARIES");
- cmSystemTools::ExpandListArgument(
- ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker),
- ifaceLibs);
- if (ifaceLibs != impl->Libraries)
+ std::vector<cmLinkItem> ifaceLibs;
+ static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
+ if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
+ {
+ bool hadHeadSensitiveConditionDummy = false;
+ thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
+ headTarget, usage_requirements_only,
+ ifaceLibs, hadHeadSensitiveConditionDummy);
+ }
+ if (ifaceLibs != iface.Libraries)
{
std::string oldLibraries;
std::string newLibraries;
const char *sep = "";
- for(std::vector<std::string>::const_iterator it
+ for(std::vector<cmLinkImplItem>::const_iterator it
= impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
{
oldLibraries += sep;
@@ -6377,7 +6112,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
sep = ";";
}
sep = "";
- for(std::vector<std::string>::const_iterator it
+ for(std::vector<cmLinkItem>::const_iterator it
= ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
{
newLibraries += sep;
@@ -6391,9 +6126,9 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
cmOStringStream w;
w <<
- (this->Makefile->GetPolicies()
+ (thisTarget->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
- "Target \"" << this->GetName() << "\" has an "
+ "Target \"" << thisTarget->GetName() << "\" has an "
"INTERFACE_LINK_LIBRARIES property. "
"This should be preferred as the source of the link interface "
"for this library but because CMP0022 is not set CMake is "
@@ -6404,22 +6139,20 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
" " << newLibraries << "\n"
"Link implementation:\n"
" " << oldLibraries << "\n";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->Internal->PolicyWarnedCMP0022 = true;
+ thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
}
}
}
- return explicitLibraries;
}
//----------------------------------------------------------------------------
void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
const std::string& config,
OptionalLinkInterface& iface,
- cmTarget const* headTarget,
- const char* explicitLibraries) const
+ cmTarget const* headTarget) const
{
- if(explicitLibraries)
+ if(iface.ExplicitLibraries)
{
if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
|| thisTarget->GetType() == cmTarget::STATIC_LIBRARY
@@ -6427,8 +6160,8 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
{
// Shared libraries may have runtime implementation dependencies
// on other shared libraries that are not in the interface.
- std::set<std::string> emitted;
- for(std::vector<std::string>::const_iterator
+ UNORDERED_SET<std::string> emitted;
+ for(std::vector<cmLinkItem>::const_iterator
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
{
emitted.insert(*li);
@@ -6436,16 +6169,16 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
{
cmTarget::LinkImplementation const* impl =
- thisTarget->GetLinkImplementation(config, headTarget);
- for(std::vector<std::string>::const_iterator
+ thisTarget->GetLinkImplementation(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{
if(emitted.insert(*li).second)
{
- if(cmTarget* tgt = thisTarget->Makefile->FindTargetToUse(*li))
+ if(li->Target)
{
// This is a runtime dependency on another shared library.
- if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
+ if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
{
iface.SharedDeps.push_back(*li);
}
@@ -6466,8 +6199,9 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
|| thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
{
// The link implementation is the default link interface.
- cmTarget::LinkImplementation const*
- impl = thisTarget->GetLinkImplementation(config, headTarget);
+ cmTarget::LinkImplementationLibraries const*
+ impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
+ headTarget);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
}
@@ -6476,7 +6210,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
{
// Targets using this archive need its language runtime libraries.
if(cmTarget::LinkImplementation const* impl =
- thisTarget->GetLinkImplementation(config, headTarget))
+ thisTarget->GetLinkImplementation(config))
{
iface.Languages = impl->Languages;
}
@@ -6509,13 +6243,37 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
sscanf(reps, "%u", &iface.Multiplicity);
}
}
- iface.Complete = true;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetInternals::AddInterfaceEntries(
+ cmTarget const* thisTarget, std::string const& config,
+ std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
+{
+ if(cmTarget::LinkImplementationLibraries const* impl =
+ thisTarget->GetLinkImplementationLibraries(config))
+ {
+ for (std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin(), end = impl->Libraries.end();
+ it != end; ++it)
+ {
+ if(it->Target)
+ {
+ std::string genex =
+ "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+ cmGeneratorExpression ge(&it->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+ cge->SetEvaluateForBuildsystem(true);
+ entries.push_back(
+ new cmTargetInternals::TargetPropertyEntry(cge, *it));
+ }
+ }
+ }
}
//----------------------------------------------------------------------------
cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const std::string& config,
- cmTarget const* head) const
+cmTarget::GetLinkImplementation(const std::string& config) const
{
// There is no link implementation for imported targets.
if(this->IsImported())
@@ -6523,34 +6281,35 @@ cmTarget::GetLinkImplementation(const std::string& config,
return 0;
}
- // Lookup any existing link implementation for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
-
- cmTargetInternals::LinkImplMapType::iterator
- i = this->Internal->LinkImplMap.find(key);
- if(i == this->Internal->LinkImplMap.end())
+ // Populate the link implementation for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmTargetInternals::OptionalLinkImplementation&
+ impl = this->Internal->LinkImplMap[CONFIG][this];
+ if(!impl.LibrariesDone)
{
- // Compute the link implementation for this configuration.
- LinkImplementation impl;
- this->ComputeLinkImplementation(config, impl, head);
- this->ComputeLinkImplementationLanguages(config, impl, head);
-
- // Store the information for this configuration.
- cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
- i = this->Internal->LinkImplMap.insert(entry).first;
+ impl.LibrariesDone = true;
+ this->Internal
+ ->ComputeLinkImplementationLibraries(this, config, impl, this);
}
- else if (i->second.Languages.empty())
+ if(!impl.LanguagesDone)
{
- this->ComputeLinkImplementationLanguages(config, i->second, head);
+ impl.LanguagesDone = true;
+ this->Internal->ComputeLinkImplementationLanguages(this, config, impl);
}
+ return &impl;
+}
- return &i->second;
+//----------------------------------------------------------------------------
+cmTarget::LinkImplementationLibraries const*
+cmTarget::GetLinkImplementationLibraries(const std::string& config) const
+{
+ return this->GetLinkImplementationLibrariesInternal(config, this);
}
//----------------------------------------------------------------------------
-cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementationLibraries(const std::string& config,
- cmTarget const* head) const
+cmTarget::LinkImplementationLibraries const*
+cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
+ cmTarget const* head) const
{
// There is no link implementation for imported targets.
if(this->IsImported())
@@ -6558,110 +6317,150 @@ cmTarget::GetLinkImplementationLibraries(const std::string& config,
return 0;
}
- // Lookup any existing link implementation for this configuration.
- TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ // Populate the link implementation libraries for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmTargetInternals::HeadToLinkImplementationMap& hm =
+ this->Internal->LinkImplMap[CONFIG];
- cmTargetInternals::LinkImplMapType::iterator
- i = this->Internal->LinkImplMap.find(key);
- if(i == this->Internal->LinkImplMap.end())
+ // If the link implementation does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
{
- // Compute the link implementation for this configuration.
- LinkImplementation impl;
- this->ComputeLinkImplementation(config, impl, head);
-
- // Store the information for this configuration.
- cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
- i = this->Internal->LinkImplMap.insert(entry).first;
+ return &hm.begin()->second;
}
- return &i->second;
+ cmTargetInternals::OptionalLinkImplementation& impl = hm[head];
+ if(!impl.LibrariesDone)
+ {
+ impl.LibrariesDone = true;
+ this->Internal
+ ->ComputeLinkImplementationLibraries(this, config, impl, head);
+ }
+ return &impl;
}
//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementation(const std::string& config,
- LinkImplementation& impl,
- cmTarget const* head) const
+void
+cmTargetInternals::ComputeLinkImplementationLibraries(
+ cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkImplementation& impl,
+ cmTarget const* head) const
{
// Collect libraries directly linked in this configuration.
- std::vector<std::string> llibs;
- this->GetDirectLinkLibraries(config, llibs, head);
- for(std::vector<std::string>::const_iterator li = llibs.begin();
- li != llibs.end(); ++li)
+ for (std::vector<cmValueWithOrigin>::const_iterator
+ le = this->LinkImplementationPropertyEntries.begin(),
+ end = this->LinkImplementationPropertyEntries.end();
+ le != end; ++le)
{
- // Skip entries that resolve to the target itself or are empty.
- std::string item = this->CheckCMP0004(*li);
- if(item == this->GetName() || item.empty())
+ std::vector<std::string> llibs;
+ cmGeneratorExpressionDAGChecker dagChecker(
+ thisTarget->GetName(),
+ "LINK_LIBRARIES", 0, 0);
+ cmGeneratorExpression ge(&le->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
+ ge.Parse(le->Value);
+ std::string const evaluated =
+ cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker);
+ cmSystemTools::ExpandListArgument(evaluated, llibs);
+ if(cge->GetHadHeadSensitiveCondition())
+ {
+ impl.HadHeadSensitiveCondition = true;
+ }
+
+ for(std::vector<std::string>::const_iterator li = llibs.begin();
+ li != llibs.end(); ++li)
{
- if(item == this->GetName())
+ // Skip entries that resolve to the target itself or are empty.
+ std::string name = thisTarget->CheckCMP0004(*li);
+ if(name == thisTarget->GetName() || name.empty())
{
- bool noMessage = false;
- cmake::MessageType messageType = cmake::FATAL_ERROR;
- cmOStringStream e;
- switch(this->GetPolicyStatusCMP0038())
+ if(name == thisTarget->GetName())
{
- case cmPolicies::WARN:
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ cmOStringStream e;
+ switch(thisTarget->GetPolicyStatusCMP0038())
{
- e << (this->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0038)) << "\n";
- messageType = cmake::AUTHOR_WARNING;
+ case cmPolicies::WARN:
+ {
+ e << (thisTarget->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0038)) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
}
- break;
- case cmPolicies::OLD:
- noMessage = true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Issue the fatal message.
- break;
- }
- if(!noMessage)
- {
- e << "Target \"" << this->GetName() << "\" links to itself.";
- this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
- e.str(),
- this->GetBacktrace());
- if (messageType == cmake::FATAL_ERROR)
+ if(!noMessage)
{
- return;
+ e << "Target \"" << thisTarget->GetName() << "\" links to itself.";
+ thisTarget->Makefile->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), thisTarget->GetBacktrace());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return;
+ }
}
}
+ continue;
}
- continue;
+
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(
+ cmLinkImplItem(name, thisTarget->FindTargetToLink(name),
+ le->Backtrace, evaluated != le->Value));
}
- // The entry is meant for this configuration.
- impl.Libraries.push_back(item);
+ std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+ for (std::set<std::string>::const_iterator it = seenProps.begin();
+ it != seenProps.end(); ++it)
+ {
+ if (!thisTarget->GetProperty(*it))
+ {
+ thisTarget->LinkImplicitNullProperties.insert(*it);
+ }
+ }
+ cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards);
}
- cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
- LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
+ cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config);
+ cmTarget::LinkLibraryVectorType const& oldllibs =
+ thisTarget->GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
li != oldllibs.end(); ++li)
{
if(li->second != cmTarget::GENERAL && li->second != linkType)
{
- std::string item = this->CheckCMP0004(li->first);
- if(item == this->GetName() || item.empty())
+ std::string name = thisTarget->CheckCMP0004(li->first);
+ if(name == thisTarget->GetName() || name.empty())
{
continue;
}
// Support OLD behavior for CMP0003.
- impl.WrongConfigLibraries.push_back(item);
+ impl.WrongConfigLibraries.push_back(
+ cmLinkItem(name, thisTarget->FindTargetToLink(name)));
}
}
}
//----------------------------------------------------------------------------
void
-cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
- LinkImplementation& impl,
- cmTarget const* head) const
+cmTargetInternals::ComputeLinkImplementationLanguages(
+ cmTarget const* thisTarget,
+ const std::string& config,
+ OptionalLinkImplementation& impl) const
{
// This target needs runtime libraries for its source languages.
std::set<std::string> languages;
// Get languages used in our source files.
- this->GetLanguages(languages, config, head);
+ thisTarget->GetLanguages(languages, config);
// Copy the set of langauges to the link implementation.
for(std::set<std::string>::iterator li = languages.begin();
li != languages.end(); ++li)
@@ -6671,6 +6470,37 @@ cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
}
//----------------------------------------------------------------------------
+cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
+{
+ cmTarget const* tgt = this->Makefile->FindTargetToUse(name);
+
+ // Skip targets that will not really be linked. This is probably a
+ // name conflict between an external library and an executable
+ // within the project.
+ if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
+ !tgt->IsExecutableWithExports())
+ {
+ tgt = 0;
+ }
+
+ if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Target \"" << this->GetName() << "\" links to "
+ "OBJECT library \"" << tgt->GetName() << "\" but this is not "
+ "allowed. "
+ "One may link only to STATIC or SHARED libraries, or to executables "
+ "with the ENABLE_EXPORTS property set.";
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
+ tgt = 0;
+ }
+
+ // Return the target found, if any.
+ return tgt;
+}
+
+//----------------------------------------------------------------------------
std::string cmTarget::CheckCMP0004(std::string const& item) const
{
// Strip whitespace off the library names because we used to do this
@@ -6868,9 +6698,13 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
std::set<std::string> emittedBools;
+ static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
std::set<std::string> emittedStrings;
+ static std::string strString = "COMPATIBLE_INTERFACE_STRING";
std::set<std::string> emittedMinNumbers;
+ static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
std::set<std::string> emittedMaxNumbers;
+ static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
for(cmComputeLinkInformation::ItemVector::const_iterator li =
deps.begin();
@@ -6882,14 +6716,14 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
}
checkPropertyConsistency<bool>(this, li->Target,
- std::string("COMPATIBLE_INTERFACE_BOOL"),
+ strBool,
emittedBools, config, BoolType, 0);
if (cmSystemTools::GetErrorOccuredFlag())
{
return;
}
checkPropertyConsistency<const char *>(this, li->Target,
- std::string("COMPATIBLE_INTERFACE_STRING"),
+ strString,
emittedStrings, config,
StringType, 0);
if (cmSystemTools::GetErrorOccuredFlag())
@@ -6897,7 +6731,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
return;
}
checkPropertyConsistency<const char *>(this, li->Target,
- std::string("COMPATIBLE_INTERFACE_NUMBER_MIN"),
+ strNumMin,
emittedMinNumbers, config,
NumberMinType, 0);
if (cmSystemTools::GetErrorOccuredFlag())
@@ -6905,7 +6739,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
return;
}
checkPropertyConsistency<const char *>(this, li->Target,
- std::string("COMPATIBLE_INTERFACE_NUMBER_MAX"),
+ strNumMax,
emittedMaxNumbers, config,
NumberMaxType, 0);
if (cmSystemTools::GetErrorOccuredFlag())
@@ -6921,26 +6755,27 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
if (!prop.empty())
{
+ // Use a std::set to keep the error message sorted.
std::set<std::string> props;
std::set<std::string>::const_iterator i = emittedBools.find(prop);
if (i != emittedBools.end())
{
- props.insert("COMPATIBLE_INTERFACE_BOOL");
+ props.insert(strBool);
}
i = emittedStrings.find(prop);
if (i != emittedStrings.end())
{
- props.insert("COMPATIBLE_INTERFACE_STRING");
+ props.insert(strString);
}
i = emittedMinNumbers.find(prop);
if (i != emittedMinNumbers.end())
{
- props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
+ props.insert(strNumMin);
}
i = emittedMaxNumbers.find(prop);
if (i != emittedMaxNumbers.end())
{
- props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
+ props.insert(strNumMax);
}
std::string propsString = *props.begin();
@@ -6967,19 +6802,17 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
//----------------------------------------------------------------------------
cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const std::string& config,
- cmTarget const* head) const
+cmTarget::GetLinkInformation(const std::string& config) const
{
- cmTarget const* headTarget = head ? head : this;
// Lookup any existing information for this configuration.
- TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config));
+ std::string key(cmSystemTools::UpperCase(config));
cmTargetLinkInformationMap::iterator
i = this->LinkInformation.find(key);
if(i == this->LinkInformation.end())
{
// Compute information for this configuration.
cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config, headTarget);
+ new cmComputeLinkInformation(this, config);
if(!info || !info->Compute())
{
delete info;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2d51835..a3ecca0 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -18,6 +18,9 @@
#include "cmListFileCache.h"
#include <cmsys/auto_ptr.hxx>
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_map.hxx>
+#endif
#define CM_FOR_EACH_TARGET_POLICY(F) \
F(CMP0003) \
@@ -43,12 +46,36 @@ class cmTarget;
class cmGeneratorTarget;
class cmTargetTraceDependencies;
+// Basic information about each link item.
+class cmLinkItem: public std::string
+{
+ typedef std::string std_string;
+public:
+ cmLinkItem(): std_string(), Target(0) {}
+ cmLinkItem(const std_string& n,
+ cmTarget const* t): std_string(n), Target(t) {}
+ cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
+ cmTarget const* Target;
+};
+class cmLinkImplItem: public cmLinkItem
+{
+public:
+ cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {}
+ cmLinkImplItem(std::string const& n,
+ cmTarget const* t,
+ cmListFileBacktrace const& bt,
+ bool fromGenex):
+ cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
+ cmLinkImplItem(cmLinkImplItem const& r):
+ cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
+ cmListFileBacktrace Backtrace;
+ bool FromGenex;
+};
+
struct cmTargetLinkInformationMap:
- public std::map<std::pair<cmTarget const* , std::string>,
- cmComputeLinkInformation*>
+ public std::map<std::string, cmComputeLinkInformation*>
{
- typedef std::map<std::pair<cmTarget const* , std::string>,
- cmComputeLinkInformation*> derived;
+ typedef std::map<std::string, cmComputeLinkInformation*> derived;
cmTargetLinkInformationMap() {}
cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
~cmTargetLinkInformationMap();
@@ -137,8 +164,7 @@ public:
* Get the list of the source files used by this target
*/
void GetSourceFiles(std::vector<cmSourceFile*> &files,
- const std::string& config,
- cmTarget const* head = 0) const;
+ const std::string& config) const;
bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
/**
@@ -155,16 +181,8 @@ public:
typedef std::pair<std::string, LinkLibraryType> LibraryID;
typedef std::vector<LibraryID > LinkLibraryVectorType;
- const LinkLibraryVectorType &GetLinkLibraries() const {
- return this->LinkLibraries;}
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
{return this->OriginalLinkLibraries;}
- void GetDirectLinkLibraries(const std::string& config,
- std::vector<std::string> &,
- cmTarget const* head) const;
- void GetInterfaceLinkLibraries(const std::string& config,
- std::vector<std::string> &,
- cmTarget const* head) const;
/** Compute the link type to use for the given configuration. */
LinkLibraryType ComputeLinkType(const std::string& config) const;
@@ -221,6 +239,7 @@ public:
void AddUtility(const std::string& u, cmMakefile *makefile = 0);
///! Get the utilities used by this target
std::set<std::string>const& GetUtilities() const { return this->Utilities; }
+ std::set<cmLinkItem>const& GetUtilityItems() const;
cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const;
/** Finalize the target at the end of the Configure step. */
@@ -246,16 +265,18 @@ public:
/** The link interface specifies transitive library dependencies and
other information needed by targets that link to this target. */
- struct LinkInterface
+ struct LinkInterfaceLibraries
+ {
+ // Libraries listed in the interface.
+ std::vector<cmLinkItem> Libraries;
+ };
+ struct LinkInterface: public LinkInterfaceLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
- // Libraries listed in the interface.
- std::vector<std::string> Libraries;
-
// Shared library dependencies needed for linking on some platforms.
- std::vector<std::string> SharedDeps;
+ std::vector<cmLinkItem> SharedDeps;
// Number of repetitions of a strongly connected component of two
// or more static libraries.
@@ -263,7 +284,7 @@ public:
// Libraries listed for other configurations.
// Needed only for OLD behavior of CMP0003.
- std::vector<std::string> WrongConfigLibraries;
+ std::vector<cmLinkItem> WrongConfigLibraries;
bool ImplementationIsInterface;
@@ -274,35 +295,45 @@ public:
if the target cannot be linked. */
LinkInterface const* GetLinkInterface(const std::string& config,
cmTarget const* headTarget) const;
- LinkInterface const* GetLinkInterfaceLibraries(const std::string& config,
- cmTarget const* headTarget) const;
- void GetTransitivePropertyTargets(const std::string& config,
- cmTarget const* headTarget,
- std::vector<cmTarget*> &libs) const;
- void GetTransitiveTargetClosure(const std::string& config,
- cmTarget const* headTarget,
- std::vector<cmTarget*> &libs) const;
+ LinkInterfaceLibraries const*
+ GetLinkInterfaceLibraries(const std::string& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only) const;
+
+ std::vector<cmTarget const*> const&
+ GetLinkImplementationClosure(const std::string& config) const;
+
+ struct CompatibleInterfaces
+ {
+ std::set<std::string> PropsBool;
+ std::set<std::string> PropsString;
+ std::set<std::string> PropsNumberMax;
+ std::set<std::string> PropsNumberMin;
+ };
+ CompatibleInterfaces const&
+ GetCompatibleInterfaces(std::string const& config) const;
/** The link implementation specifies the direct library
dependencies needed by the object files of the target. */
- struct LinkImplementation
+ struct LinkImplementationLibraries
{
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
-
// Libraries linked directly in this configuration.
- std::vector<std::string> Libraries;
+ std::vector<cmLinkImplItem> Libraries;
// Libraries linked directly in other configurations.
// Needed only for OLD behavior of CMP0003.
- std::vector<std::string> WrongConfigLibraries;
+ std::vector<cmLinkItem> WrongConfigLibraries;
+ };
+ struct LinkImplementation: public LinkImplementationLibraries
+ {
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
};
- LinkImplementation const* GetLinkImplementation(const std::string& config,
- cmTarget const* head) const;
+ LinkImplementation const*
+ GetLinkImplementation(const std::string& config) const;
- LinkImplementation const* GetLinkImplementationLibraries(
- const std::string& config,
- cmTarget const* head) const;
+ LinkImplementationLibraries const*
+ GetLinkImplementationLibraries(const std::string& config) const;
/** Link information from the transitive closure of the link
implementation and the interfaces of its dependencies. */
@@ -314,8 +345,9 @@ public:
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
};
- LinkClosure const* GetLinkClosure(const std::string& config,
- cmTarget const* head) const;
+ LinkClosure const* GetLinkClosure(const std::string& config) const;
+
+ cmTarget const* FindTargetToLink(std::string const& name) const;
/** Strip off leading and trailing whitespace from an item named in
the link dependencies of this target. */
@@ -361,8 +393,7 @@ public:
GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
///! Return the preferred linker language for this target
- std::string GetLinkerLanguage(const std::string& config = "",
- cmTarget const* head = 0) const;
+ std::string GetLinkerLanguage(const std::string& config = "") const;
/** Get the full name of the target according to the settings in its
makefile. */
@@ -446,8 +477,8 @@ public:
* install tree. For example: "\@rpath/" or "\@loader_path/". */
std::string GetInstallNameDirForInstallTree() const;
- cmComputeLinkInformation* GetLinkInformation(const std::string& config,
- cmTarget const* head = 0) const;
+ cmComputeLinkInformation*
+ GetLinkInformation(const std::string& config) const;
// Get the properties
cmPropertyMap &GetProperties() const { return this->Properties; }
@@ -473,8 +504,7 @@ public:
// information to forward these property changes to the targets
// until we have per-target object file properties.
void GetLanguages(std::set<std::string>& languages,
- std::string const& config,
- cmTarget const* head = 0) const;
+ std::string const& config) const;
/** Return whether this target is an executable with symbol exports
enabled. */
@@ -595,6 +625,11 @@ public:
return this->MaxLanguageStandards;
}
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
+ return this->LinkLibrariesForVS6;}
+#endif
+
private:
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
@@ -604,6 +639,7 @@ private:
std::vector<std::pair<TLLSignature, cmListFileBacktrace> > TLLCommands;
+#if defined(_WIN32) && !defined(__CYGWIN__)
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
*/
@@ -620,16 +656,16 @@ private:
/**
* Inserts \a dep at the end of the dependency list of \a lib.
*/
- void InsertDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep);
+ void InsertDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep);
/*
* Deletes \a dep from the dependency list of \a lib.
*/
- void DeleteDependency( DependencyMap& depMap,
- const LibraryID& lib,
- const LibraryID& dep);
+ void DeleteDependencyForVS6( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep);
/**
* Emits the library \a lib and all its dependencies into link_line.
@@ -639,21 +675,22 @@ private:
* link_line is in reverse order, in that the dependencies of a
* library are listed before the library itself.
*/
- void Emit( const LibraryID lib,
- const DependencyMap& dep_map,
- std::set<LibraryID>& emitted,
- std::set<LibraryID>& visited,
- DependencyList& link_line);
+ void EmitForVS6( const LibraryID lib,
+ const DependencyMap& dep_map,
+ std::set<LibraryID>& emitted,
+ std::set<LibraryID>& visited,
+ DependencyList& link_line);
/**
* Finds the dependencies for \a lib and inserts them into \a
* dep_map.
*/
- void GatherDependencies( const cmMakefile& mf,
- const LibraryID& lib,
- DependencyMap& dep_map);
+ void GatherDependenciesForVS6( const cmMakefile& mf,
+ const LibraryID& lib,
+ DependencyMap& dep_map);
- void AnalyzeLibDependencies( const cmMakefile& mf );
+ void AnalyzeLibDependenciesForVS6( const cmMakefile& mf );
+#endif
const char* GetSuffixVariableInternal(bool implib) const;
const char* GetPrefixVariableInternal(bool implib) const;
@@ -694,17 +731,18 @@ private:
bool contentOnly) const;
void GetSourceFiles(std::vector<std::string> &files,
- const std::string& config,
- cmTarget const* head = 0) const;
+ const std::string& config) const;
private:
std::string Name;
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
TargetType TargetTypeValue;
- LinkLibraryVectorType LinkLibraries;
LinkLibraryVectorType PrevLinkedLibraries;
- bool LinkLibrariesAnalyzed;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ LinkLibraryVectorType LinkLibrariesForVS6;
+ bool LinkLibrariesForVS6Analyzed;
+#endif
std::vector<std::string> LinkDirectories;
std::set<std::string> LinkDirectoriesEmmitted;
bool HaveInstallRule;
@@ -717,6 +755,7 @@ private:
mutable cmPropertyMap Properties;
LinkLibraryVectorType OriginalLinkLibraries;
bool DLLPlatform;
+ bool IsAndroid;
bool IsApple;
bool IsImportedTarget;
mutable bool DebugIncludesDone;
@@ -740,10 +779,9 @@ private:
// Cache import information from properties for each configuration.
struct ImportInfo;
- ImportInfo const* GetImportInfo(const std::string& config,
- cmTarget const* workingTarget) const;
- void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
- cmTarget const* head) const;
+ ImportInfo const* GetImportInfo(const std::string& config) const;
+ void ComputeImportInfo(std::string const& desired_config,
+ ImportInfo& info) const;
// Cache target compile paths for each configuration.
struct CompileInfo;
@@ -753,19 +791,22 @@ private:
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
const std::string& config) const;
- const char* ComputeLinkInterfaceLibraries(const std::string& config,
- LinkInterface& iface,
- cmTarget const* head,
- bool &exists) const;
+ LinkInterface const*
+ GetImportLinkInterface(const std::string& config, cmTarget const* head,
+ bool usage_requirements_only) const;
- void ComputeLinkImplementation(const std::string& config,
- LinkImplementation& impl,
- cmTarget const* head) const;
- void ComputeLinkImplementationLanguages(const std::string& config,
- LinkImplementation& impl,
- cmTarget const* head) const;
- void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
- cmTarget const* head) const;
+ LinkImplementationLibraries const*
+ GetLinkImplementationLibrariesInternal(const std::string& config,
+ cmTarget const* head) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+
+ void ExpandLinkItems(std::string const& prop, std::string const& value,
+ std::string const& config, cmTarget const* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const;
+ void LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const;
std::string ProcessSourceItemCMP0049(const std::string& s);
@@ -803,7 +844,11 @@ private:
mutable bool LinkImplementationLanguageIsContextDependent;
};
+#ifdef CMAKE_BUILD_WITH_CMAKE
+typedef cmsys::hash_map<std::string,cmTarget> cmTargets;
+#else
typedef std::map<std::string,cmTarget> cmTargets;
+#endif
class cmTargetSet: public std::set<std::string> {};
class cmTargetManifest: public std::map<std::string, cmTargetSet> {};
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index ac26503..6fd6ab7 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -33,15 +33,13 @@ std::string cmTimestamp::CurrentTime(
std::string cmTimestamp::FileModificationTime(const char* path,
const std::string& formatString, bool utcFlag)
{
- struct stat info;
- memset(&info, 0, sizeof(info));
-
- if(stat(path, &info) != 0)
+ if(!cmsys::SystemTools::FileExists(path))
{
return std::string();
}
- return CreateTimestampFromTimeT(info.st_mtime, formatString, utcFlag);
+ time_t mtime = cmsys::SystemTools::ModifiedTime(path);
+ return CreateTimestampFromTimeT(mtime, formatString, utcFlag);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
new file mode 100644
index 0000000..8b5b7ae
--- /dev/null
+++ b/Source/cmUuid.cxx
@@ -0,0 +1,214 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmUuid.h"
+
+#include <string.h>
+
+#include <cmsys/MD5.h>
+#include "cm_sha2.h"
+
+cmUuid::cmUuid()
+{
+ Groups.push_back(4);
+ Groups.push_back(2);
+ Groups.push_back(2);
+ Groups.push_back(2);
+ Groups.push_back(6);
+}
+
+std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const
+{
+ std::vector<unsigned char> hashInput;
+ this->CreateHashInput(uuidNamespace, name, hashInput);
+
+ cmsysMD5_s *md5 = cmsysMD5_New();
+ cmsysMD5_Initialize(md5);
+ cmsysMD5_Append(md5, &hashInput[0], int(hashInput.size()));
+
+ unsigned char digest[16] = {0};
+ cmsysMD5_Finalize(md5, digest);
+
+ cmsysMD5_Delete(md5);
+
+ return this->FromDigest(digest, 3);
+}
+
+std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const
+{
+ std::vector<unsigned char> hashInput;
+ this->CreateHashInput(uuidNamespace, name, hashInput);
+
+ SHA_CTX *sha = new SHA_CTX;
+ SHA1_Init(sha);
+ SHA1_Update(sha, &hashInput[0], hashInput.size());
+
+ unsigned char digest[SHA1_DIGEST_LENGTH] = {0};
+ SHA1_Final(digest, sha);
+
+ delete sha;
+
+ return this->FromDigest(digest, 5);
+}
+
+void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name, std::vector<unsigned char> &output) const
+{
+ output = uuidNamespace;
+
+ if(name.size())
+ {
+ output.resize(output.size() + name.size());
+
+ memcpy(&output[0] + uuidNamespace.size(),
+ name.c_str(), name.size());
+ }
+}
+
+std::string cmUuid::FromDigest(
+ const unsigned char* digest, unsigned char version) const
+{
+ typedef unsigned char byte_t;
+
+ byte_t uuid[16] = {0};
+ memcpy(uuid, digest, 16);
+
+ uuid[6] &= 0xF;
+ uuid[6] |= byte_t(version << 4);
+
+ uuid[8] &= 0x3F;
+ uuid[8] |= 0x80;
+
+ return this->BinaryToString(uuid);
+}
+
+bool cmUuid::StringToBinary(std::string const& input,
+ std::vector<unsigned char> &output) const
+{
+ output.clear();
+ output.reserve(16);
+
+ if(input.length() != 36)
+ {
+ return false;
+ }
+ size_t index = 0;
+ for(size_t i = 0; i < this->Groups.size(); ++i)
+ {
+ if(i != 0 && input[index++] != '-')
+ {
+ return false;
+ }
+ size_t digits = this->Groups[i] * 2;
+ if(!StringToBinaryImpl(input.substr(index, digits), output))
+ {
+ return false;
+ }
+
+ index += digits;
+ }
+
+ return true;
+}
+
+std::string cmUuid::BinaryToString(const unsigned char* input) const
+{
+ std::string output;
+
+ size_t inputIndex = 0;
+ for(size_t i = 0; i < this->Groups.size(); ++i)
+ {
+ if(i != 0)
+ {
+ output += '-';
+ }
+
+ size_t bytes = this->Groups[i];
+ for(size_t j = 0; j < bytes; ++j)
+ {
+ unsigned char byte = input[inputIndex++];
+ output += this->ByteToHex(byte);
+ }
+ }
+
+ return output;
+}
+
+std::string cmUuid::ByteToHex(unsigned char byte) const
+{
+ std::string result;
+ for(int i = 0; i < 2; ++i)
+ {
+ unsigned char rest = byte % 16;
+ byte /= 16;
+
+ char c = (rest < 0xA) ?
+ char('0' + rest) :
+ char('a' + (rest - 0xA));
+
+ result = c + result;
+ }
+
+ return result;
+}
+
+bool cmUuid::StringToBinaryImpl(std::string const& input,
+ std::vector<unsigned char> &output) const
+{
+ if(input.size()%2)
+ {
+ return false;
+ }
+
+ for(size_t i = 0; i < input.size(); i +=2)
+ {
+ char c1 = 0;
+ if(!IntFromHexDigit(input[i], c1))
+ {
+ return false;
+ }
+
+ char c2 = 0;
+ if(!IntFromHexDigit(input[i + 1], c2))
+ {
+ return false;
+ }
+
+ output.push_back(char(c1 << 4 | c2));
+ }
+
+ return true;
+}
+
+bool cmUuid::IntFromHexDigit(char input, char& output) const
+{
+ if(input >= '0' && input <= '9')
+ {
+ output = char(input - '0');
+ return true;
+ }
+ else if(input >= 'a' && input <= 'f')
+ {
+ output = char(input - 'a' + 0xA);
+ return true;
+ }
+ else if(input >= 'A' && input <= 'F')
+ {
+ output = char(input - 'A' + 0xA);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/cmUuid.h b/Source/cmUuid.h
new file mode 100644
index 0000000..0dda357
--- /dev/null
+++ b/Source/cmUuid.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2014 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmUuid_h
+#define cmUuid_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmUuid
+ * \brief Utility class to generate UUIDs as defined by RFC4122
+ *
+ */
+class cmUuid
+{
+public:
+ cmUuid();
+
+ std::string FromMd5(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const;
+
+ std::string FromSha1(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name) const;
+
+ bool StringToBinary(std::string const& input,
+ std::vector<unsigned char> &output) const;
+
+private:
+ std::string ByteToHex(unsigned char byte) const;
+
+ void CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
+ std::string const& name, std::vector<unsigned char> &output) const;
+
+ std::string FromDigest(const unsigned char* digest,
+ unsigned char version) const;
+
+ bool StringToBinaryImpl(std::string const& input,
+ std::vector<unsigned char> &output) const;
+
+ std::string BinaryToString(const unsigned char* input) const;
+
+ bool IntFromHexDigit(char input, char& output) const;
+
+ std::vector<int> Groups;
+};
+
+
+#endif
diff --git a/Source/cmVS10MASMFlagTable.h b/Source/cmVS10MASMFlagTable.h
new file mode 100644
index 0000000..8fb6f33
--- /dev/null
+++ b/Source/cmVS10MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS10MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS10RCFlagTable.h b/Source/cmVS10RCFlagTable.h
new file mode 100644
index 0000000..9049986
--- /dev/null
+++ b/Source/cmVS10RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS10RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS11MASMFlagTable.h b/Source/cmVS11MASMFlagTable.h
new file mode 100644
index 0000000..2ff95ad
--- /dev/null
+++ b/Source/cmVS11MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS11MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS11RCFlagTable.h b/Source/cmVS11RCFlagTable.h
new file mode 100644
index 0000000..a7d2de1
--- /dev/null
+++ b/Source/cmVS11RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS11RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS12MASMFlagTable.h b/Source/cmVS12MASMFlagTable.h
new file mode 100644
index 0000000..74d529c
--- /dev/null
+++ b/Source/cmVS12MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS12MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS12RCFlagTable.h b/Source/cmVS12RCFlagTable.h
new file mode 100644
index 0000000..1551c66
--- /dev/null
+++ b/Source/cmVS12RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS12RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14CLFlagTable.h b/Source/cmVS14CLFlagTable.h
new file mode 100644
index 0000000..422f47b
--- /dev/null
+++ b/Source/cmVS14CLFlagTable.h
@@ -0,0 +1,296 @@
+static cmVS7FlagTable cmVS14CLFlagTable[] =
+{
+
+ //Enum Properties
+ {"DebugInformationFormat", "",
+ "None", "None", 0},
+ {"DebugInformationFormat", "Z7",
+ "C7 compatible", "OldStyle", 0},
+ {"DebugInformationFormat", "Zi",
+ "Program Database", "ProgramDatabase", 0},
+ {"DebugInformationFormat", "ZI",
+ "Program Database for Edit And Continue", "EditAndContinue", 0},
+
+ {"WarningLevel", "W0",
+ "Turn Off All Warnings", "TurnOffAllWarnings", 0},
+ {"WarningLevel", "W1",
+ "Level1", "Level1", 0},
+ {"WarningLevel", "W2",
+ "Level2", "Level2", 0},
+ {"WarningLevel", "W3",
+ "Level3", "Level3", 0},
+ {"WarningLevel", "W4",
+ "Level4", "Level4", 0},
+ {"WarningLevel", "Wall",
+ "EnableAllWarnings", "EnableAllWarnings", 0},
+
+ {"Optimization", "",
+ "Custom", "Custom", 0},
+ {"Optimization", "Od",
+ "Disabled", "Disabled", 0},
+ {"Optimization", "O1",
+ "Minimize Size", "MinSpace", 0},
+ {"Optimization", "O2",
+ "Maximize Speed", "MaxSpeed", 0},
+ {"Optimization", "Ox",
+ "Full Optimization", "Full", 0},
+
+ {"InlineFunctionExpansion", "",
+ "Default", "Default", 0},
+ {"InlineFunctionExpansion", "Ob0",
+ "Disabled", "Disabled", 0},
+ {"InlineFunctionExpansion", "Ob1",
+ "Only __inline", "OnlyExplicitInline", 0},
+ {"InlineFunctionExpansion", "Ob2",
+ "Any Suitable", "AnySuitable", 0},
+
+ {"FavorSizeOrSpeed", "Os",
+ "Favor small code", "Size", 0},
+ {"FavorSizeOrSpeed", "Ot",
+ "Favor fast code", "Speed", 0},
+ {"FavorSizeOrSpeed", "",
+ "Neither", "Neither", 0},
+
+ {"ExceptionHandling", "EHa",
+ "Yes with SEH Exceptions", "Async", 0},
+ {"ExceptionHandling", "EHsc",
+ "Yes", "Sync", 0},
+ {"ExceptionHandling", "EHs",
+ "Yes with Extern C functions", "SyncCThrow", 0},
+ {"ExceptionHandling", "",
+ "No", "false", 0},
+
+ {"BasicRuntimeChecks", "RTCs",
+ "Stack Frames", "StackFrameRuntimeCheck", 0},
+ {"BasicRuntimeChecks", "RTCu",
+ "Uninitialized variables", "UninitializedLocalUsageCheck", 0},
+ {"BasicRuntimeChecks", "RTC1",
+ "Both (/RTC1, equiv. to /RTCsu)", "EnableFastChecks", 0},
+ {"BasicRuntimeChecks", "",
+ "Default", "Default", 0},
+
+ {"RuntimeLibrary", "MT",
+ "Multi-threaded", "MultiThreaded", 0},
+ {"RuntimeLibrary", "MTd",
+ "Multi-threaded Debug", "MultiThreadedDebug", 0},
+ {"RuntimeLibrary", "MD",
+ "Multi-threaded DLL", "MultiThreadedDLL", 0},
+ {"RuntimeLibrary", "MDd",
+ "Multi-threaded Debug DLL", "MultiThreadedDebugDLL", 0},
+
+ {"StructMemberAlignment", "Zp1",
+ "1 Byte", "1Byte", 0},
+ {"StructMemberAlignment", "Zp2",
+ "2 Bytes", "2Bytes", 0},
+ {"StructMemberAlignment", "Zp4",
+ "4 Byte", "4Bytes", 0},
+ {"StructMemberAlignment", "Zp8",
+ "8 Bytes", "8Bytes", 0},
+ {"StructMemberAlignment", "Zp16",
+ "16 Bytes", "16Bytes", 0},
+ {"StructMemberAlignment", "",
+ "Default", "Default", 0},
+
+ {"BufferSecurityCheck", "GS-",
+ "Disable Security Check", "false", 0},
+ {"BufferSecurityCheck", "GS",
+ "Enable Security Check", "true", 0},
+
+ {"EnableEnhancedInstructionSet", "arch:SSE",
+ "Streaming SIMD Extensions", "StreamingSIMDExtensions", 0},
+ {"EnableEnhancedInstructionSet", "arch:SSE2",
+ "Streaming SIMD Extensions 2", "StreamingSIMDExtensions2", 0},
+ {"EnableEnhancedInstructionSet", "arch:AVX",
+ "Advanced Vector Extensions", "AdvancedVectorExtensions", 0},
+ {"EnableEnhancedInstructionSet", "arch:AVX2",
+ "Advanced Vector Extensions 2", "AdvancedVectorExtensions2", 0},
+ {"EnableEnhancedInstructionSet", "arch:IA32",
+ "No Enhanced Instructions", "NoExtensions", 0},
+ {"EnableEnhancedInstructionSet", "",
+ "Not Set", "NotSet", 0},
+
+ {"FloatingPointModel", "fp:precise",
+ "Precise", "Precise", 0},
+ {"FloatingPointModel", "fp:strict",
+ "Strict", "Strict", 0},
+ {"FloatingPointModel", "fp:fast",
+ "Fast", "Fast", 0},
+
+ {"PrecompiledHeader", "Yc",
+ "Create", "Create",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeader", "Yu",
+ "Use", "Use",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeader", "",
+ "Not Using Precompiled Headers", "NotUsing", 0},
+
+ {"AssemblerOutput", "",
+ "No Listing", "NoListing", 0},
+ {"AssemblerOutput", "FA",
+ "Assembly-Only Listing", "AssemblyCode", 0},
+ {"AssemblerOutput", "FAc",
+ "Assembly With Machine Code", "AssemblyAndMachineCode", 0},
+ {"AssemblerOutput", "FAs",
+ "Assembly With Source Code", "AssemblyAndSourceCode", 0},
+ {"AssemblerOutput", "FAcs",
+ "Assembly, Machine Code and Source", "All", 0},
+
+ {"CallingConvention", "Gd",
+ "__cdecl", "Cdecl", 0},
+ {"CallingConvention", "Gr",
+ "__fastcall", "FastCall", 0},
+ {"CallingConvention", "Gz",
+ "__stdcall", "StdCall", 0},
+ {"CallingConvention", "Gv",
+ "__vectorcall", "VectorCall", 0},
+
+ {"CompileAs", "",
+ "Default", "Default", 0},
+ {"CompileAs", "TC",
+ "Compile as C Code", "CompileAsC", 0},
+ {"CompileAs", "TP",
+ "Compile as C++ Code", "CompileAsCpp", 0},
+
+ {"ErrorReporting", "errorReport:none",
+ "Do Not Send Report", "None", 0},
+ {"ErrorReporting", "errorReport:prompt",
+ "Prompt Immediately", "Prompt", 0},
+ {"ErrorReporting", "errorReport:queue",
+ "Queue For Next Login", "Queue", 0},
+ {"ErrorReporting", "errorReport:send",
+ "Send Automatically", "Send", 0},
+
+ {"CompileAsManaged", "",
+ "No Common Language RunTime Support", "false", 0},
+ {"CompileAsManaged", "clr",
+ "Common Language RunTime Support", "true", 0},
+ {"CompileAsManaged", "clr:pure",
+ "Pure MSIL Common Language RunTime Support", "Pure", 0},
+ {"CompileAsManaged", "clr:safe",
+ "Safe MSIL Common Language RunTime Support", "Safe", 0},
+ {"CompileAsManaged", "clr:oldSyntax",
+ "Common Language RunTime Support, Old Syntax", "OldSyntax", 0},
+
+
+ //Bool Properties
+ {"CompileAsWinRT", "ZW", "", "true", 0},
+ {"WinRTNoStdLib", "ZW:nostdlib", "", "true", 0},
+ {"SuppressStartupBanner", "nologo", "", "true", 0},
+ {"TreatWarningAsError", "WX-", "", "false", 0},
+ {"TreatWarningAsError", "WX", "", "true", 0},
+ {"SDLCheck", "sdl-", "", "false", 0},
+ {"SDLCheck", "sdl", "", "true", 0},
+ {"IntrinsicFunctions", "Oi", "", "true", 0},
+ {"OmitFramePointers", "Oy-", "", "false", 0},
+ {"OmitFramePointers", "Oy", "", "true", 0},
+ {"EnableFiberSafeOptimizations", "GT", "", "true", 0},
+ {"WholeProgramOptimization", "GL", "", "true", 0},
+ {"UndefineAllPreprocessorDefinitions", "u", "", "true", 0},
+ {"IgnoreStandardIncludePath", "X", "", "true", 0},
+ {"PreprocessToFile", "P", "", "true", 0},
+ {"PreprocessSuppressLineNumbers", "EP", "", "true", 0},
+ {"PreprocessKeepComments", "C", "", "true", 0},
+ {"StringPooling", "GF-", "", "false", 0},
+ {"StringPooling", "GF", "", "true", 0},
+ {"MinimalRebuild", "Gm-", "", "false", 0},
+ {"MinimalRebuild", "Gm", "", "true", 0},
+ {"SmallerTypeCheck", "RTCc", "", "true", 0},
+ {"FunctionLevelLinking", "Gy-", "", "false", 0},
+ {"FunctionLevelLinking", "Gy", "", "true", 0},
+ {"EnableParallelCodeGeneration", "Qpar-", "", "false", 0},
+ {"EnableParallelCodeGeneration", "Qpar", "", "true", 0},
+ {"FloatingPointExceptions", "fp:except-", "", "false", 0},
+ {"FloatingPointExceptions", "fp:except", "", "true", 0},
+ {"CreateHotpatchableImage", "hotpatch", "", "true", 0},
+ {"DisableLanguageExtensions", "Za", "", "true", 0},
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t-", "", "false", 0},
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t", "", "true", 0},
+ {"ForceConformanceInForLoopScope", "Zc:forScope-", "", "false", 0},
+ {"ForceConformanceInForLoopScope", "Zc:forScope", "", "true", 0},
+ {"RuntimeTypeInfo", "GR-", "", "false", 0},
+ {"RuntimeTypeInfo", "GR", "", "true", 0},
+ {"OpenMPSupport", "openmp-", "", "false", 0},
+ {"OpenMPSupport", "openmp", "", "true", 0},
+ {"ExpandAttributedSource", "Fx", "", "true", 0},
+ {"UseUnicodeForAssemblerListing", "FAu", "", "true", 0},
+ {"ShowIncludes", "showIncludes", "", "true", 0},
+ {"EnablePREfast", "analyze-", "", "false", 0},
+ {"EnablePREfast", "analyze", "", "true", 0},
+ {"UseFullPaths", "FC", "", "true", 0},
+ {"OmitDefaultLibName", "Zl", "", "true", 0},
+
+ //Bool Properties With Argument
+ {"MultiProcessorCompilation", "MP", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"ProcessorNumber", "MP", "Multi-processor Compilation", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"GenerateXMLDocumentationFiles", "doc", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"XMLDocumentationFileName", "doc", "Generate XML Documentation Files", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"BrowseInformation", "FR", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"BrowseInformationFile", "FR", "Enable Browse Information", "",
+ cmVS7FlagTable::UserValueRequired},
+
+ //String List Properties
+ {"AdditionalIncludeDirectories", "I",
+ "Additional Include Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AdditionalUsingDirectories", "AI",
+ "Additional #using Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PreprocessorDefinitions", "D ",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"UndefinePreprocessorDefinitions", "U",
+ "Undefine Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"DisableSpecificWarnings", "wd",
+ "Disable Specific Warnings",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForcedIncludeFiles", "FI",
+ "Forced Include File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForcedUsingFiles", "FU",
+ "Forced #using File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"PREfastLog", "analyze:log",
+ "Code Analysis Log",
+ "", cmVS7FlagTable::UserFollowing},
+ {"PREfastAdditionalPlugins", "analyze:plugin",
+ "Additional Code Analysis Native plugins",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"TreatSpecificWarningsAsErrors", "we",
+ "Treat Specific Warnings As Errors",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {"PreprocessOutputPath", "Fi",
+ "Preprocess Output Path",
+ "", cmVS7FlagTable::UserValue},
+ {"PrecompiledHeaderFile", "Yc",
+ "Precompiled Header Name",
+ "", cmVS7FlagTable::UserValueRequired},
+ {"PrecompiledHeaderFile", "Yu",
+ "Precompiled Header Name",
+ "", cmVS7FlagTable::UserValueRequired},
+ {"PrecompiledHeaderOutputFile", "Fp",
+ "Precompiled Header Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"AssemblerListingLocation", "Fa",
+ "ASM List Location",
+ "", cmVS7FlagTable::UserValue},
+ {"ObjectFileName", "Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"ProgramDataBaseFileName", "Fd",
+ "Program Database File Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [XMLDocumentationFileName] - no command line Switch.
+ // Skip [BrowseInformationFile] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14LibFlagTable.h b/Source/cmVS14LibFlagTable.h
new file mode 100644
index 0000000..a33f273
--- /dev/null
+++ b/Source/cmVS14LibFlagTable.h
@@ -0,0 +1,102 @@
+static cmVS7FlagTable cmVS14LibFlagTable[] =
+{
+
+ //Enum Properties
+ {"ErrorReporting", "ERRORREPORT:PROMPT",
+ "PromptImmediately", "PromptImmediately", 0},
+ {"ErrorReporting", "ERRORREPORT:QUEUE",
+ "Queue For Next Login", "QueueForNextLogin", 0},
+ {"ErrorReporting", "ERRORREPORT:SEND",
+ "Send Error Report", "SendErrorReport", 0},
+ {"ErrorReporting", "ERRORREPORT:NONE",
+ "No Error Report", "NoErrorReport", 0},
+
+ {"TargetMachine", "MACHINE:ARM",
+ "MachineARM", "MachineARM", 0},
+ {"TargetMachine", "MACHINE:EBC",
+ "MachineEBC", "MachineEBC", 0},
+ {"TargetMachine", "MACHINE:IA64",
+ "MachineIA64", "MachineIA64", 0},
+ {"TargetMachine", "MACHINE:MIPS",
+ "MachineMIPS", "MachineMIPS", 0},
+ {"TargetMachine", "MACHINE:MIPS16",
+ "MachineMIPS16", "MachineMIPS16", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU",
+ "MachineMIPSFPU", "MachineMIPSFPU", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU16",
+ "MachineMIPSFPU16", "MachineMIPSFPU16", 0},
+ {"TargetMachine", "MACHINE:SH4",
+ "MachineSH4", "MachineSH4", 0},
+ {"TargetMachine", "MACHINE:THUMB",
+ "MachineTHUMB", "MachineTHUMB", 0},
+ {"TargetMachine", "MACHINE:X64",
+ "MachineX64", "MachineX64", 0},
+ {"TargetMachine", "MACHINE:X86",
+ "MachineX86", "MachineX86", 0},
+
+ {"SubSystem", "SUBSYSTEM:CONSOLE",
+ "Console", "Console", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWS",
+ "Windows", "Windows", 0},
+ {"SubSystem", "SUBSYSTEM:NATIVE",
+ "Native", "Native", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_APPLICATION",
+ "EFI Application", "EFI Application", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER",
+ "EFI Boot Service Driver", "EFI Boot Service Driver", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_ROM",
+ "EFI ROM", "EFI ROM", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER",
+ "EFI Runtime", "EFI Runtime", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWSCE",
+ "WindowsCE", "WindowsCE", 0},
+ {"SubSystem", "SUBSYSTEM:POSIX",
+ "POSIX", "POSIX", 0},
+
+
+ //Bool Properties
+ {"SuppressStartupBanner", "NOLOGO", "", "true", 0},
+ {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0},
+ {"TreatLibWarningAsErrors", "WX:NO", "", "false", 0},
+ {"TreatLibWarningAsErrors", "WX", "", "true", 0},
+ {"Verbose", "VERBOSE", "", "true", 0},
+ {"LinkTimeCodeGeneration", "LTCG", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ // Skip [AdditionalDependencies] - no command line Switch.
+ {"AdditionalLibraryDirectories", "LIBPATH:",
+ "Additional Library Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:",
+ "Ignore Specific Default Libraries",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ExportNamedFunctions", "EXPORT:",
+ "Export Named Functions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"RemoveObjects", "REMOVE:",
+ "Remove Objects",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ {"OutputFile", "OUT:",
+ "Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"ModuleDefinitionFile", "DEF:",
+ "Module Definition File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"ForceSymbolReferences", "INCLUDE:",
+ "Force Symbol References",
+ "", cmVS7FlagTable::UserValue},
+ {"DisplayLibrary", "LIST:",
+ "Display Library to standard output",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [MinimumRequiredVersion] - no command line Switch.
+ {"Name", "NAME:",
+ "Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [AdditionalOptions] - no command line Switch.
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14LinkFlagTable.h b/Source/cmVS14LinkFlagTable.h
new file mode 100644
index 0000000..6d81d12
--- /dev/null
+++ b/Source/cmVS14LinkFlagTable.h
@@ -0,0 +1,340 @@
+static cmVS7FlagTable cmVS14LinkFlagTable[] =
+{
+
+ //Enum Properties
+ {"ShowProgress", "",
+ "Not Set", "NotSet", 0},
+ {"ShowProgress", "VERBOSE",
+ "Display all progress messages", "LinkVerbose", 0},
+ {"ShowProgress", "VERBOSE:Lib",
+ "For Libraries Searched", "LinkVerboseLib", 0},
+ {"ShowProgress", "VERBOSE:ICF",
+ "About COMDAT folding during optimized linking", "LinkVerboseICF", 0},
+ {"ShowProgress", "VERBOSE:REF",
+ "About data removed during optimized linking", "LinkVerboseREF", 0},
+ {"ShowProgress", "VERBOSE:SAFESEH",
+ "About Modules incompatible with SEH", "LinkVerboseSAFESEH", 0},
+ {"ShowProgress", "VERBOSE:CLR",
+ "About linker activity related to managed code", "LinkVerboseCLR", 0},
+
+ {"ForceFileOutput", "FORCE",
+ "Enabled", "Enabled", 0},
+ {"ForceFileOutput", "FORCE:MULTIPLE",
+ "Multiply Defined Symbol Only", "MultiplyDefinedSymbolOnly", 0},
+ {"ForceFileOutput", "FORCE:UNRESOLVED",
+ "Undefined Symbol Only", "UndefinedSymbolOnly", 0},
+
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN",
+ "Enabled", "Enabled", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:5",
+ "X86 Image Only", "X86Image", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:6",
+ "X64 Image Only", "X64Image", 0},
+ {"CreateHotPatchableImage", "FUNCTIONPADMIN:16",
+ "Itanium Image Only", "ItaniumImage", 0},
+
+ {"UACExecutionLevel", "level='asInvoker'",
+ "asInvoker", "AsInvoker", 0},
+ {"UACExecutionLevel", "level='highestAvailable'",
+ "highestAvailable", "HighestAvailable", 0},
+ {"UACExecutionLevel", "level='requireAdministrator'",
+ "requireAdministrator", "RequireAdministrator", 0},
+
+ {"SubSystem", "",
+ "Not Set", "NotSet", 0},
+ {"SubSystem", "SUBSYSTEM:CONSOLE",
+ "Console", "Console", 0},
+ {"SubSystem", "SUBSYSTEM:WINDOWS",
+ "Windows", "Windows", 0},
+ {"SubSystem", "SUBSYSTEM:NATIVE",
+ "Native", "Native", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_APPLICATION",
+ "EFI Application", "EFI Application", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER",
+ "EFI Boot Service Driver", "EFI Boot Service Driver", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_ROM",
+ "EFI ROM", "EFI ROM", 0},
+ {"SubSystem", "SUBSYSTEM:EFI_RUNTIME_DRIVER",
+ "EFI Runtime", "EFI Runtime", 0},
+ {"SubSystem", "SUBSYSTEM:POSIX",
+ "POSIX", "POSIX", 0},
+
+ {"Driver", "",
+ "Not Set", "NotSet", 0},
+ {"Driver", "Driver",
+ "Driver", "Driver", 0},
+ {"Driver", "DRIVER:UPONLY",
+ "UP Only", "UpOnly", 0},
+ {"Driver", "DRIVER:WDM",
+ "WDM", "WDM", 0},
+
+ {"LinkTimeCodeGeneration", "",
+ "Default", "Default", 0},
+ {"LinkTimeCodeGeneration", "LTCG",
+ "Use Link Time Code Generation", "UseLinkTimeCodeGeneration", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGInstrument",
+ "Profile Guided Optimization - Instrument", "PGInstrument", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGOptimize",
+ "Profile Guided Optimization - Optimization", "PGOptimization", 0},
+ {"LinkTimeCodeGeneration", "LTCG:PGUpdate",
+ "Profile Guided Optimization - Update", "PGUpdate", 0},
+
+ {"GenerateWindowsMetadata", "WINMD",
+ "Yes", "true", 0},
+ {"GenerateWindowsMetadata", "WINMD:NO",
+ "No", "false", 0},
+
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA1",
+ "SHA1", "SHA1", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA256",
+ "SHA256", "SHA256", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA384",
+ "SHA384", "SHA384", 0},
+ {"WindowsMetadataSignHash", "WINMDSIGNHASH:SHA512",
+ "SHA512", "SHA512", 0},
+
+ {"TargetMachine", "",
+ "Not Set", "NotSet", 0},
+ {"TargetMachine", "MACHINE:ARM",
+ "MachineARM", "MachineARM", 0},
+ {"TargetMachine", "MACHINE:EBC",
+ "MachineEBC", "MachineEBC", 0},
+ {"TargetMachine", "MACHINE:IA64",
+ "MachineIA64", "MachineIA64", 0},
+ {"TargetMachine", "MACHINE:MIPS",
+ "MachineMIPS", "MachineMIPS", 0},
+ {"TargetMachine", "MACHINE:MIPS16",
+ "MachineMIPS16", "MachineMIPS16", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU",
+ "MachineMIPSFPU", "MachineMIPSFPU", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU16",
+ "MachineMIPSFPU16", "MachineMIPSFPU16", 0},
+ {"TargetMachine", "MACHINE:SH4",
+ "MachineSH4", "MachineSH4", 0},
+ {"TargetMachine", "MACHINE:THUMB",
+ "MachineTHUMB", "MachineTHUMB", 0},
+ {"TargetMachine", "MACHINE:X64",
+ "MachineX64", "MachineX64", 0},
+ {"TargetMachine", "MACHINE:X86",
+ "MachineX86", "MachineX86", 0},
+
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:MTA",
+ "MTA threading attribute", "MTAThreadingAttribute", 0},
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:STA",
+ "STA threading attribute", "STAThreadingAttribute", 0},
+ {"CLRThreadAttribute", "CLRTHREADATTRIBUTE:NONE",
+ "Default threading attribute", "DefaultThreadingAttribute", 0},
+
+ {"CLRImageType", "CLRIMAGETYPE:IJW",
+ "Force IJW image", "ForceIJWImage", 0},
+ {"CLRImageType", "CLRIMAGETYPE:PURE",
+ "Force Pure IL Image", "ForcePureILImage", 0},
+ {"CLRImageType", "CLRIMAGETYPE:SAFE",
+ "Force Safe IL Image", "ForceSafeILImage", 0},
+ {"CLRImageType", "",
+ "Default image type", "Default", 0},
+
+ {"SignHash", "CLRSIGNHASH:SHA1",
+ "SHA1", "SHA1", 0},
+ {"SignHash", "CLRSIGNHASH:SHA256",
+ "SHA256", "SHA256", 0},
+ {"SignHash", "CLRSIGNHASH:SHA384",
+ "SHA384", "SHA384", 0},
+ {"SignHash", "CLRSIGNHASH:SHA512",
+ "SHA512", "SHA512", 0},
+
+ {"LinkErrorReporting", "ERRORREPORT:PROMPT",
+ "PromptImmediately", "PromptImmediately", 0},
+ {"LinkErrorReporting", "ERRORREPORT:QUEUE",
+ "Queue For Next Login", "QueueForNextLogin", 0},
+ {"LinkErrorReporting", "ERRORREPORT:SEND",
+ "Send Error Report", "SendErrorReport", 0},
+ {"LinkErrorReporting", "ERRORREPORT:NONE",
+ "No Error Report", "NoErrorReport", 0},
+
+ {"CLRSupportLastError", "CLRSupportLastError",
+ "Enabled", "Enabled", 0},
+ {"CLRSupportLastError", "CLRSupportLastError:NO",
+ "Disabled", "Disabled", 0},
+ {"CLRSupportLastError", "CLRSupportLastError:SYSTEMDLL",
+ "System Dlls Only", "SystemDlls", 0},
+
+
+ //Bool Properties
+ {"LinkIncremental", "INCREMENTAL:NO", "", "false", 0},
+ {"LinkIncremental", "INCREMENTAL", "", "true", 0},
+ {"SuppressStartupBanner", "NOLOGO", "", "true", 0},
+ {"LinkStatus", "LTCG:NOSTATUS", "", "false", 0},
+ {"LinkStatus", "LTCG:STATUS", "", "true", 0},
+ {"PreventDllBinding", "ALLOWBIND:NO", "", "false", 0},
+ {"PreventDllBinding", "ALLOWBIND", "", "true", 0},
+ {"TreatLinkerWarningAsErrors", "WX:NO", "", "false", 0},
+ {"TreatLinkerWarningAsErrors", "WX", "", "true", 0},
+ {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "", "true", 0},
+ {"GenerateManifest", "MANIFEST:NO", "", "false", 0},
+ {"GenerateManifest", "MANIFEST", "", "true", 0},
+ {"AllowIsolation", "ALLOWISOLATION:NO", "", "false", 0},
+ {"UACUIAccess", "uiAccess='false'", "", "false", 0},
+ {"UACUIAccess", "uiAccess='true'", "", "true", 0},
+ {"ManifestEmbed", "manifest:embed", "", "true", 0},
+ {"GenerateDebugInformation", "DEBUG", "", "true", 0},
+ {"MapExports", "MAPINFO:EXPORTS", "", "true", 0},
+ {"AssemblyDebug", "ASSEMBLYDEBUG:DISABLE", "", "false", 0},
+ {"AssemblyDebug", "ASSEMBLYDEBUG", "", "true", 0},
+ {"LargeAddressAware", "LARGEADDRESSAWARE:NO", "", "false", 0},
+ {"LargeAddressAware", "LARGEADDRESSAWARE", "", "true", 0},
+ {"TerminalServerAware", "TSAWARE:NO", "", "false", 0},
+ {"TerminalServerAware", "TSAWARE", "", "true", 0},
+ {"SwapRunFromCD", "SWAPRUN:CD", "", "true", 0},
+ {"SwapRunFromNET", "SWAPRUN:NET", "", "true", 0},
+ {"OptimizeReferences", "OPT:NOREF", "", "false", 0},
+ {"OptimizeReferences", "OPT:REF", "", "true", 0},
+ {"EnableCOMDATFolding", "OPT:NOICF", "", "false", 0},
+ {"EnableCOMDATFolding", "OPT:ICF", "", "true", 0},
+ {"IgnoreEmbeddedIDL", "IGNOREIDL", "", "true", 0},
+ {"AppContainer", "APPCONTAINER", "", "true", 0},
+ {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN:NO", "", "false", 0},
+ {"WindowsMetadataLinkDelaySign", "WINMDDELAYSIGN", "", "true", 0},
+ {"NoEntryPoint", "NOENTRY", "", "true", 0},
+ {"SetChecksum", "RELEASE", "", "true", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE:NO", "", "false", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE", "", "true", 0},
+ {"FixedBaseAddress", "FIXED:NO", "", "false", 0},
+ {"FixedBaseAddress", "FIXED", "", "true", 0},
+ {"DataExecutionPrevention", "NXCOMPAT:NO", "", "false", 0},
+ {"DataExecutionPrevention", "NXCOMPAT", "", "true", 0},
+ {"TurnOffAssemblyGeneration", "NOASSEMBLY", "", "true", 0},
+ {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0},
+ {"SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0},
+ {"Profile", "PROFILE", "", "true", 0},
+ {"LinkDelaySign", "DELAYSIGN:NO", "", "false", 0},
+ {"LinkDelaySign", "DELAYSIGN", "", "true", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
+ {"DetectOneDefinitionRule", "ODR", "", "true", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH", "", "true", 0},
+ {"LinkDLL", "DLL", "", "true", 0},
+
+ //Bool Properties With Argument
+ {"EnableUAC", "MANIFESTUAC:NO", "", "false", 0},
+ {"EnableUAC", "MANIFESTUAC:", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"UACUIAccess", "MANIFESTUAC:", "Enable User Account Control (UAC)", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"GenerateMapFile", "MAP", "", "true",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"MapFileName", "MAP:", "Generate Map File", "",
+ cmVS7FlagTable::UserValueRequired},
+
+ //String List Properties
+ {"AdditionalLibraryDirectories", "LIBPATH:",
+ "Additional Library Directories",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+ {"IgnoreSpecificDefaultLibraries", "NODEFAULTLIB:",
+ "Ignore Specific Default Libraries",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AddModuleNamesToAssembly", "ASSEMBLYMODULE:",
+ "Add Module to Assembly",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"EmbedManagedResourceFile", "ASSEMBLYRESOURCE:",
+ "Embed Managed Resource File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ForceSymbolReferences", "INCLUDE:",
+ "Force Symbol References",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"DelayLoadDLLs", "DELAYLOAD:",
+ "Delay Loaded Dlls",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AssemblyLinkResource", "ASSEMBLYLINKRESOURCE:",
+ "Assembly Link Resource",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"AdditionalManifestDependencies", "MANIFESTDEPENDENCY:",
+ "Additional Manifest Dependencies",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"ManifestInput", "manifestinput:",
+ "Manifest Input",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ //String Properties
+ {"OutputFile", "OUT:",
+ "Output File",
+ "", cmVS7FlagTable::UserValue},
+ {"Version", "VERSION:",
+ "Version",
+ "", cmVS7FlagTable::UserValue},
+ {"SpecifySectionAttributes", "SECTION:",
+ "Specify Section Attributes",
+ "", cmVS7FlagTable::UserValue},
+ {"MSDOSStubFileName", "STUB:",
+ "MS-DOS Stub File Name",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [TrackerLogDirectory] - no command line Switch.
+ {"ModuleDefinitionFile", "DEF:",
+ "Module Definition File",
+ "", cmVS7FlagTable::UserValue},
+ {"ManifestFile", "ManifestFile:",
+ "Manifest File",
+ "", cmVS7FlagTable::UserValue},
+ {"ProgramDatabaseFile", "PDB:",
+ "Generate Program Database File",
+ "", cmVS7FlagTable::UserValue},
+ {"StripPrivateSymbols", "PDBSTRIPPED:",
+ "Strip Private Symbols",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [MapFileName] - no command line Switch.
+ // Skip [MinimumRequiredVersion] - no command line Switch.
+ {"HeapReserveSize", "HEAP:",
+ "Heap Reserve Size",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [HeapCommitSize] - no command line Switch.
+ {"StackReserveSize", "STACK:",
+ "Stack Reserve Size",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [StackCommitSize] - no command line Switch.
+ {"FunctionOrder", "ORDER:@",
+ "Function Order",
+ "", cmVS7FlagTable::UserValue},
+ {"ProfileGuidedDatabase", "PGD:",
+ "Profile Guided Database",
+ "", cmVS7FlagTable::UserValue},
+ {"MidlCommandFile", "MIDL:@",
+ "MIDL Commands",
+ "", cmVS7FlagTable::UserValue},
+ {"MergedIDLBaseFileName", "IDLOUT:",
+ "Merged IDL Base File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"TypeLibraryFile", "TLBOUT:",
+ "Type Library",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataFile", "WINMDFILE:",
+ "Windows Metadata File",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataLinkKeyFile", "WINMDKEYFILE:",
+ "Windows Metadata Key File",
+ "", cmVS7FlagTable::UserValue},
+ {"WindowsMetadataKeyContainer", "WINMDKEYCONTAINER:",
+ "Windows Metadata Key Container",
+ "", cmVS7FlagTable::UserValue},
+ {"EntryPointSymbol", "ENTRY:",
+ "Entry Point",
+ "", cmVS7FlagTable::UserValue},
+ {"BaseAddress", "BASE:",
+ "Base Address",
+ "", cmVS7FlagTable::UserValue},
+ {"ImportLibrary", "IMPLIB:",
+ "Import Library",
+ "", cmVS7FlagTable::UserValue},
+ {"MergeSections", "MERGE:",
+ "Merge Sections",
+ "", cmVS7FlagTable::UserValue},
+ {"LinkKeyFile", "KEYFILE:",
+ "Key File",
+ "", cmVS7FlagTable::UserValue},
+ {"KeyContainer", "KEYCONTAINER:",
+ "Key Container",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14MASMFlagTable.h b/Source/cmVS14MASMFlagTable.h
new file mode 100644
index 0000000..dce846f
--- /dev/null
+++ b/Source/cmVS14MASMFlagTable.h
@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS14MASMFlagTable[] =
+{
+
+ //Enum Properties
+ {"PreserveIdentifierCase", "",
+ "Default", "0", 0},
+ {"PreserveIdentifierCase", "/Cp",
+ "Preserves Identifier Case (/Cp)", "1", 0},
+ {"PreserveIdentifierCase", "/Cu",
+ "Maps all identifiers to upper case. (/Cu)", "2", 0},
+ {"PreserveIdentifierCase", "/Cx",
+ "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+ {"WarningLevel", "/W0",
+ "Warning Level 0 (/W0)", "0", 0},
+ {"WarningLevel", "/W1",
+ "Warning Level 1 (/W1)", "1", 0},
+ {"WarningLevel", "/W2",
+ "Warning Level 2 (/W2)", "2", 0},
+ {"WarningLevel", "/W3",
+ "Warning Level 3 (/W3)", "3", 0},
+
+ {"PackAlignmentBoundary", "",
+ "Default", "0", 0},
+ {"PackAlignmentBoundary", "/Zp1",
+ "One Byte Boundary (/Zp1)", "1", 0},
+ {"PackAlignmentBoundary", "/Zp2",
+ "Two Byte Boundary (/Zp2)", "2", 0},
+ {"PackAlignmentBoundary", "/Zp4",
+ "Four Byte Boundary (/Zp4)", "3", 0},
+ {"PackAlignmentBoundary", "/Zp8",
+ "Eight Byte Boundary (/Zp8)", "4", 0},
+ {"PackAlignmentBoundary", "/Zp16",
+ "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+ {"CallingConvention", "",
+ "Default", "0", 0},
+ {"CallingConvention", "/Gd",
+ "Use C-style Calling Convention (/Gd)", "1", 0},
+ {"CallingConvention", "/Gz",
+ "Use stdcall Calling Convention (/Gz)", "2", 0},
+ {"CallingConvention", "/Gc",
+ "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+ {"ErrorReporting", "/errorReport:prompt",
+ "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+ {"ErrorReporting", "/errorReport:queue",
+ "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+ {"ErrorReporting", "/errorReport:send",
+ "Automatically send report (/errorReport:send)", "2", 0},
+ {"ErrorReporting", "/errorReport:none",
+ "Do not send report (/errorReport:none)", "3", 0},
+
+
+ //Bool Properties
+ {"NoLogo", "/nologo", "", "true", 0},
+ {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+ {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+ {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+ {"AddFirstPassListing", "/Sf", "", "true", 0},
+ {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+ {"DisableSymbolTable", "/Sn", "", "true", 0},
+ {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+ {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+ {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+ {"GenerateDebugInformation", "/Zi", "", "true", 0},
+ {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+ {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+ //Bool Properties With Argument
+
+ //String List Properties
+ {"PreprocessorDefinitions", "/D",
+ "Preprocessor Definitions",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IncludePaths", "/I",
+ "Include Paths",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"BrowseFile", "/FR",
+ "Generate Browse Information File",
+ "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ // Skip [AdditionalDependencies] - no command line Switch.
+
+ //String Properties
+ // Skip [Inputs] - no command line Switch.
+ {"ObjectFileName", "/Fo",
+ "Object File Name",
+ "", cmVS7FlagTable::UserValue},
+ {"AssembledCodeListingFile", "/Fl",
+ "Assembled Code Listing File",
+ "", cmVS7FlagTable::UserValue},
+ // Skip [CommandLineTemplate] - no command line Switch.
+ // Skip [ExecutionDescription] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS14RCFlagTable.h b/Source/cmVS14RCFlagTable.h
new file mode 100644
index 0000000..ebd8d65
--- /dev/null
+++ b/Source/cmVS14RCFlagTable.h
@@ -0,0 +1,7 @@
+static cmVS7FlagTable cmVS14RCFlagTable[] =
+{
+ //Bool Properties
+ {"NullTerminateStrings", "n", "", "true", 0},
+
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 72bb020..26fc317 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -21,48 +21,116 @@
#include "cmLocalVisualStudio7Generator.h"
#include "cmCustomCommandGenerator.h"
#include "cmVS10CLFlagTable.h"
+#include "cmVS10RCFlagTable.h"
#include "cmVS10LinkFlagTable.h"
#include "cmVS10LibFlagTable.h"
+#include "cmVS10MASMFlagTable.h"
#include "cmVS11CLFlagTable.h"
+#include "cmVS11RCFlagTable.h"
#include "cmVS11LinkFlagTable.h"
#include "cmVS11LibFlagTable.h"
+#include "cmVS11MASMFlagTable.h"
#include "cmVS12CLFlagTable.h"
+#include "cmVS12RCFlagTable.h"
#include "cmVS12LinkFlagTable.h"
#include "cmVS12LibFlagTable.h"
+#include "cmVS12MASMFlagTable.h"
+#include "cmVS14CLFlagTable.h"
+#include "cmVS14RCFlagTable.h"
+#include "cmVS14LinkFlagTable.h"
+#include "cmVS14LibFlagTable.h"
+#include "cmVS14MASMFlagTable.h"
#include <cmsys/auto_ptr.hxx>
-static cmVS7FlagTable const*
-cmVSGetCLFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetClFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12CLFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11CLFlagTable; }
- else
- { return cmVS10CLFlagTable; }
+ if(this->MSTools)
+ {
+ cmLocalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmLocalVisualStudioGenerator::VS14)
+ { return cmVS14CLFlagTable; }
+ else if(v >= cmLocalVisualStudioGenerator::VS12)
+ { return cmVS12CLFlagTable; }
+ else if(v == cmLocalVisualStudioGenerator::VS11)
+ { return cmVS11CLFlagTable; }
+ else
+ { return cmVS10CLFlagTable; }
+ }
+ return 0;
}
-static cmVS7FlagTable const*
-cmVSGetLibFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetRcFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12LibFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11LibFlagTable; }
- else
- { return cmVS10LibFlagTable; }
+ if(this->MSTools)
+ {
+ cmLocalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmLocalVisualStudioGenerator::VS14)
+ { return cmVS14RCFlagTable; }
+ else if(v >= cmLocalVisualStudioGenerator::VS12)
+ { return cmVS12RCFlagTable; }
+ else if(v == cmLocalVisualStudioGenerator::VS11)
+ { return cmVS11RCFlagTable; }
+ else
+ { return cmVS10RCFlagTable; }
+ }
+ return 0;
}
-static cmVS7FlagTable const*
-cmVSGetLinkFlagTable(cmLocalVisualStudioGenerator* lg)
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLibFlagTable() const
{
- if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
- { return cmVS12LinkFlagTable; }
- else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
- { return cmVS11LinkFlagTable; }
- else
- { return cmVS10LinkFlagTable; }
+ if(this->MSTools)
+ {
+ cmLocalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmLocalVisualStudioGenerator::VS14)
+ { return cmVS14LibFlagTable; }
+ else if(v >= cmLocalVisualStudioGenerator::VS12)
+ { return cmVS12LibFlagTable; }
+ else if(v == cmLocalVisualStudioGenerator::VS11)
+ { return cmVS11LibFlagTable; }
+ else
+ { return cmVS10LibFlagTable; }
+ }
+ return 0;
+}
+
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLinkFlagTable() const
+{
+ if(this->MSTools)
+ {
+ cmLocalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmLocalVisualStudioGenerator::VS14)
+ { return cmVS14LinkFlagTable; }
+ else if(v >= cmLocalVisualStudioGenerator::VS12)
+ { return cmVS12LinkFlagTable; }
+ else if(v == cmLocalVisualStudioGenerator::VS11)
+ { return cmVS11LinkFlagTable; }
+ else
+ { return cmVS10LinkFlagTable; }
+ }
+ return 0;
+}
+
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetMasmFlagTable() const
+{
+ if(this->MSTools)
+ {
+ cmLocalVisualStudioGenerator::VSVersion
+ v = this->LocalGenerator->GetVersion();
+ if(v >= cmLocalVisualStudioGenerator::VS14)
+ { return cmVS14MASMFlagTable; }
+ else if(v >= cmLocalVisualStudioGenerator::VS12)
+ { return cmVS12MASMFlagTable; }
+ else if(v == cmLocalVisualStudioGenerator::VS11)
+ { return cmVS11MASMFlagTable; }
+ else
+ { return cmVS10MASMFlagTable; }
+ }
+ return 0;
}
static std::string cmVS10EscapeXML(std::string arg)
@@ -112,7 +180,22 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
this->GlobalGenerator->CreateGUID(this->Name.c_str());
this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
this->Platform = gg->GetPlatformName();
+ this->NsightTegra = gg->IsNsightTegra();
+ for(int i =
+ sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
+ &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
+ &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
+ i < 4; ++i)
+ {
+ this->NsightTegraVersion[i] = 0;
+ }
+ this->MSTools = !this->NsightTegra;
+ this->TargetCompileAsWinRT = false;
this->BuildFileStream = 0;
+ this->IsMissingFiles = false;
+ this->DefaultArtifactDir =
+ this->Makefile->GetStartOutputDirectory() + std::string("/") +
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
}
cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -200,6 +283,14 @@ void cmVisualStudio10TargetGenerator::Generate()
{
return;
}
+ if(!this->ComputeRcOptions())
+ {
+ return;
+ }
+ if(!this->ComputeMasmOptions())
+ {
+ return;
+ }
if(!this->ComputeLinkOptions())
{
return;
@@ -230,11 +321,41 @@ void cmVisualStudio10TargetGenerator::Generate()
"xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
this->WriteString(project_defaults.c_str(),0);
+ if(this->NsightTegra)
+ {
+ this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1);
+ if(this->NsightTegraVersion[0] >= 2)
+ {
+ // Nsight Tegra 2.0 uses project revision 8.
+ this->WriteString("<NsightTegraProjectRevisionNumber>"
+ "8"
+ "</NsightTegraProjectRevisionNumber>\n", 2);
+ // Tell newer versions to upgrade silently when loading.
+ this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>"
+ "true"
+ "</NsightTegraUpgradeOnceWithoutPrompt>\n", 2);
+ }
+ else
+ {
+ // Require Nsight Tegra 1.6 for JCompile support.
+ this->WriteString("<NsightTegraProjectRevisionNumber>"
+ "7"
+ "</NsightTegraProjectRevisionNumber>\n", 2);
+ }
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+
this->WriteProjectConfigurations();
this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
this->WriteString("<ProjectGUID>", 2);
(*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGUID>\n";
+ if(this->MSTools && this->Target->GetType() <= cmTarget::GLOBAL_TARGET)
+ {
+ this->WriteApplicationTypeSettings();
+ this->VerifyNecessaryFiles();
+ }
+
const char* vsProjectTypes =
this->Target->GetProperty("VS_GLOBAL_PROJECT_TYPES");
if(vsProjectTypes)
@@ -269,6 +390,11 @@ void cmVisualStudio10TargetGenerator::Generate()
}
}
+ if(this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+ {
+ this->WriteString("<WinMDAssembly>true</WinMDAssembly>\n", 2);
+ }
+
const char* vsGlobalKeyword =
this->Target->GetProperty("VS_GLOBAL_KEYWORD");
if(!vsGlobalKeyword)
@@ -292,19 +418,20 @@ void cmVisualStudio10TargetGenerator::Generate()
}
this->WriteString("<Platform>", 2);
- (*this->BuildFileStream) << this->Platform << "</Platform>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform)
+ << "</Platform>\n";
const char* projLabel = this->Target->GetProperty("PROJECT_LABEL");
if(!projLabel)
{
projLabel = this->Name.c_str();
}
this->WriteString("<ProjectName>", 2);
- (*this->BuildFileStream) << projLabel << "</ProjectName>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(projLabel) << "</ProjectName>\n";
if(const char* targetFrameworkVersion = this->Target->GetProperty(
"VS_DOTNET_TARGET_FRAMEWORK_VERSION"))
{
this->WriteString("<TargetFrameworkVersion>", 2);
- (*this->BuildFileStream) << targetFrameworkVersion
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetFrameworkVersion)
<< "</TargetFrameworkVersion>\n";
}
this->WriteString("</PropertyGroup>\n", 1);
@@ -324,9 +451,10 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1);
this->WriteString("<Import Project=\"" VS10_USER_PROPS "\""
" Condition=\"exists('" VS10_USER_PROPS "')\""
- " Label=\"LocalAppDataPlatform\" />", 2);
+ " Label=\"LocalAppDataPlatform\" />\n", 2);
this->WriteString("</ImportGroup>\n", 1);
this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1);
+ this->WriteWinRTPackageCertificateKeyFile();
this->WritePathAndIncrementalLinkOptions();
this->WriteItemDefinitionGroups();
this->WriteCustomCommands();
@@ -338,6 +466,7 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString(
"<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\""
" />\n", 1);
+ this->WriteTargetSpecificReferences();
this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
if (this->GlobalGenerator->IsMasmEnabled())
{
@@ -417,6 +546,22 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
}
}
+void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences()
+{
+ if(this->MSTools)
+ {
+ if(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0")
+ {
+ this->WriteString(
+ "<Import Project=\""
+ "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v"
+ "$(TargetPlatformVersion)\\Microsoft.Cpp.WindowsPhone."
+ "$(TargetPlatformVersion).targets\" />\n", 1);
+ }
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
{
std::vector<std::string> references;
@@ -425,6 +570,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
{
cmSystemTools::ExpandListArgument(vsWinRTReferences, references);
}
+
+ if(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0" &&
+ references.empty())
+ {
+ references.push_back("platform.winmd");
+ }
if(!references.empty())
{
this->WriteString("<ItemGroup>\n", 1);
@@ -456,7 +608,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations()
this->WriteString("<Configuration>", 3);
(*this->BuildFileStream ) << *i << "</Configuration>\n";
this->WriteString("<Platform>", 3);
- (*this->BuildFileStream) << this->Platform << "</Platform>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform)
+ << "</Platform>\n";
this->WriteString("</ProjectConfiguration>\n", 2);
}
this->WriteString("</ItemGroup>\n", 1);
@@ -464,8 +617,6 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurations()
void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
{
- cmGlobalVisualStudio10Generator* gg =
- static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
std::vector<std::string> *configs =
static_cast<cmGlobalVisualStudio7Generator *>
(this->GlobalGenerator)->GetConfigurations();
@@ -487,12 +638,29 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
configType += "StaticLibrary";
break;
case cmTarget::EXECUTABLE:
- configType += "Application";
+ if(this->NsightTegra &&
+ !this->Target->GetPropertyAsBool("ANDROID_GUI"))
+ {
+ // Android executables are .so too.
+ configType += "DynamicLibrary";
+ }
+ else
+ {
+ configType += "Application";
+ }
break;
case cmTarget::UTILITY:
- configType += "Utility";
- break;
case cmTarget::GLOBAL_TARGET:
+ if(this->NsightTegra)
+ {
+ // Tegra-Android platform does not understand "Utility".
+ configType += "StaticLibrary";
+ }
+ else
+ {
+ configType += "Utility";
+ }
+ break;
case cmTarget::UNKNOWN_LIBRARY:
case cmTarget::INTERFACE_LIBRARY:
break;
@@ -500,55 +668,94 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
configType += "</ConfigurationType>\n";
this->WriteString(configType.c_str(), 2);
- const char* mfcFlag =
- this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG");
- std::string mfcFlagValue = mfcFlag ? mfcFlag : "0";
-
- std::string useOfMfcValue = "false";
- if(mfcFlagValue == "1")
- {
- useOfMfcValue = "Static";
- }
- else if(mfcFlagValue == "2")
- {
- useOfMfcValue = "Dynamic";
- }
- std::string mfcLine = "<UseOfMfc>";
- mfcLine += useOfMfcValue + "</UseOfMfc>\n";
- this->WriteString(mfcLine.c_str(), 2);
-
- if((this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
- this->ClOptions[*i]->UsingUnicode()) ||
- this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
- {
- this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
- }
- else if (this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
- this->ClOptions[*i]->UsingSBCS())
- {
- this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2);
- }
- else
+ if(this->MSTools)
{
- this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2);
+ this->WriteMSToolConfigurationValues(*i);
}
- if(const char* toolset = gg->GetPlatformToolset())
+ else if(this->NsightTegra)
{
- std::string pts = "<PlatformToolset>";
- pts += toolset;
- pts += "</PlatformToolset>\n";
- this->WriteString(pts.c_str(), 2);
- }
- if(this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
- {
- this->WriteString("<WindowsAppContainer>true"
- "</WindowsAppContainer>\n", 2);
+ this->WriteNsightTegraConfigurationValues(*i);
}
this->WriteString("</PropertyGroup>\n", 1);
}
}
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator
+::WriteMSToolConfigurationValues(std::string const& config)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ const char* mfcFlag =
+ this->Target->GetMakefile()->GetDefinition("CMAKE_MFC_FLAG");
+ std::string mfcFlagValue = mfcFlag ? mfcFlag : "0";
+
+ std::string useOfMfcValue = "false";
+ if(mfcFlagValue == "1")
+ {
+ useOfMfcValue = "Static";
+ }
+ else if(mfcFlagValue == "2")
+ {
+ useOfMfcValue = "Dynamic";
+ }
+ std::string mfcLine = "<UseOfMfc>";
+ mfcLine += useOfMfcValue + "</UseOfMfc>\n";
+ this->WriteString(mfcLine.c_str(), 2);
+
+ if((this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
+ this->ClOptions[config]->UsingUnicode()) ||
+ this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
+ this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore() ||
+ this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
+ {
+ this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
+ }
+ else if (this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
+ this->ClOptions[config]->UsingSBCS())
+ {
+ this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2);
+ }
+ else
+ {
+ this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2);
+ }
+ if(const char* toolset = gg->GetPlatformToolset())
+ {
+ std::string pts = "<PlatformToolset>";
+ pts += toolset;
+ pts += "</PlatformToolset>\n";
+ this->WriteString(pts.c_str(), 2);
+ }
+ if(this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
+ this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
+ {
+ this->WriteString("<WindowsAppContainer>true"
+ "</WindowsAppContainer>\n", 2);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator
+::WriteNsightTegraConfigurationValues(std::string const&)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+ const char* toolset = gg->GetPlatformToolset();
+ std::string ntv = "<NdkToolchainVersion>";
+ ntv += toolset? toolset : "Default";
+ ntv += "</NdkToolchainVersion>\n";
+ this->WriteString(ntv.c_str(), 2);
+ if(const char* api = this->Target->GetProperty("ANDROID_API"))
+ {
+ this->WriteString("<AndroidTargetAPI>", 2);
+ (*this->BuildFileStream ) <<
+ "android-" << cmVS10EscapeXML(api) << "</AndroidTargetAPI>\n";
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
{
this->SourcesVisited.clear();
@@ -639,7 +846,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
(*this->BuildFileStream ) << script << "</Command>\n";
this->WritePlatformConfigTag("AdditionalInputs", i->c_str(), 3);
- (*this->BuildFileStream ) << source->GetFullPath();
+ (*this->BuildFileStream ) << cmVS10EscapeXML(source->GetFullPath());
for(std::vector<std::string>::const_iterator d =
ccg.GetDepends().begin();
d != ccg.GetDepends().end();
@@ -649,7 +856,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
if(this->LocalGenerator->GetRealDependency(d->c_str(), i->c_str(), dep))
{
this->ConvertToWindowsSlash(dep);
- (*this->BuildFileStream ) << ";" << dep;
+ (*this->BuildFileStream ) << ";" << cmVS10EscapeXML(dep);
}
}
(*this->BuildFileStream ) << ";%(AdditionalInputs)</AdditionalInputs>\n";
@@ -662,7 +869,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
{
std::string out = *o;
this->ConvertToWindowsSlash(out);
- (*this->BuildFileStream ) << sep << out;
+ (*this->BuildFileStream ) << sep << cmVS10EscapeXML(out);
sep = ";";
}
(*this->BuildFileStream ) << "</Outputs>\n";
@@ -752,6 +959,49 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups);
}
+ // Added files are images and the manifest.
+ if (!this->AddedFiles.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::vector<std::string>::const_iterator
+ oi = this->AddedFiles.begin(); oi != this->AddedFiles.end(); ++oi)
+ {
+ std::string fileName = cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameName(*oi));
+ if (fileName == "wmappmanifest.xml")
+ {
+ this->WriteString("<XML Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</XML>\n", 2);
+ }
+ else if(cmSystemTools::GetFilenameExtension(fileName) ==
+ ".appxmanifest")
+ {
+ this->WriteString("<AppxManifest Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</AppxManifest>\n", 2);
+ }
+ else if(cmSystemTools::GetFilenameExtension(fileName) ==
+ ".pfx")
+ {
+ this->WriteString("<None Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</None>\n", 2);
+ }
+ else
+ {
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << *oi << "\">\n";
+ this->WriteString("<Filter>Resource Files</Filter>\n", 3);
+ this->WriteString("</Image>\n", 2);
+ }
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+
std::vector<cmSourceFile const*> resxObjs;
this->GeneratorTarget->GetResxSources(resxObjs, "");
if(!resxObjs.empty())
@@ -763,7 +1013,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string obj = (*oi)->GetFullPath();
this->WriteString("<EmbeddedResource Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\">\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\">\n";
this->WriteString("<Filter>Resource Files</Filter>\n", 3);
this->WriteString("</EmbeddedResource>\n", 2);
}
@@ -782,7 +1032,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string obj = *oi;
this->WriteString("<Object Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\">\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\">\n";
this->WriteString("<Filter>Object Libraries</Filter>\n", 3);
this->WriteString("</Object>\n", 2);
}
@@ -825,7 +1075,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteString("</Filter>\n", 2);
}
- if(!resxObjs.empty())
+ if(!resxObjs.empty() || !this->AddedFiles.empty())
{
this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
std::string guidName = "SG_Filter_Resource Files";
@@ -917,7 +1167,7 @@ WriteGroupSources(const char* name,
std::string path = this->ConvertPath(source, s->RelativePath);
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << name << " Include=\""
- << path;
+ << cmVS10EscapeXML(path);
if(strlen(filter))
{
(*this->BuildFileStream) << "\">\n";
@@ -934,8 +1184,129 @@ WriteGroupSources(const char* name,
this->WriteString("</ItemGroup>\n", 1);
}
+void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
+{
+ if(this->IsResxHeader(sf->GetFullPath()))
+ {
+ this->WriteSource("ClInclude", sf, ">\n");
+ this->WriteString("<FileType>CppForm</FileType>\n", 3);
+ this->WriteString("</ClInclude>\n", 2);
+ }
+ else
+ {
+ this->WriteSource("ClInclude", sf);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
+{
+ bool toolHasSettings = false;
+ std::string tool = "None";
+ std::string shaderType;
+ std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ if(ext == "hlsl")
+ {
+ tool = "FXCompile";
+ // Figure out the type of shader compiler to use.
+ if(const char* st = sf->GetProperty("VS_SHADER_TYPE"))
+ {
+ shaderType = st;
+ toolHasSettings = true;
+ }
+ }
+ else if(ext == "jpg" ||
+ ext == "png")
+ {
+ tool = "Image";
+ }
+ else if(ext == "xml")
+ {
+ tool = "XML";
+ }
+ if(this->NsightTegra)
+ {
+ // Nsight Tegra needs specific file types to check up-to-dateness.
+ std::string name =
+ cmSystemTools::LowerCase(sf->GetLocation().GetName());
+ if(name == "androidmanifest.xml" ||
+ name == "build.xml" ||
+ name == "proguard.cfg" ||
+ name == "proguard-project.txt" ||
+ ext == "properties")
+ {
+ tool = "AndroidBuild";
+ }
+ else if(ext == "java")
+ {
+ tool = "JCompile";
+ }
+ else if(ext == "asm" || ext == "s")
+ {
+ tool = "ClCompile";
+ }
+ }
+
+ std::string deployContent;
+ if(this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
+ if(content && *content)
+ {
+ toolHasSettings = true;
+ deployContent = content;
+ }
+ }
+
+ if(toolHasSettings)
+ {
+ this->WriteSource(tool, sf, ">\n");
+
+ if(!deployContent.empty())
+ {
+ std::vector<std::string> const* configs =
+ this->GlobalGenerator->GetConfigurations();
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(deployContent);
+ for(size_t i = 0; i != configs->size(); ++i)
+ {
+ if(0 == strcmp(cge->Evaluate(this->Makefile, (*configs)[i]), "1"))
+ {
+ this->WriteString("<DeploymentContent Condition=\""
+ "'$(Configuration)|$(Platform)'=='", 3);
+ (*this->BuildFileStream) << (*configs)[i] << "|"
+ << this->Platform << "'\">true";
+ this->WriteString("</DeploymentContent>\n", 0);
+ }
+ else
+ {
+ this->WriteString("<ExcludedFromBuild Condition=\""
+ "'$(Configuration)|$(Platform)'=='", 3);
+ (*this->BuildFileStream) << (*configs)[i] << "|"
+ << this->Platform << "'\">true";
+ this->WriteString("</ExcludedFromBuild>\n", 0);
+ }
+ }
+ }
+ if(!shaderType.empty())
+ {
+ this->WriteString("<ShaderType>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(shaderType)
+ << "</ShaderType>\n";
+ }
+
+ this->WriteString("</", 2);
+ (*this->BuildFileStream) << tool << ">\n";
+ }
+ else
+ {
+ this->WriteSource(tool, sf);
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteSource(
- const char* tool, cmSourceFile const* sf, const char* end)
+ std::string const& tool, cmSourceFile const* sf, const char* end)
{
// Visual Studio tools append relative paths to the current dir, as in:
//
@@ -972,26 +1343,16 @@ void cmVisualStudio10TargetGenerator::WriteSource(
}
this->ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
- (*this->BuildFileStream ) << tool << " Include=\"" << sourceFile << "\"";
-
- if(sf->GetExtension() == "h" &&
- this->IsResxHeader(sf->GetFullPath()))
- {
- (*this->BuildFileStream ) << ">\n";
- this->WriteString("<FileType>CppForm</FileType>\n", 3);
- this->WriteString("</ClInclude>\n", 2);
- }
- else
- {
- (*this->BuildFileStream ) << (end? end : " />\n");
- }
+ (*this->BuildFileStream ) << tool << " Include=\""
+ << cmVS10EscapeXML(sourceFile) << "\""
+ << (end? end : " />\n");
ToolSource toolSource = {sf, forceRelative};
this->Tools[tool].push_back(toolSource);
}
void cmVisualStudio10TargetGenerator::WriteSources(
- const char* tool, std::vector<cmSourceFile const*> const& sources)
+ std::string const& tool, std::vector<cmSourceFile const*> const& sources)
{
for(std::vector<cmSourceFile const*>::const_iterator
si = sources.begin(); si != sources.end(); ++si)
@@ -1010,7 +1371,11 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmSourceFile const*> headerSources;
this->GeneratorTarget->GetHeaderSources(headerSources, "");
- this->WriteSources("ClInclude", headerSources);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = headerSources.begin(); si != headerSources.end(); ++si)
+ {
+ this->WriteHeaderSource(*si);
+ }
std::vector<cmSourceFile const*> idlSources;
this->GeneratorTarget->GetIDLSources(idlSources, "");
this->WriteSources("Midl", idlSources);
@@ -1022,12 +1387,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
si != objectSources.end(); ++si)
{
const std::string& lang = (*si)->GetLanguage();
- const char* tool = NULL;
+ std::string tool;
if (lang == "C"|| lang == "CXX")
{
tool = "ClCompile";
}
- else if (lang == "ASM_NASM" &&
+ else if (lang == "ASM_MASM" &&
this->GlobalGenerator->IsMasmEnabled())
{
tool = "MASM";
@@ -1037,7 +1402,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
tool = "ResourceCompile";
}
- if (tool)
+ if (!tool.empty())
{
this->WriteSource(tool, *si, " ");
if (this->OutputSourceSpecificFlags(*si))
@@ -1056,6 +1421,14 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
}
}
+ std::vector<cmSourceFile const*> manifestSources;
+ this->GeneratorTarget->GetAppManifest(manifestSources, "");
+ this->WriteSources("AppxManifest", manifestSources);
+
+ std::vector<cmSourceFile const*> certificateSources;
+ this->GeneratorTarget->GetCertificates(certificateSources, "");
+ this->WriteSources("None", certificateSources);
+
std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects, "");
for(std::vector<cmSourceFile const*>::iterator
@@ -1093,7 +1466,11 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmSourceFile const*> extraSources;
this->GeneratorTarget->GetExtraSources(extraSources, "");
- this->WriteSources("None", extraSources);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ si = extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ this->WriteExtraSource(*si);
+ }
// Add object library contents as external objects.
std::vector<std::string> objs;
@@ -1104,7 +1481,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::string obj = *oi;
this->WriteString("<Object Include=\"", 2);
this->ConvertToWindowsSlash(obj);
- (*this->BuildFileStream ) << obj << "\" />\n";
+ (*this->BuildFileStream ) << cmVS10EscapeXML(obj) << "\" />\n";
+ }
+
+ if (this->IsMissingFiles)
+ {
+ this->WriteMissingFiles();
}
this->WriteString("</ItemGroup>\n", 1);
@@ -1144,19 +1526,21 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
// if the source file does not match the linker language
// then force c or c++
+ const char* compileAs = 0;
if(needForceLang || (linkLanguage != lang))
{
if(lang == "CXX")
{
// force a C++ file type
- flags += " /TP ";
+ compileAs = "CompileAsCpp";
}
else if(lang == "C")
{
// force to c
- flags += " /TC ";
+ compileAs = "CompileAsC";
}
}
+ bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
bool hasFlags = false;
// for the first time we need a new line if there is something
// produced here.
@@ -1190,7 +1574,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
// if we have flags or defines for this config then
// use them
- if(flags.size() || configDefines.size())
+ if(!flags.empty() || !configDefines.empty() || compileAs || noWinRT)
{
(*this->BuildFileStream ) << firstString;
firstString = ""; // only do firstString once
@@ -1198,8 +1582,21 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmVisualStudioGeneratorOptions
clOptions(this->LocalGenerator,
cmVisualStudioGeneratorOptions::Compiler,
- cmVSGetCLFlagTable(this->LocalGenerator), 0, this);
+ this->GetClFlagTable(), 0, this);
+ if(compileAs)
+ {
+ clOptions.AddFlag("CompileAs", compileAs);
+ }
+ if(noWinRT)
+ {
+ clOptions.AddFlag("CompileAsWinRT", "false");
+ }
clOptions.Parse(flags.c_str());
+ if(clOptions.HasFlag("AdditionalIncludeDirectories"))
+ {
+ clOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
+ }
clOptions.AddDefines(configDefines.c_str());
clOptions.SetConfiguration((*config).c_str());
clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
@@ -1260,23 +1657,28 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
this->ConvertToWindowsSlash(outDir);
this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
- *this->BuildFileStream << outDir
+ *this->BuildFileStream << cmVS10EscapeXML(outDir)
<< "</OutDir>\n";
this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
- *this->BuildFileStream << intermediateDir
+ *this->BuildFileStream << cmVS10EscapeXML(intermediateDir)
<< "</IntDir>\n";
+ std::string name =
+ cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
this->WritePlatformConfigTag("TargetName", config->c_str(), 3);
- *this->BuildFileStream
- << cmSystemTools::GetFilenameWithoutLastExtension(
- targetNameFull.c_str())
- << "</TargetName>\n";
+ *this->BuildFileStream << cmVS10EscapeXML(name) << "</TargetName>\n";
+ std::string ext =
+ cmSystemTools::GetFilenameLastExtension(targetNameFull);
+ if(ext.empty())
+ {
+ // An empty TargetExt causes a default extension to be used.
+ // A single "." appears to be treated as an empty extension.
+ ext = ".";
+ }
this->WritePlatformConfigTag("TargetExt", config->c_str(), 3);
- *this->BuildFileStream
- << cmSystemTools::GetFilenameLastExtension(targetNameFull.c_str())
- << "</TargetExt>\n";
+ *this->BuildFileStream << cmVS10EscapeXML(ext) << "</TargetExt>\n";
this->OutputLinkIncremental(*config);
}
@@ -1290,6 +1692,10 @@ void
cmVisualStudio10TargetGenerator::
OutputLinkIncremental(std::string const& configName)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
// static libraries and things greater than modules do not need
// to set this option
if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
@@ -1355,62 +1761,64 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
cmsys::auto_ptr<Options> pOptions(
new Options(this->LocalGenerator, Options::Compiler,
- cmVSGetCLFlagTable(this->LocalGenerator)));
+ this->GetClFlagTable()));
Options& clOptions = *pOptions;
std::string flags;
- // collect up flags for
- if(this->Target->GetType() < cmTarget::UTILITY)
+ const std::string& linkLanguage =
+ this->Target->GetLinkerLanguage(configName.c_str());
+ if(linkLanguage.empty())
{
- const std::string& linkLanguage =
- this->Target->GetLinkerLanguage(configName.c_str());
- if(linkLanguage.empty())
- {
- cmSystemTools::Error
- ("CMake can not determine linker language for target: ",
- this->Name.c_str());
- return false;
- }
- if(linkLanguage == "C" || linkLanguage == "CXX"
- || linkLanguage == "Fortran")
- {
- std::string baseFlagVar = "CMAKE_";
- baseFlagVar += linkLanguage;
- baseFlagVar += "_FLAGS";
- flags = this->
- Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
- std::string flagVar = baseFlagVar + std::string("_") +
- cmSystemTools::UpperCase(configName);
- flags += " ";
- flags += this->
- Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
- }
- // set the correct language
- if(linkLanguage == "C")
- {
- flags += " /TC ";
- }
- if(linkLanguage == "CXX")
- {
- flags += " /TP ";
- }
- this->LocalGenerator->AddCompileOptions(flags, this->Target,
- linkLanguage, configName.c_str());
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target: ",
+ this->Name.c_str());
+ return false;
+ }
+ if(linkLanguage == "C" || linkLanguage == "CXX"
+ || linkLanguage == "Fortran")
+ {
+ std::string baseFlagVar = "CMAKE_";
+ baseFlagVar += linkLanguage;
+ baseFlagVar += "_FLAGS";
+ flags = this->
+ Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
+ std::string flagVar = baseFlagVar + std::string("_") +
+ cmSystemTools::UpperCase(configName);
+ flags += " ";
+ flags += this->
+ Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
}
+ // set the correct language
+ if(linkLanguage == "C")
+ {
+ clOptions.AddFlag("CompileAs", "CompileAsC");
+ }
+ if(linkLanguage == "CXX")
+ {
+ clOptions.AddFlag("CompileAs", "CompileAsCpp");
+ }
+ this->LocalGenerator->AddCompileOptions(flags, this->Target,
+ linkLanguage, configName.c_str());
// Get preprocessor definitions for this directory.
std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
- clOptions.FixExceptionHandlingDefault();
- clOptions.AddFlag("PrecompiledHeader", "NotUsing");
- std::string asmLocation = configName + "/";
- clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ if(this->MSTools)
+ {
+ clOptions.FixExceptionHandlingDefault();
+ clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ std::string asmLocation = configName + "/";
+ clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ }
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
this->Target->GetCompileDefinitions(targetDefines, configName.c_str());
clOptions.AddDefines(targetDefines);
- clOptions.SetVerboseMakefile(
- this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+ if(this->MSTools)
+ {
+ clOptions.SetVerboseMakefile(
+ this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+ }
// Add a definition for the configuration name.
std::string configDefine = "CMAKE_INTDIR=\"";
@@ -1422,6 +1830,36 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.AddDefine(exportMacro);
}
+ if (this->MSTools)
+ {
+ // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT.
+ if (this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+ {
+ clOptions.AddFlag("CompileAsWinRT", "true");
+ // For WinRT components, add the _WINRT_DLL define to produce a lib
+ if (this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->Target->GetType() == cmTarget::MODULE_LIBRARY )
+ {
+ clOptions.AddDefine("_WINRT_DLL");
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore() ||
+ this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (!clOptions.IsWinRt())
+ {
+ clOptions.AddFlag("CompileAsWinRT", "false");
+ }
+ }
+ if(const char* winRT = clOptions.GetFlag("CompileAsWinRT"))
+ {
+ if(cmSystemTools::IsOn(winRT))
+ {
+ this->TargetCompileAsWinRT = true;
+ }
+ }
+ }
+
this->ClOptions[configName] = pOptions.release();
return true;
}
@@ -1434,63 +1872,166 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
Options& clOptions = *(this->ClOptions[configName]);
this->WriteString("<ClCompile>\n", 2);
clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
- this->OutputIncludes(includes);
+ clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ clOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
-
- // If not in debug mode, write the DebugInformationFormat field
- // without value so PDBs don't get generated uselessly.
- if(!clOptions.IsDebug())
- {
- this->WriteString("<DebugInformationFormat>"
- "</DebugInformationFormat>\n", 3);
- }
-
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
"\n", "CXX");
- this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
- // Specify the compiler program database file if configured.
- std::string pdb = this->Target->GetCompilePDBPath(configName.c_str());
- if(!pdb.empty())
+ if(this->MSTools)
{
- this->ConvertToWindowsSlash(pdb);
- this->WriteString("<ProgramDataBaseFileName>", 3);
- *this->BuildFileStream << cmVS10EscapeXML(pdb)
- << "</ProgramDataBaseFileName>\n";
+ this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
+
+ // If not in debug mode, write the DebugInformationFormat field
+ // without value so PDBs don't get generated uselessly.
+ if(!clOptions.IsDebug())
+ {
+ this->WriteString("<DebugInformationFormat>"
+ "</DebugInformationFormat>\n", 3);
+ }
+
+ // Specify the compiler program database file if configured.
+ std::string pdb = this->Target->GetCompilePDBPath(configName.c_str());
+ if(!pdb.empty())
+ {
+ this->ConvertToWindowsSlash(pdb);
+ this->WriteString("<ProgramDataBaseFileName>", 3);
+ *this->BuildFileStream << cmVS10EscapeXML(pdb)
+ << "</ProgramDataBaseFileName>\n";
+ }
}
this->WriteString("</ClCompile>\n", 2);
}
-void cmVisualStudio10TargetGenerator::
-OutputIncludes(std::vector<std::string> const & includes)
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeRcOptions()
{
- this->WriteString("<AdditionalIncludeDirectories>", 3);
- for(std::vector<std::string>::const_iterator i = includes.begin();
- i != includes.end(); ++i)
+ std::vector<std::string> const* configs =
+ this->GlobalGenerator->GetConfigurations();
+ for(std::vector<std::string>::const_iterator i = configs->begin();
+ i != configs->end(); ++i)
{
- std::string incDir = *i;
- this->ConvertToWindowsSlash(incDir);
- *this->BuildFileStream << cmVS10EscapeXML(incDir) << ";";
+ if(!this->ComputeRcOptions(*i))
+ {
+ return false;
+ }
}
- this->WriteString("%(AdditionalIncludeDirectories)"
- "</AdditionalIncludeDirectories>\n", 0);
+ return true;
}
-
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
+ std::string const& configName)
+{
+ cmsys::auto_ptr<Options> pOptions(
+ new Options(this->LocalGenerator, Options::ResourceCompiler,
+ this->GetRcFlagTable()));
+ Options& rcOptions = *pOptions;
+
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ std::string rcConfigFlagsVar = std::string("CMAKE_RC_FLAGS_") + CONFIG;
+ std::string flags =
+ std::string(this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS")) +
+ std::string(" ") +
+ std::string(this->Makefile->GetSafeDefinition(rcConfigFlagsVar));
+
+ rcOptions.Parse(flags.c_str());
+ this->RcOptions[configName] = pOptions.release();
+ return true;
+}
void cmVisualStudio10TargetGenerator::
WriteRCOptions(std::string const& configName,
std::vector<std::string> const & includes)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
this->WriteString("<ResourceCompile>\n", 2);
+
+ // Preprocessor definitions and includes are shared with clOptions.
Options& clOptions = *(this->ClOptions[configName]);
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
"\n", "RC");
- this->OutputIncludes(includes);
+
+ Options& rcOptions = *(this->RcOptions[configName]);
+ rcOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+ rcOptions.AppendFlag("AdditionalIncludeDirectories",
+ "%(AdditionalIncludeDirectories)");
+ rcOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ rcOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+
this->WriteString("</ResourceCompile>\n", 2);
}
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
+{
+ if(!this->GlobalGenerator->IsMasmEnabled())
+ {
+ return true;
+ }
+ std::vector<std::string> const* configs =
+ this->GlobalGenerator->GetConfigurations();
+ for(std::vector<std::string>::const_iterator i = configs->begin();
+ i != configs->end(); ++i)
+ {
+ if(!this->ComputeMasmOptions(*i))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
+ std::string const& configName)
+{
+ cmsys::auto_ptr<Options> pOptions(
+ new Options(this->LocalGenerator, Options::MasmCompiler,
+ this->GetMasmFlagTable()));
+ Options& masmOptions = *pOptions;
+
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG;
+ std::string flags =
+ std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS")) +
+ std::string(" ") +
+ std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
+
+ masmOptions.Parse(flags.c_str());
+ this->MasmOptions[configName] = pOptions.release();
+ return true;
+}
+
+void cmVisualStudio10TargetGenerator::
+WriteMasmOptions(std::string const& configName,
+ std::vector<std::string> const& includes)
+{
+ if(!this->MSTools || !this->GlobalGenerator->IsMasmEnabled())
+ {
+ return;
+ }
+ this->WriteString("<MASM>\n", 2);
+
+ // Preprocessor definitions and includes are shared with clOptions.
+ Options& clOptions = *(this->ClOptions[configName]);
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "ASM_MASM");
+
+ Options& masmOptions = *(this->MasmOptions[configName]);
+ masmOptions.AppendFlag("IncludePaths", includes);
+ masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)");
+ masmOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ masmOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+
+ this->WriteString("</MASM>\n", 2);
+}
+
void
cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
@@ -1508,12 +2049,68 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
cmVisualStudioGeneratorOptions
libOptions(this->LocalGenerator,
cmVisualStudioGeneratorOptions::Linker,
- cmVSGetLibFlagTable(this->LocalGenerator), 0, this);
+ this->GetLibFlagTable(), 0, this);
libOptions.Parse(libflags.c_str());
libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
libOptions.OutputFlagMap(*this->BuildFileStream, " ");
this->WriteString("</Lib>\n", 2);
}
+
+ // We cannot generate metadata for static libraries. WindowsPhone
+ // and WindowsStore tools look at GenerateWindowsMetadata in the
+ // Link tool options even for static libraries.
+ if(this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ this->WriteString("<Link>\n", 2);
+ this->WriteString("<GenerateWindowsMetadata>false"
+ "</GenerateWindowsMetadata>\n", 3);
+ this->WriteString("</Link>\n", 2);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
+ std::string const&)
+{
+ // Look through the sources for AndroidManifest.xml and use
+ // its location as the root source directory.
+ std::string rootDir = this->Makefile->GetCurrentDirectory();
+ {
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, "");
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ if("androidmanifest.xml" == cmSystemTools::LowerCase(
+ (*si)->GetLocation().GetName()))
+ {
+ rootDir = (*si)->GetLocation().GetDirectory();
+ break;
+ }
+ }
+ }
+
+ // Tell MSBuild to launch Ant.
+ {
+ std::string antBuildPath = rootDir;
+ this->WriteString("<AntBuild>\n", 2);
+ this->WriteString("<AntBuildPath>", 3);
+ this->ConvertToWindowsSlash(antBuildPath);
+ (*this->BuildFileStream) <<
+ cmVS10EscapeXML(antBuildPath) << "</AntBuildPath>\n";
+ }
+
+ {
+ std::string manifest_xml = rootDir + "/AndroidManifest.xml";
+ this->ConvertToWindowsSlash(manifest_xml);
+ this->WriteString("<AndroidManifestLocation>", 3);
+ (*this->BuildFileStream) <<
+ cmVS10EscapeXML(manifest_xml) << "</AndroidManifestLocation>\n";
+ }
+
+ this->WriteString("</AntBuild>\n", 2);
}
//----------------------------------------------------------------------------
@@ -1543,7 +2140,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
{
cmsys::auto_ptr<Options> pOptions(
new Options(this->LocalGenerator, Options::Linker,
- cmVSGetLinkFlagTable(this->LocalGenerator), 0, this));
+ this->GetLinkFlagTable(), 0, this));
Options& linkOptions = *pOptions;
const std::string& linkLanguage =
@@ -1567,16 +2164,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
{
linkType = "EXE";
}
- std::string stackVar = "CMAKE_";
- stackVar += linkLanguage;
- stackVar += "_STACK_SIZE";
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
std::string flags;
- if(stackVal)
- {
- flags += " /STACK:";
- flags += stackVal;
- }
std::string linkFlagVarBase = "CMAKE_";
linkFlagVarBase += linkType;
linkFlagVarBase += "_LINKER_FLAGS";
@@ -1600,14 +2188,6 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
flags += " ";
flags += flagsConfig;
}
- if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
- {
- linkOptions.AddFlag("SubSystem", "Windows");
- }
- else
- {
- linkOptions.AddFlag("SubSystem", "Console");
- }
std::string standardLibsVar = "CMAKE_";
standardLibsVar += linkLanguage;
standardLibsVar += "_STANDARD_LIBRARIES";
@@ -1628,6 +2208,9 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
}
// Replace spaces in libs with ;
cmSystemTools::ReplaceString(libs, " ", ";");
+ std::vector<std::string> libVec;
+ cmSystemTools::ExpandListArgument(libs, libVec);
+
cmComputeLinkInformation* pcli =
this->Target->GetLinkInformation(config.c_str());
if(!pcli)
@@ -1639,37 +2222,22 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
}
// add the libraries for the target to libs string
cmComputeLinkInformation& cli = *pcli;
- this->AddLibraries(cli, libs);
- linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
+ this->AddLibraries(cli, libVec);
+ linkOptions.AddFlag("AdditionalDependencies", libVec);
std::vector<std::string> const& ldirs = cli.GetDirectories();
- const char* sep = "";
- std::string linkDirs;
+ std::vector<std::string> linkDirs;
for(std::vector<std::string>::const_iterator d = ldirs.begin();
d != ldirs.end(); ++d)
{
// first just full path
- linkDirs += sep;
- linkDirs += *d;
- sep = ";";
- linkDirs += sep;
+ linkDirs.push_back(*d);
// next path with configuration type Debug, Release, etc
- linkDirs += *d;
- linkDirs += "/$(Configuration)";
- linkDirs += sep;
- }
- linkDirs += "%(AdditionalLibraryDirectories)";
- linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs.c_str());
- linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
- linkOptions.AddFlag("Version", "");
- if(linkOptions.IsDebug() || flags.find("/debug") != flags.npos)
- {
- linkOptions.AddFlag("GenerateDebugInformation", "true");
- }
- else
- {
- linkOptions.AddFlag("GenerateDebugInformation", "false");
+ linkDirs.push_back(*d + "/$(Configuration)");
}
+ linkDirs.push_back("%(AdditionalLibraryDirectories)");
+ linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs);
+
std::string targetName;
std::string targetNameSO;
std::string targetNameFull;
@@ -1688,20 +2256,103 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
config.c_str());
}
- std::string pdb = this->Target->GetPDBDirectory(config.c_str());
- pdb += "/";
- pdb += targetNamePDB;
- std::string imLib = this->Target->GetDirectory(config.c_str(), true);
- imLib += "/";
- imLib += targetNameImport;
+ if(this->MSTools)
+ {
+ linkOptions.AddFlag("Version", "");
+
+ if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ if (this->GlobalGenerator->TargetsWindowsCE())
+ {
+ linkOptions.AddFlag("SubSystem", "WindowsCE");
+ if (this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup");
+ }
+ }
+ else
+ {
+ linkOptions.AddFlag("SubSystem", "Windows");
+ }
+ }
+ else
+ {
+ if (this->GlobalGenerator->TargetsWindowsCE())
+ {
+ linkOptions.AddFlag("SubSystem", "WindowsCE");
+ if (this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup");
+ }
+ }
+ else
+ {
+ linkOptions.AddFlag("SubSystem", "Console");
+ };
+ }
+
+ if(const char* stackVal =
+ this->Makefile->GetDefinition("CMAKE_"+linkLanguage+"_STACK_SIZE"))
+ {
+ linkOptions.AddFlag("StackReserveSize", stackVal);
+ }
+
+ if(linkOptions.IsDebug() || flags.find("/debug") != flags.npos)
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "true");
+ }
+ else
+ {
+ linkOptions.AddFlag("GenerateDebugInformation", "false");
+ }
+ std::string pdb = this->Target->GetPDBDirectory(config.c_str());
+ pdb += "/";
+ pdb += targetNamePDB;
+ std::string imLib = this->Target->GetDirectory(config.c_str(), true);
+ imLib += "/";
+ imLib += targetNameImport;
+
+ linkOptions.AddFlag("ImportLibrary", imLib.c_str());
+ linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
+
+ // A Windows Runtime component uses internal .NET metadata,
+ // so does not have an import library.
+ if(this->Target->GetPropertyAsBool("VS_WINRT_COMPONENT"))
+ {
+ linkOptions.AddFlag("GenerateWindowsMetadata", "true");
+ }
+ else if (this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->GlobalGenerator->TargetsWindowsStore())
+ {
+ // WindowsPhone and WindowsStore components are in an app container
+ // and produce WindowsMetadata. If we are not producing a WINRT
+ // component, then do not generate the metadata here.
+ linkOptions.AddFlag("GenerateWindowsMetadata", "false");
+ }
+
+ if (this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0")
+ {
+ // WindowsPhone 8.0 does not have ole32.
+ linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", "ole32.lib");
+ }
+ }
+ else if(this->NsightTegra)
+ {
+ linkOptions.AddFlag("SoName", targetNameSO.c_str());
+ }
- linkOptions.AddFlag("ImportLibrary", imLib.c_str());
- linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
linkOptions.Parse(flags.c_str());
- std::string def = this->GeneratorTarget->GetModuleDefinitionFile("");
- if(!def.empty())
+
+ if(this->MSTools)
{
- linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
+ std::string def = this->GeneratorTarget->GetModuleDefinitionFile("");
+ if(!def.empty())
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
+ }
+ linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries",
+ "%(IgnoreSpecificDefaultLibraries)");
}
this->LinkOptions[config] = pOptions.release();
@@ -1735,11 +2386,10 @@ cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
void cmVisualStudio10TargetGenerator::AddLibraries(
cmComputeLinkInformation& cli,
- std::string& libstring)
+ std::vector<std::string>& libVec)
{
typedef cmComputeLinkInformation::ItemVector ItemVector;
ItemVector libs = cli.GetItems();
- const char* sep = ";";
for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
{
if(l->IsPath)
@@ -1749,14 +2399,12 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::UNCHANGED);
this->ConvertToWindowsSlash(path);
- libstring += sep;
- libstring += path;
+ libVec.push_back(path);
}
else if (!l->Target
|| l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
- libstring += sep;
- libstring += l->Value;
+ libVec.push_back(l->Value);
}
}
}
@@ -1766,6 +2414,11 @@ void cmVisualStudio10TargetGenerator::
WriteMidlOptions(std::string const& /*config*/,
std::vector<std::string> const & includes)
{
+ if(!this->MSTools)
+ {
+ return;
+ }
+
// This processes *any* of the .idl files specified in the project's file
// list (and passed as the item metadata %(Filename) expressing the rule
// input filename) into output files at the per-config *build* dir
@@ -1782,7 +2435,14 @@ WriteMidlOptions(std::string const& /*config*/,
// only). Perhaps there's something to be done to make this more automatic
// on the CMake side?
this->WriteString("<Midl>\n", 2);
- this->OutputIncludes(includes);
+ this->WriteString("<AdditionalIncludeDirectories>", 3);
+ for(std::vector<std::string>::const_iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ *this->BuildFileStream << cmVS10EscapeXML(*i) << ";";
+ }
+ this->WriteString("%(AdditionalIncludeDirectories)"
+ "</AdditionalIncludeDirectories>\n", 0);
this->WriteString("<OutputDirectory>$(IntDir)</OutputDirectory>\n", 3);
this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3);
this->WriteString(
@@ -1807,6 +2467,11 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->LocalGenerator->GetIncludeDirectories(includes,
this->GeneratorTarget,
"C", i->c_str());
+ for(std::vector<std::string>::iterator ii = includes.begin();
+ ii != includes.end(); ++ii)
+ {
+ this->ConvertToWindowsSlash(*ii);
+ }
this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
*this->BuildFileStream << "\n";
// output cl compile flags <ClCompile></ClCompile>
@@ -1815,6 +2480,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WriteClOptions(*i, includes);
// output rc compile flags <ResourceCompile></ResourceCompile>
this->WriteRCOptions(*i, includes);
+ this->WriteMasmOptions(*i, includes);
}
// output midl flags <Midl></Midl>
this->WriteMidlOptions(*i, includes);
@@ -1824,6 +2490,12 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WriteLinkOptions(*i);
// output lib flags <Lib></Lib>
this->WriteLibOptions(*i);
+ if(this->NsightTegra &&
+ this->Target->GetType() == cmTarget::EXECUTABLE &&
+ this->Target->GetPropertyAsBool("ANDROID_GUI"))
+ {
+ this->WriteAntBuildOptions(*i);
+ }
this->WriteString("</ItemDefinitionGroup>\n", 1);
}
}
@@ -1914,7 +2586,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
path += dt->GetName();
path += ".vcxproj";
}
- (*this->BuildFileStream) << path << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n";
this->WriteString("<Project>", 3);
(*this->BuildFileStream)
<< this->GlobalGenerator->GetGUID(name.c_str())
@@ -1924,6 +2596,67 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
this->WriteString("</ItemGroup>\n", 1);
}
+void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
+{
+ if((this->GlobalGenerator->TargetsWindowsStore() ||
+ this->GlobalGenerator->TargetsWindowsPhone())
+ && (cmTarget::EXECUTABLE == this->Target->GetType()))
+ {
+ std::string pfxFile;
+ std::vector<cmSourceFile const*> certificates;
+ this->GeneratorTarget->GetCertificates(certificates, "");
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ certificates.begin(); si != certificates.end(); ++si)
+ {
+ pfxFile = this->ConvertPath((*si)->GetFullPath(), false);
+ this->ConvertToWindowsSlash(pfxFile);
+ break;
+ }
+
+ if(this->IsMissingFiles &&
+ !(this->GlobalGenerator->TargetsWindowsPhone() &&
+ this->GlobalGenerator->GetSystemVersion() == "8.0"))
+ {
+ // Move the manifest to a project directory to avoid clashes
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->ConvertToWindowsSlash(artifactDir);
+ this->WriteString("<PropertyGroup>\n", 1);
+ this->WriteString("<AppxPackageArtifactsDir>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
+ "\\</AppxPackageArtifactsDir>\n";
+ this->WriteString("<ProjectPriFullPath>"
+ "$(TargetDir)resources.pri</ProjectPriFullPath>", 2);
+
+ // If we are missing files and we don't have a certificate and
+ // aren't targeting WP8.0, add a default certificate
+ if(pfxFile.empty())
+ {
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+ pfxFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
+ cmSystemTools::CopyAFile(templateFolder + "/Windows_TemporaryKey.pfx",
+ pfxFile, false);
+ this->ConvertToWindowsSlash(pfxFile);
+ this->AddedFiles.push_back(pfxFile);
+ }
+
+ this->WriteString("<", 2);
+ (*this->BuildFileStream) << "PackageCertificateKeyFile>"
+ << pfxFile << "</PackageCertificateKeyFile>\n";
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+ else if(!pfxFile.empty())
+ {
+ this->WriteString("<PropertyGroup>\n", 1);
+ this->WriteString("<", 2);
+ (*this->BuildFileStream) << "PackageCertificateKeyFile>"
+ << pfxFile << "</PackageCertificateKeyFile>\n";
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+ }
+}
+
bool cmVisualStudio10TargetGenerator::
IsResxHeader(const std::string& headerFile)
{
@@ -1934,3 +2667,460 @@ bool cmVisualStudio10TargetGenerator::
expectedResxHeaders.find(headerFile);
return it != expectedResxHeaders.end();
}
+
+void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
+{
+ bool isAppContainer = false;
+ bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
+ bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(isWindowsPhone || isWindowsStore)
+ {
+ this->WriteString("<ApplicationType>", 2);
+ (*this->BuildFileStream) << (isWindowsPhone ?
+ "Windows Phone" : "Windows Store")
+ << "</ApplicationType>\n";
+ this->WriteString("<ApplicationTypeRevision>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(v)
+ << "</ApplicationTypeRevision>\n";
+ if(v == "8.1")
+ {
+ // Visual Studio 12.0 is necessary for building 8.1 apps
+ this->WriteString("<MinimumVisualStudioVersion>12.0"
+ "</MinimumVisualStudioVersion>\n", 2);
+
+ if (this->Target->GetType() < cmTarget::UTILITY)
+ {
+ isAppContainer = true;
+ }
+ }
+ else if (v == "8.0")
+ {
+ // Visual Studio 11.0 is necessary for building 8.0 apps
+ this->WriteString("<MinimumVisualStudioVersion>11.0"
+ "</MinimumVisualStudioVersion>\n", 2);
+
+ if (isWindowsStore && this->Target->GetType() < cmTarget::UTILITY)
+ {
+ isAppContainer = true;
+ }
+ else if (isWindowsPhone &&
+ this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ this->WriteString("<XapOutputs>true</XapOutputs>\n", 2);
+ this->WriteString("<XapFilename>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(this->Name.c_str()) <<
+ "_$(Configuration)_$(Platform).xap</XapFilename>\n";
+ }
+ }
+ }
+ if(isAppContainer)
+ {
+ this->WriteString("<AppContainerApplication>true"
+ "</AppContainerApplication>", 2);
+ }
+ else if (this->Platform == "ARM")
+ {
+ this->WriteString("<WindowsSDKDesktopARMSupport>true"
+ "</WindowsSDKDesktopARMSupport>", 2);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
+{
+ // For Windows and Windows Phone executables, we will assume that if a
+ // manifest is not present that we need to add all the necessary files
+ if (this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ std::vector<cmSourceFile const*> manifestSources;
+ this->GeneratorTarget->GetAppManifest(manifestSources, "");
+ {
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (v == "8.0")
+ {
+ // Look through the sources for WMAppManifest.xml
+ std::vector<cmSourceFile const*> extraSources;
+ this->GeneratorTarget->GetExtraSources(extraSources, "");
+ bool foundManifest = false;
+ for(std::vector<cmSourceFile const*>::const_iterator si =
+ extraSources.begin(); si != extraSources.end(); ++si)
+ {
+ // Need to do a lowercase comparison on the filename
+ if("wmappmanifest.xml" == cmSystemTools::LowerCase(
+ (*si)->GetLocation().GetName()))
+ {
+ foundManifest = true;
+ break;
+ }
+ }
+ if (!foundManifest)
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ else if (v == "8.1")
+ {
+ if(manifestSources.empty())
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore())
+ {
+ if (manifestSources.empty())
+ {
+ if (v == "8.0")
+ {
+ this->IsMissingFiles = true;
+ }
+ else if (v == "8.1")
+ {
+ this->IsMissingFiles = true;
+ }
+ }
+ }
+ }
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFiles()
+{
+ std::string const& v = this->GlobalGenerator->GetSystemVersion();
+ if(this->GlobalGenerator->TargetsWindowsPhone())
+ {
+ if (v == "8.0")
+ {
+ this->WriteMissingFilesWP80();
+ }
+ else if (v == "8.1")
+ {
+ this->WriteMissingFilesWP81();
+ }
+ }
+ else if (this->GlobalGenerator->TargetsWindowsStore())
+ {
+ if (v == "8.0")
+ {
+ this->WriteMissingFilesWS80();
+ }
+ else if (v == "8.1")
+ {
+ this->WriteMissingFilesWS81();
+ }
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80()
+{
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+
+ // For WP80, the manifest needs to be in the same folder as the project
+ // this can cause an overwrite problem if projects aren't organized in
+ // folders
+ std::string manifestFile = this->Makefile->GetStartOutputDirectory() +
+ std::string("/WMAppManifest.xml");
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML = cmVS10EscapeXML(this->Target->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Deployment"
+ " xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\""
+ " AppPlatformVersion=\"8.0\">\n"
+ "\t<DefaultLanguage xmlns=\"\" code=\"en-US\"/>\n"
+ "\t<App xmlns=\"\" ProductID=\"{" << this->GUID << "}\""
+ " Title=\"CMake Test Program\" RuntimeType=\"Modern Native\""
+ " Version=\"1.0.0.0\" Genre=\"apps.normal\" Author=\"CMake\""
+ " Description=\"Default CMake App\" Publisher=\"CMake\""
+ " PublisherID=\"{" << this->GUID << "}\">\n"
+ "\t\t<IconPath IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\ApplicationIcon.png</IconPath>\n"
+ "\t\t<Capabilities/>\n"
+ "\t\t<Tasks>\n"
+ "\t\t\t<DefaultTask Name=\"_default\""
+ " ImagePath=\"" << targetNameXML << ".exe\" ImageParams=\"\" />\n"
+ "\t\t</Tasks>\n"
+ "\t\t<Tokens>\n"
+ "\t\t\t<PrimaryToken TokenID=\"" << targetNameXML << "Token\""
+ " TaskName=\"_default\">\n"
+ "\t\t\t\t<TemplateFlip>\n"
+ "\t\t\t\t\t<SmallImageURI IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\SmallLogo.png</SmallImageURI>\n"
+ "\t\t\t\t\t<Count>0</Count>\n"
+ "\t\t\t\t\t<BackgroundImageURI IsRelative=\"true\" IsResource=\"false\">"
+ << artifactDirXML << "\\Logo.png</BackgroundImageURI>\n"
+ "\t\t\t\t</TemplateFlip>\n"
+ "\t\t\t</PrimaryToken>\n"
+ "\t\t</Tokens>\n"
+ "\t\t<ScreenResolutions>\n"
+ "\t\t\t<ScreenResolution Name=\"ID_RESOLUTION_WVGA\" />\n"
+ "\t\t</ScreenResolutions>\n"
+ "\t</App>\n"
+ "</Deployment>\n";
+
+ std::string sourceFile = this->ConvertPath(manifestFile, false);
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<Xml Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ this->WriteString("<SubType>Designer</SubType>\n", 3);
+ this->WriteString("</Xml>\n", 2);
+ this->AddedFiles.push_back(sourceFile);
+
+ std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png",
+ smallLogo, false);
+ this->ConvertToWindowsSlash(smallLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ this->AddedFiles.push_back(smallLogo);
+
+ std::string logo = this->DefaultArtifactDir + "/Logo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/Logo.png",
+ logo, false);
+ this->ConvertToWindowsSlash(logo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ this->AddedFiles.push_back(logo);
+
+ std::string applicationIcon =
+ this->DefaultArtifactDir + "/ApplicationIcon.png";
+ cmSystemTools::CopyAFile(templateFolder + "/ApplicationIcon.png",
+ applicationIcon, false);
+ this->ConvertToWindowsSlash(applicationIcon);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(applicationIcon) << "\" />\n";
+ this->AddedFiles.push_back(applicationIcon);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML = cmVS10EscapeXML(this->Target->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\""
+ " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\""
+ " xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID << "\""
+ " PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.3.1</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.3.1</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<m2:VisualElements\n"
+ "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tBackgroundColor=\"#336699\"\n"
+ "\t\t\t\tForegroundText=\"light\"\n"
+ "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+ "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n"
+ "\t\t\t\t\t<m2:ShowNameOnTiles>\n"
+ "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n"
+ "\t\t\t\t\t</m2:ShowNameOnTiles>\n"
+ "\t\t\t\t</m2:DefaultTile>\n"
+ "\t\t\t\t<m2:SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</m2:VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML = cmVS10EscapeXML(this->Target->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.2.1</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.2.1</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<VisualElements"
+ " DisplayName=\"" << targetNameXML << "\""
+ " Description=\"" << targetNameXML << "\""
+ " BackgroundColor=\"#336699\" ForegroundText=\"light\""
+ " Logo=\"" << artifactDirXML << "\\Logo.png\""
+ " SmallLogo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<DefaultTile ShowName=\"allLogos\""
+ " ShortName=\"" << targetNameXML << "\" />\n"
+ "\t\t\t\t<SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81()
+{
+ std::string manifestFile =
+ this->DefaultArtifactDir + "/package.appxManifest";
+ std::string artifactDir =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->ConvertToWindowsSlash(artifactDir);
+ std::string artifactDirXML = cmVS10EscapeXML(artifactDir);
+ std::string targetNameXML = cmVS10EscapeXML(this->Target->GetName());
+
+ cmGeneratedFileStream fout(manifestFile.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\""
+ " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\">\n"
+ "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\""
+ " Version=\"1.0.0.0\" />\n"
+ "\t<Properties>\n"
+ "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n"
+ "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n"
+ "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n"
+ "\t</Properties>\n"
+ "\t<Prerequisites>\n"
+ "\t\t<OSMinVersion>6.3</OSMinVersion>\n"
+ "\t\t<OSMaxVersionTested>6.3</OSMaxVersionTested>\n"
+ "\t</Prerequisites>\n"
+ "\t<Resources>\n"
+ "\t\t<Resource Language=\"x-generate\" />\n"
+ "\t</Resources>\n"
+ "\t<Applications>\n"
+ "\t\t<Application Id=\"App\""
+ " Executable=\"" << targetNameXML << ".exe\""
+ " EntryPoint=\"" << targetNameXML << ".App\">\n"
+ "\t\t\t<m2:VisualElements\n"
+ "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tDescription=\"" << targetNameXML << "\"\n"
+ "\t\t\t\tBackgroundColor=\"#336699\"\n"
+ "\t\t\t\tForegroundText=\"light\"\n"
+ "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n"
+ "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n"
+ "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n"
+ "\t\t\t\t\t<m2:ShowNameOnTiles>\n"
+ "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n"
+ "\t\t\t\t\t</m2:ShowNameOnTiles>\n"
+ "\t\t\t\t</m2:DefaultTile>\n"
+ "\t\t\t\t<m2:SplashScreen"
+ " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n"
+ "\t\t\t</m2:VisualElements>\n"
+ "\t\t</Application>\n"
+ "\t</Applications>\n"
+ "</Package>\n";
+
+ this->WriteCommonMissingFiles(manifestFile);
+}
+
+void
+cmVisualStudio10TargetGenerator
+::WriteCommonMissingFiles(const std::string& manifestFile)
+{
+ std::string templateFolder = cmSystemTools::GetCMakeRoot() +
+ "/Templates/Windows";
+
+ std::string sourceFile = this->ConvertPath(manifestFile, false);
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<AppxManifest Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ this->WriteString("<SubType>Designer</SubType>\n", 3);
+ this->WriteString("</AppxManifest>\n", 2);
+ this->AddedFiles.push_back(sourceFile);
+
+ std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png",
+ smallLogo, false);
+ this->ConvertToWindowsSlash(smallLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ this->AddedFiles.push_back(smallLogo);
+
+ std::string logo = this->DefaultArtifactDir + "/Logo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/Logo.png",
+ logo, false);
+ this->ConvertToWindowsSlash(logo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ this->AddedFiles.push_back(logo);
+
+ std::string storeLogo = this->DefaultArtifactDir + "/StoreLogo.png";
+ cmSystemTools::CopyAFile(templateFolder + "/StoreLogo.png",
+ storeLogo, false);
+ this->ConvertToWindowsSlash(storeLogo);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(storeLogo) << "\" />\n";
+ this->AddedFiles.push_back(storeLogo);
+
+ std::string splashScreen = this->DefaultArtifactDir + "/SplashScreen.png";
+ cmSystemTools::CopyAFile(templateFolder + "/SplashScreen.png",
+ splashScreen, false);
+ this->ConvertToWindowsSlash(splashScreen);
+ this->WriteString("<Image Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(splashScreen) << "\" />\n";
+ this->AddedFiles.push_back(splashScreen);
+
+ // This file has already been added to the build so don't copy it
+ std::string keyFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
+ this->ConvertToWindowsSlash(keyFile);
+ this->WriteString("<None Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(keyFile) << "\" />\n";
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index d72c6fd..a02dfa8 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -23,6 +23,7 @@ class cmCustomCommand;
class cmLocalVisualStudio7Generator;
class cmComputeLinkInformation;
class cmVisualStudioGeneratorOptions;
+struct cmIDEFlagTable;
#include "cmSourceGroup.h"
class cmVisualStudio10TargetGenerator
@@ -55,29 +56,48 @@ private:
void WriteString(const char* line, int indentLevel);
void WriteProjectConfigurations();
void WriteProjectConfigurationValues();
- void WriteSource(const char* tool, cmSourceFile const* sf,
+ void WriteMSToolConfigurationValues(std::string const& config);
+ void WriteHeaderSource(cmSourceFile const* sf);
+ void WriteExtraSource(cmSourceFile const* sf);
+ void WriteNsightTegraConfigurationValues(std::string const& config);
+ void WriteSource(std::string const& tool, cmSourceFile const* sf,
const char* end = 0);
- void WriteSources(const char* tool,
+ void WriteSources(std::string const& tool,
std::vector<cmSourceFile const*> const&);
void WriteAllSources();
void WriteDotNetReferences();
void WriteEmbeddedResourceGroup();
void WriteWinRTReferences();
+ void WriteWinRTPackageCertificateKeyFile();
void WritePathAndIncrementalLinkOptions();
void WriteItemDefinitionGroups();
+ void VerifyNecessaryFiles();
+ void WriteMissingFiles();
+ void WriteMissingFilesWP80();
+ void WriteMissingFilesWP81();
+ void WriteMissingFilesWS80();
+ void WriteMissingFilesWS81();
+ void WriteCommonMissingFiles(const std::string& manifestFile);
+ void WriteTargetSpecificReferences();
bool ComputeClOptions();
bool ComputeClOptions(std::string const& configName);
void WriteClOptions(std::string const& config,
std::vector<std::string> const & includes);
+ bool ComputeRcOptions();
+ bool ComputeRcOptions(std::string const& config);
void WriteRCOptions(std::string const& config,
std::vector<std::string> const & includes);
+ bool ComputeMasmOptions();
+ bool ComputeMasmOptions(std::string const& config);
+ void WriteMasmOptions(std::string const& config,
+ std::vector<std::string> const& includes);
bool ComputeLinkOptions();
bool ComputeLinkOptions(std::string const& config);
void WriteLinkOptions(std::string const& config);
void WriteMidlOptions(std::string const& config,
std::vector<std::string> const & includes);
- void OutputIncludes(std::vector<std::string> const & includes);
+ void WriteAntBuildOptions(std::string const& config);
void OutputLinkIncremental(std::string const& configName);
void WriteCustomRule(cmSourceFile const* source,
cmCustomCommand const & command);
@@ -85,8 +105,10 @@ private:
void WriteCustomCommand(cmSourceFile const* sf);
void WriteGroups();
void WriteProjectReferences();
+ void WriteApplicationTypeSettings();
bool OutputSourceSpecificFlags(cmSourceFile const* source);
- void AddLibraries(cmComputeLinkInformation& cli, std::string& libstring);
+ void AddLibraries(cmComputeLinkInformation& cli,
+ std::vector<std::string>& libVec);
void WriteLibOptions(std::string const& config);
void WriteEvents(std::string const& configName);
void WriteEvent(const char* name,
@@ -98,10 +120,18 @@ private:
const std::vector<cmSourceGroup>& allGroups);
bool IsResxHeader(const std::string& headerFile);
+ cmIDEFlagTable const* GetClFlagTable() const;
+ cmIDEFlagTable const* GetRcFlagTable() const;
+ cmIDEFlagTable const* GetLibFlagTable() const;
+ cmIDEFlagTable const* GetLinkFlagTable() const;
+ cmIDEFlagTable const* GetMasmFlagTable() const;
+
private:
typedef cmVisualStudioGeneratorOptions Options;
typedef std::map<std::string, Options*> OptionsMap;
OptionsMap ClOptions;
+ OptionsMap RcOptions;
+ OptionsMap MasmOptions;
OptionsMap LinkOptions;
std::string PathToVcxproj;
cmTarget* Target;
@@ -110,10 +140,17 @@ private:
std::string Platform;
std::string GUID;
std::string Name;
+ bool MSTools;
+ bool NsightTegra;
+ int NsightTegraVersion[4];
+ bool TargetCompileAsWinRT;
cmGlobalVisualStudio10Generator* GlobalGenerator;
cmGeneratedFileStream* BuildFileStream;
cmLocalVisualStudio7Generator* LocalGenerator;
std::set<cmSourceFile const*> SourcesVisited;
+ bool IsMissingFiles;
+ std::vector<std::string> AddedFiles;
+ std::string DefaultArtifactDir;
typedef std::map<std::string, ToolSources> ToolSourceMap;
ToolSourceMap Tools;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 81adb56..cdc8879 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -3,9 +3,9 @@
#include <cmsys/System.h>
#include "cmVisualStudio10TargetGenerator.h"
-inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
+static
+std::string cmVisualStudio10GeneratorOptionsEscapeForXML(std::string ret)
{
- std::string ret = s;
cmSystemTools::ReplaceString(ret, ";", "%3B");
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -13,9 +13,9 @@ inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
return ret;
}
-inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
+static
+std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret)
{
- std::string ret = s;
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "\"", "&quot;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -68,6 +68,7 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
case cmLocalVisualStudioGenerator::VS10:
case cmLocalVisualStudioGenerator::VS11:
case cmLocalVisualStudioGenerator::VS12:
+ case cmLocalVisualStudioGenerator::VS14:
// by default VS puts <ExceptionHandling></ExceptionHandling> empty
// for a project, to make our projects look the same put a new line
// and space over for the closing </ExceptionHandling> as the default
@@ -106,6 +107,12 @@ bool cmVisualStudioGeneratorOptions::IsDebug() const
}
//----------------------------------------------------------------------------
+bool cmVisualStudioGeneratorOptions::IsWinRt() const
+{
+ return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();
+}
+
+//----------------------------------------------------------------------------
bool cmVisualStudioGeneratorOptions::UsingUnicode() const
{
// Look for the a _UNICODE definition.
@@ -268,7 +275,7 @@ cmVisualStudioGeneratorOptions
// Escape this flag for the IDE.
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
{
- define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
+ define = cmVisualStudio10GeneratorOptionsEscapeForXML(define);
if(lang == "RC")
{
@@ -277,7 +284,7 @@ cmVisualStudioGeneratorOptions
}
else
{
- define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
+ define = cmVisualStudioGeneratorOptionsEscapeForXML(define);
}
// Store the flag in the project file.
fout << sep << define;
@@ -300,7 +307,7 @@ cmVisualStudioGeneratorOptions
{
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
{
- for(std::map<std::string, std::string>::iterator m = this->FlagMap.begin();
+ for(std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
m != this->FlagMap.end(); ++m)
{
fout << indent;
@@ -316,20 +323,30 @@ cmVisualStudioGeneratorOptions
{
fout << "<" << m->first << ">";
}
- fout << m->second;
- if (m->first == "AdditionalIncludeDirectories")
+ const char* sep = "";
+ for(std::vector<std::string>::iterator i = m->second.begin();
+ i != m->second.end(); ++i)
{
- fout << ";%(AdditionalIncludeDirectories)";
+ fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(*i);
+ sep = ";";
}
fout << "</" << m->first << ">\n";
}
}
else
{
- for(std::map<std::string, std::string>::iterator m = this->FlagMap.begin();
+ for(std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
m != this->FlagMap.end(); ++m)
{
- fout << indent << m->first << "=\"" << m->second << "\"\n";
+ fout << indent << m->first << "=\"";
+ const char* sep = "";
+ for(std::vector<std::string>::iterator i = m->second.begin();
+ i != m->second.end(); ++i)
+ {
+ fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(*i);
+ sep = ";";
+ }
+ fout << "\"\n";
}
}
}
@@ -358,14 +375,13 @@ cmVisualStudioGeneratorOptions
{
fout << "<AdditionalOptions>";
}
- fout << this->FlagString.c_str()
+ fout << cmVisualStudio10GeneratorOptionsEscapeForXML(this->FlagString)
<< " %(AdditionalOptions)</AdditionalOptions>\n";
}
else
{
fout << prefix << "AdditionalOptions=\"";
- fout <<
- cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString.c_str());
+ fout << cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString);
fout << "\"" << suffix;
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 214b893..9951033 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -27,6 +27,8 @@ public:
enum Tool
{
Compiler,
+ ResourceCompiler,
+ MasmCompiler,
Linker,
FortranCompiler
};
@@ -51,6 +53,7 @@ public:
bool UsingSBCS() const;
bool IsDebug() const;
+ bool IsWinRt() const;
// Write options to output.
void OutputPreprocessorDefinitions(std::ostream& fout,
const char* prefix,
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 7d2eead..851c4cb 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -10,7 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmWhileCommand.h"
-#include "cmIfCommand.h"
+#include "cmConditionEvaluator.h"
bool cmWhileFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
@@ -34,12 +34,14 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
std::string errorString;
- std::vector<std::string> expandedArguments;
+ std::vector<cmExpandedCommandArgument> expandedArguments;
mf.ExpandArguments(this->Args, expandedArguments);
cmake::MessageType messageType;
- bool isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- &mf, messageType);
+
+ cmConditionEvaluator conditionEvaluator(mf);
+
+ bool isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messageType);
while (isTrue)
{
@@ -86,9 +88,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
}
expandedArguments.clear();
mf.ExpandArguments(this->Args, expandedArguments);
- isTrue =
- cmIfCommand::IsTrue(expandedArguments,errorString,
- &mf, messageType);
+ isTrue = conditionEvaluator.IsTrue(
+ expandedArguments, errorString, messageType);
}
return true;
}
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index a73fd70..391b874 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -20,6 +20,8 @@ cmXMLParser::cmXMLParser()
{
this->Parser = 0;
this->ParseError = 0;
+ this->ReportCallback = 0;
+ this->ReportCallbackData = 0;
}
//----------------------------------------------------------------------------
@@ -233,6 +235,13 @@ void cmXMLParser::ReportXmlParseError()
//----------------------------------------------------------------------------
void cmXMLParser::ReportError(int line, int, const char* msg)
{
- std::cerr << "Error parsing XML in stream at line "
- << line << ": " << msg << std::endl;
+ if(this->ReportCallback)
+ {
+ this->ReportCallback(line, msg, this->ReportCallbackData);
+ }
+ else
+ {
+ std::cerr << "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl;
+ }
}
diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h
index 84a5a7d..e72da66 100644
--- a/Source/cmXMLParser.h
+++ b/Source/cmXMLParser.h
@@ -50,11 +50,18 @@ public:
virtual int ParseChunk(const char* inputString,
std::string::size_type length);
virtual int CleanupParser();
-
+ typedef void (*ReportFunction)(int, const char*, void*);
+ void SetErrorCallback(ReportFunction f, void* d)
+ {
+ this->ReportCallback = f;
+ this->ReportCallbackData = d;
+ }
protected:
//! This variable is true if there was a parse error while parsing in
//chunks.
int ParseError;
+ ReportFunction ReportCallback;
+ void* ReportCallbackData;
//1 Expat parser structure. Exists only during call to Parse().
void* Parser;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index e3bebbd..09d270d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -58,6 +58,7 @@
# include "cmGlobalVisualStudio10Generator.h"
# include "cmGlobalVisualStudio11Generator.h"
# include "cmGlobalVisualStudio12Generator.h"
+# include "cmGlobalVisualStudio14Generator.h"
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
# include "cmGlobalJOMMakefileGenerator.h"
@@ -343,16 +344,24 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
// The value is transformed if it is a filepath for example, so
// we can't compare whether the value is already in the cache until
// after we call AddCacheEntry.
- const char *cachedValue =
- this->CacheManager->GetCacheValue(var);
+ bool haveValue = false;
+ std::string cachedValue;
+ if(this->WarnUnusedCli)
+ {
+ if(const char *v = this->CacheManager->GetCacheValue(var))
+ {
+ haveValue = true;
+ cachedValue = v;
+ }
+ }
this->CacheManager->AddCacheEntry(var, value.c_str(),
"No help, variable specified on the command line.", type);
+
if(this->WarnUnusedCli)
{
- if (!cachedValue
- || strcmp(this->CacheManager->GetCacheValue(var),
- cachedValue) != 0)
+ if (!haveValue ||
+ cachedValue != this->CacheManager->GetCacheValue(var))
{
this->WatchUnusedCli(var);
}
@@ -630,6 +639,7 @@ void cmake::SetArgs(const std::vector<std::string>& args,
{
bool directoriesSet = directoriesSetBefore;
bool haveToolset = false;
+ bool havePlatform = false;
for(unsigned int i=1; i < args.size(); ++i)
{
std::string arg = args[i];
@@ -758,6 +768,27 @@ void cmake::SetArgs(const std::vector<std::string>& args,
"uninitialized variables.\n";
this->SetCheckSystemVars(true);
}
+ else if(arg.find("-A",0) == 0)
+ {
+ std::string value = arg.substr(2);
+ if(value.size() == 0)
+ {
+ ++i;
+ if(i >= args.size())
+ {
+ cmSystemTools::Error("No platform specified for -A");
+ return;
+ }
+ value = args[i];
+ }
+ if(havePlatform)
+ {
+ cmSystemTools::Error("Multiple -A options not allowed");
+ return;
+ }
+ this->GeneratorPlatform = value;
+ havePlatform = true;
+ }
else if(arg.find("-T",0) == 0)
{
std::string value = arg.substr(2);
@@ -1372,6 +1403,7 @@ int cmake::ActualConfigure()
{"10.0", "Visual Studio 10 2010"},
{"11.0", "Visual Studio 11 2012"},
{"12.0", "Visual Studio 12 2013"},
+ {"14.0", "Visual Studio 14"},
{0, 0}};
for(int i=0; version[i].MSVersion != 0; i++)
{
@@ -1435,6 +1467,34 @@ int cmake::ActualConfigure()
cmCacheManager::INTERNAL);
}
+ if(const char* platformName =
+ this->CacheManager->GetCacheValue("CMAKE_GENERATOR_PLATFORM"))
+ {
+ if(this->GeneratorPlatform.empty())
+ {
+ this->GeneratorPlatform = platformName;
+ }
+ else if(this->GeneratorPlatform != platformName)
+ {
+ std::string message = "Error: generator platform: ";
+ message += this->GeneratorPlatform;
+ message += "\nDoes not match the platform used previously: ";
+ message += platformName;
+ message +=
+ "\nEither remove the CMakeCache.txt file and CMakeFiles "
+ "directory or choose a different binary directory.";
+ cmSystemTools::Error(message.c_str());
+ return -2;
+ }
+ }
+ else
+ {
+ this->CacheManager->AddCacheEntry("CMAKE_GENERATOR_PLATFORM",
+ this->GeneratorPlatform.c_str(),
+ "Name of generator platform.",
+ cmCacheManager::INTERNAL);
+ }
+
if(const char* tsName =
this->CacheManager->GetCacheValue("CMAKE_GENERATOR_TOOLSET"))
{
@@ -1705,7 +1765,7 @@ int cmake::Generate()
{
return -1;
}
- this->GlobalGenerator->Generate();
+ this->GlobalGenerator->DoGenerate();
if ( !this->GraphVizFile.empty() )
{
std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
@@ -1771,6 +1831,8 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(
cmGlobalVisualStudio12Generator::NewFactory());
this->Generators.push_back(
+ cmGlobalVisualStudio14Generator::NewFactory());
+ this->Generators.push_back(
cmGlobalVisualStudio71Generator::NewFactory());
this->Generators.push_back(
cmGlobalVisualStudio8Generator::NewFactory());
@@ -2745,7 +2807,7 @@ int cmake::Build(const std::string& dir,
projName = it.GetValue();
return gen->Build("", dir,
projName, target,
- &output,
+ output,
"",
config, clean, false, 0,
cmSystemTools::OUTPUT_PASSTHROUGH,
diff --git a/Source/cmake.h b/Source/cmake.h
index 2d04902..60ffcd4 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -191,6 +191,14 @@ class cmake
///! Get the names of the current registered generators
void GetRegisteredGenerators(std::vector<std::string>& names);
+ ///! Set the name of the selected generator-specific platform.
+ void SetGeneratorPlatform(std::string const& ts)
+ { this->GeneratorPlatform = ts; }
+
+ ///! Get the name of the selected generator-specific platform.
+ std::string const& GetGeneratorPlatform() const
+ { return this->GeneratorPlatform; }
+
///! Set the name of the selected generator-specific toolset.
void SetGeneratorToolset(std::string const& ts)
{ this->GeneratorToolset = ts; }
@@ -403,6 +411,7 @@ protected:
std::string StartOutputDirectory;
bool SuppressDevWarnings;
bool DoSuppressDevWarnings;
+ std::string GeneratorPlatform;
std::string GeneratorToolset;
///! read in a cmake list file to initialize the cache
@@ -467,6 +476,7 @@ private:
{"-U <globbing_expr>", "Remove matching entries from CMake cache."}, \
{"-G <generator-name>", "Specify a build system generator."},\
{"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
+ {"-A <platform-name>", "Specify platform name if supported by generator."}, \
{"-Wno-dev", "Suppress developer warnings."},\
{"-Wdev", "Enable developer warnings."}
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 9f9f6bb..61b175e 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -42,6 +42,18 @@ static const char * cmDocumentationUsage[][2] =
{0,
" cmake [options] <path-to-source>\n"
" cmake [options] <path-to-existing-build>"},
+ {0,
+ "Specify a source directory to (re-)generate a build system for "
+ "it in the current working directory. Specify an existing build "
+ "directory to re-generate its build system."},
+ {0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsageNote[][2] =
+{
+ {0,
+ "Run 'cmake --help' for more information."},
{0,0}
};
@@ -163,7 +175,7 @@ static void cmakemainProgressCallback(const char *m, float prog,
int main(int ac, char const* const* av)
{
- setlocale(LC_ALL, "");
+ setlocale(LC_CTYPE, "");
cmsys::Encoding::CommandLineArguments args =
cmsys::Encoding::CommandLineArguments::Main(ac, av);
ac = args.argc();
@@ -223,6 +235,10 @@ int do_cmake(int ac, char const* const* av)
doc.SetName("cmake");
doc.SetSection("Name",cmDocumentationName);
doc.SetSection("Usage",cmDocumentationUsage);
+ if ( ac == 1 )
+ {
+ doc.AppendSection("Usage",cmDocumentationUsageNote);
+ }
doc.AppendSection("Generators",generators);
doc.PrependSection("Options",cmDocumentationOptions);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 9aee975..a0c67e0 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -61,6 +61,8 @@ void CMakeCommandUsage(const char* program)
<< " echo [string]... - displays arguments as text\n"
<< " echo_append [string]... - displays arguments as text but no new "
"line\n"
+ << " env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...\n"
+ << " - run command in a modified environment\n"
<< " environment - display the current environment\n"
<< " make_directory dir - create a directory\n"
<< " md5sum file1 [...] - compute md5sum of files\n"
@@ -190,6 +192,55 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0;
}
+ else if (args[1] == "env" )
+ {
+ std::vector<std::string>::const_iterator ai = args.begin() + 2;
+ std::vector<std::string>::const_iterator ae = args.end();
+ for(; ai != ae; ++ai)
+ {
+ std::string const& a = *ai;
+ if(cmHasLiteralPrefix(a, "--unset="))
+ {
+ // Unset environment variable.
+ cmSystemTools::UnPutEnv(a.c_str() + 8);
+ }
+ else if(!a.empty() && a[0] == '-')
+ {
+ // Environment variable and command names cannot start in '-',
+ // so this must be an unknown option.
+ std::cerr << "cmake -E env: unknown option '" << a << "'"
+ << std::endl;
+ return 1;
+ }
+ else if(a.find("=") != a.npos)
+ {
+ // Set environment variable.
+ cmSystemTools::PutEnv(a.c_str());
+ }
+ else
+ {
+ // This is the beginning of the command.
+ break;
+ }
+ }
+
+ if(ai == ae)
+ {
+ std::cerr << "cmake -E env: no command given" << std::endl;
+ return 1;
+ }
+
+ // Execute command from remaining arguments.
+ std::vector<std::string> cmd(ai, ae);
+ int retval;
+ if(cmSystemTools::RunSingleCommand(
+ cmd, 0, &retval, NULL, cmSystemTools::OUTPUT_PASSTHROUGH))
+ {
+ return retval;
+ }
+ return 1;
+ }
+
#if defined(CMAKE_BUILD_WITH_CMAKE)
// Command to create a symbolic link. Fails on platforms not
// supporting them.
diff --git a/Source/cmparseMSBuildXML.py b/Source/cmparseMSBuildXML.py
index d1b61ef..056a0db 100755
--- a/Source/cmparseMSBuildXML.py
+++ b/Source/cmparseMSBuildXML.py
@@ -12,6 +12,9 @@
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/cl.xml"
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/lib.xml"
# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/v120/1033/link.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/cl.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/lib.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V140/1033/link.xml"
#
# BoolProperty <Name>true|false</Name>
# simple example:
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 167e348..fb97af6 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -48,7 +48,7 @@ static const char * cmDocumentationOptions[][2] =
{"--output-on-failure", "Output anything outputted by the test program "
"if the test should fail."},
{"-F", "Enable failover."},
- {"-j <jobs>, --parallel <jobs>", "Run the tests in parallel using the"
+ {"-j <jobs>, --parallel <jobs>", "Run the tests in parallel using the "
"given number of jobs."},
{"-Q,--quiet", "Make ctest quiet."},
{"-O <file>, --output-log <file>", "Output to log file"},
@@ -86,6 +86,7 @@ static const char * cmDocumentationOptions[][2] =
{"--build-two-config", "Run CMake twice"},
{"--build-exe-dir", "Specify the directory for the executable."},
{"--build-generator", "Specify the generator to use."},
+ {"--build-generator-platform", "Specify the generator-specific platform."},
{"--build-generator-toolset", "Specify the generator-specific toolset."},
{"--build-project", "Specify the name of the project to build."},
{"--build-makeprogram", "Specify the make program to use."},
@@ -98,7 +99,7 @@ static const char * cmDocumentationOptions[][2] =
{"--test-timeout", "The time limit in seconds, internal use only."},
{"--tomorrow-tag", "Nightly or experimental starts with next day tag."},
{"--ctest-config", "The configuration file used to initialize CTest state "
- "when submitting dashboards."},
+ "when submitting dashboards."},
{"--overwrite", "Overwrite CTest configuration option."},
{"--extra-submit <file>[;<file>]", "Submit extra files to the dashboard."},
{"--force-new-ctest-process", "Run child CTest instances as new processes"},
@@ -116,7 +117,7 @@ static const char * cmDocumentationOptions[][2] =
// this is a test driver program for cmCTest.
int main (int argc, char const* const* argv)
{
- setlocale(LC_ALL, "");
+ setlocale(LC_CTYPE, "");
cmsys::Encoding::CommandLineArguments encoding_args =
cmsys::Encoding::CommandLineArguments::Main(argc, argv);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 5e6a226..8ca4360 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -1171,10 +1171,9 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
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")
- SET(TEST_SYSTEMTOOLS_SRC_FILE
- "${CMAKE_CURRENT_SOURCE_DIR}/testSystemTools.cxx")
+
+ SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
CONFIGURE_FILE(
${PROJECT_SOURCE_DIR}/testSystemTools.h.in
${PROJECT_BINARY_DIR}/testSystemTools.h)
diff --git a/Source/kwsys/CPU.h.in b/Source/kwsys/CPU.h.in
index 2e1a584..626914b 100644
--- a/Source/kwsys/CPU.h.in
+++ b/Source/kwsys/CPU.h.in
@@ -80,6 +80,10 @@
#elif defined(__mips) || defined(__mips__) || defined(__MIPS__)
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
+/* OpenRISC 1000 */
+#elif defined(__or1k__)
+# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
+
/* RS/6000 */
#elif defined(__THW_RS600) || defined(_IBMR2) || defined(_POWER)
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index d54e607..741bcba 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -103,7 +103,7 @@ void Directory::Clear()
namespace KWSYS_NAMESPACE
{
-bool Directory::Load(const char* name)
+bool Directory::Load(const kwsys_stl::string& name)
{
this->Clear();
#if _MSC_VER < 1300
@@ -112,16 +112,25 @@ bool Directory::Load(const char* name)
intptr_t srchHandle;
#endif
char* buf;
- size_t n = strlen(name);
- if ( name[n - 1] == '/' )
+ size_t n = name.size();
+ if ( *name.rbegin() == '/' || *name.rbegin() == '\\' )
{
buf = new char[n + 1 + 1];
- sprintf(buf, "%s*", name);
+ sprintf(buf, "%s*", name.c_str());
}
else
{
+ // Make sure the slashes in the wildcard suffix are consistent with the
+ // rest of the path
buf = new char[n + 2 + 1];
- sprintf(buf, "%s/*", name);
+ if ( name.find('\\') != name.npos )
+ {
+ sprintf(buf, "%s\\*", name.c_str());
+ }
+ else
+ {
+ sprintf(buf, "%s/*", name.c_str());
+ }
}
struct _wfinddata_t data; // data of current file
@@ -144,7 +153,7 @@ bool Directory::Load(const char* name)
return _findclose(srchHandle) != -1;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& name)
{
#if _MSC_VER < 1300
long srchHandle;
@@ -152,16 +161,16 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
intptr_t srchHandle;
#endif
char* buf;
- size_t n = strlen(name);
- if ( name[n - 1] == '/' )
+ size_t n = name.size();
+ if ( *name.rbegin() == '/' )
{
buf = new char[n + 1 + 1];
- sprintf(buf, "%s*", name);
+ sprintf(buf, "%s*", name.c_str());
}
else
{
buf = new char[n + 2 + 1];
- sprintf(buf, "%s/*", name);
+ sprintf(buf, "%s/*", name.c_str());
}
struct _wfinddata_t data; // data of current file
@@ -206,15 +215,11 @@ p=1992&sid=f16167f51964f1a68fe5041b8eb213b6
namespace KWSYS_NAMESPACE
{
-bool Directory::Load(const char* name)
+bool Directory::Load(const kwsys_stl::string& name)
{
this->Clear();
- if (!name)
- {
- return 0;
- }
- DIR* dir = opendir(name);
+ DIR* dir = opendir(name.c_str());
if (!dir)
{
@@ -230,14 +235,9 @@ bool Directory::Load(const char* name)
return 1;
}
-unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& name)
{
- DIR* dir = opendir(name);
-
- if (!dir)
- {
- return 0;
- }
+ DIR* dir = opendir(name.c_str());
unsigned long count = 0;
for (dirent* d = readdir(dir); d; d = readdir(dir) )
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index 05217c4..0acb191 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -13,6 +13,13 @@
#define @KWSYS_NAMESPACE@_Directory_hxx
#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <@KWSYS_NAMESPACE@/stl/string>
+
+/* Define these macros temporarily to keep the code readable. */
+#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# define kwsys_stl @KWSYS_NAMESPACE@_stl
+# define kwsys_ios @KWSYS_NAMESPACE@_ios
+#endif
namespace @KWSYS_NAMESPACE@
{
@@ -38,7 +45,7 @@ public:
* in that directory. 0 is returned if the directory can not be
* opened, 1 if it is opened.
*/
- bool Load(const char*);
+ bool Load(const kwsys_stl::string&);
/**
* Return the number of files in the current directory.
@@ -49,7 +56,7 @@ public:
* Return the number of files in the specified directory.
* A higher performance static method.
*/
- static unsigned long GetNumberOfFilesInDirectory(const char*);
+ static unsigned long GetNumberOfFilesInDirectory(const kwsys_stl::string&);
/**
* Return the file at the given index, the indexing is 0 based
@@ -77,4 +84,10 @@ private:
} // namespace @KWSYS_NAMESPACE@
+/* Undefine temporary macros. */
+#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsys_stl
+# undef kwsys_ios
+#endif
+
#endif
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 8569b0e..0916d2e 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -218,7 +218,7 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
const kwsys_stl::string& dir)
{
kwsys::Directory d;
- if ( !d.Load(dir.c_str()) )
+ if ( !d.Load(dir) )
{
return;
}
@@ -257,8 +257,8 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
fullname = dir + "/" + fname;
}
- bool isDir = kwsys::SystemTools::FileIsDirectory(realname.c_str());
- bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname.c_str());
+ bool isDir = kwsys::SystemTools::FileIsDirectory(realname);
+ bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname);
if ( isDir && (!isSymLink || this->RecurseThroughSymlinks) )
{
@@ -297,7 +297,7 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
}
kwsys::Directory d;
- if ( !d.Load(dir.c_str()) )
+ if ( !d.Load(dir) )
{
return;
}
@@ -342,12 +342,12 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
//kwsys_ios::cout << "Full name: " << fullname << kwsys_ios::endl;
if ( !last &&
- !kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
+ !kwsys::SystemTools::FileIsDirectory(realname) )
{
continue;
}
- if ( this->Internals->Expressions[start].find(fname.c_str()) )
+ if ( this->Internals->Expressions[start].find(fname) )
{
if ( last )
{
@@ -371,7 +371,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
this->Internals->Expressions.clear();
this->Internals->Files.clear();
- if ( !kwsys::SystemTools::FileIsFullPath(expr.c_str()) )
+ if ( !kwsys::SystemTools::FileIsFullPath(expr) )
{
expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
expr += "/" + inexpr;
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 241e295..ca9d424 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -68,6 +68,7 @@ do.
#include <signal.h> /* sigaction */
#include <dirent.h> /* DIR, dirent */
#include <ctype.h> /* isspace */
+#include <assert.h> /* assert */
#if defined(__VMS)
# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
@@ -450,6 +451,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
}
for(i=0; i < n; ++i)
{
+ assert(command[i]); /* Quiet Clang scan-build. */
newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
if(!newCommands[cp->NumberOfCommands][i])
{
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index c8ec754..ef71f26 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -36,6 +36,9 @@ a UNIX-style select system call.
#pragma warning (push, 1)
#endif
#include <windows.h> /* Windows API */
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+#endif
#include <string.h> /* strlen, strdup */
#include <stdio.h> /* sprintf */
#include <io.h> /* _unlink */
@@ -335,7 +338,14 @@ kwsysProcess* kwsysProcess_New(void)
windows. */
ZeroMemory(&osv, sizeof(osv));
osv.dwOSVersionInfoSize = sizeof(osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# pragma warning (disable:4996)
+#endif
GetVersionEx(&osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
/* Win9x no longer supported. */
@@ -2370,7 +2380,14 @@ static kwsysProcess_List* kwsysProcess_List_New(void)
/* Select an implementation. */
ZeroMemory(&osv, sizeof(osv));
osv.dwOSVersionInfoSize = sizeof(osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# pragma warning (disable:4996)
+#endif
GetVersionEx(&osv);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
osv.dwMajorVersion < 5)? 1:0;
diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in
index dd4d462..7ff29b4 100644
--- a/Source/kwsys/SharedForward.h.in
+++ b/Source/kwsys/SharedForward.h.in
@@ -512,7 +512,7 @@ static void kwsys_shared_forward_execvp(const char* cmd,
/* Invoke the child process. */
#if defined(_MSC_VER)
_execvp(cmd, argv);
-#elif defined(__MINGW32__)
+#elif defined(__MINGW32__) && !defined(__MINGW64__)
execvp(cmd, argv);
#else
execvp(cmd, (char* const*)argv);
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 6544098..84b5f39 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -60,6 +60,9 @@
#if defined(_WIN32)
# include <windows.h>
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# endif
# include <errno.h>
# if defined(KWSYS_SYS_HAS_PSAPI)
# include <psapi.h>
@@ -3696,7 +3699,10 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable)
// install ours
struct sigaction sa;
sa.sa_sigaction=(SigAction)StacktraceSignalHandler;
- sa.sa_flags=SA_SIGINFO|SA_RESTART|SA_RESETHAND;
+ sa.sa_flags=SA_SIGINFO|SA_RESETHAND;
+# ifdef SA_RESTART
+ sa.sa_flags|=SA_RESTART;
+# endif
sigemptyset(&sa.sa_mask);
sigaction(SIGABRT,&sa,0);
@@ -3783,7 +3789,7 @@ bool SystemInformationImplementation::QueryLinuxMemory()
return false;
}
- if( unameInfo.release!=0 && strlen(unameInfo.release)>=3 )
+ if( strlen(unameInfo.release)>=3 )
{
// release looks like "2.6.3-15mdk-i686-up-4GB"
char majorChar=unameInfo.release[0];
@@ -5060,6 +5066,10 @@ bool SystemInformationImplementation::QueryOSInformation()
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
ZeroMemory (&osvi, sizeof (OSVERSIONINFOEXW));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# pragma warning (disable:4996)
+#endif
bOsVersionInfoEx = GetVersionExW ((OSVERSIONINFOW*)&osvi);
if (!bOsVersionInfoEx)
{
@@ -5069,6 +5079,9 @@ bool SystemInformationImplementation::QueryOSInformation()
return false;
}
}
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
switch (osvi.dwPlatformId)
{
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 704cbbc..b1221e3 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -82,6 +82,9 @@
# ifndef INVALID_FILE_ATTRIBUTES
# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
# endif
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# endif
#elif defined (__CYGWIN__)
# include <windows.h>
# undef _WIN32
@@ -187,17 +190,34 @@ static inline char *realpath(const char *path, char *resolved_path)
}
#endif
+#ifdef _WIN32
+static time_t windows_filetime_to_posix_time(const FILETIME& ft)
+{
+ LARGE_INTEGER date;
+ date.HighPart = ft.dwHighDateTime;
+ date.LowPart = ft.dwLowDateTime;
+
+ // removes the diff between 1970 and 1601
+ date.QuadPart -= ((LONGLONG)(369 * 365 + 89) * 24 * 3600 * 10000000);
+
+ // converts back from 100-nanoseconds to seconds
+ return date.QuadPart / 10000000;
+}
+#endif
+
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
#include <wctype.h>
-inline int Mkdir(const char* dir)
+inline int Mkdir(const kwsys_stl::string& dir)
{
- return _wmkdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
+ return _wmkdir(
+ KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
}
-inline int Rmdir(const char* dir)
+inline int Rmdir(const kwsys_stl::string& dir)
{
- return _wrmdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
+ return _wrmdir(
+ KWSYS_NAMESPACE::SystemTools::ConvertToWindowsExtendedPath(dir).c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
@@ -215,15 +235,15 @@ inline const char* Getcwd(char* buf, unsigned int len)
}
return 0;
}
-inline int Chdir(const char* dir)
+inline int Chdir(const kwsys_stl::string& dir)
{
#if defined(__BORLANDC__)
- return chdir(dir);
+ return chdir(dir.c_str());
#else
return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
#endif
}
-inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+inline void Realpath(const kwsys_stl::string& path, kwsys_stl::string & resolved_path)
{
kwsys_stl::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
wchar_t *ptemp;
@@ -243,28 +263,28 @@ inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
-inline int Mkdir(const char* dir)
+inline int Mkdir(const kwsys_stl::string& dir)
{
- return mkdir(dir, 00777);
+ return mkdir(dir.c_str(), 00777);
}
-inline int Rmdir(const char* dir)
+inline int Rmdir(const kwsys_stl::string& dir)
{
- return rmdir(dir);
+ return rmdir(dir.c_str());
}
inline const char* Getcwd(char* buf, unsigned int len)
{
return getcwd(buf, len);
}
-inline int Chdir(const char* dir)
+inline int Chdir(const kwsys_stl::string& dir)
{
- return chdir(dir);
+ return chdir(dir.c_str());
}
-inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+inline void Realpath(const kwsys_stl::string& path, kwsys_stl::string & resolved_path)
{
char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
- char *ret = realpath(path, resolved_name);
+ char *ret = realpath(path.c_str(), resolved_name);
if(ret)
{
resolved_path = ret;
@@ -317,9 +337,9 @@ class SystemToolsTranslationMap :
void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char* env)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* pathSep = ";";
+ const char pathSep = ';';
#else
- const char* pathSep = ":";
+ const char pathSep = ':';
#endif
if(!env)
{
@@ -334,7 +354,7 @@ void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char
kwsys_stl::string pathEnv = cpathEnv;
// A hack to make the below algorithm work.
- if(!pathEnv.empty() && pathEnv[pathEnv.length()-1] != pathSep[0])
+ if(!pathEnv.empty() && *pathEnv.rbegin() != pathSep)
{
pathEnv += pathSep;
}
@@ -606,13 +626,13 @@ const char* SystemTools::GetExecutableExtension()
#endif
}
-FILE* SystemTools::Fopen(const char* file, const char* mode)
+FILE* SystemTools::Fopen(const kwsys_stl::string& file, const char* mode)
{
#ifdef _WIN32
- return _wfopen(Encoding::ToWide(file).c_str(),
+ return _wfopen(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
Encoding::ToWide(mode).c_str());
#else
- return fopen(file, mode);
+ return fopen(file.c_str(), mode);
#endif
}
@@ -622,15 +642,20 @@ bool SystemTools::MakeDirectory(const char* path)
{
return false;
}
+ return SystemTools::MakeDirectory(kwsys_stl::string(path));
+}
+
+bool SystemTools::MakeDirectory(const kwsys_stl::string& path)
+{
if(SystemTools::FileExists(path))
{
return SystemTools::FileIsDirectory(path);
}
- kwsys_stl::string dir = path;
- if(dir.empty())
+ if(path.empty())
{
return false;
}
+ kwsys_stl::string dir = path;
SystemTools::ConvertToUnixSlashes(dir);
kwsys_stl::string::size_type pos = 0;
@@ -638,11 +663,11 @@ bool SystemTools::MakeDirectory(const char* path)
while((pos = dir.find('/', pos)) != kwsys_stl::string::npos)
{
topdir = dir.substr(0, pos);
- Mkdir(topdir.c_str());
+ Mkdir(topdir);
pos++;
}
topdir = dir;
- if(Mkdir(topdir.c_str()) != 0)
+ if(Mkdir(topdir) != 0)
{
// There is a bug in the Borland Run time library which makes MKDIR
// return EACCES when it should return EEXISTS
@@ -1004,7 +1029,7 @@ bool SystemTools::DeleteRegistryValue(const char *, KeyWOW64)
}
#endif
-bool SystemTools::SameFile(const char* file1, const char* file2)
+bool SystemTools::SameFile(const kwsys_stl::string& file1, const kwsys_stl::string& file2)
{
#ifdef _WIN32
HANDLE hFile1, hFile2;
@@ -1049,7 +1074,7 @@ bool SystemTools::SameFile(const char* file1, const char* file2)
fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
#else
struct stat fileStat1, fileStat2;
- if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
+ if (stat(file1.c_str(), &fileStat1) == 0 && stat(file2.c_str(), &fileStat2) == 0)
{
// see if the files are the same file
// check the device inode and size
@@ -1068,23 +1093,34 @@ bool SystemTools::SameFile(const char* file1, const char* file2)
//----------------------------------------------------------------------------
bool SystemTools::FileExists(const char* filename)
{
- if(!(filename && *filename))
+ if(!filename)
+ {
+ return false;
+ }
+ return SystemTools::FileExists(kwsys_stl::string(filename));
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::FileExists(const kwsys_stl::string& filename)
+{
+ if(filename.empty())
{
return false;
}
#if defined(__CYGWIN__)
// Convert filename to native windows path if possible.
char winpath[MAX_PATH];
- if(SystemTools::PathCygwinToWin32(filename, winpath))
+ if(SystemTools::PathCygwinToWin32(filename.c_str(), winpath))
{
return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
}
- return access(filename, R_OK) == 0;
+ return access(filename.c_str(), R_OK) == 0;
#elif defined(_WIN32)
- return (GetFileAttributesW(Encoding::ToWide(filename).c_str())
+ return (GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str())
!= INVALID_FILE_ATTRIBUTES);
#else
- return access(filename, R_OK) == 0;
+ return access(filename.c_str(), R_OK) == 0;
#endif
}
@@ -1101,6 +1137,18 @@ bool SystemTools::FileExists(const char* filename, bool isFile)
}
//----------------------------------------------------------------------------
+bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile)
+{
+ if(SystemTools::FileExists(filename))
+ {
+ // If isFile is set return not FileIsDirectory,
+ // so this will only be true if it is a file
+ return !isFile || !SystemTools::FileIsDirectory(filename);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
{
@@ -1124,7 +1172,7 @@ bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
}
#endif
-bool SystemTools::Touch(const char* filename, bool create)
+bool SystemTools::Touch(const kwsys_stl::string& filename, bool create)
{
if(create && !SystemTools::FileExists(filename))
{
@@ -1137,10 +1185,11 @@ bool SystemTools::Touch(const char* filename, bool create)
return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- HANDLE h = CreateFileW(Encoding::ToWide(filename).c_str(),
- FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_WRITE, 0, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, 0);
+ HANDLE h = CreateFileW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_WRITE, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, 0);
if(!h)
{
return false;
@@ -1155,13 +1204,13 @@ bool SystemTools::Touch(const char* filename, bool create)
CloseHandle(h);
#elif KWSYS_CXX_HAS_UTIMENSAT
struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}};
- if(utimensat(AT_FDCWD, filename, times, 0) < 0)
+ if(utimensat(AT_FDCWD, filename.c_str(), times, 0) < 0)
{
return false;
}
#else
struct stat st;
- if(stat(filename, &st) < 0)
+ if(stat(filename.c_str(), &st) < 0)
{
return false;
}
@@ -1177,13 +1226,13 @@ bool SystemTools::Touch(const char* filename, bool create)
# endif
mtime
};
- if(utimes(filename, times) < 0)
+ if(utimes(filename.c_str(), times) < 0)
{
return false;
}
# else
struct utimbuf times = {st.st_atime, mtime.tv_sec};
- if(utime(filename, &times) < 0)
+ if(utime(filename.c_str(), &times) < 0)
{
return false;
}
@@ -1192,7 +1241,8 @@ bool SystemTools::Touch(const char* filename, bool create)
return true;
}
-bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
+bool SystemTools::FileTimeCompare(const kwsys_stl::string& f1,
+ const kwsys_stl::string& f2,
int* result)
{
// Default to same time.
@@ -1200,12 +1250,12 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
#if !defined(_WIN32) || defined(__CYGWIN__)
// POSIX version. Use stat function to get file modification time.
struct stat s1;
- if(stat(f1, &s1) != 0)
+ if(stat(f1.c_str(), &s1) != 0)
{
return false;
}
struct stat s2;
- if(stat(f2, &s2) != 0)
+ if(stat(f2.c_str(), &s2) != 0)
{
return false;
}
@@ -1242,13 +1292,15 @@ bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
// Windows version. Get the modification time from extended file attributes.
WIN32_FILE_ATTRIBUTE_DATA f1d;
WIN32_FILE_ATTRIBUTE_DATA f2d;
- if(!GetFileAttributesExW(Encoding::ToWide(f1).c_str(),
- GetFileExInfoStandard, &f1d))
+ if(!GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(f1).c_str(),
+ GetFileExInfoStandard, &f1d))
{
return false;
}
- if(!GetFileAttributesExW(Encoding::ToWide(f2).c_str(),
- GetFileExInfoStandard, &f2d))
+ if(!GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(f2).c_str(),
+ GetFileExInfoStandard, &f2d))
{
return false;
}
@@ -1514,6 +1566,17 @@ bool SystemTools::StringStartsWith(const char* str1, const char* str2)
return len1 >= len2 && !strncmp(str1, str2, len2) ? true : false;
}
+// Returns if string starts with another string
+bool SystemTools::StringStartsWith(const kwsys_stl::string& str1, const char* str2)
+{
+ if (!str2)
+ {
+ return false;
+ }
+ size_t len1 = str1.size(), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1.c_str(), str2, len2) ? true : false;
+}
+
// Returns if string ends with another string
bool SystemTools::StringEndsWith(const char* str1, const char* str2)
{
@@ -1525,6 +1588,17 @@ bool SystemTools::StringEndsWith(const char* str1, const char* str2)
return len1 >= len2 && !strncmp(str1 + (len1 - len2), str2, len2) ? true : false;
}
+// Returns if string ends with another string
+bool SystemTools::StringEndsWith(const kwsys_stl::string& str1, const char* str2)
+{
+ if (!str2)
+ {
+ return false;
+ }
+ size_t len1 = str1.size(), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1.c_str() + (len1 - len2), str2, len2) ? true : false;
+}
+
// Returns a pointer to the last occurence of str2 in str1
const char* SystemTools::FindLastString(const char* str1, const char* str2)
{
@@ -1594,7 +1668,7 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
}
//----------------------------------------------------------------------------
-kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char sep, bool isPath)
+kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const kwsys_stl::string& p, char sep, bool isPath)
{
kwsys_stl::string path = p;
kwsys_stl::vector<kwsys::String> paths;
@@ -1830,8 +1904,73 @@ void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
}
}
+#ifdef _WIN32
+// Convert local paths to UNC style paths
+kwsys_stl::wstring
+SystemTools::ConvertToWindowsExtendedPath(const kwsys_stl::string &source)
+{
+ kwsys_stl::wstring wsource = Encoding::ToWide(source);
+
+ // Resolve any relative paths
+ DWORD wfull_len;
+
+ /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that
+ * won't return a large enough buffer size if the input is too small */
+ wfull_len = GetFullPathNameW(wsource.c_str(), 0, NULL, NULL) + 3;
+ kwsys_stl::vector<wchar_t> wfull(wfull_len);
+ GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], NULL);
+
+ /* This should get the correct size without any extra padding from the
+ * previous size workaround. */
+ wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
+
+ if(wfull_len >= 2 && isalpha(wfull[0]) && wfull[1] == L':')
+ { /* C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + kwsys_stl::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 2 && wfull[0] == L'\\' && wfull[1] == L'\\')
+ { /* Starts with \\ */
+ if(wfull_len >= 4 && wfull[2] == L'?' && wfull[3] == L'\\')
+ { /* Starts with \\?\ */
+ if(wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' &&
+ wfull[6] == L'C' && wfull[7] == L'\\')
+ { /* \\?\UNC\Foo\bar\FooBar.txt */
+ return kwsys_stl::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+ { /* \\?\C:\Foo\bar\FooBar.txt */
+ return kwsys_stl::wstring(&wfull[0]);
+ }
+ else if(wfull_len >= 5)
+ { /* \\?\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[4]);
+ }
+ }
+ else if(wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\')
+ { /* Starts with \\.\ a device name */
+ if(wfull_len >= 6 && isalpha(wfull[4]) && wfull[5] == L':')
+ { /* \\.\C:\Foo\bar\FooBar.txt */
+ return L"\\\\?\\" + kwsys_stl::wstring(&wfull[4]);
+ }
+ else if(wfull_len >= 5)
+ { /* \\.\Foo\bar\ Device name is left unchanged */
+ return kwsys_stl::wstring(&wfull[0]);
+ }
+ }
+ else if(wfull_len >= 3)
+ { /* \\Foo\bar\FooBar.txt */
+ return L"\\\\?\\UNC\\" + kwsys_stl::wstring(&wfull[2]);
+ }
+ }
+
+ // If this case has been reached, then the path is invalid. Leave it
+ // unchanged
+ return Encoding::ToWide(source);
+}
+#endif
+
// change // to /, and escape any spaces in the path
-kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
+kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const kwsys_stl::string& path)
{
kwsys_stl::string ret = path;
@@ -1861,7 +2000,7 @@ kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
return ret;
}
-kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path)
+kwsys_stl::string SystemTools::ConvertToOutputPath(const kwsys_stl::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return SystemTools::ConvertToWindowsOutputPath(path);
@@ -1871,13 +2010,12 @@ kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path)
}
// remove double slashes not at the start
-kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path)
+kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const kwsys_stl::string& path)
{
kwsys_stl::string ret;
// make it big enough for all of path and double quotes
- ret.reserve(strlen(path)+3);
+ ret.reserve(path.size()+3);
// put path into the string
- ret.assign(path);
ret = path;
kwsys_stl::string::size_type pos = 0;
// first convert all of the slashes
@@ -1919,8 +2057,8 @@ kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path)
return ret;
}
-bool SystemTools::CopyFileIfDifferent(const char* source,
- const char* destination)
+bool SystemTools::CopyFileIfDifferent(const kwsys_stl::string& source,
+ const kwsys_stl::string& destination)
{
// special check for a destination that is a directory
// FilesDiffer does not handle file to directory compare
@@ -1931,7 +2069,7 @@ bool SystemTools::CopyFileIfDifferent(const char* source,
new_destination += '/';
kwsys_stl::string source_name = source;
new_destination += SystemTools::GetFilenameName(source_name);
- if(SystemTools::FilesDiffer(source, new_destination.c_str()))
+ if(SystemTools::FilesDiffer(source, new_destination))
{
return SystemTools::CopyFileAlways(source, destination);
}
@@ -1954,23 +2092,25 @@ bool SystemTools::CopyFileIfDifferent(const char* source,
#define KWSYS_ST_BUFFER 4096
-bool SystemTools::FilesDiffer(const char* source,
- const char* destination)
+bool SystemTools::FilesDiffer(const kwsys_stl::string& source,
+ const kwsys_stl::string& destination)
{
#if defined(_WIN32)
WIN32_FILE_ATTRIBUTE_DATA statSource;
- if (GetFileAttributesExW(Encoding::ToWide(source).c_str(),
- GetFileExInfoStandard,
- &statSource) == 0)
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(source).c_str(),
+ GetFileExInfoStandard,
+ &statSource) == 0)
{
return true;
}
WIN32_FILE_ATTRIBUTE_DATA statDestination;
- if (GetFileAttributesExW(Encoding::ToWide(destination).c_str(),
- GetFileExInfoStandard,
- &statDestination) == 0)
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(destination).c_str(),
+ GetFileExInfoStandard,
+ &statDestination) == 0)
{
return true;
}
@@ -1991,13 +2131,13 @@ bool SystemTools::FilesDiffer(const char* source,
#else
struct stat statSource;
- if (stat(source, &statSource) != 0)
+ if (stat(source.c_str(), &statSource) != 0)
{
return true;
}
struct stat statDestination;
- if (stat(destination, &statDestination) != 0)
+ if (stat(destination.c_str(), &statDestination) != 0)
{
return true;
}
@@ -2015,15 +2155,15 @@ bool SystemTools::FilesDiffer(const char* source,
#endif
#if defined(_WIN32)
- kwsys::ifstream finSource(source,
+ kwsys::ifstream finSource(source.c_str(),
(kwsys_ios::ios::binary |
kwsys_ios::ios::in));
- kwsys::ifstream finDestination(destination,
+ kwsys::ifstream finDestination(destination.c_str(),
(kwsys_ios::ios::binary |
kwsys_ios::ios::in));
#else
- kwsys::ifstream finSource(source);
- kwsys::ifstream finDestination(destination);
+ kwsys::ifstream finSource(source.c_str());
+ kwsys::ifstream finDestination(destination.c_str());
#endif
if(!finSource || !finDestination)
{
@@ -2068,7 +2208,7 @@ bool SystemTools::FilesDiffer(const char* source,
/**
* Copy a file named by "source" to the file named by "destination".
*/
-bool SystemTools::CopyFileAlways(const char* source, const char* destination)
+bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_stl::string& destination)
{
// If files are the same do not copy
if ( SystemTools::SameFile(source, destination) )
@@ -2084,31 +2224,33 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
// If destination is a directory, try to create a file with the same
// name as the source in that directory.
- kwsys_stl::string new_destination;
+ kwsys_stl::string real_destination = destination;
+ kwsys_stl::string destination_dir;
if(SystemTools::FileExists(destination) &&
SystemTools::FileIsDirectory(destination))
{
- new_destination = destination;
- SystemTools::ConvertToUnixSlashes(new_destination);
- new_destination += '/';
+ destination_dir = real_destination;
+ SystemTools::ConvertToUnixSlashes(real_destination);
+ real_destination += '/';
kwsys_stl::string source_name = source;
- new_destination += SystemTools::GetFilenameName(source_name);
- destination = new_destination.c_str();
+ real_destination += SystemTools::GetFilenameName(source_name);
+ }
+ else
+ {
+ destination_dir = SystemTools::GetFilenamePath(destination);
}
// Create destination directory
- kwsys_stl::string destination_dir = destination;
- destination_dir = SystemTools::GetFilenamePath(destination_dir);
- SystemTools::MakeDirectory(destination_dir.c_str());
+ SystemTools::MakeDirectory(destination_dir);
// Open files
#if defined(_WIN32) || defined(__CYGWIN__)
- kwsys::ifstream fin(source,
+ kwsys::ifstream fin(source.c_str(),
kwsys_ios::ios::binary | kwsys_ios::ios::in);
#else
- kwsys::ifstream fin(source);
+ kwsys::ifstream fin(source.c_str());
#endif
if(!fin)
{
@@ -2119,13 +2261,13 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
// can be written to.
// If the remove fails continue so that files in read only directories
// that do not allow file removal can be modified.
- SystemTools::RemoveFile(destination);
+ SystemTools::RemoveFile(real_destination);
#if defined(_WIN32) || defined(__CYGWIN__)
- kwsys::ofstream fout(destination,
+ kwsys::ofstream fout(real_destination.c_str(),
kwsys_ios::ios::binary | kwsys_ios::ios::out | kwsys_ios::ios::trunc);
#else
- kwsys::ofstream fout(destination,
+ kwsys::ofstream fout(real_destination.c_str(),
kwsys_ios::ios::out | kwsys_ios::ios::trunc);
#endif
if(!fout)
@@ -2161,7 +2303,7 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
}
if ( perms )
{
- if ( !SystemTools::SetPermissions(destination, perm) )
+ if ( !SystemTools::SetPermissions(real_destination, perm) )
{
return false;
}
@@ -2170,7 +2312,7 @@ bool SystemTools::CopyFileAlways(const char* source, const char* destination)
}
//----------------------------------------------------------------------------
-bool SystemTools::CopyAFile(const char* source, const char* destination,
+bool SystemTools::CopyAFile(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always)
{
if(always)
@@ -2187,11 +2329,16 @@ bool SystemTools::CopyAFile(const char* source, const char* destination,
* Copy a directory content from "source" directory to the directory named by
* "destination".
*/
-bool SystemTools::CopyADirectory(const char* source, const char* destination,
+bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always)
{
Directory dir;
+#ifdef _WIN32
+ dir.Load(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(source)));
+#else
dir.Load(source);
+#endif
size_t fileNum;
if ( !SystemTools::MakeDirectory(destination) )
{
@@ -2205,13 +2352,13 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
kwsys_stl::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(SystemTools::FileIsDirectory(fullPath.c_str()))
+ if(SystemTools::FileIsDirectory(fullPath))
{
kwsys_stl::string fullDestPath = destination;
fullDestPath += "/";
fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if (!SystemTools::CopyADirectory(fullPath.c_str(),
- fullDestPath.c_str(),
+ if (!SystemTools::CopyADirectory(fullPath,
+ fullDestPath,
always))
{
return false;
@@ -2219,7 +2366,7 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
}
else
{
- if(!SystemTools::CopyAFile(fullPath.c_str(), destination, always))
+ if(!SystemTools::CopyAFile(fullPath, destination, always))
{
return false;
}
@@ -2234,15 +2381,28 @@ bool SystemTools::CopyADirectory(const char* source, const char* destination,
// return size of file; also returns zero if no file exists
unsigned long SystemTools::FileLength(const char* filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ unsigned long length = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard, &fs) != 0)
{
- return 0;
+ /* To support the full 64-bit file size, use fs.nFileSizeHigh
+ * and fs.nFileSizeLow to construct the 64 bit size
+
+ length = ((__int64)fs.nFileSizeHigh << 32) + fs.nFileSizeLow;
+ */
+ length = static_cast<unsigned long>(fs.nFileSizeLow);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename, &fs) == 0)
{
- return static_cast<unsigned long>(fs.st_size);
+ length = static_cast<unsigned long>(fs.st_size);
}
+#endif
+ return length;
}
int SystemTools::Strucmp(const char *s1, const char *s2)
@@ -2259,31 +2419,49 @@ int SystemTools::Strucmp(const char *s1, const char *s2)
}
// return file's modified time
-long int SystemTools::ModifiedTime(const char* filename)
+long int SystemTools::ModifiedTime(const kwsys_stl::string& filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ long int mt = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard,
+ &fs) != 0)
{
- return 0;
+ mt = windows_filetime_to_posix_time(fs.ftLastWriteTime);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename.c_str(), &fs) == 0)
{
- return static_cast<long int>(fs.st_mtime);
+ mt = static_cast<long int>(fs.st_mtime);
}
+#endif
+ return mt;
}
// return file's creation time
-long int SystemTools::CreationTime(const char* filename)
+long int SystemTools::CreationTime(const kwsys_stl::string& filename)
{
- struct stat fs;
- if (stat(filename, &fs) != 0)
+ long int ct = 0;
+#ifdef _WIN32
+ WIN32_FILE_ATTRIBUTE_DATA fs;
+ if (GetFileAttributesExW(
+ SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
+ GetFileExInfoStandard,
+ &fs) != 0)
{
- return 0;
+ ct = windows_filetime_to_posix_time(fs.ftCreationTime);
}
- else
+#else
+ struct stat fs;
+ if (stat(filename.c_str(), &fs) == 0)
{
- return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
+ ct = fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
}
+#endif
+ return ct;
}
bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt)
@@ -2394,7 +2572,7 @@ kwsys_stl::string SystemTools::GetLastSystemError()
return strerror(e);
}
-bool SystemTools::RemoveFile(const char* source)
+bool SystemTools::RemoveFile(const kwsys_stl::string& source)
{
#ifdef _WIN32
mode_t mode;
@@ -2406,9 +2584,10 @@ bool SystemTools::RemoveFile(const char* source)
SystemTools::SetPermissions(source, S_IWRITE);
#endif
#ifdef _WIN32
- bool res = _wunlink(Encoding::ToWide(source).c_str()) != 0 ? false : true;
+ bool res =
+ _wunlink(SystemTools::ConvertToWindowsExtendedPath(source).c_str()) == 0;
#else
- bool res = unlink(source) != 0 ? false : true;
+ bool res = unlink(source.c_str()) != 0 ? false : true;
#endif
#ifdef _WIN32
if ( !res )
@@ -2419,7 +2598,7 @@ bool SystemTools::RemoveFile(const char* source)
return res;
}
-bool SystemTools::RemoveADirectory(const char* source)
+bool SystemTools::RemoveADirectory(const kwsys_stl::string& source)
{
// Add write permission to the directory so we can modify its
// content to remove files and directories from it.
@@ -2435,7 +2614,12 @@ bool SystemTools::RemoveADirectory(const char* source)
}
Directory dir;
+#ifdef _WIN32
+ dir.Load(Encoding::ToNarrow(
+ SystemTools::ConvertToWindowsExtendedPath(source)));
+#else
dir.Load(source);
+#endif
size_t fileNum;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
{
@@ -2445,17 +2629,17 @@ bool SystemTools::RemoveADirectory(const char* source)
kwsys_stl::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
- if(SystemTools::FileIsDirectory(fullPath.c_str()) &&
- !SystemTools::FileIsSymlink(fullPath.c_str()))
+ if(SystemTools::FileIsDirectory(fullPath) &&
+ !SystemTools::FileIsSymlink(fullPath))
{
- if (!SystemTools::RemoveADirectory(fullPath.c_str()))
+ if (!SystemTools::RemoveADirectory(fullPath))
{
return false;
}
}
else
{
- if(!SystemTools::RemoveFile(fullPath.c_str()))
+ if(!SystemTools::RemoveFile(fullPath))
{
return false;
}
@@ -2517,7 +2701,7 @@ kwsys_stl::string SystemTools
{
tryPath = *p;
tryPath += name;
- if(SystemTools::FileExists(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath))
{
return tryPath;
}
@@ -2537,7 +2721,7 @@ kwsys_stl::string SystemTools
bool no_system_path)
{
kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
- if(tryPath != "" && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(!tryPath.empty() && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2556,7 +2740,7 @@ kwsys_stl::string SystemTools
bool no_system_path)
{
kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
- if(tryPath != "" && SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(!tryPath.empty() && SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2578,7 +2762,14 @@ kwsys_stl::string SystemTools::FindProgram(
{
return "";
}
- kwsys_stl::string name = nameIn;
+ return SystemTools::FindProgram(kwsys_stl::string(nameIn), userPaths, no_system_path);
+}
+
+kwsys_stl::string SystemTools::FindProgram(
+ const kwsys_stl::string& name,
+ const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+ bool no_system_path)
+{
kwsys_stl::vector<kwsys_stl::string> extensions;
#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
bool hasExtension = false;
@@ -2603,16 +2794,16 @@ kwsys_stl::string SystemTools::FindProgram(
{
tryPath = name;
tryPath += *i;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath) &&
+ !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
}
// now try just the name
tryPath = name;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath) &&
+ !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2658,8 +2849,8 @@ kwsys_stl::string SystemTools::FindProgram(
tryPath = *p;
tryPath += name;
tryPath += *ext;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath) &&
+ !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2667,8 +2858,8 @@ kwsys_stl::string SystemTools::FindProgram(
// now try it without them
tryPath = *p;
tryPath += name;
- if(SystemTools::FileExists(tryPath.c_str()) &&
- !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath) &&
+ !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2686,7 +2877,7 @@ kwsys_stl::string SystemTools::FindProgram(
it != names.end() ; ++it)
{
// Try to find the program.
- kwsys_stl::string result = SystemTools::FindProgram(it->c_str(),
+ kwsys_stl::string result = SystemTools::FindProgram(*it,
path,
noSystemPath);
if ( !result.empty() )
@@ -2703,7 +2894,7 @@ kwsys_stl::string SystemTools::FindProgram(
* found. Otherwise, the empty string is returned.
*/
kwsys_stl::string SystemTools
-::FindLibrary(const char* name,
+::FindLibrary(const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& userPaths)
{
// See if the executable exists as written.
@@ -2744,8 +2935,8 @@ kwsys_stl::string SystemTools
tryPath = *p;
tryPath += name;
tryPath += ".framework";
- if(SystemTools::FileExists(tryPath.c_str())
- && SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2754,8 +2945,8 @@ kwsys_stl::string SystemTools
tryPath = *p;
tryPath += name;
tryPath += ".lib";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2764,8 +2955,8 @@ kwsys_stl::string SystemTools
tryPath += "lib";
tryPath += name;
tryPath += ".so";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2773,8 +2964,8 @@ kwsys_stl::string SystemTools
tryPath += "lib";
tryPath += name;
tryPath += ".a";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2782,8 +2973,8 @@ kwsys_stl::string SystemTools
tryPath += "lib";
tryPath += name;
tryPath += ".sl";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2791,8 +2982,8 @@ kwsys_stl::string SystemTools
tryPath += "lib";
tryPath += name;
tryPath += ".dylib";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2800,8 +2991,8 @@ kwsys_stl::string SystemTools
tryPath += "lib";
tryPath += name;
tryPath += ".dll";
- if(SystemTools::FileExists(tryPath.c_str())
- && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ if(SystemTools::FileExists(tryPath)
+ && !SystemTools::FileIsDirectory(tryPath))
{
return SystemTools::CollapseFullPath(tryPath);
}
@@ -2812,32 +3003,33 @@ kwsys_stl::string SystemTools
return "";
}
-kwsys_stl::string SystemTools::GetRealPath(const char* path)
+kwsys_stl::string SystemTools::GetRealPath(const kwsys_stl::string& path)
{
kwsys_stl::string ret;
Realpath(path, ret);
return ret;
}
-bool SystemTools::FileIsDirectory(const char* name)
+bool SystemTools::FileIsDirectory(const kwsys_stl::string& inName)
{
- if (!*name)
+ if (inName.empty())
{
return false;
}
- size_t length = strlen(name);
+ size_t length = inName.size();
+ const char* name = inName.c_str();
// Remove any trailing slash from the name except in a root component.
char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
std::string string_buffer;
size_t last = length-1;
if(last > 0 && (name[last] == '/' || name[last] == '\\')
- && strcmp(name, "/") !=0 && name[last-1] != ':')
+ && strcmp(name, "/") != 0 && name[last-1] != ':')
{
- if(last < sizeof(local_buffer))
+ if (last < sizeof(local_buffer))
{
memcpy(local_buffer, name, last);
- local_buffer[last] = 0;
+ local_buffer[last] = '\0';
name = local_buffer;
}
else
@@ -2849,7 +3041,8 @@ bool SystemTools::FileIsDirectory(const char* name)
// Now check the file node type.
#if defined( _WIN32 )
- DWORD attr = GetFileAttributesW(Encoding::ToWide(name).c_str());
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES)
{
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
@@ -2866,14 +3059,14 @@ bool SystemTools::FileIsDirectory(const char* name)
}
}
-bool SystemTools::FileIsSymlink(const char* name)
+bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
{
#if defined( _WIN32 )
(void)name;
return false;
#else
struct stat fs;
- if(lstat(name, &fs) == 0)
+ if(lstat(name.c_str(), &fs) == 0)
{
return S_ISLNK(fs.st_mode);
}
@@ -2922,7 +3115,7 @@ bool SystemTools::ReadSymlink(const char* newName,
}
#endif
-int SystemTools::ChangeDirectory(const char *dir)
+int SystemTools::ChangeDirectory(const kwsys_stl::string& dir)
{
return Chdir(dir);
}
@@ -2959,7 +3152,7 @@ bool SystemTools::SplitProgramPath(const char* in_name,
file = "";
SystemTools::ConvertToUnixSlashes(dir);
- if(!SystemTools::FileIsDirectory(dir.c_str()))
+ if(!SystemTools::FileIsDirectory(dir))
{
kwsys_stl::string::size_type slashPos = dir.rfind("/");
if(slashPos != kwsys_stl::string::npos)
@@ -2973,7 +3166,7 @@ bool SystemTools::SplitProgramPath(const char* in_name,
dir = "";
}
}
- if(!(dir == "") && !SystemTools::FileIsDirectory(dir.c_str()))
+ if(!(dir.empty()) && !SystemTools::FileIsDirectory(dir))
{
kwsys_stl::string oldDir = in_name;
SystemTools::ConvertToUnixSlashes(oldDir);
@@ -2994,8 +3187,8 @@ bool SystemTools::FindProgramPath(const char* argv0,
kwsys_stl::string self = argv0 ? argv0 : "";
failures.push_back(self);
SystemTools::ConvertToUnixSlashes(self);
- self = SystemTools::FindProgram(self.c_str());
- if(!SystemTools::FileExists(self.c_str()))
+ self = SystemTools::FindProgram(self);
+ if(!SystemTools::FileExists(self))
{
if(buildDir)
{
@@ -3013,7 +3206,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
}
if(installPrefix)
{
- if(!SystemTools::FileExists(self.c_str()))
+ if(!SystemTools::FileExists(self))
{
failures.push_back(self);
self = installPrefix;
@@ -3021,7 +3214,7 @@ bool SystemTools::FindProgramPath(const char* argv0,
self += exeName;
}
}
- if(!SystemTools::FileExists(self.c_str()))
+ if(!SystemTools::FileExists(self))
{
failures.push_back(self);
kwsys_ios::ostringstream msg;
@@ -3062,12 +3255,12 @@ void SystemTools::AddTranslationPath(const kwsys_stl::string& a, const kwsys_stl
SystemTools::ConvertToUnixSlashes(path_b);
// First check this is a directory path, since we don't want the table to
// grow too fat
- if( SystemTools::FileIsDirectory( path_a.c_str() ) )
+ if( SystemTools::FileIsDirectory( path_a ) )
{
// Make sure the path is a full path and does not contain no '..'
// Ken--the following code is incorrect. .. can be in a valid path
// for example /home/martink/MyHubba...Hubba/Src
- if( SystemTools::FileIsFullPath(path_b.c_str()) && path_b.find("..")
+ if( SystemTools::FileIsFullPath(path_b) && path_b.find("..")
== kwsys_stl::string::npos )
{
// Before inserting make sure path ends with '/'
@@ -3224,7 +3417,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
}
// compute the relative path from here to there
-kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remote)
+kwsys_stl::string SystemTools::RelativePath(const kwsys_stl::string& local, const kwsys_stl::string& remote)
{
if(!SystemTools::FileIsFullPath(local))
{
@@ -3235,9 +3428,12 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot
return "";
}
+ kwsys_stl::string l = SystemTools::CollapseFullPath(local);
+ kwsys_stl::string r = SystemTools::CollapseFullPath(remote);
+
// split up both paths into arrays of strings using / as a separator
- kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(local, '/', true);
- kwsys_stl::vector<kwsys::String> remoteSplit = SystemTools::SplitString(remote, '/', true);
+ kwsys_stl::vector<kwsys::String> localSplit = SystemTools::SplitString(l, '/', true);
+ kwsys_stl::vector<kwsys::String> remoteSplit = SystemTools::SplitString(r, '/', true);
kwsys_stl::vector<kwsys::String> commonPath; // store shared parts of path in this array
kwsys_stl::vector<kwsys::String> finalPath; // store the final relative path here
// count up how many matching directory names there are from the start
@@ -3343,6 +3539,16 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
kwsys_stl::string test_str = casePath;
test_str += path_components[idx];
+ // If path component contains wildcards, we skip matching
+ // because these filenames are not allowed on windows,
+ // and we do not want to match a different file.
+ if(path_components[idx].find('*') != kwsys_stl::string::npos ||
+ path_components[idx].find('?') != kwsys_stl::string::npos)
+ {
+ casePath = "";
+ return 0;
+ }
+
WIN32_FIND_DATAW findData;
HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
&findData);
@@ -3614,7 +3820,7 @@ bool SystemTools::ComparePath(const kwsys_stl::string& c1, const kwsys_stl::stri
}
//----------------------------------------------------------------------------
-bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines, char separator)
+bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_stl::string>& lines, char separator)
{
kwsys_stl::string data(str);
kwsys_stl::string::size_type lpos = 0;
@@ -3638,7 +3844,7 @@ bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& l
}
//----------------------------------------------------------------------------
-bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines)
+bool SystemTools::Split(const kwsys_stl::string& str, kwsys_stl::vector<kwsys_stl::string>& lines)
{
kwsys_stl::string data(str);
kwsys_stl::string::size_type lpos = 0;
@@ -3931,7 +4137,7 @@ bool SystemTools::LocateFileInDir(const char *filename,
}
temp += filename_base;
- if (SystemTools::FileExists(temp.c_str()))
+ if (SystemTools::FileExists(temp))
{
res = true;
filename_found = temp;
@@ -3980,9 +4186,18 @@ bool SystemTools::LocateFileInDir(const char *filename,
return res;
}
+bool SystemTools::FileIsFullPath(const kwsys_stl::string& in_name)
+{
+ return SystemTools::FileIsFullPath(in_name.c_str(), in_name.size());
+}
+
bool SystemTools::FileIsFullPath(const char* in_name)
{
- size_t len = strlen(in_name);
+ return SystemTools::FileIsFullPath(in_name, in_name[0] ? (in_name[1] ? 2 : 1) : 0);
+}
+
+bool SystemTools::FileIsFullPath(const char* in_name, size_t len)
+{
#if defined(_WIN32) || defined(__CYGWIN__)
// On Windows, the name must be at least two characters long.
if(len < 2)
@@ -4041,7 +4256,7 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string&
kwsys_stl::wstring wtempPath = Encoding::ToWide(tempPath);
kwsys_stl::vector<wchar_t> buffer(wtempPath.size()+1);
buffer[0] = 0;
- ret = GetShortPathNameW(Encoding::ToWide(tempPath).c_str(),
+ ret = GetShortPathNameW(wtempPath.c_str(),
&buffer[0], static_cast<DWORD>(wtempPath.size()));
if(buffer[0] == 0 || ret > wtempPath.size())
@@ -4091,7 +4306,7 @@ void SystemTools::SplitProgramFromArgs(const char* path,
{
kwsys_stl::string tryProg = dir.substr(0, spacePos);
// See if the file exists
- if(SystemTools::FileExists(tryProg.c_str()))
+ if(SystemTools::FileExists(tryProg))
{
program = tryProg;
// remove trailing spaces from program
@@ -4105,7 +4320,7 @@ void SystemTools::SplitProgramFromArgs(const char* path,
return;
}
// Now try and find the program in the path
- findProg = SystemTools::FindProgram(tryProg.c_str(), e);
+ findProg = SystemTools::FindProgram(tryProg, e);
if(!findProg.empty())
{
program = findProg;
@@ -4277,9 +4492,14 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
{
return false;
}
+ return SystemTools::GetPermissions(kwsys_stl::string(file), mode);
+}
+bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode)
+{
#if defined(_WIN32)
- DWORD attr = GetFileAttributesW(Encoding::ToWide(file).c_str());
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(file).c_str());
if(attr == INVALID_FILE_ATTRIBUTES)
{
return false;
@@ -4301,7 +4521,8 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
{
mode |= S_IFREG;
}
- const char* ext = strrchr(file, '.');
+ size_t dotPos = file.rfind('.');
+ const char* ext = dotPos == file.npos ? 0 : (file.c_str() + dotPos);
if(ext && (Strucmp(ext, ".exe") == 0 ||
Strucmp(ext, ".com") == 0 ||
Strucmp(ext, ".cmd") == 0 ||
@@ -4311,7 +4532,7 @@ bool SystemTools::GetPermissions(const char* file, mode_t& mode)
}
#else
struct stat st;
- if ( stat(file, &st) < 0 )
+ if ( stat(file.c_str(), &st) < 0 )
{
return false;
}
@@ -4326,14 +4547,20 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode)
{
return false;
}
+ return SystemTools::SetPermissions(kwsys_stl::string(file), mode);
+}
+
+bool SystemTools::SetPermissions(const kwsys_stl::string& file, mode_t mode)
+{
if ( !SystemTools::FileExists(file) )
{
return false;
}
#ifdef _WIN32
- if ( _wchmod(Encoding::ToWide(file).c_str(), mode) < 0 )
+ if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
+ mode) < 0 )
#else
- if ( chmod(file, mode) < 0 )
+ if ( chmod(file.c_str(), mode) < 0 )
#endif
{
return false;
@@ -4342,7 +4569,7 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode)
return true;
}
-kwsys_stl::string SystemTools::GetParentDirectory(const char* fileOrDir)
+kwsys_stl::string SystemTools::GetParentDirectory(const kwsys_stl::string& fileOrDir)
{
return SystemTools::GetFilenamePath(fileOrDir);
}
@@ -4389,111 +4616,6 @@ void SystemTools::Delay(unsigned int msec)
#endif
}
-void SystemTools::ConvertWindowsCommandLineToUnixArguments(
- const char *cmd_line, int *argc, char ***argv)
-{
- if (!cmd_line || !argc || !argv)
- {
- return;
- }
-
- // A space delimites an argument except when it is inside a quote
-
- (*argc) = 1;
-
- size_t cmd_line_len = strlen(cmd_line);
-
- size_t i;
- for (i = 0; i < cmd_line_len; i++)
- {
- while (isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- if (i < cmd_line_len)
- {
- if (cmd_line[i] == '\"')
- {
- i++;
- while (cmd_line[i] != '\"' && i < cmd_line_len)
- {
- i++;
- }
- (*argc)++;
- }
- else
- {
- while (!isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- (*argc)++;
- }
- }
- }
-
- (*argv) = new char* [(*argc) + 1];
- (*argv)[(*argc)] = NULL;
-
- // Set the first arg to be the exec name
-
- (*argv)[0] = new char [1024];
-#ifdef _WIN32
- wchar_t tmp[1024];
- ::GetModuleFileNameW(0, tmp, 1024);
- strcpy((*argv)[0], Encoding::ToNarrow(tmp).c_str());
-#else
- (*argv)[0][0] = '\0';
-#endif
-
- // Allocate the others
-
- int j;
- for (j = 1; j < (*argc); j++)
- {
- (*argv)[j] = new char [cmd_line_len + 10];
- }
-
- // Grab the args
-
- size_t pos;
- int argc_idx = 1;
-
- for (i = 0; i < cmd_line_len; i++)
- {
- while (isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- if (i < cmd_line_len)
- {
- if (cmd_line[i] == '\"')
- {
- i++;
- pos = i;
- while (cmd_line[i] != '\"' && i < cmd_line_len)
- {
- i++;
- }
- memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
- (*argv)[argc_idx][i - pos] = '\0';
- argc_idx++;
- }
- else
- {
- pos = i;
- while (!isspace(cmd_line[i]) && i < cmd_line_len)
- {
- i++;
- }
- memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
- (*argv)[argc_idx][i - pos] = '\0';
- argc_idx++;
- }
- }
- }
- }
-
kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
{
kwsys_stl::string res;
@@ -4510,6 +4632,10 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (push)
+# pragma warning (disable:4996)
+#endif
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi);
if (!bOsVersionInfoEx)
{
@@ -4519,6 +4645,9 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion()
return 0;
}
}
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
+# pragma warning (pop)
+#endif
switch (osvi.dwPlatformId)
{
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index fb55848..e88bc8f 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -158,7 +158,9 @@ public:
* Returns true if str1 starts (respectively ends) with str2
*/
static bool StringStartsWith(const char* str1, const char* str2);
+ static bool StringStartsWith(const kwsys_stl::string& str1, const char* str2);
static bool StringEndsWith(const char* str1, const char* str2);
+ static bool StringEndsWith(const kwsys_stl::string& str1, const char* str2);
/**
* Returns a pointer to the last occurence of str2 in str1
@@ -183,7 +185,7 @@ public:
s starts with a / then the first element of the returned array will
be /, so /foo/bar will be [/, foo, bar]
*/
- static kwsys_stl::vector<String> SplitString(const char* s, char separator = '/',
+ static kwsys_stl::vector<String> SplitString(const kwsys_stl::string& s, char separator = '/',
bool isPath = false);
/**
* Perform a case-independent string comparison
@@ -201,8 +203,8 @@ public:
* Split a string on its newlines into multiple lines
* Return false only if the last line stored had no newline
*/
- static bool Split(const char* s, kwsys_stl::vector<kwsys_stl::string>& l);
- static bool Split(const char* s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
+ static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l);
+ static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
/**
* Return string with space added between capitalized words
@@ -249,18 +251,29 @@ public:
* Replace Windows file system slashes with Unix-style slashes.
*/
static void ConvertToUnixSlashes(kwsys_stl::string& path);
-
+
+#ifdef _WIN32
+ /**
+ * Convert the path to an extended length path to avoid MAX_PATH length
+ * limitations on Windows. If the input is a local path the result will be
+ * prefixed with \\?\; if the input is instead a network path, the result
+ * will be prefixed with \\?\UNC\. All output will also be converted to
+ * absolute paths with Windows-style backslashes.
+ **/
+ static kwsys_stl::wstring ConvertToWindowsExtendedPath(const kwsys_stl::string&);
+#endif
+
/**
* For windows this calls ConvertToWindowsOutputPath and for unix
* it calls ConvertToUnixOutputPath
*/
- static kwsys_stl::string ConvertToOutputPath(const char*);
+ static kwsys_stl::string ConvertToOutputPath(const kwsys_stl::string&);
/**
* Convert the path to a string that can be used in a unix makefile.
* double slashes are removed, and spaces are escaped.
*/
- static kwsys_stl::string ConvertToUnixOutputPath(const char*);
+ static kwsys_stl::string ConvertToUnixOutputPath(const kwsys_stl::string&);
/**
* Convert the path to string that can be used in a windows project or
@@ -268,7 +281,7 @@ public:
* the string, the slashes are converted to windows style backslashes, and
* if there are spaces in the string it is double quoted.
*/
- static kwsys_stl::string ConvertToWindowsOutputPath(const char*);
+ static kwsys_stl::string ConvertToWindowsOutputPath(const kwsys_stl::string&);
/**
* Return true if a file exists in the current directory.
@@ -277,7 +290,9 @@ public:
* if it is a file or a directory.
*/
static bool FileExists(const char* filename, bool isFile);
+ static bool FileExists(const kwsys_stl::string& filename, bool isFile);
static bool FileExists(const char* filename);
+ static bool FileExists(const kwsys_stl::string& filename);
/**
* Converts Cygwin path to Win32 path. Uses dictionary container for
@@ -296,7 +311,7 @@ public:
/**
Change the modification time or create a file
*/
- static bool Touch(const char* filename, bool create);
+ static bool Touch(const kwsys_stl::string& filename, bool create);
/**
* Compare file modification times.
@@ -304,7 +319,8 @@ public:
* When true is returned, result has -1, 0, +1 for
* f1 older, same, or newer than f2.
*/
- static bool FileTimeCompare(const char* f1, const char* f2,
+ static bool FileTimeCompare(const kwsys_stl::string& f1,
+ const kwsys_stl::string& f2,
int* result);
/**
@@ -366,7 +382,7 @@ public:
* the event of an error (non-existent path, permissions issue,
* etc.) the original path is returned.
*/
- static kwsys_stl::string GetRealPath(const char* path);
+ static kwsys_stl::string GetRealPath(const kwsys_stl::string& path);
/**
* Split a path name into its root component and the rest of the
@@ -459,6 +475,7 @@ public:
/**
* Return whether the path represents a full path (not relative)
*/
+ static bool FileIsFullPath(const kwsys_stl::string&);
static bool FileIsFullPath(const char*);
/**
@@ -482,7 +499,7 @@ public:
/**
* Get the parent directory of the directory or file
*/
- static kwsys_stl::string GetParentDirectory(const char* fileOrDir);
+ static kwsys_stl::string GetParentDirectory(const kwsys_stl::string& fileOrDir);
/**
* Check if the given file or directory is in subdirectory of dir
@@ -497,7 +514,7 @@ public:
/**
* Open a file considering unicode.
*/
- static FILE* Fopen(const char* file, const char* mode);
+ static FILE* Fopen(const kwsys_stl::string& file, const char* mode);
/**
* Make a new directory if it is not there. This function
@@ -505,35 +522,36 @@ public:
* prior to calling this function.
*/
static bool MakeDirectory(const char* path);
+ static bool MakeDirectory(const kwsys_stl::string& path);
/**
* Copy the source file to the destination file only
* if the two files differ.
*/
- static bool CopyFileIfDifferent(const char* source,
- const char* destination);
+ static bool CopyFileIfDifferent(const kwsys_stl::string& source,
+ const kwsys_stl::string& destination);
/**
* Compare the contents of two files. Return true if different
*/
- static bool FilesDiffer(const char* source, const char* destination);
+ static bool FilesDiffer(const kwsys_stl::string& source, const kwsys_stl::string& destination);
/**
* Return true if the two files are the same file
*/
- static bool SameFile(const char* file1, const char* file2);
+ static bool SameFile(const kwsys_stl::string& file1, const kwsys_stl::string& file2);
/**
* Copy a file.
*/
- static bool CopyFileAlways(const char* source, const char* destination);
+ static bool CopyFileAlways(const kwsys_stl::string& source, const kwsys_stl::string& destination);
/**
* Copy a file. If the "always" argument is true the file is always
* copied. If it is false, the file is copied only if it is new or
* has changed.
*/
- static bool CopyAFile(const char* source, const char* destination,
+ static bool CopyAFile(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always = true);
/**
@@ -542,18 +560,18 @@ public:
* always copied. If it is false, only files that have changed or
* are new are copied.
*/
- static bool CopyADirectory(const char* source, const char* destination,
+ static bool CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always = true);
/**
* Remove a file
*/
- static bool RemoveFile(const char* source);
+ static bool RemoveFile(const kwsys_stl::string& source);
/**
* Remove a directory
*/
- static bool RemoveADirectory(const char* source);
+ static bool RemoveADirectory(const kwsys_stl::string& source);
/**
* Get the maximum full file path length
@@ -583,12 +601,17 @@ public:
*/
static kwsys_stl::string FindProgram(
const char* name,
- const kwsys_stl::vector<kwsys_stl::string>& path =
+ const kwsys_stl::vector<kwsys_stl::string>& path =
+ kwsys_stl::vector<kwsys_stl::string>(),
+ bool no_system_path = false);
+ static kwsys_stl::string FindProgram(
+ const kwsys_stl::string& name,
+ const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false);
static kwsys_stl::string FindProgram(
const kwsys_stl::vector<kwsys_stl::string>& names,
- const kwsys_stl::vector<kwsys_stl::string>& path =
+ const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false);
@@ -596,18 +619,18 @@ public:
* Find a library in the system PATH, with optional extra paths
*/
static kwsys_stl::string FindLibrary(
- const char* name,
+ const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path);
/**
* Return true if the file is a directory
*/
- static bool FileIsDirectory(const char* name);
+ static bool FileIsDirectory(const kwsys_stl::string& name);
/**
* Return true if the file is a symlink
*/
- static bool FileIsSymlink(const char* name);
+ static bool FileIsSymlink(const kwsys_stl::string& name);
/**
* Return true if the file has a given signature (first set of bytes)
@@ -675,17 +698,17 @@ public:
/a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
*/
- static kwsys_stl::string RelativePath(const char* local, const char* remote);
+ static kwsys_stl::string RelativePath(const kwsys_stl::string& local, const kwsys_stl::string& remote);
/**
* Return file's modified time
*/
- static long int ModifiedTime(const char* filename);
+ static long int ModifiedTime(const kwsys_stl::string& filename);
/**
* Return file's creation time (Win32: works only for NTFS, not FAT)
*/
- static long int CreationTime(const char* filename);
+ static long int CreationTime(const kwsys_stl::string& filename);
#if defined( _MSC_VER )
typedef unsigned short mode_t;
@@ -695,7 +718,9 @@ public:
* Get and set permissions of the file.
*/
static bool GetPermissions(const char* file, mode_t& mode);
+ static bool GetPermissions(const kwsys_stl::string& file, mode_t& mode);
static bool SetPermissions(const char* file, mode_t mode);
+ static bool SetPermissions(const kwsys_stl::string& file, mode_t mode);
/** -----------------------------------------------------------------
* Time Manipulation Routines
@@ -782,7 +807,7 @@ public:
/**
* Change directory to the directory specified
*/
- static int ChangeDirectory(const char* dir);
+ static int ChangeDirectory(const kwsys_stl::string& dir);
/**
* Get the result of strerror(errno)
@@ -831,15 +856,6 @@ public:
*/
static kwsys_stl::string GetOperatingSystemNameAndVersion();
- /**
- * Convert windows-style arguments given as a command-line string
- * into more traditional argc/argv arguments.
- * Note that argv[0] will be assigned the executable name using
- * the GetModuleFileName() function.
- */
- static void ConvertWindowsCommandLineToUnixArguments(
- const char *cmd_line, int *argc, char ***argv);
-
/** -----------------------------------------------------------------
* URL Manipulation Routines
* -----------------------------------------------------------------
@@ -890,6 +906,11 @@ private:
}
/**
+ * Actual implementation of FileIsFullPath.
+ */
+ static bool FileIsFullPath(const char*, size_t);
+
+ /**
* Find a filename (file or directory) in the system PATH, with
* optional extra paths.
*/
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index 6d7ec41..e13003f 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -104,11 +104,11 @@ void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...)
}
/*--------------------------------------------------------------------------*/
-/* Detect cases when a stream is definately not interactive. */
+/* Detect cases when a stream is definitely not interactive. */
#if !defined(KWSYS_TERMINAL_ISATTY_WORKS)
static int kwsysTerminalStreamIsNotInteractive(FILE* stream)
{
- /* The given stream is definately not interactive if it is a regular
+ /* The given stream is definitely not interactive if it is a regular
file. */
struct stat stream_stat;
if(fstat(fileno(stream), &stream_stat) == 0)
@@ -212,7 +212,7 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
(void)default_tty;
return isatty(fileno(stream))? 1:0;
#else
- /* Check for cases in which the stream is definately not a tty. */
+ /* Check for cases in which the stream is definitely not a tty. */
if(kwsysTerminalStreamIsNotInteractive(stream))
{
return 0;
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index f9ee254..16bc969 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -13,7 +13,7 @@ SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
MACRO(KWSYS_PLATFORM_TEST lang var description invert)
- IF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
+ IF(NOT DEFINED ${var}_COMPILED)
MESSAGE(STATUS "${description}")
TRY_COMPILE(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
@@ -43,7 +43,7 @@ MACRO(KWSYS_PLATFORM_TEST lang var description invert)
MESSAGE(STATUS "${description} - no")
ENDIF(${var}_COMPILED)
ENDIF(${invert} MATCHES INVERT)
- ENDIF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
SET(${var} 0)
@@ -60,7 +60,7 @@ MACRO(KWSYS_PLATFORM_TEST lang var description invert)
ENDMACRO(KWSYS_PLATFORM_TEST)
MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
- IF("${var}" MATCHES "^${var}$")
+ IF(NOT DEFINED ${var})
MESSAGE(STATUS "${description}")
TRY_RUN(${var} ${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
@@ -107,7 +107,7 @@ MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
MESSAGE(STATUS "${description} - failed to compile")
ENDIF(${var}_COMPILED)
ENDIF(${invert} MATCHES INVERT)
- ENDIF("${var}" MATCHES "^${var}$")
+ ENDIF()
IF(${invert} MATCHES INVERT)
IF(${var}_COMPILED)
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 3b84c38..b65c37f 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -21,6 +21,7 @@
# include "kwsys_ios_iostream.h.in"
#endif
+#include <assert.h> /* assert */
#include <string.h> /* strcmp */
int testCommandLineArguments1(int argc, char* argv[])
@@ -83,6 +84,7 @@ int testCommandLineArguments1(int argc, char* argv[])
}
for ( cc = 0; cc < newArgc; ++ cc )
{
+ assert(newArgv[cc]); /* Quiet Clang scan-build. */
kwsys_ios::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
<< kwsys_ios::endl;
if ( cc >= 9 )
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 1bff707..58adb84 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -108,7 +108,7 @@ int testDynamicLoader(int argc, char *argv[])
// Make sure that inexistent lib is giving correct result
res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
// Make sure that random binary file cannot be assimilated as dylib
- res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
+ res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin", "wp",0,0,0);
#endif
#ifdef __linux__
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 6d5eb71..47c3fb0 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -11,13 +11,16 @@
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
+#include KWSYS_HEADER(Encoding.h)
/* Work-around CMake dependency scanning limitation. This must
duplicate the above list of headers. */
#if 0
# include "Process.h.in"
+# include "Encoding.h.in"
#endif
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -102,6 +105,7 @@ static int test4(int argc, const char* argv[])
fprintf(stderr, "Output before crash on stderr from crash test.\n");
fflush(stdout);
fflush(stderr);
+ assert(invalidAddress); /* Quiet Clang scan-build. */
/* Provoke deliberate crash by writing to the invalid address. */
*invalidAddress = 0;
fprintf(stdout, "Output after crash on stdout from crash test.\n");
@@ -393,6 +397,19 @@ int runChild(const char* cmd[], int state, int exception, int value,
int main(int argc, const char* argv[])
{
int n = 0;
+
+#ifdef _WIN32
+ int i;
+ char new_args[10][_MAX_PATH];
+ LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &argc);
+ for(i=0; i<argc; i++)
+ {
+ kwsysEncoding_wcstombs(new_args[i], w_av[i], _MAX_PATH);
+ argv[i] = new_args[i];
+ }
+ LocalFree(w_av);
+#endif
+
#if 0
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 69825a8..b41532b 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -98,32 +98,124 @@ static bool CheckEscapeChars(kwsys_stl::string input,
static bool CheckFileOperations()
{
bool res = true;
-
- if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_BIN_FILE) !=
+ const kwsys_stl::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemTools.bin");
+ const kwsys_stl::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemTools.cxx");
+ const kwsys_stl::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR
+ "/testSystemToolsNewDir");
+ const kwsys_stl::string testNewFile(testNewDir + "/testNewFile.txt");
+
+ if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
kwsys::SystemTools::FileTypeBinary)
{
kwsys_ios::cerr
<< "Problem with DetectFileType - failed to detect type of: "
- << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
+ << testBinFile << kwsys_ios::endl;
res = false;
}
- if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_SRC_FILE) !=
+ if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) !=
kwsys::SystemTools::FileTypeText)
{
kwsys_ios::cerr
<< "Problem with DetectFileType - failed to detect type of: "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << testTxtFile << kwsys_ios::endl;
res = false;
}
-
- if (kwsys::SystemTools::FileLength(TEST_SYSTEMTOOLS_BIN_FILE) != 766)
+
+ if (kwsys::SystemTools::FileLength(testBinFile.c_str()) != 766)
{
kwsys_ios::cerr
<< "Problem with FileLength - incorrect length for: "
- << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
- res = false;
+ << testBinFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::MakeDirectory(testNewDir))
+ {
+ kwsys_ios::cerr
+ << "Problem with MakeDirectory for: "
+ << testNewDir << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true))
+ {
+ kwsys_ios::cerr
+ << "Problem with Touch for: "
+ << testNewFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::RemoveFile(testNewFile))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveFile: "
+ << testNewFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ kwsys::SystemTools::Touch(testNewFile.c_str(), true);
+ if (!kwsys::SystemTools::RemoveADirectory(testNewDir))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveADirectory for: "
+ << testNewDir << kwsys_ios::endl;
+ res = false;
+ }
+
+#ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
+ // Perform the same file and directory creation and deletion tests but
+ // with paths > 256 characters in length.
+
+ const kwsys_stl::string testNewLongDir(
+ TEST_SYSTEMTOOLS_BINARY_DIR "/"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "01234567890123");
+ const kwsys_stl::string testNewLongFile(testNewLongDir + "/"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "012345678901234567890123456789012345678901234567890123456789"
+ "0123456789.txt");
+
+ if (!kwsys::SystemTools::MakeDirectory(testNewLongDir))
+ {
+ kwsys_ios::cerr
+ << "Problem with MakeDirectory for: "
+ << testNewLongDir << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true))
+ {
+ kwsys_ios::cerr
+ << "Problem with Touch for: "
+ << testNewLongFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::RemoveFile(testNewLongFile))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveFile: "
+ << testNewLongFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ kwsys::SystemTools::Touch(testNewLongFile.c_str(), true);
+ if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveADirectory for: "
+ << testNewLongDir << kwsys_ios::endl;
+ res = false;
}
+#endif
return res;
}
@@ -138,7 +230,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with CapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << '"' << test << '"' << kwsys_ios::endl;
res = false;
}
@@ -148,7 +240,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with UnCapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << '"' << test << '"' << kwsys_ios::endl;
res = false;
}
@@ -158,7 +250,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with AddSpaceBetweenCapitalizedWords "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << '"' << test << '"' << kwsys_ios::endl;
res = false;
}
@@ -168,7 +260,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with AppendStrings "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A\" \" Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres;
@@ -179,7 +271,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with AppendStrings "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had\" \" A \" \"Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres;
@@ -188,7 +280,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with CountChar "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
@@ -198,7 +290,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with RemoveChars "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres;
@@ -209,7 +301,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with RemoveCharsButUpperHex "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres;
@@ -221,7 +313,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with ReplaceChars "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres2;
@@ -231,7 +323,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with StringStartsWith "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
@@ -240,7 +332,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with StringEndsWith "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
@@ -249,7 +341,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with DuplicateString "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
delete [] cres;
@@ -260,7 +352,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with CropString "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
res = false;
}
@@ -271,16 +363,124 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with Split "
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
+ << "\"Mary Had A Little Lamb.\"" << kwsys_ios::endl;
+ res = false;
+ }
+
+#ifdef _WIN32
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("L:/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath
+ ("//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\""
+ << kwsys_ios::endl;
+ res = false;
}
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("//") !=
+ L"//")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"//\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\") !=
+ L"\\\\.\\")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X") !=
+ L"\\\\.\\X")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:") !=
+ L"\\\\?\\X:")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X:\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("\\\\.\\X:\\") !=
+ L"\\\\?\\X:\\")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"\\\\.\\X:\\\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsExtendedPath("NUL") !=
+ L"\\\\.\\NUL")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsExtendedPath "
+ << "\"NUL\""
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+#endif
+
if (kwsys::SystemTools::ConvertToWindowsOutputPath
("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
"\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
{
kwsys_ios::cerr
<< "Problem with ConvertToWindowsOutputPath "
+ << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl;
res = false;
}
@@ -291,6 +491,7 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with ConvertToWindowsOutputPath "
+ << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl;
res = false;
}
@@ -301,29 +502,11 @@ static bool CheckStringOperations()
{
kwsys_ios::cerr
<< "Problem with ConvertToUnixOutputPath "
+ << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\""
<< kwsys_ios::endl;
res = false;
}
- int targc;
- char **targv;
- kwsys::SystemTools::ConvertWindowsCommandLineToUnixArguments
- ("\"Local Mojo\\Voodoo.asp\" -CastHex \"D:\\My Secret Mojo\\Voodoo.mp3\"", &targc, &targv);
- if (targc != 4 || strcmp(targv[1],"Local Mojo\\Voodoo.asp") ||
- strcmp(targv[2],"-CastHex") ||
- strcmp(targv[3],"D:\\My Secret Mojo\\Voodoo.mp3"))
- {
- kwsys_ios::cerr
- << "Problem with ConvertWindowsCommandLineToUnixArguments"
- << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
- res = false;
- }
- for (;targc >=0; --targc)
- {
- delete [] targv[targc];
- }
- delete [] targv;
-
return res;
}
@@ -379,6 +562,55 @@ static bool CheckEnvironmentOperations()
return res;
}
+
+static bool CheckRelativePath(
+ const kwsys_stl::string& local,
+ const kwsys_stl::string& remote,
+ const kwsys_stl::string& expected)
+{
+ kwsys_stl::string result = kwsys::SystemTools::RelativePath(local, remote);
+ if(expected != result)
+ {
+ kwsys_ios::cerr << "RelativePath(" << local << ", " << remote
+ << ") yielded " << result << " instead of " << expected << kwsys_ios::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckRelativePaths()
+{
+ bool res = true;
+ res &= CheckRelativePath("/usr/share", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/./share/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr//share/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash");
+ res &= CheckRelativePath("/usr/share", "/usr/share//bin", "bin");
+ return res;
+}
+
+static bool CheckCollapsePath(
+ const kwsys_stl::string& path,
+ const kwsys_stl::string& expected)
+{
+ kwsys_stl::string result = kwsys::SystemTools::CollapseFullPath(path);
+ if(expected != result)
+ {
+ kwsys_ios::cerr << "CollapseFullPath(" << path
+ << ") yielded " << result << " instead of " << expected << kwsys_ios::endl;
+ return false;
+ }
+ return true;
+}
+
+static bool CheckCollapsePath()
+{
+ bool res = true;
+ res &= CheckCollapsePath("/usr/share/*", "/usr/share/*");
+ res &= CheckCollapsePath("C:/Windows/*", "C:/Windows/*");
+ return res;
+}
+
//----------------------------------------------------------------------------
int testSystemTools(int, char*[])
{
@@ -410,5 +642,9 @@ int testSystemTools(int, char*[])
res &= CheckEnvironmentOperations();
+ res &= CheckRelativePaths();
+
+ res &= CheckCollapsePath();
+
return res ? 0 : 1;
}
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
index 4b94bb6..66f0f72 100644
--- a/Source/kwsys/testSystemTools.h.in
+++ b/Source/kwsys/testSystemTools.h.in
@@ -14,7 +14,8 @@
#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
-#define TEST_SYSTEMTOOLS_BIN_FILE "@TEST_SYSTEMTOOLS_BIN_FILE@"
-#define TEST_SYSTEMTOOLS_SRC_FILE "@TEST_SYSTEMTOOLS_SRC_FILE@"
+#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
+#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"
+#cmakedefine KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS
#endif