Imported Upstream version 2.8.11.2 sandbox/pcoval/previous/upstream upstream/2.8.11.2
authorAnas Nashif <anas.nashif@intel.com>
Tue, 13 Aug 2013 11:48:01 +0000 (07:48 -0400)
committerAnas Nashif <anas.nashif@intel.com>
Tue, 13 Aug 2013 11:48:01 +0000 (07:48 -0400)
965 files changed:
CMakeCPackOptions.cmake.in
CMakeLists.txt
CTestCustom.cmake.in
ChangeLog.manual
CompileFlags.cmake
Modules/BundleUtilities.cmake
Modules/CMakeAddNewLanguage.txt
Modules/CMakeCCompiler.cmake.in
Modules/CMakeCCompilerId.c.in
Modules/CMakeCXXCompiler.cmake.in
Modules/CMakeCXXCompilerId.cpp.in
Modules/CMakeDetermineASM-ATTCompiler.cmake
Modules/CMakeDetermineASMCompiler.cmake
Modules/CMakeDetermineASM_NASMCompiler.cmake
Modules/CMakeDetermineCCompiler.cmake
Modules/CMakeDetermineCXXCompiler.cmake
Modules/CMakeDetermineCompilerABI.cmake
Modules/CMakeDetermineCompilerId.cmake
Modules/CMakeDetermineFortranCompiler.cmake
Modules/CMakeDetermineJavaCompiler.cmake
Modules/CMakeDetermineSystem.cmake
Modules/CMakeExpandImportedTargets.cmake
Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
Modules/CMakeFindBinUtils.cmake
Modules/CMakeFindEclipseCDT4.cmake
Modules/CMakeFortranCompiler.cmake.in
Modules/CMakeFortranCompilerId.F.in
Modules/CMakePackageConfigHelpers.cmake
Modules/CMakeParseImplicitLinkInfo.cmake
Modules/CMakePlatformId.h.in
Modules/CMakeVS12FindMake.cmake [new file with mode: 0644]
Modules/CPack.cmake
Modules/CPackDeb.cmake
Modules/CPackRPM.cmake
Modules/CPackWIX.cmake [new file with mode: 0644]
Modules/CTestTargets.cmake
Modules/CTestUseLaunchers.cmake
Modules/CheckCSourceCompiles.cmake
Modules/CheckCSourceRuns.cmake
Modules/CheckCXXSourceCompiles.cmake
Modules/CheckCXXSourceRuns.cmake
Modules/CheckForPthreads.c
Modules/CheckFortranFunctionExists.cmake
Modules/CheckFunctionExists.cmake
Modules/CheckLibraryExists.cmake
Modules/CheckPrototypeDefinition.cmake
Modules/CheckSymbolExists.cmake
Modules/CheckTypeSize.cmake
Modules/CheckVariableExists.cmake
Modules/Compiler/Clang.cmake
Modules/Compiler/NAG-Fortran.cmake
Modules/Compiler/TI-ASM.cmake [new file with mode: 0644]
Modules/Compiler/TI-C.cmake [new file with mode: 0644]
Modules/Compiler/TI-CXX.cmake [new file with mode: 0644]
Modules/Compiler/XL.cmake
Modules/CompilerId/VS-7.vcproj.in
Modules/CompilerId/Xcode-3.pbxproj.in
Modules/DeployQt4.cmake
Modules/ExternalData.cmake [new file with mode: 0644]
Modules/ExternalData_config.cmake.in [new file with mode: 0644]
Modules/ExternalProject.cmake
Modules/FeatureSummary.cmake
Modules/FindBISON.cmake
Modules/FindBLAS.cmake
Modules/FindBZip2.cmake
Modules/FindBoost.cmake
Modules/FindBullet.cmake
Modules/FindCUDA.cmake
Modules/FindCups.cmake
Modules/FindCurses.cmake
Modules/FindFLEX.cmake
Modules/FindFLTK.cmake
Modules/FindFreetype.cmake
Modules/FindGIF.cmake
Modules/FindGLU.cmake
Modules/FindGLUT.cmake
Modules/FindGTK2.cmake
Modules/FindGnuplot.cmake
Modules/FindHDF5.cmake
Modules/FindIcotool.cmake [new file with mode: 0644]
Modules/FindImageMagick.cmake
Modules/FindJNI.cmake
Modules/FindJava.cmake
Modules/FindKDE3.cmake
Modules/FindLAPACK.cmake
Modules/FindLua51.cmake
Modules/FindMPEG2.cmake
Modules/FindMPI.cmake
Modules/FindOpenGL.cmake
Modules/FindOpenMP.cmake
Modules/FindOpenSceneGraph.cmake
Modules/FindPackageHandleStandardArgs.cmake
Modules/FindPerl.cmake
Modules/FindPerlLibs.cmake
Modules/FindPythonLibs.cmake
Modules/FindQt.cmake
Modules/FindQt3.cmake
Modules/FindQt4.cmake
Modules/FindRuby.cmake
Modules/FindSDL.cmake
Modules/FindSDL_image.cmake
Modules/FindSDL_mixer.cmake
Modules/FindSDL_net.cmake
Modules/FindSDL_sound.cmake
Modules/FindSDL_ttf.cmake
Modules/FindSelfPackers.cmake
Modules/FindSquish.cmake
Modules/FindTCL.cmake
Modules/FindTclStub.cmake
Modules/FindUnixCommands.cmake
Modules/FindVTK.cmake
Modules/FindWget.cmake
Modules/FindX11.cmake
Modules/Findosg.cmake
Modules/FindosgAnimation.cmake
Modules/FindosgDB.cmake
Modules/FindosgFX.cmake
Modules/FindosgGA.cmake
Modules/FindosgIntrospection.cmake
Modules/FindosgManipulator.cmake
Modules/FindosgParticle.cmake
Modules/FindosgPresentation.cmake
Modules/FindosgProducer.cmake
Modules/FindosgQt.cmake
Modules/FindosgShadow.cmake
Modules/FindosgSim.cmake
Modules/FindosgTerrain.cmake
Modules/FindosgText.cmake
Modules/FindosgUtil.cmake
Modules/FindosgViewer.cmake
Modules/FindosgVolume.cmake
Modules/FindosgWidget.cmake
Modules/FindwxWindows.cmake
Modules/GenerateExportHeader.cmake
Modules/GetPrerequisites.cmake
Modules/InstallRequiredSystemLibraries.cmake
Modules/NSIS.template.in
Modules/Platform/AIX-GNU.cmake
Modules/Platform/AIX-XL.cmake
Modules/Platform/Darwin-Clang.cmake
Modules/Platform/Darwin-GNU.cmake
Modules/Platform/Darwin.cmake
Modules/Platform/FreeBSD.cmake
Modules/Platform/NetBSD.cmake
Modules/Platform/OpenBSD.cmake
Modules/Platform/Windows-Embarcadero.cmake
Modules/Platform/Windows-Intel.cmake
Modules/Platform/Windows-MSVC.cmake
Modules/Qt4ConfigDependentSettings.cmake
Modules/Qt4Macros.cmake
Modules/SelectLibraryConfigurations.cmake
Modules/Squish4RunTestCase.bat [new file with mode: 0755]
Modules/Squish4RunTestCase.sh [new file with mode: 0755]
Modules/SquishTestScript.cmake
Modules/TestForANSIStreamHeaders.cmake
Modules/UseJava.cmake
Modules/UseQt4.cmake
Modules/WIX.template.in [new file with mode: 0644]
Modules/readme.txt
Source/CMakeLists.txt
Source/CMakeVersion.cmake
Source/CPack/WiX/cmCPackWIXGenerator.cxx [new file with mode: 0644]
Source/CPack/WiX/cmCPackWIXGenerator.h [new file with mode: 0644]
Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx [new file with mode: 0644]
Source/CPack/WiX/cmWIXRichTextFormatWriter.h [new file with mode: 0644]
Source/CPack/WiX/cmWIXSourceWriter.cxx [new file with mode: 0644]
Source/CPack/WiX/cmWIXSourceWriter.h [new file with mode: 0644]
Source/CPack/cmCPackComponentGroup.h
Source/CPack/cmCPackDebGenerator.cxx
Source/CPack/cmCPackDragNDropGenerator.cxx
Source/CPack/cmCPackGenerator.cxx
Source/CPack/cmCPackGeneratorFactory.cxx
Source/CPack/cmCPackNSISGenerator.cxx
Source/CPack/cmCPackNSISGenerator.h
Source/CPack/cmCPackPackageMakerGenerator.cxx
Source/CPack/cmCPackPackageMakerGenerator.h
Source/CPack/cmCPackRPMGenerator.cxx
Source/CPack/cpack.cxx
Source/CTest/cmCTestBuildAndTestHandler.cxx
Source/CTest/cmCTestBuildAndTestHandler.h
Source/CTest/cmCTestConfigureCommand.cxx
Source/CTest/cmCTestCoverageHandler.cxx
Source/CTest/cmCTestGIT.cxx
Source/CTest/cmCTestHandlerCommand.cxx
Source/CTest/cmCTestMultiProcessHandler.cxx
Source/CTest/cmCTestTestHandler.cxx
Source/CursesDialog/cmCursesStringWidget.cxx
Source/QtDialog/CMakeLists.txt
Source/QtDialog/QCMakeCacheView.cxx
Source/cmAddCustomCommandCommand.h
Source/cmAddDependenciesCommand.cxx
Source/cmAddLibraryCommand.h
Source/cmAddSubDirectoryCommand.cxx
Source/cmBootstrapCommands.cxx
Source/cmBuildCommand.cxx
Source/cmCTest.cxx
Source/cmCTest.h
Source/cmCacheManager.cxx
Source/cmCommandArgumentParser.cxx
Source/cmCommands.cxx
Source/cmComputeLinkDepends.cxx
Source/cmComputeLinkDepends.h
Source/cmComputeLinkInformation.cxx
Source/cmComputeLinkInformation.h
Source/cmComputeTargetDepends.cxx
Source/cmComputeTargetDepends.h
Source/cmConfigureFileCommand.h
Source/cmCoreTryCompile.cxx
Source/cmCryptoHash.cxx
Source/cmCustomCommandGenerator.cxx
Source/cmDepends.cxx
Source/cmDepends.h
Source/cmDependsC.cxx
Source/cmDependsC.h
Source/cmDependsFortran.cxx
Source/cmDependsFortran.h
Source/cmDependsJava.cxx
Source/cmDependsJava.h
Source/cmDocumentGeneratorExpressions.h
Source/cmDocumentVariables.cxx
Source/cmEnableLanguageCommand.h
Source/cmExportBuildFileGenerator.cxx
Source/cmExportBuildFileGenerator.h
Source/cmExportFileGenerator.cxx
Source/cmExportFileGenerator.h
Source/cmExportInstallFileGenerator.cxx
Source/cmExportInstallFileGenerator.h
Source/cmExportTryCompileFileGenerator.cxx [new file with mode: 0644]
Source/cmExportTryCompileFileGenerator.h [new file with mode: 0644]
Source/cmExtraCodeBlocksGenerator.cxx
Source/cmExtraEclipseCDT4Generator.cxx
Source/cmExtraEclipseCDT4Generator.h
Source/cmExtraSublimeTextGenerator.cxx [new file with mode: 0644]
Source/cmExtraSublimeTextGenerator.h [new file with mode: 0644]
Source/cmFLTKWrapUICommand.cxx
Source/cmFileCommand.cxx
Source/cmFileCommand.h
Source/cmFindBase.cxx
Source/cmFindBase.h
Source/cmFindLibraryCommand.cxx
Source/cmFindLibraryCommand.h
Source/cmFindPackageCommand.cxx
Source/cmFindPathCommand.cxx
Source/cmFunctionCommand.h
Source/cmGeneratorExpression.cxx
Source/cmGeneratorExpression.h
Source/cmGeneratorExpressionDAGChecker.cxx
Source/cmGeneratorExpressionDAGChecker.h
Source/cmGeneratorExpressionEvaluator.cxx
Source/cmGeneratorExpressionEvaluator.h
Source/cmGeneratorExpressionParser.cxx
Source/cmGeneratorTarget.cxx
Source/cmGeneratorTarget.h
Source/cmGetFilenameComponentCommand.h
Source/cmGlobalBorlandMakefileGenerator.cxx
Source/cmGlobalBorlandMakefileGenerator.h
Source/cmGlobalGenerator.cxx
Source/cmGlobalGenerator.h
Source/cmGlobalGeneratorFactory.h [new file with mode: 0644]
Source/cmGlobalJOMMakefileGenerator.cxx
Source/cmGlobalJOMMakefileGenerator.h
Source/cmGlobalMSYSMakefileGenerator.cxx
Source/cmGlobalMSYSMakefileGenerator.h
Source/cmGlobalMinGWMakefileGenerator.cxx
Source/cmGlobalMinGWMakefileGenerator.h
Source/cmGlobalNMakeMakefileGenerator.cxx
Source/cmGlobalNMakeMakefileGenerator.h
Source/cmGlobalNinjaGenerator.cxx
Source/cmGlobalNinjaGenerator.h
Source/cmGlobalUnixMakefileGenerator3.cxx
Source/cmGlobalUnixMakefileGenerator3.h
Source/cmGlobalVisualStudio10Generator.cxx
Source/cmGlobalVisualStudio10Generator.h
Source/cmGlobalVisualStudio10IA64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio10IA64Generator.h [deleted file]
Source/cmGlobalVisualStudio10Win64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio10Win64Generator.h [deleted file]
Source/cmGlobalVisualStudio11ARMGenerator.cxx [deleted file]
Source/cmGlobalVisualStudio11ARMGenerator.h [deleted file]
Source/cmGlobalVisualStudio11Generator.cxx
Source/cmGlobalVisualStudio11Generator.h
Source/cmGlobalVisualStudio11Win64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio11Win64Generator.h [deleted file]
Source/cmGlobalVisualStudio12Generator.cxx [new file with mode: 0644]
Source/cmGlobalVisualStudio12Generator.h [new file with mode: 0644]
Source/cmGlobalVisualStudio6Generator.cxx
Source/cmGlobalVisualStudio6Generator.h
Source/cmGlobalVisualStudio71Generator.cxx
Source/cmGlobalVisualStudio71Generator.h
Source/cmGlobalVisualStudio7Generator.cxx
Source/cmGlobalVisualStudio7Generator.h
Source/cmGlobalVisualStudio8Generator.cxx
Source/cmGlobalVisualStudio8Generator.h
Source/cmGlobalVisualStudio8Win64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio8Win64Generator.h [deleted file]
Source/cmGlobalVisualStudio9Generator.cxx
Source/cmGlobalVisualStudio9Generator.h
Source/cmGlobalVisualStudio9IA64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio9IA64Generator.h [deleted file]
Source/cmGlobalVisualStudio9Win64Generator.cxx [deleted file]
Source/cmGlobalVisualStudio9Win64Generator.h [deleted file]
Source/cmGlobalVisualStudioGenerator.cxx
Source/cmGlobalVisualStudioGenerator.h
Source/cmGlobalWatcomWMakeGenerator.cxx
Source/cmGlobalWatcomWMakeGenerator.h
Source/cmGlobalXCodeGenerator.cxx
Source/cmGlobalXCodeGenerator.h
Source/cmGraphVizWriter.cxx
Source/cmIDEOptions.cxx
Source/cmIDEOptions.h
Source/cmIncludeDirectoryCommand.cxx
Source/cmIncludeDirectoryCommand.h
Source/cmInstallExportGenerator.h
Source/cmInstallTargetGenerator.cxx
Source/cmInstallTargetGenerator.h
Source/cmLinkDirectoriesCommand.h
Source/cmListCommand.cxx
Source/cmListFileCache.h
Source/cmLocalGenerator.cxx
Source/cmLocalGenerator.h
Source/cmLocalUnixMakefileGenerator3.cxx
Source/cmLocalUnixMakefileGenerator3.h
Source/cmLocalVisualStudio6Generator.cxx
Source/cmLocalVisualStudio7Generator.cxx
Source/cmLocalVisualStudio7Generator.h
Source/cmLocalVisualStudioGenerator.cxx
Source/cmLocalVisualStudioGenerator.h
Source/cmMacroCommand.h
Source/cmMakefile.cxx
Source/cmMakefile.h
Source/cmMakefileLibraryTargetGenerator.cxx
Source/cmMakefileTargetGenerator.cxx
Source/cmMathCommand.h
Source/cmMessageCommand.h
Source/cmNinjaNormalTargetGenerator.cxx
Source/cmNinjaTargetGenerator.cxx
Source/cmPolicies.cxx
Source/cmPolicies.h
Source/cmQtAutomoc.cxx
Source/cmQtAutomoc.h
Source/cmSetTargetPropertiesCommand.h
Source/cmSourceFile.cxx
Source/cmSourceGroup.cxx
Source/cmSourceGroupCommand.h
Source/cmStringCommand.cxx
Source/cmStringCommand.h
Source/cmSystemTools.cxx
Source/cmTarget.cxx
Source/cmTarget.h
Source/cmTargetCompileDefinitionsCommand.cxx [new file with mode: 0644]
Source/cmTargetCompileDefinitionsCommand.h [new file with mode: 0644]
Source/cmTargetIncludeDirectoriesCommand.cxx [new file with mode: 0644]
Source/cmTargetIncludeDirectoriesCommand.h [new file with mode: 0644]
Source/cmTargetLinkLibrariesCommand.cxx
Source/cmTargetLinkLibrariesCommand.h
Source/cmTargetPropCommandBase.cxx [new file with mode: 0644]
Source/cmTargetPropCommandBase.h [new file with mode: 0644]
Source/cmTestGenerator.cxx
Source/cmTimestamp.cxx [new file with mode: 0644]
Source/cmTimestamp.h [new file with mode: 0644]
Source/cmTryCompileCommand.h
Source/cmTryRunCommand.h
Source/cmVS10LinkFlagTable.h
Source/cmVS12CLFlagTable.h [new file with mode: 0644]
Source/cmVS12LibFlagTable.h [new file with mode: 0644]
Source/cmVS12LinkFlagTable.h [new file with mode: 0644]
Source/cmVisualStudio10TargetGenerator.cxx
Source/cmVisualStudio10TargetGenerator.h
Source/cmVisualStudioGeneratorOptions.cxx
Source/cmVisualStudioWCEPlatformParser.cxx [new file with mode: 0644]
Source/cmVisualStudioWCEPlatformParser.h [new file with mode: 0644]
Source/cmWin32ProcessExecution.cxx
Source/cmXCodeObject.cxx
Source/cmXCodeObject.h
Source/cmake.cxx
Source/cmake.h
Source/cmakemain.cxx
Source/cmcldeps.cxx
Source/cmparseMSBuildXML.py
Source/cmw9xcom.cxx
Source/ctest.cxx
Source/kwsys/CMakeLists.txt
Source/kwsys/CPU.h.in
Source/kwsys/CTestConfig.cmake
Source/kwsys/Configure.h.in
Source/kwsys/DynamicLoader.cxx
Source/kwsys/EncodeExecutable.c [deleted file]
Source/kwsys/Glob.cxx
Source/kwsys/IOStream.cxx
Source/kwsys/IOStream.hxx.in
Source/kwsys/ProcessFwd9x.c [deleted file]
Source/kwsys/ProcessUNIX.c
Source/kwsys/ProcessWin32.c
Source/kwsys/Registry.cxx [deleted file]
Source/kwsys/Registry.hxx.in [deleted file]
Source/kwsys/SystemInformation.cxx
Source/kwsys/SystemInformation.hxx.in
Source/kwsys/SystemTools.cxx
Source/kwsys/SystemTools.hxx.in
Source/kwsys/kwsysPlatformTestsCXX.cxx
Source/kwsys/testCommandLineArguments.cxx
Source/kwsys/testDynamicLoader.cxx
Source/kwsys/testProcess.c
Source/kwsys/testRegistry.cxx [deleted file]
Source/kwsys/testSystemInformation.cxx
Source/kwsys/testSystemTools.cxx
Tests/BuildDepends/CMakeLists.txt
Tests/BuildDepends/Project/CMakeLists.txt
Tests/BuildDepends/Project/dep_custom2.cxx [new file with mode: 0644]
Tests/BuildDepends/Project/link_depends_no_shared_check.cmake [new file with mode: 0644]
Tests/BuildDepends/Project/link_depends_no_shared_exe.c [new file with mode: 0644]
Tests/BuildDepends/Project/link_depends_no_shared_lib.c [new file with mode: 0644]
Tests/CMakeBuildTest.cmake.in
Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt [new file with mode: 0644]
Tests/CMakeCommands/target_compile_definitions/consumer.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_compile_definitions/main.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_include_directories/CMakeLists.txt [new file with mode: 0644]
Tests/CMakeCommands/target_include_directories/consumer.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_include_directories/main.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_include_directories/relative_dir/relative_dir.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
Tests/CMakeCommands/target_link_libraries/depB.cpp
Tests/CMakeCommands/target_link_libraries/depD.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/depD.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/depG.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/depG.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/empty.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/libgenex.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/libgenex.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/targetA.cpp
Tests/CMakeCommands/target_link_libraries/targetB.cpp [new file with mode: 0644]
Tests/CMakeCommands/target_link_libraries/targetC.cpp [new file with mode: 0644]
Tests/CMakeLists.txt
Tests/CMakeOnly/AllFindModules/CMakeLists.txt
Tests/CMakeOnly/CMakeLists.txt
Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt [new file with mode: 0644]
Tests/CMakeOnly/Test.cmake.in
Tests/CMakeOnly/find_library/A/libtestA.a [new file with mode: 0644]
Tests/CMakeOnly/find_library/B/libtestB.a [new file with mode: 0644]
Tests/CMakeOnly/find_library/CMakeLists.txt
Tests/CMakeOnly/find_path/CMakeLists.txt [new file with mode: 0644]
Tests/CMakeOnly/find_path/include/arch/test1arch.h [new file with mode: 0644]
Tests/CMakeOnly/find_path/include/test1.h [new file with mode: 0644]
Tests/CMakeTests/CMakeLists.txt
Tests/CMakeTests/CheckCMakeTest.cmake
Tests/CMakeTests/File-Glob-NoArg.cmake [new file with mode: 0644]
Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake [new file with mode: 0644]
Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake [new file with mode: 0644]
Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake [new file with mode: 0644]
Tests/CMakeTests/File-TIMESTAMP-Works.cmake [new file with mode: 0644]
Tests/CMakeTests/FileTest.cmake.in
Tests/CMakeTests/GetProperty-Doc-Properties.cmake [deleted file]
Tests/CMakeTests/GetPropertyTest.cmake.in
Tests/CMakeTests/IfTest.cmake.in
Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
Tests/CMakeTests/List-Get-CMP0007-Warn.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Get-Invalid-Index.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Insert-Invalid-Index.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Invalid-Subcommand.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake [new file with mode: 0644]
Tests/CMakeTests/List-No-Arguments.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Sort-Nonexistent-List.cmake [new file with mode: 0644]
Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake [new file with mode: 0644]
Tests/CMakeTests/ListTest.cmake.in
Tests/CMakeTests/Make_Directory-NoArg.cmake [new file with mode: 0644]
Tests/CMakeTests/ProcessorCountTest.cmake.in
Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake [new file with mode: 0644]
Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake [new file with mode: 0644]
Tests/CMakeTests/StringTest.cmake.in
Tests/CMakeTests/WhileTest.cmake.in
Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
Tests/CPackTestAllGenerators/RunCPack.cmake
Tests/CPackWiXGenerator/CMakeLists.txt [new file with mode: 0644]
Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake [new file with mode: 0644]
Tests/CPackWiXGenerator/file with spaces.h [new file with mode: 0644]
Tests/CPackWiXGenerator/mylib.cpp [new file with mode: 0644]
Tests/CPackWiXGenerator/mylib.h [new file with mode: 0644]
Tests/CPackWiXGenerator/mylibapp.cpp [new file with mode: 0644]
Tests/CTestConfig/dashboard.cmake.in
Tests/CTestConfig/script.cmake.in
Tests/CTestLimitDashJ/CMakeLists.txt [new file with mode: 0644]
Tests/CTestLimitDashJ/CreateSleepDelete.cmake [new file with mode: 0644]
Tests/CTestTest/test.cmake.in
Tests/CTestTest2/test.cmake.in
Tests/CTestTestBadExe/test.cmake.in
Tests/CTestTestChecksum/test.cmake.in
Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
Tests/CTestTestCostSerial/test.cmake.in
Tests/CTestTestCrash/test.cmake.in
Tests/CTestTestCycle/test.cmake.in
Tests/CTestTestDepends/test.cmake.in
Tests/CTestTestFailedSubmits/test.cmake.in
Tests/CTestTestFailure/testNoBuild.cmake.in
Tests/CTestTestFailure/testNoExe.cmake.in
Tests/CTestTestMemcheck/CMakeLists.txt
Tests/CTestTestMemcheck/DummyBC/test.cmake.in
Tests/CTestTestMemcheck/DummyPurify/test.cmake.in
Tests/CTestTestMemcheck/DummyValgrind/test.cmake.in
Tests/CTestTestMemcheck/DummyValgrindFailPost/test.cmake.in
Tests/CTestTestMemcheck/DummyValgrindFailPre/test.cmake.in
Tests/CTestTestMemcheck/DummyValgrindIgnoreMemcheck/test.cmake.in
Tests/CTestTestMemcheck/DummyValgrindPrePost/test.cmake.in
Tests/CTestTestMemcheck/NotExist/test.cmake.in
Tests/CTestTestMemcheck/Unknown/test.cmake.in
Tests/CTestTestMemcheck/UnknownQuoted/test.cmake.in
Tests/CTestTestParallel/test.cmake.in
Tests/CTestTestResourceLock/test.cmake.in
Tests/CTestTestScheduler/test.cmake.in
Tests/CTestTestStopTime/test.cmake.in
Tests/CTestTestSubdir/test.cmake.in
Tests/CTestTestTimeout/test.cmake.in
Tests/CTestTestUpload/test.cmake.in
Tests/CTestTestZeroTimeout/test.cmake.in
Tests/CTestUpdateGIT.cmake.in
Tests/CheckCompilerRelatedVariables/CMakeLists.txt
Tests/CompatibleInterface/CMakeLists.txt [new file with mode: 0644]
Tests/CompatibleInterface/empty.cpp [new file with mode: 0644]
Tests/CompatibleInterface/iface2.cpp [new file with mode: 0644]
Tests/CompatibleInterface/iface2.h [new file with mode: 0644]
Tests/CompatibleInterface/main.cpp [new file with mode: 0644]
Tests/CompileDefinitions/CMakeLists.txt
Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt
Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt
Tests/CompileDefinitions/compiletest.cpp
Tests/CompileDefinitions/runtest.c [new file with mode: 0644]
Tests/CompileDefinitions/target_prop/CMakeLists.txt
Tests/Complex/Executable/CMakeLists.txt
Tests/EmptyDepends/CMakeLists.txt [new file with mode: 0644]
Tests/ExportImport/CMakeLists.txt
Tests/ExportImport/Export/CMakeLists.txt
Tests/ExportImport/Export/sublib/CMakeLists.txt [new file with mode: 0644]
Tests/ExportImport/Export/sublib/subdir.cpp [new file with mode: 0644]
Tests/ExportImport/Export/sublib/subdir.h [new file with mode: 0644]
Tests/ExportImport/Export/testLibDepends.c
Tests/ExportImport/Export/testSharedLibDepends.cpp [new file with mode: 0644]
Tests/ExportImport/Export/testSharedLibDepends.h [new file with mode: 0644]
Tests/ExportImport/Export/testSharedLibRequired.cpp [new file with mode: 0644]
Tests/ExportImport/Export/testSharedLibRequired.h [new file with mode: 0644]
Tests/ExportImport/Import/A/CMakeLists.txt
Tests/ExportImport/Import/A/deps_iface.c [new file with mode: 0644]
Tests/ExportImport/Import/A/deps_shared_iface.cpp [new file with mode: 0644]
Tests/ExportImport/Import/CMakeLists.txt
Tests/ExportImport/Import/try_compile/CMakeLists.txt [new file with mode: 0644]
Tests/ExternalProject/CMakeLists.txt
Tests/ExternalProjectUpdate/CMakeLists.txt [new file with mode: 0644]
Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake [new file with mode: 0644]
Tests/ExternalProjectUpdate/gitrepo.tgz [new file with mode: 0644]
Tests/FindPackageTest/CMakeLists.txt
Tests/FindPackageTest/FindSomePackage.cmake [new file with mode: 0644]
Tests/FindPackageTest/FindUpperCasePackage.cmake [new file with mode: 0644]
Tests/Fortran/CMakeLists.txt
Tests/FortranC/Flags.cmake.in
Tests/GeneratorExpression/CMakeLists.txt
Tests/GeneratorExpression/check-common.cmake [new file with mode: 0644]
Tests/GeneratorExpression/check-part1.cmake [moved from Tests/GeneratorExpression/check.cmake with 59% similarity]
Tests/GeneratorExpression/check-part2.cmake [new file with mode: 0644]
Tests/GeneratorExpression/empty.cpp [new file with mode: 0644]
Tests/IncludeDirectories/CMakeLists.txt
Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp [new file with mode: 0644]
Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp [new file with mode: 0644]
Tests/IncludeDirectories/TargetIncludeDirectories/other.cpp [new file with mode: 0644]
Tests/IncludeDirectories/empty.cpp [new file with mode: 0644]
Tests/Module/ExternalData/CMakeLists.txt [new file with mode: 0644]
Tests/Module/ExternalData/Data Space.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data1Check.cmake [new file with mode: 0644]
Tests/Module/ExternalData/Data2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data2/CMakeLists.txt [new file with mode: 0644]
Tests/Module/ExternalData/Data2/Data2Check.cmake [new file with mode: 0644]
Tests/Module/ExternalData/Data2/SeriesC_1_.my.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data2/SeriesC_2_.my.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data2/SeriesC_3_.my.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data2b.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data3/CMakeLists.txt [new file with mode: 0644]
Tests/Module/ExternalData/Data3/Data.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Data3/Data3Check.cmake [new file with mode: 0644]
Tests/Module/ExternalData/Data3/Other.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Directory/A.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Directory/B.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/Directory/C.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/.gitattributes [new file with mode: 0644]
Tests/Module/ExternalData/MD5/08cfcf221f76ace7b906b312284e73d7 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/30ba0acdee9096b3b9fc6c69362c6b42 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/31eff09e84fca01415f8cd9d82ec432b [new file with mode: 0644]
Tests/Module/ExternalData/MD5/401767f22a456b3522953722090a2c36 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/8c018830e3efa5caf3c7415028335a57 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/8f4add4581551facf27237e6577fd662 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/9d980b06c2f0fec3d4872d68175b9822 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/aaad162b85f60d1eb57ca71a23e8efd7 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/c1030719c95f3435d8abc39c0d442946 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/ce38ea6c3c1e00fa6405dd64b8bf6da0 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/ecfa1ecd417d4253af81ae04d1bd6581 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/f41c94425d01ecbbee70440b951cb058 [new file with mode: 0644]
Tests/Module/ExternalData/MD5/f7ab5a04aae9cb9a520e70b20b9c8ed7 [new file with mode: 0644]
Tests/Module/ExternalData/MetaA.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/MetaB.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/MetaC.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/MetaTop.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/PairedA.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/PairedB.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SHA1/.gitattributes [new file with mode: 0644]
Tests/Module/ExternalData/SHA1/2af59a7022024974f3b8521b7ed8137c996a79f1 [new file with mode: 0644]
Tests/Module/ExternalData/SHA224/.gitattributes [new file with mode: 0644]
Tests/Module/ExternalData/SHA224/3b679da7908562fe1cc28db47ffb89bae025f4551dceb343a5869174 [new file with mode: 0644]
Tests/Module/ExternalData/SHA256/.gitattributes [new file with mode: 0644]
Tests/Module/ExternalData/SHA256/969171a0dd70d49ce096bd3e8178c7e26c711c9b20dbcaa3853d869d3871f133 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesA.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesA1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesA2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesA3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesAn1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesAn2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesAn3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesB.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesB_1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesB_2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesB_3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesBn_1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesBn_2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesBn_3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesC.1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesC.2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesC.3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesC.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesCn.1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesCn.2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesCn.3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesD-1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesD-2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesD-3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesD.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesDn-1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesDn-2.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesDn-3.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesMixed.1.dat.md5 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesMixed.2.dat.sha1 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesMixed.3.dat.sha224 [new file with mode: 0644]
Tests/Module/ExternalData/SeriesMixed.4.dat.sha256 [new file with mode: 0644]
Tests/ObjectLibrary/A/CMakeLists.txt
Tests/ObjectLibrary/B/CMakeLists.txt
Tests/ObjectLibrary/B/b.h
Tests/ObjectLibrary/CMakeLists.txt
Tests/ObjectLibrary/mainAB.c
Tests/Preprocess/CMakeLists.txt
Tests/Qt4Targets/CMakeLists.txt [new file with mode: 0644]
Tests/Qt4Targets/activeqtexe.cpp [new file with mode: 0644]
Tests/Qt4Targets/main.cpp [new file with mode: 0644]
Tests/QtAutomoc/Adir/CMakeLists.txt [new file with mode: 0644]
Tests/QtAutomoc/Adir/libA.cpp [new file with mode: 0644]
Tests/QtAutomoc/Adir/libA.h [new file with mode: 0644]
Tests/QtAutomoc/Bdir/CMakeLists.txt [new file with mode: 0644]
Tests/QtAutomoc/Bdir/libB.cpp [new file with mode: 0644]
Tests/QtAutomoc/Bdir/libB.h [new file with mode: 0644]
Tests/QtAutomoc/CMakeLists.txt
Tests/QtAutomoc/empty.cpp [new file with mode: 0644]
Tests/QtAutomoc/empty.h [new file with mode: 0644]
Tests/QtAutomoc/libC.cpp [new file with mode: 0644]
Tests/QtAutomoc/libC.h [new file with mode: 0644]
Tests/QtAutomoc/main.cpp
Tests/QtAutomocNoQt/CMakeLists.txt [new file with mode: 0644]
Tests/QtAutomocNoQt/main.c [new file with mode: 0644]
Tests/RegexEscapeString.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-NEW.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-OLD.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0004/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/CMP0004/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0004/empty.cpp [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMP0019-NEW.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMP0019-OLD.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMP0019-WARN.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMP0019-code.cmake [new file with mode: 0644]
Tests/RunCMake/CMP0019/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/CMP0019/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/CMakeLists.txt
Tests/RunCMake/CTest/BeforeProject-result.txt [new file with mode: 0644]
Tests/RunCMake/CTest/BeforeProject-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CTest/BeforeProject.cmake [new file with mode: 0644]
Tests/RunCMake/CTest/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/CTest/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/CompatibleInterface/main.cpp [new file with mode: 0644]
Tests/RunCMake/CompilerChange/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/EmptyCompiler.cmake [new file with mode: 0644]
Tests/RunCMake/CompilerChange/FindCompiler.cmake [new file with mode: 0644]
Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/FirstCompiler.cmake [new file with mode: 0644]
Tests/RunCMake/CompilerChange/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt [new file with mode: 0644]
Tests/RunCMake/CompilerChange/SecondCompiler.cmake [new file with mode: 0644]
Tests/RunCMake/CompilerChange/cc.sh.in [new file with mode: 0755]
Tests/RunCMake/ExternalData/BadHashAlgo1-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadHashAlgo1-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadHashAlgo1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadHashAlgo1.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption1-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption1-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption2-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption2-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadOption2.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries1-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries1-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries2-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries2-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries2.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries3-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries3-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/BadSeries3.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Data.txt.md5 [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory1-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory1-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory1/DirData1.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory2-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory2-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory2.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory2.md5 [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory2/DirData2.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory3-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory3-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory3.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory3/DirData3.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory4-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory4-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory4.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory4/DirData4.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory5-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory5-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Directory5.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkContentMD5-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkContentMD5.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkContentSHA1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkContentSHA1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/LinkDirectory1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/MissingData-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/MissingData-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/MissingData.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoLinkInSource-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoLinkInSource-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoLinkInSource.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoURLTemplates-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NoURLTemplates.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData2-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData2.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData3-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalData3.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalDataSub1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NormalDataSub1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/NotUnderRoot-result.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NotUnderRoot-stderr.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/NotUnderRoot.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon2-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon2.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon3-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/Semicolon3.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/SubDirectory1-stdout.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/SubDirectory1.cmake [new file with mode: 0644]
Tests/RunCMake/ExternalData/SubDirectory1/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/ExternalData/SubDirectory1/Data.txt.md5 [new file with mode: 0644]
Tests/RunCMake/FPHSA/BadFoundVar-result.txt [new file with mode: 0644]
Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt [new file with mode: 0644]
Tests/RunCMake/FPHSA/BadFoundVar.cmake [new file with mode: 0644]
Tests/RunCMake/FPHSA/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/FPHSA/FindBadFoundVar.cmake [new file with mode: 0644]
Tests/RunCMake/FPHSA/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt
Tests/RunCMake/GeneratorExpression/BadAND.cmake
Tests/RunCMake/GeneratorExpression/BadInstallPrefix-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadInstallPrefix-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadInstallPrefix.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt
Tests/RunCMake/GeneratorExpression/BadOR.cmake
Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadTargetName.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadZero-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/BadZero.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
Tests/RunCMake/GeneratorToolset/BadToolset-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/BadToolset.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/NoToolset-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/NoToolset-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/NoToolset.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TestToolset-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TestToolset-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TestToolset.cmake [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TwoToolsets-result.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TwoToolsets-stderr.txt [new file with mode: 0644]
Tests/RunCMake/GeneratorToolset/TwoToolsets.cmake [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/IncompatibleQt-result.txt [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/IncompatibleQt-stderr.txt [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/IncompatibleQt.cmake [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/IncompatibleQt/main.cpp [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict1.cmake [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict2.cmake [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/Conflict3.cmake [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/PositionIndependentCode/main.cpp [new file with mode: 0644]
Tests/RunCMake/RunCMake.cmake
Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/MorePost.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/MorePre.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/OnePost.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/OnePre.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/Override1.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/Override2.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/PrePost.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake [new file with mode: 0644]
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8-stderr.txt
Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt
Tests/RunCMake/add_dependencies/CMakeLists.txt [new file with mode: 0644]
Tests/RunCMake/add_dependencies/NoTarget-result.txt [new file with mode: 0644]
Tests/RunCMake/add_dependencies/NoTarget-stderr.txt [new file with mode: 0644]
Tests/RunCMake/add_dependencies/NoTarget.cmake [new file with mode: 0644]
Tests/RunCMake/add_dependencies/RunCMakeTest.cmake [new file with mode: 0644]
Tests/RunCMake/build_command/BeforeProject-result.txt [new file with mode: 0644]
Tests/RunCMake/build_command/BeforeProject-stderr.txt [new file with mode: 0644]
Tests/RunCMake/build_command/BeforeProject.cmake [new file with mode: 0644]
Tests/RunCMake/build_command/CMakeLists.txt
Tests/RunCMake/build_command/ErrorsCommon.cmake [new file with mode: 0644]
Tests/RunCMake/build_command/ErrorsOFF.cmake
Tests/RunCMake/build_command/ErrorsON-stderr.txt
Tests/RunCMake/build_command/ErrorsON.cmake
Tests/RunCMake/build_command/RunCMakeTest.cmake
Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/DebugIncludes-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/DebugIncludes-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/DebugIncludes.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/ImportedTarget-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/ImportedTarget-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/ImportedTarget.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInGenex-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInGenex.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInInterface-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/RelativePathInInterface.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/RunCMakeTest.cmake
Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/TID-bad-target-result.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/TID-bad-target-stderr.txt [new file with mode: 0644]
Tests/RunCMake/include_directories/TID-bad-target.cmake [new file with mode: 0644]
Tests/RunCMake/include_directories/empty.cpp [new file with mode: 0644]
Tests/SystemInformation/SystemInformation.in
Tests/VSExcludeFromDefaultBuild/CMakeLists.txt [new file with mode: 0644]
Tests/VSExcludeFromDefaultBuild/ClearExes.cmake [new file with mode: 0644]
Tests/VSExcludeFromDefaultBuild/ResultTest.cmake [new file with mode: 0644]
Tests/VSExcludeFromDefaultBuild/main.c [new file with mode: 0644]
Tests/VSExternalInclude/CMakeLists.txt
Tests/VSExternalInclude/Lib1/CMakeLists.txt
Tests/VSExternalInclude/Lib2/CMakeLists.txt
Utilities/Git/pre-commit
Utilities/KWIML/ABI.h.in
Utilities/cmcurl/CMakeLists.txt
Utilities/cmcurl/Platforms/WindowsCache.cmake
Utilities/cmcurl/Platforms/config-aix.h
Utilities/cmcurl/config.h.in
Utilities/cmcurl/socks.c
Utilities/cmcurl/strequal.c
Utilities/cmcurl/strequal.h
Utilities/cmlibarchive/libarchive/archive_endian.h
bootstrap

index 3a72eaa..47dad49 100644 (file)
@@ -51,3 +51,27 @@ if("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
     set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr")
   endif()
 endif()
+
+if("${CPACK_GENERATOR}" STREQUAL "WIX")
+  # Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
+  # But the file names still use the full CMake_VERSION value:
+  set(CPACK_PACKAGE_FILE_NAME
+    "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-${CPACK_SYSTEM_NAME}")
+  set(CPACK_SOURCE_PACKAGE_FILE_NAME
+    "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-Source")
+
+  if(NOT CPACK_WIX_SIZEOF_VOID_P)
+    set(CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
+  endif()
+
+  set(CPACK_PACKAGE_VERSION
+    "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@.@CMake_VERSION_PATCH@")
+  # WIX installers require at most a 4 component version number, where
+  # each component is an integer between 0 and 65534 inclusive
+  set(tweak "@CMake_VERSION_TWEAK@")
+  if(tweak MATCHES "^[0-9]+$")
+    if(tweak GREATER 0 AND tweak LESS 65535)
+      set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${tweak}")
+    endif()
+  endif()
+endif()
index ea1c033..75d372d 100644 (file)
@@ -122,9 +122,11 @@ macro(CMAKE_SETUP_TESTING)
       "Generator used when running tests")
     if(NOT CMAKE_TEST_GENERATOR)
       set(CMAKE_TEST_GENERATOR "${CMAKE_GENERATOR}")
+      set(CMAKE_TEST_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}")
       set(CMAKE_TEST_MAKEPROGRAM "${MAKEPROGRAM}")
     else()
       set(CMAKE_TEST_DIFFERENT_GENERATOR TRUE)
+      set(CMAKE_TEST_GENERATOR_TOOLSET "")
     endif()
 
     # Are we testing with the MSVC compiler?
@@ -234,8 +236,6 @@ macro (CMAKE_BUILD_UTILITIES)
   set(kwsys_folder "Utilities/KWSys")
   CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE} "${kwsys_folder}")
   CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}_c "${kwsys_folder}")
-  CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}EncodeExecutable "${kwsys_folder}")
-  CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}ProcessFwd9x "${kwsys_folder}")
   if(BUILD_TESTING)
     CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestDynload "${kwsys_folder}")
     CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestProcess "${kwsys_folder}")
@@ -585,6 +585,29 @@ option(CMAKE_STRICT
   "Perform strict testing to record property and variable access. Can be used to report any undefined properties or variables" OFF)
 mark_as_advanced(CMAKE_STRICT)
 
+if(NOT CMake_VERSION_IS_RELEASE)
+  if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" AND
+      NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2)
+    set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
+                     -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
+                     -Wmissing-format-attribute -fno-common -Wundef
+    )
+    set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W
+                       -Wshadow -Wpointer-arith -Wformat-security -Wundef
+    )
+
+    foreach(FLAG_LANG  C CXX)
+      foreach(FLAG ${${FLAG_LANG}_FLAGS_LIST})
+        if(NOT " ${CMAKE_${FLAG_LANG}_FLAGS} " MATCHES " ${FLAG} ")
+          set(CMAKE_${FLAG_LANG}_FLAGS "${CMAKE_${FLAG_LANG}_FLAGS} ${FLAG}")
+        endif()
+      endforeach()
+    endforeach()
+
+    unset(C_FLAGS_LIST)
+    unset(CXX_FLAGS_LIST)
+  endif()
+endif()
 
 # build the remaining subdirectories
 add_subdirectory(Source)
index 1e6224b..495d156 100644 (file)
@@ -31,6 +31,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
   "remark: .*LOOP WAS VECTORIZED"
   "warning .980: wrong number of actual arguments to intrinsic function .std::basic_"
   "LINK : warning LNK4089: all references to.*ADVAPI32.dll.*discarded by /OPT:REF"
+  "LINK : warning LNK4089: all references to.*PSAPI.DLL.*discarded by /OPT:REF"
   "LINK : warning LNK4089: all references to.*USER32.dll.*discarded by /OPT:REF"
   "Warning: library was too large for page size.*"
   "Warning: public.*_archive_.*in module.*archive_*clashes with prior module.*archive_.*"
index 90c9162..134b4aa 100644 (file)
@@ -1,3 +1,690 @@
+Changes in CMake 2.8.11.2 (since 2.8.11.1)
+------------------------------------------
+Alex Neundorf (1):
+      asm support: adapt to changes in CMakeDetectCompiler in 2.8.10
+
+Bjoern Thiel (1):
+      SelectLibraryConfigurations: Fix for cached <base>_LIBRARY
+
+Brad King (5):
+      cmCryptoHash: Increase alignment of HashFile buffer
+      cmcurl: Backport curl bug 1192 fix (#14250)
+      VS12: Add Visual Studio 12 generator (#14251)
+      VS12: Generate flag tables from MSBuild v120 tool files
+      FindBoost: Add -vc120 mangling for VS 12
+
+Robert Maynard (1):
+      VS: Clarify Visual Studio product year for each version
+
+Changes in CMake 2.8.11.1 (since 2.8.11)
+----------------------------------------
+Brad King (5):
+      ExternalData: Do not re-stage staged object files
+      try_compile: Fix quoting of libraries in generated CMakeLists.txt
+      KWSys: Fix SystemTools::FileIsDirectory with long paths (#14176)
+      FindBoost: Fix handling of \ in input paths (#14179)
+      Xcode: Fix framework search paths in STATIC library targets (#14191)
+
+Modestas Vainius (1):
+      Fix test failures caused by regexp-sensitive characters in the build paths
+
+Stephen Kelly (9):
+      include_directories: Fix handling of empty or space-only entries
+      try_compile: Trim whitespace from LINK_LIBRARIES entries
+      cmTarget: Remove some hardcoding of transitive property names.
+      GenexEval: Extract a getLinkedTargetsContent from TargetPropertyNode.
+      GenexEval: Fix evaluation of INCLUDE_DIRECTORIES target property.
+      GenexEval: Test evaluation of INCLUDE_DIRECTORIES target property.
+      FindQt4: Don't fail if certain Qt modules are unavailable.
+      Qt4Macros: Handle Qt ActiveX libraries in qt4_use_modules.
+      Genex: Fix the HEAD target used for evaluated expressions
+
+Changes in CMake 2.8.11 (since 2.8.11-rc4)
+----------------------------------------
+None
+
+Changes in CMake 2.8.11-rc4 (since 2.8.11-rc3)
+----------------------------------------------
+Brad King (1):
+      target_link_libraries: Update usage requirements documentation
+
+Stephen Kelly (3):
+      Centralize maintenance of usage requirement include directories
+      Fix include dir propagation from conditionally linked targets
+      Memoize usage requirement include directories in a config-specific map
+
+Changes in CMake 2.8.11-rc3 (since 2.8.11-rc2)
+----------------------------------------------
+Brad King (1):
+      get_filename_component: Document path components more clearly (#14091)
+
+Rolf Eike Beer (1):
+      try_compile: add missing fclose() to recently added error case
+
+Stephen Kelly (1):
+      Fix clearing of the INCLUDE_DIRECTORIES DIRECTORY property.
+
+Changes in CMake 2.8.11-rc2 (since 2.8.11-rc1)
+----------------------------------------------
+Alex Neundorf (6):
+      Determine C/CXX/Fortran compiler: minor restructuring
+      Determine C/CXX/Fortran compiler: fix indentation
+      rename TI_DSP toolchain to TI, since it works also for the ARM compiler
+      TI compiler: add automatic detection of prefix and suffixes
+      Modules/readme.txt: switch from "XXX" to "Xxx"
+      Modules/readme.txt: make lines a bit shorter for easier readability
+
+Ben Boeckel (1):
+      Clang: Add -isystem flag support everywhere
+
+Bill Hoffman (1):
+      ExternalProject: Retry on a failed git clone
+
+Brad King (8):
+      string: Fix regex documentation of '^' and '$' (#14028)
+      Rename variable for including current directory in interfaces
+      Replace <TARGET> in CMAKE_<LANG>_COMPILE_OBJECT rule variables
+      Test evaluation of per-config COMPILE_DEFINITIONS (#14037)
+      VS: Fix VS 10/11 .sln headers (#14038)
+      add_dependencies: Distinguish target v. file dependencies in error (#14050)
+      automoc: Use a pre-build event in VS >= 7
+      Handle usr-move without forcing absolute paths (#14041)
+
+Clinton Stimpson (2):
+      FindQt4: If Qt5 is in CMAKE_PREFIX_PATH, be sure to find Qt4 includes.
+      Qt4: Fix typo setting a variable for FindThreads.
+
+James Bigler (1):
+      FindCUDA: Use the PRE_LINK mode only for MSVC >= 10
+
+Matthew Woehlke (4):
+      UseJava.cmake: simplify path logic
+      UseJava.cmake: fix passing jars to add_jar
+      UseJava.cmake: accept jar targets in add_jar
+      UseJava.cmake: require explicit request to include jars
+
+Paul Kunysch (1):
+      CPack: Avoid "format expects 'unsigned int'" warnings
+
+Petr Kmoch (1):
+      cmSystemTools: Generalize TrimWhitespace to all whitespace
+
+Rex Dieter (1):
+      FindImageMagick: Search versioned suffixes (#14012)
+
+Rolf Eike Beer (1):
+      FindRuby: improve version selection
+
+Stephen Kelly (13):
+      FindQt4: Set the Qt4_FOUND variable if Qt4 is found
+      FindQt4: Set the INTERFACE_QT_MAJOR_VERSION for Qt4::QtCore
+      Document that CMAKE_AUTOMOC works with Qt 5.
+      FPHSA: Fix FOUND_VAR check to work with if() auto-dereference
+      Fix cmGeneratorExpression::Preprocess for interleaved inputs.
+      cmake-gui: Use the QStandardItemModel workaround until 5.1.0.
+      Automoc: append implicit includes after user-specified dirs
+      Fix the evaluation of per-config COMPILE_DEFINITIONS (#14037)
+      Fix new target commands documentation.
+      install(EXPORT): Ensure clean INTERFACE_INCLUDE_DIRECTORIES
+      Report an error on IMPORTED targets with a faulty INTERFACE
+      Error if linked target has relative paths in INTERFACE_INCLUDE_DIRECTORIES
+      Fix the Qt 5 version required to run the IncompatibleQt test.
+
+Changes in CMake 2.8.11-rc1 (since 2.8.10.2)
+----------------------------------------------
+Alan Witkowski (1):
+      FindBullet: Search in per-config dirs on Windows (#13738)
+
+Aleksey Avdeev (1):
+      Add module FindIcotool
+
+Alex Neundorf (30):
+      Eclipse: add switch to disable linked resources (#13189)
+      Eclipse: set source path once to fix Eclipse indexer (#13596)
+      cmDependsC: remove unused member variable
+      cmDependsC: remove code duplication
+      cmDependsC: fix indentation
+      cmDepends: allow multiple dependees per depender
+      AddCustomCommand: Handle multiple IMPLICIT_DEPENDS files (#10048)
+      Add support for Texas Instruments DSP compiler (#12405)
+      Squish: detect version
+      Squish: use FPHSA
+      Squish: find executables also under Windows
+      Squish: rename squish_add_test() to squish_v3_add_test() and fix docs a bit
+      Squish: use ${CMAKE_CURRENT_LIST_DIR}
+      Squish: add support for squish 4 (#9734)
+      Squish: fix new squish_v4_add_test() macro
+      Automoc: "inherit" FOLDER target property from target (#13688)
+      FPHSA: don't succeed if only checking for XX_FOUND (#13755)
+      CONFIGURE_PACKAGE_CONFIG_FILE(): improve generated comments
+      Automoc: get include dirs without stripping implicit include dirs off
+      configure_package_config_file: force absolute paths for usr-move
+      configure_package_config_file(): fix indentation
+      configure_package_config_file(): extend documentation
+      documentation: handling of relative paths by include- and link_directories()
+      automoc: use a std::vector<> instead a std::list
+      automoc: use the header extensions from cmMakefile
+      Eclipse: also detect include dirs and macro for clang (#13823)
+      cmLocalGenerator: remove "virtual" where not used
+      export files: rewrite the code for checking required targets
+      FPHSA: Add FOUND_VAR option to specify _FOUND variable name
+      FPHSA: improve documentation
+
+Alexander Chehovsky (2):
+      Xcode: Fix nested source group handling (#12943)
+      Xcode: Sort source files
+
+Amine Chadly (2):
+      file: remove dead code
+      Add test to secure the file(GLOB empty) behavior.
+
+Amit Kulkarni (6):
+      OpenBSD: Install shared libraries without executable permission
+      OpenBSD: Add paths for Java 1.6.0/1.7.0 JRE/JDK
+      OpenBSD: Add path for Freetype under X.org
+      OpenBSD: Add paths for Tcl/Tk 8.4/8.5
+      OpenBSD: Add path for Lua 5.1
+      OpenBSD: Add paths for Qt3/Qt4
+
+Andreas Mohr (4):
+      Documentation: Correct typos and grammar
+      Documentation: Clarify some command descriptions
+      Correct string literal typo (have "(NULL)" like all other cases).
+      Remove seemingly bogus duplicate CPACK_PACKAGE_FILE_NAME call.
+
+Anton Helwart (1):
+      VS: Avoid empty source groups in some cases (#3474)
+
+Benjamin Eikel (2):
+      Swap linking order of SDLmain and SDL (#0013769)
+      FindSDL_...: Restore dropped search paths (#13819)
+
+Brad King (109):
+      find_library: Refactor internal name iteration
+      find_library: Simplify framework search logic
+      find_library: Generalize helper macro in test case
+      find_library: Optionally consider all names in each directory
+      FindBoost: Remove extra indentation level
+      FindBoost: Mark Boost_DIR cache entry as advanced
+      FindBoost: Use PATH_SUFFIXES to look in "Program Files"
+      FindBoost: Overhaul caching and search repeat behavior
+      FindBoost: Construct a clean Boost_LIBRARIES value
+      FindBoost: Refactor Boost_FOUND computation and version check
+      FindBoost: Rewrite documentation
+      BSD: Do not require dlfcn.h to build shared libs (#13573)
+      Xcode: Fix ReRunCMake.make path to cmake.check_cache (#13603)
+      VS10: Refactor link options collection
+      VS10: Honor /DELAYSIGN and /KEYFILE flags (#13601)
+      Document external language support policy
+      CTest: Allow SUBMIT_INDEX with CDash
+      KWSys: Submit dashboard builds to PublicDashboard
+      pre-commit: Update KWSys rejection message for new workflow
+      CTestCustom: Suppress LNK4089 warning about PSAPI
+      load_command: Deprecate and document pending removal
+      Documentation: Clarify configure_file behavior
+      OS X: Warn about known SDK breakage by Xcode 3.2.6
+      Optionally skip link dependencies on shared library files
+      Teach BuildDepends test to cover LINK_DEPENDS_NO_SHARED
+      Serialize tests for EXCLUDE_FROM_DEFAULT_BUILD
+      MSVC: Drop default use of /Zm1000 for VS >= 7.1
+      Teach find_(path|file) about Linux multiarch (#13742)
+      Test find_path multiarch support (#13742)
+      Add policy CMP0019 to skip include/link variable re-expansion
+      Xcode: Add frameworks search paths from link dependeny closure (#13397)
+      Makefile: Use modern link information for framework search paths
+      Documentation: Clarify handling of implicit link directories
+      Remove references to KWSys Process Win9x support
+      add_library: Document object library portability suggestion
+      OS X: Link with all framework search paths, not just the last
+      OS X: Detect implicit link directories on modern toolchains
+      OS X: Detect implicit linker framework search paths
+      Revert "load_command: Deprecate and document pending removal"
+      VS11: Simplify external object file handling (#13831)
+      KWIML: Teach ABI about 'long long' on older GNU
+      CMake: Skip empty link.txt lines (#13845)
+      ExternalProject: Allow DEPENDS on normal targets (#13849)
+      VS11: Fix VSExternalInclude test
+      target_link_libraries: Document that new sigs privatize old (#13876)
+      Tests: Avoid CTestLimitDashJ crash on Borland 5.8 builds
+      Fix use of cmTypeMacro in new command classes
+      Fix cmSystemTools::RenameFile race on Windows
+      VS 6: Create .rule file directory before file
+      Add ExternalData module
+      ExternalData: Remove compatibility with CMake < 2.8.5
+      ExternalData: Do not match directory names when resolving DATA{}
+      ExternalData: Cleanup stray TODO and typo in comments
+      ExternalData: Remove unused private interface
+      ExternalData: Improve series matching using an explicit syntax
+      ExternalData: Add tests covering interfaces and errors
+      ExternalData: Allow ()-groups in series match regex
+      ExternalData: Allow DATA{} syntax to reference directories
+      ExternalData: Generalize hash algo/ext handling
+      ExternalData: Add support for SHA 1 and 2 hash algorithms
+      ExternalData: Collapse ../ components in DATA{} paths
+      Fix Module.ExternalData test on Cygwin
+      Fix Module.ExternalData test on VS 6
+      ExternalData: Attach download rules to content links in IDEs
+      find_package: Reword <package>_NO_INTERFACES documentation
+      Normalize full paths in implicit link library list
+      Fail early if no current working directory exists
+      MSVC: Fix CMAKE_CL_64 in CXX-only projects (#13896)
+      ExternalProject: Simplify CMake command line generation
+      Tests: Run ctest custom commands with VERBATIM
+      CMake: Add -T option to choose a generator toolset
+      VS: Implement generator toolset selection (#10722, #13774)
+      Xcode: Implement generator toolset selection (#9831, #13802)
+      CTest: Add options to set generator toolset
+      ExternalProject: Propagate the generator toolset
+      Tests: Consolidate ctest --build-and-test generator options
+      Tests: Add generator toolset support
+      Fix crash on empty CMAKE_<lang>_COMPILER value (#13901)
+      file: Do not remove symlinked directories recursively (#10538)
+      Embarcadero: Fix default link stack/heap flags (#13912)
+      Avoid duplicate RPATH entries
+      AIX-GNU: Put implicit link directories in runtime libpath (#13909)
+      VS: Replace generation timestamp file atomically
+      VS,Xcode: Remove unused CMAKE_GENERATOR_* variables
+      Delete entire CMakeFiles directory when deleting CMakeCache.txt (#13756)
+      Tests/RunCMake: Allow tests to control build tree behavior
+      Test Unix Makefiles generator support for changing compilers
+      Xcode: Drop check for circular target dependencies
+      Xcode: Each target dependency edge needs a unique object (#13935)
+      Tests: Replace exec_program with execute_process
+      Tests: Generalize decision for 'make' tool supporting spaces
+      ExternalData: Test content link with a space in its name
+      FPHSA: Convert FOUND_VAR failure test to RunCMake
+      VS: Restore CMAKE_GENERATOR_FC variable
+      Xcode: Generate recommended artwork setting (#13954)
+      CTest: Fix ctest_update with 'HEAD' file in source tree
+      VS 10: Fix CMAKE_<LANG>_STACK_SIZE implementation (#13968)
+      install(EXPORT): Force absolute paths for usr-move
+      AIX: Do not use -brtl to create shared libraries (#13997)
+      add_subdirectory: Compute output dir with consistent slashes (#10072)
+      ExternalData: Preserve escaped semicolons during argument expansion
+      Avoid crash when checking property link dependencies without link info
+      Avoid crash when checking property compatibility without link info
+      Refactor RunCMake.build_command test to allow more cases
+      build_command: Fail early without CMAKE_MAKE_PROGRAM (#14005)
+      CTest: Fail early without PROJECT_BINARY_DIR (#14005)
+      FindQt4: Fix QT_QMAKE{_QMAKE => }_EXECUTABLE typo
+      XL: Use -qpic for position independent code (#14010)
+      Configure Tests/CMakeTests only with BUILD_TESTING ON
+
+Casey Goodlett (1):
+      CTest: Prevent creation of unbounded number of tests in ctest (#12904)
+
+Clemens Heppner (1):
+      CMake: source_group needs to check its own regex after its children (#13611)
+
+Clinton Stimpson (5):
+      Fix for possible Rez errors when creating dmg.
+      PackageMaker: Enable postflight script in component mode (#12375)
+      CPack: Fix RPM/Deb package names to not include "ALL_COMPONENTS_IN_ONE"
+      Qt4: Add SYSTEM option to include_directories.
+      FindQt4: set QT_VERSION_* variables sooner.
+
+David Cole (19):
+      Begin post-2.8.10 development
+      CPack: Add automatic detection of the Unicode makensis (#9629)
+      BundleUtilities: Use a more inclusive REGEX for frameworks (#13600)
+      VS: Avoid empty, unreferenced solution folders... (#13571)
+      NMake: Add a test to demonstrate EmptyDepends issue (#13392)
+      NMake: Fix problem with empty DEPENDS args (#13392)
+      CMake: Remove "/STACK:10000000" from default linker flags (#12437)
+      Watcom: Avoid prompt from wmake about dll with no exports...
+      Tests: Use the right path to CPack value for running CPack tests
+      VS11: Allow using folders with the VS11 Express Edition (#13770)
+      CPack: Fix dashboard errors (#11575)
+      CPack: Fix dashboard warnings (#11575)
+      CPack: Fix dashboard errors and warnings (#11575)
+      CMake: Stylistic changes and documentation tweaks
+      CMake: Fix dashboard warnings
+      CMake: Fix dashboard test failure
+      CMake: Fix dashboard build errors and warnings
+      CTest: Coverage handler: expect certain output lines from gcov 4.7 (#13657)
+      Add CTestLimitDashJ test (#12904)
+
+David Golub (2):
+      CPack/NSIS: Fix compatibility issues with prerelease NSIS (#13202)
+      CPack/NSIS: Add support for 64-bit NSIS (#13203)
+
+Eric LaFranchi (1):
+      CPack: WIX Product Icon, UI Banner, UI Dialog support (#13789)
+
+Eric NOULARD (1):
+      CPackRPM fix #13898 uses IF(DEFINED var) to avoid wrong var value logic
+
+Gerald Hofmann (1):
+      CPack: Fix NSIS version check without release version (#9721)
+
+James Bigler (4):
+      Use PRE_LINK instead of PRE_BUILD when testing PRE_LINK.
+      FindCUDA: Remove linkage against CUDA driver library (#13084)
+      FindCUDA: Add support for separable compilation
+      FindCUDA: Added cupti library.
+
+Janne Rönkkö (1):
+      FindQt4: Do not use qmake from Qt5
+
+Jean-Christophe Fillion-Robin (1):
+      Add $<SEMICOLON> generator expression.
+
+Marcus D. Hanwell (1):
+      Removed GenerateExportHeader warnings about old compilers
+
+Mark Salisbury (2):
+      VS: Specify WinCE subsystem also for DLLs
+      VS: Specify WinCE subsystems correctly in VS 9 2008
+
+Mathias Gaunard (2):
+      enable CTEST_USE_LAUNCHERS with Ninja too
+      Ninja: fix usage of cldeps with ctest launchers
+
+Matt McCormick (7):
+      ExternalProject: Only run 'git fetch' when required.
+      ExternalProject: Do smoke tests for Git Tutorial builds.
+      ExternalProject: Add tests for UPDATE_COMMAND.
+      ExternalProject: Always do a git fetch for a remote ref.
+      ExternalProject: Make sure the ExternalProjectUpdate setup is available.
+      ExternalProject: Verify when a fetch occurs during update test.
+      ExternalProjectUpdateTest: Only support Git 1.6.5 and greater.
+
+Matthew Woehlke (1):
+      ccmake: Allow DEL key in first column
+
+Michael Tänzer (4):
+      GetPrerequisites: Move tool search paths up
+      GetPrerequisites: Add support for objdump
+      GetPrerequisites: Enable test for BundleUtilities on MinGW
+      GetPrerequisites: Add documentation for objdump
+
+Michael Wild (1):
+      cmDepends: No dependency-vector erasure in CheckDependencies
+
+Morné Chamberlain (15):
+      Added a generator for Sublime Text 2 project files.
+      Added some support for sublimeclang_options in the generated project file.
+      Changed SublimeClang include path generation to expand to absolute paths.
+      Cleaned up the Sublime Text 2 Generator code a bit.
+      Fixed support for the Ninja build system.
+      Added and cleaned up some comments.
+      The generator no longer generates an explicit list of source files.
+      The generator no longer generates absolute paths to the ninja.build/Makefiles.
+      Added a CMAKE_SUBLIMECLANG_DISABLED variable that disables SublimeClang.
+      Fixed Sublime Text project generation for in-source builds
+      Define flags in CMAKE_C(XX)_FLAGS are now included in SublimeClang settings.
+      SublimeText2 Gen: Improved use of define, include flags from CMAKE_C(XX)_FLAGS
+      SublimeText2 Gen: Fixed the issue where include directory flags used -D
+      Sublime Text 2 Gen: Per-source Compile flags are now saved in a separate file.
+      SublimeText 2 Gen: Set the sublimeclang_options_script property.
+
+Neil Carlson (1):
+      NAG: Use -PIC for Fortran position-independent code (#13932)
+
+Nils Gladitz (2):
+      CPack: Add a WiX Generator (#11575)
+      CMake: Add TIMESTAMP subcommand to string and file commands
+
+Patrick Gansterer (28):
+      Introduce the abstract class cmGlobalGeneratorFactory
+      Add cmGlobalGeneratorFactory::GetGenerators()
+      Search generator in cmake::ExtraGenerators before in cmake::Generators
+      Allow a GeneratorFactory handling of more than one generator
+      Make cmGlobalGenerator::GetDocumentation() a static function
+      VS: Remove AddPlatformDefinitions from platform-specific generators
+      VS: Fix ArchitectureId of Visual Studio 10 IA64 generator
+      VS: Remove GetPlatformName from platform-specific generators
+      VS: Remove EnableLanguage from platform-specific generators
+      VS: Remove platform specific generator files
+      FindBISON: Add support for the Win flex-bison distribution
+      FindFLEX: Add support for the Win flex-bison distribution
+      VS: Remove TargetMachine for linker when checking compiler id
+      VS: Add CMAKE_VS_PLATFORM_NAME definition to cmMakefile
+      VS: Add static method to get the base of the registry
+      VS: Change variable type of ArchitectureId from const char* to string
+      VS: Change variable type of Name from const char* to string
+      VS: Support setting correct subsystem and entry point for WinCE
+      VS: Add parser for WCE.VCPlatform.config to read WinCE platforms
+      VS: Allow setting the name of the target platform
+      VS: Make DetermineCompilerId working with WinCE too
+      VS: Added "Deploy" at project configuration for WindowsCE targets
+      Add command to generate environment for a Windows CE SDK
+      VS: Set the correct SubSystem when determinating the CompilerId
+      VS: Add the entry point when compiling for WindowsCE
+      VS: Ignore LIBC.lib when linking the CompilerId executables
+      Set WINCE to 1 when building for WindowsCE
+      Ninja: Avoid LNK1170 linker error
+
+Peter Kümmel (6):
+      Ninja: encode LINK_FLAGS to handle bash variables
+      Ninja: fix building from Codeblocks GUI
+      Ninja: remove implicit dependency on custom command outputs
+      Ninja: use MinGW generator code in EnableLanguage()
+      Ninja: the Ninja generator does not support Fortran yet.
+      Ninja: escape line breaks in literals
+
+Petr Kmoch (11):
+      Add tests for list() argument count
+      Add tests for list() invalid arguments
+      Consolidate list() argument count testing
+      Add several get_property() tests
+      Add tests for EXCLUDE_FROM_DEFAULT_BUILD
+      Add property EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>
+      Define property EXCLUDE_FROM_DEFAULT_BUILD
+      Add tests for VS_SOLUTION_GLOBAL_SECTIONS
+      Implement properties VS_GLOBAL_SECTION_*
+      Define properties VS_GLOBAL_SECTION_*
+      Documentation: Clarify a few subtleties
+
+Riku Voipio (1):
+      KWIML: Teach ABI.h about Aarch64
+
+Robert Maynard (4):
+      XCode generator won't infinitely parse compiler flags (bug #13354).
+      Correct missing parameter to CMP0018Flags call.
+      Remove ability to generate sublime clang files.
+      Update generator to use new cmGeneratorTarget api.
+
+Rodolfo Schulz de Lima (1):
+      FindGTK2: Fix GTK2_LIBRARIES order for static gtk libraries
+
+Rolf Eike Beer (21):
+      FindQt: improve version selection
+      FindQt: add some more places to look for Qt3
+      Tests: add MajorVersionSelection tests
+      Linux/PA-RISC: Link with --unique=.text.* to help binutils
+      FindQt: add to MajorVersionSelection test
+      CMakeTests: allow to call the check_cmake_test macro with a given file
+      list: add tests for CMP0007 behavior
+      GetProperty test: move doc property tests into main process
+      Find* (and some other): use ${CMAKE_CURRENT_LIST_DIR} in include()
+      bootstrap: use better defaults for Haiku
+      Haiku no longer defines __BEOS__
+      check for Haiku only with __HAIKU__
+      FindLua51: do not try to link libm on BeOS
+      FindGLUT: BeOS does not have libXi and libXmu
+      FindOpenGL: add Haiku paths
+      doc: fix linebreaks in generator expression documentation
+      ProcessorCount test: fix path to cmsysTestsCxx executable
+      ProcessorCount test: require SystemInformation process to work
+      FindOpenMP: improve documentation (#13895)
+      properly detect processor architecture on Windows
+      fix Windows processor detection
+
+Sean McBride (1):
+      libarchive: fixed undefined left shift with signed ints
+
+Slava Sysoltsev (1):
+      FindImageMagick: Search quantum depth suffixes (#13859)
+
+Stephen Kelly (158):
+      GenEx: Test early determination of AND and OR
+      Enable some compiler warnings when building CMake.
+      Resolve warnings about unused variables.
+      Resolve warnings about used enum values in switch blocks.
+      Resolve warnings about shadowing parameters and local variables.
+      Resolve ambiguity warning regarding use of && and ||.
+      Remove references to ancient and removed parts of the code.
+      Always use the auto_ptr from cmsys.
+      Port cmGeneratorExpression to cmTarget from cmGeneratorTarget.
+      Split link information processing into two steps.
+      Revert "Move GetLinkInformation to cmGeneratorTarget"
+      Genex: Extract a method to parse parameters.
+      Genex: Ensure that $<0:...> has a parameter.
+      Genex: Don't segfault on $<FOO,>
+      Generate an early-return guard in target Export files.
+      Fix some warnings from -Wundef
+      Make targets depend on the link interface of their dependees.
+      Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions
+      Keep track of INCLUDE_DIRECTORIES as a vector of structs.
+      Add a way to print the origins of used include directories.
+      Tests: Fix warning about unused variable
+      Qt4: Add module dependencies to the IMPORTED targets
+      Don't crash when a target is expected but is not available.
+      Add test for custom command with a genex referring to a target.
+      GenEx: Add expressions to specify build- or install-only values
+      Allow generator expressions to require literals.
+      Add the TARGET_NAME generator expression.
+      Add API to extract target names from a genex string.
+      Add API to populate INTERFACE properties in exported targets.
+      Make all relevant targets available in the genex context.
+      Use mapped config properties to evaluate $<CONFIG>
+      Make cycles in target properties ignored, not an error.
+      Populate the ExportedTargets member early in GenerateMainFile
+      Handle INTERFACE properties transitively for includes and defines.
+      Add CMAKE_BUILD_INTERFACE_INCLUDES build-variable.
+      Make linking APIs aware of 'head' target
+      Add LINK_LIBRARIES property for direct target link dependencies
+      Allow target_link_libraries with IMPORTED targets.
+      Add the -Wundef flag when compiling CMake.
+      FindQt4: Add INTERFACE includes and defines to Qt4 targets
+      Add the target_include_directories command.
+      Add the target_compile_definitions command.
+      Keep track of properties used to determine linker libraries.
+      Add API to calculate link-interface-dependent bool properties or error.
+      Process the INTERFACE_PIC property from linked dependencies
+      Fix linking to imported libraries test.
+      Add cmGeneratorExpression::Split() API.
+      Don't pass a position when determining if a target name is a literal.
+      Extract the AddTargetNamespace method.
+      Split the generator expression before extracting targets.
+      Split LINK_INTERFACE_LIBRARIES export handling into dedicated method.
+      Allow generator expressions in LINK_INTERFACE_LIBRARIES.
+      Add a way to check INTERFACE user property compatibility.
+      Don't include generator expressions in old-style link handling.
+      Document the use of generator expressions in new commands.
+      Add the TARGET_DEFINED generator expression
+      Strip consecutive semicolons when preprocessing genex strings.
+      Don't write a comment in the export file without the code.
+      Only generate one check per missing target.
+      Move the exported check for dependencies of targets
+      Move the exported check for file existence.
+      Add a test for the interfaces in targets exported from the build tree.
+      Make the BUILD_INTERFACE of export()ed targets work.
+      Export the INTERFACE_PIC property.
+      Test evaluation target via export for generator expressions
+      Make sure generator expressions can be used with target_include_directories.
+      Populate the link information cache before checking dependent properties.
+      Exit early if we find an inconsistent property.
+      Make INTERFACE determined properties readable in generator expressions.
+      Clear the link information in ClearLinkMaps.
+      Export the COMPATIBLE_INTERFACE_BOOL content properties
+      Add the $<TARGET_POLICY> expression
+      Automatically link to the qtmain library when linking to QtCore.
+      Don't wrap all targets in LINK_LIBRARIES in a TARGET_NAME genex.
+      Generate new-style cmake code during export.
+      Store includes from the same include_directories call together.
+      Only output includes once after the start of 'generate-time' when debugging.
+      Specify the target whose includes are being listed.
+      Output include directories as LOG messages, not warnings.
+      Revert "Allow target_link_libraries with IMPORTED targets."
+      Disallow porcelain to populate includes and defines of IMPORTED targets.
+      Exclude the LINK_LIBRARIES related properties from INTERFACE evaluation.
+      Make calculation of link-interface-dependent properties type-sensitive.
+      Add the COMPATIBLE_INTERFACE_STRING property.
+      Move GetCompileDefinitions to cmTarget.
+      Process COMPILE_DEFINITIONS as generator expressions in QtAutomoc.
+      Generate the _IMPORT_PREFIX in the non-config export file.
+      Add the INSTALL_PREFIX genex.
+      Fix TARGET_PROPERTY target extractions.
+      Make the Property name protected so that subclasses can use it.
+      Don't allow targets args in the new target commands.
+      Make subclasses responsible for joining content.
+      Use the result of converting to a unix path.
+      Handle reading empty properties defined by the link interface.
+      Advance more when preprocessing exported strings.
+      Make it an error for INSTALL_PREFIX to be evaluated.
+      Export targets to a targets file, not a Config file.
+      Add a way to exclude INTERFACE properties from exported targets.
+      Add API to check if we're reading a includes or defines property.
+      Add the $<LINKED:...> generator expression.
+      Add includes and compile definitions with target_link_libraries.
+      Test workaround of bad interface include directories from depends.
+      Optimize genex evaluation for includes and defines.
+      Cache context-independent includes on evaluation.
+      Style: Use this-> when invoking member functions.
+      Process generator expressions for 'system' include directories.
+      Deduplicate the isGeneratorExpression method.
+      De-duplicate validation of genex target names.
+      Test printing origin of include dirs from tll().
+      The COMPATIBLE_INTERFACE does not affect the target it is set on.
+      Ensure type specific compatible interface properties do not intersect.
+      Fix generation of COMPILE_DEFINITIONS in DependInfo.cmake.
+      Fix determination of evaluating link libraries.
+      Only use early evaluation termination for transitive properties.
+      Move a special case for PIC from the genex to the cmTarget code.
+      Don't keep track of content determined by target property values.
+      Only append build interface include dirs to particular targets.
+      Ensure that the build interface includes have been added.
+      Whitelist target types in target_{include_directories,compile_definitions}
+      Make sure INTERFACE properties work with OBJECT libraries.
+      Don't allow utility or global targets in the LINKED expression.
+      Generate config-specific interface link libraries propeties.
+      Fix determination of when we're evaluating compile definitions.
+      Rename the IncludeDirectoriesEntry to be more generic.
+      Don't use LINKED where not needed.
+      Use the link information as a source of compile definitions and includes.
+      Revert "Don't allow utility or global targets in the LINKED expression."
+      Don't populate INTERFACE includes and defines properties in tll.
+      Revert "Add the $<LINKED:...> generator expression."
+      Revert "find_package: Reword <package>_NO_INTERFACES documentation"
+      Revert "Add a way to exclude INTERFACE properties from exported targets."
+      Don't add target-specific interface includes and defines to Qt 4 targets.
+      Fix GenerateExportHeader documentation #13936
+      automoc: Add source file to target early to set the linker language
+      Keep track of all targets seen while evaluating a genex.
+      Add a new Export generator for IMPORTED targets.
+      Handle targets in the LINK_LIBRARIES of try_compile.
+      Strip stray semicolons when evaluating generator expressions.
+      Workaround broken code where a target has itself in its link iface.
+      Fix DAG checker finding cycling dependencies.
+      Expand includes and defines transitively in 'external' genexes.
+      Fix constness of accessors.
+      Fix the tests for evaluating includes and defines.
+      Memoize includes and defines from interface libraries.
+      Remove use of TARGET_DEFINED from target_include_directories test.
+      Remove use of TARGET_DEFINED from the ExportImport test.
+      Remove use of TARGET_DEFINED from the target_link_libraries test.
+      Revert "Add the TARGET_DEFINED generator expression"
+      Only add existing targets to the Qt4 target depends properties.
+      Fix the cmGeneratorExpression::Split when leading chars are present.
+      Fix RPATH information when only a genex is used as a link library.
+      Mention that IMPORTED targets may be created by a find_package call.
+      Remove unused parameters from target_link_libraries tests.
+      Only process transitive interface properties for valid target names.
+      Restore support for target names with '+' (#13986)
+      Automoc: Don't create automoc targets if Qt is not used (#13999)
+      cmake-gui: Use -fPIE if required by Qt.
+      cmake-gui: Workaround bug in Qt 5.0.0 to 5.0.3 QStandardItemModel
+
+Thomas Klausner (1):
+      KWIML: Teach ABI.h that VAX is big endian
+
+Yury G. Kudryashov (3):
+      Automoc: Fix automoc for OBJECT libraries.
+      Automoc: add OBJECT library to QtAutomoc test
+      spell: fix a few typos in comments
+
 Changes in CMake 2.8.10.2 (since 2.8.10.1)
 ----------------------------------------------
 Alex Neundorf (1):
index b2044e4..20f5dec 100644 (file)
@@ -62,3 +62,9 @@ endif ()
 if (CMAKE_ANSI_CFLAGS)
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
 endif ()
+
+# avoid binutils problem with large binaries, e.g. when building CMake in debug mode
+# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230
+if (CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL parisc)
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--unique=.text.*")
+endif ()
index 4557be6..0f6cd05 100644 (file)
@@ -369,7 +369,7 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag)
       # For frameworks, construct the name under the embedded path from the
       # opening "${item_name}.framework/" to the closing "/${item_name}":
       #
-      string(REGEX REPLACE "^.*(${item_name}.framework/.*/${item_name}).*$" "${default_embedded_path}/\\1" embedded_item "${item}")
+      string(REGEX REPLACE "^.*(${item_name}.framework/.*/?${item_name}).*$" "${default_embedded_path}/\\1" embedded_item "${item}")
     else()
       # For other items, just use the same name as the original, but in the
       # embedded path:
index 6a30dd8..612e1a3 100644 (file)
@@ -1,3 +1,19 @@
+This file provides a few notes to CMake developers about how to add
+support for a new language to CMake.  It is also possible to place
+these files in CMAKE_MODULE_PATH within an outside project to add
+languages not supported by upstream CMake.  However, this is not
+a fully supported use case.
+
+The implementation behind the scenes of project/enable_language,
+including the compiler/platform modules, is an *internal* API that
+does not make any compatibility guarantees.  It is not covered in the
+official reference documentation that is versioned with the source code.
+Maintainers of external language support are responsible for porting
+it to each version of CMake as upstream changes are made.  Since
+the API is internal we will not necessarily include notice of any
+changes in release notes.
+
+
 CMakeDetermine(LANG)Compiler.cmake  -> this should find the compiler for LANG and configure CMake(LANG)Compiler.cmake.in
 
 CMake(LANG)Compiler.cmake.in  -> used by CMakeDetermine(LANG)Compiler.cmake
index d74dcdc..c41adc9 100644 (file)
@@ -50,6 +50,7 @@ endif()
 
 set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "@CMAKE_C_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@")
+set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 
 @SET_CMAKE_CMCLDEPS_EXECUTABLE@
 @SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
index 2d76c7a..c25df0c 100644 (file)
 # define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
 
 #elif defined(__TI_COMPILER_VERSION__)
-# define COMPILER_ID "TI_DSP"
+# define COMPILER_ID "TI"
   /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
 # define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
 # define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000   % 1000)
index 8c5d84e..9287b81 100644 (file)
@@ -51,6 +51,7 @@ endif()
 
 set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
+set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 
 @SET_CMAKE_CMCLDEPS_EXECUTABLE@
 @SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
index 5e70a41..e2119c2 100644 (file)
 # define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
 
 #elif defined(__TI_COMPILER_VERSION__)
-# define COMPILER_ID "TI_DSP"
+# define COMPILER_ID "TI"
   /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
 # define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
 # define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000   % 1000)
index cec09e9..03c5668 100644 (file)
@@ -15,6 +15,6 @@
 # determine the compiler to use for ASM using AT&T syntax, e.g. GNU as
 
 set(ASM_DIALECT "-ATT")
-set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}gas ${_CMAKE_TOOLCHAIN_PREFIX}as)
+set(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gas ${_CMAKE_TOOLCHAIN_PREFIX}as)
 include(CMakeDetermineASMCompiler)
 set(ASM_DIALECT)
index 9f0b30a..99b04e3 100644 (file)
@@ -39,8 +39,8 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
       endif()
     endif()
   else() # some specific assembler "dialect"
-    if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
-      message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT must be preset !")
+    if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT  AND NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST)
+      message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT or CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST must be preset !")
     endif()
   endif()
 
@@ -99,9 +99,9 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "/?")
   set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft")
 
-  list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI_DSP )
-  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_TI_DSP "-h")
-  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_TI_DSP "Texas Instruments")
+  list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI )
+  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_TI "-h")
+  set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_TI "Texas Instruments")
 
   include(CMakeDetermineCompilerId)
   CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT})
index 50f71dd..5d783b1 100644 (file)
@@ -14,7 +14,7 @@
 
 # Find the nasm assembler. yasm (http://www.tortall.net/projects/yasm/) is nasm compatible
 
-set(CMAKE_ASM_NASM_COMPILER_INIT nasm yasm)
+set(CMAKE_ASM_NASM_COMPILER_LIST nasm yasm)
 
 if(NOT CMAKE_ASM_NASM_COMPILER)
   find_program(CMAKE_ASM_NASM_COMPILER nasm
index 275fc47..d2220e0 100644 (file)
@@ -145,19 +145,27 @@ endif ()
 # NAME_WE cannot be used since then this test will fail for names lile
 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING
-    AND "${CMAKE_C_COMPILER_ID}" MATCHES "GNU"
-    AND NOT _CMAKE_TOOLCHAIN_PREFIX)
-  get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
-  if (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
-
-  # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
-  # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
-  if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
+if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+  if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+    get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+
+    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+  elseif("${CMAKE_C_COMPILER_ID}" MATCHES "TI")
+    # TI compilers are named e.g. cl6x, cl470 or armcl.exe
+    get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX "${CMAKE_MATCH_1}")
+      set(_CMAKE_TOOLCHAIN_SUFFIX "${CMAKE_MATCH_2}")
+    endif ()
+  endif()
 
 endif ()
 
index 59da3e6..6f7e8f6 100644 (file)
@@ -141,19 +141,30 @@ endif ()
 # NAME_WE cannot be used since then this test will fail for names lile
 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING
-    AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"
-    AND NOT _CMAKE_TOOLCHAIN_PREFIX)
-  get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
-  if (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
-
-  # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
-  # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
-  if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
+
+
+if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
+
+  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+    get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+
+    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "TI")
+    # TI compilers are named e.g. cl6x, cl470 or armcl.exe
+    get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX "${CMAKE_MATCH_1}")
+      set(_CMAKE_TOOLCHAIN_SUFFIX "${CMAKE_MATCH_2}")
+    endif ()
+
+  endif()
 
 endif ()
 
index 75247d9..25d6bbe 100644 (file)
@@ -72,19 +72,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
       # Parse implicit linker information for this language, if available.
       set(implicit_dirs "")
       set(implicit_libs "")
-      set(MULTI_ARCH FALSE)
-      if(DEFINED CMAKE_OSX_ARCHITECTURES)
-        if( "${CMAKE_OSX_ARCHITECTURES}" MATCHES ";" )
-          set(MULTI_ARCH TRUE)
-        endif()
-      endif()
-      if(CMAKE_${lang}_VERBOSE_FLAG
-          # Implicit link information cannot be used explicitly for
-          # multiple OS X architectures, so we skip it.
-          AND NOT MULTI_ARCH
-          # Skip this with Xcode for now.
-          AND NOT "${CMAKE_GENERATOR}" MATCHES Xcode)
-        CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs log
+      set(implicit_fwks "")
+      if(CMAKE_${lang}_VERBOSE_FLAG)
+        CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log
           "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}")
         file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
           "Parsed ${lang} implicit link information from above output:\n${log}\n\n")
@@ -112,8 +102,17 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
         message(STATUS "${_desc}")
       endif()
 
+      # Implicit link libraries cannot be used explicitly for multiple
+      # OS X architectures, so we skip it.
+      if(DEFINED CMAKE_OSX_ARCHITECTURES)
+        if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
+          set(implicit_libs "")
+        endif()
+      endif()
+
       set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
       set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
+      set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)
 
       # Detect library architecture directory name.
       if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
index 906a5e7..b918092 100644 (file)
@@ -107,11 +107,14 @@ Id flags: ${testflags}
 ")
 
   # Compile the compiler identification source.
-  if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)( .NET)?( 200[358])? *((Win64|IA64|ARM))?")
+  if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)")
     set(vs_version ${CMAKE_MATCH_1})
-    set(vs_arch ${CMAKE_MATCH_4})
+    set(id_arch ${CMAKE_VS_PLATFORM_NAME})
     set(id_lang "${lang}")
     set(id_cl cl.exe)
+    if(NOT id_arch)
+      set(id_arch Win32)
+    endif()
     if(NOT "${vs_version}" VERSION_LESS 10)
       set(v 10)
       set(ext vcxproj)
@@ -123,25 +126,26 @@ Id flags: ${testflags}
       set(v 6)
       set(ext dsp)
     endif()
-    if("${vs_arch}" STREQUAL "Win64")
-      set(id_machine_7 17)
+    if("${id_arch}" STREQUAL "x64")
       set(id_machine_10 MachineX64)
-      set(id_arch x64)
-    elseif("${vs_arch}" STREQUAL "IA64")
-      set(id_machine_7 5)
+    elseif("${id_arch}" STREQUAL "Itanium")
       set(id_machine_10 MachineIA64)
       set(id_arch ia64)
     else()
       set(id_machine_6 x86)
-      set(id_machine_7 1)
       set(id_machine_10 MachineX86)
-      set(id_arch Win32)
     endif()
     if(CMAKE_VS_PLATFORM_TOOLSET)
       set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
     else()
       set(id_toolset "")
     endif()
+    if(CMAKE_VS_WINCE_VERSION)
+      set(id_entrypoint "mainACRTStartup")
+      set(id_subsystem 9)
+    else()
+      set(id_subsystem 1)
+    endif()
     if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]")
       set(build /p:Configuration=Debug /p:Platform=@id_arch@ /p:VisualStudioVersion=${vs_version}.0)
     elseif("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Dd][Ee][Vv]")
@@ -173,6 +177,11 @@ Id flags: ${testflags}
     set(id_type ${CMAKE_${lang}_COMPILER_XCODE_TYPE})
     set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
     get_filename_component(id_src "${src}" NAME)
+    if(CMAKE_XCODE_PLATFORM_TOOLSET)
+      set(id_toolset "GCC_VERSION = ${CMAKE_XCODE_PLATFORM_TOOLSET};")
+    else()
+      set(id_toolset "")
+    endif()
     if(NOT ${XCODE_VERSION} VERSION_LESS 3)
       set(v 3)
       set(ext xcodeproj)
index f861e39..4d3fb90 100644 (file)
@@ -200,19 +200,21 @@ endif ()
 # NAME_WE cannot be used since then this test will fail for names lile
 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING
-    AND "${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU"
-    AND NOT _CMAKE_TOOLCHAIN_PREFIX)
-  get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
-  if (COMPILER_BASENAME MATCHES "^(.+-)g?fortran(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
-
-  # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
-  # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
-  if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
-    set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
-  endif ()
+if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+  if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+    get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+-)g?fortran(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+
+    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+  endif()
+
 endif ()
 
 include(CMakeFindBinUtils)
index c4217f5..ae9f5fc 100644 (file)
@@ -63,6 +63,8 @@ if(NOT CMAKE_Java_COMPILER)
     /usr/java/j2sdk1.4.2_09/bin
     /usr/lib/j2sdk1.5-sun/bin
     /opt/sun-jdk-1.5.0.04/bin
+    /usr/local/jdk-1.7.0/bin
+    /usr/local/jdk-1.6.0/bin
     )
   # if no compiler has been specified yet, then look for one
   if(CMAKE_Java_COMPILER_INIT)
index cd33447..3a95d2a 100644 (file)
@@ -73,7 +73,11 @@ if(CMAKE_HOST_UNIX)
 else()
   if(CMAKE_HOST_WIN32)
     set (CMAKE_HOST_SYSTEM_NAME "Windows")
-    set (CMAKE_HOST_SYSTEM_PROCESSOR "$ENV{PROCESSOR_ARCHITECTURE}")
+    if (DEFINED ENV{PROCESSOR_ARCHITEW6432})
+      set (CMAKE_HOST_SYSTEM_PROCESSOR "$ENV{PROCESSOR_ARCHITEW6432}")
+    else()
+      set (CMAKE_HOST_SYSTEM_PROCESSOR "$ENV{PROCESSOR_ARCHITECTURE}")
+    endif()
   endif()
 endif()
 
@@ -106,6 +110,12 @@ if(CMAKE_SYSTEM_NAME)
     set(CMAKE_CROSSCOMPILING TRUE)
   endif()
   set(PRESET_CMAKE_SYSTEM_NAME TRUE)
+elseif(CMAKE_VS_WINCE_VERSION)
+  set(CMAKE_SYSTEM_NAME      "WindowsCE")
+  set(CMAKE_SYSTEM_VERSION   "${CMAKE_VS_WINCE_VERSION}")
+  set(CMAKE_SYSTEM_PROCESSOR "${MSVC_C_ARCHITECTURE_ID}")
+  set(CMAKE_CROSSCOMPILING TRUE)
+  set(PRESET_CMAKE_SYSTEM_NAME TRUE)
 else()
   set(CMAKE_SYSTEM_NAME      "${CMAKE_HOST_SYSTEM_NAME}")
   set(CMAKE_SYSTEM_VERSION   "${CMAKE_HOST_SYSTEM_VERSION}")
index 14551d1..f5c009c 100644 (file)
@@ -30,7 +30,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CMakeParseArguments)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
 
 function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT )
 
index 1fa0157..365d381 100644 (file)
@@ -90,7 +90,7 @@ set(ENV{LANG}        C)
 
 # Now check for C, works for gcc and Intel compiler at least
 if (NOT CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS)
-  if ("${CMAKE_C_COMPILER_ID}" MATCHES GNU  OR  "${CMAKE_C_COMPILER_ID}" MATCHES Intel)
+  if ("${CMAKE_C_COMPILER_ID}" MATCHES GNU  OR  "${CMAKE_C_COMPILER_ID}" MATCHES Intel  OR  "${CMAKE_C_COMPILER_ID}" MATCHES Clang)
     _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c _dirs _defines)
     set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "C compiler system include directories")
     set(CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "C compiler system defined macros")
@@ -99,7 +99,7 @@ endif ()
 
 # And now the same for C++
 if (NOT CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS)
-  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES GNU  OR  "${CMAKE_CXX_COMPILER_ID}" MATCHES Intel)
+  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES GNU  OR  "${CMAKE_CXX_COMPILER_ID}" MATCHES Intel  OR  "${CMAKE_CXX_COMPILER_ID}" MATCHES Clang)
     _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS(c++ _dirs _defines)
     set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS "${_dirs}" CACHE INTERNAL "CXX compiler system include directories")
     set(CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS "${_defines}" CACHE INTERNAL "CXX compiler system defined macros")
index e08c1c6..e70c013 100644 (file)
@@ -41,14 +41,14 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC"
 # in all other cases search for ar, ranlib, etc.
 else()
 
-  find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+  find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
 
   find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   if(NOT CMAKE_RANLIB)
     set(CMAKE_RANLIB : CACHE INTERNAL "noop for ranlib")
   endif()
 
-  find_program(CMAKE_STRIP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}strip HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+  find_program(CMAKE_STRIP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}strip${_CMAKE_TOOLCHAIN_SUFFIX} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_LINKER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ld HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_OBJDUMP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objdump HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
index 37b72fa..ae17454 100644 (file)
@@ -77,6 +77,8 @@ endif()
 # This variable is used by the Eclipse generator and appended to the make invocation commands.
 set(CMAKE_ECLIPSE_MAKE_ARGUMENTS "${_CMAKE_ECLIPSE_INITIAL_MAKE_ARGS}" CACHE STRING "Additional command line arguments when Eclipse invokes make. Enter e.g. -j<some_number> to get parallel builds")
 
+set(CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES TRUE CACHE BOOL "If disabled, CMake will not generate linked resource to the subprojects and to the source files within targets")
+
 # This variable is used by the Eclipse generator in out-of-source builds only.
 set(CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT FALSE CACHE BOOL "If enabled, CMake will generate a source project for Eclipse in CMAKE_SOURCE_DIR")
 mark_as_advanced(CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT)
index 55f8277..d193881 100644 (file)
@@ -52,3 +52,4 @@ endif()
 
 set(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "@CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES@")
+set(CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
index 4d25de0..f84852a 100644 (file)
         PRINT *, 'INFO:platform[IRIX]'
 #elif defined(__hpux) || defined(__hpux__)
         PRINT *, 'INFO:platform[HP-UX]'
-#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+#elif defined(__HAIKU__)
         PRINT *, 'INFO:platform[Haiku]'
-#       if 0
-!       Haiku also defines __BEOS__ so we must
-!       put it prior to the check for __BEOS__
-#       endif
 #elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
         PRINT *, 'INFO:platform[BeOS]'
 #elif defined(__QNX__) || defined(__QNXNTO__)
index 96ecb42..d042d5e 100644 (file)
@@ -173,6 +173,7 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
   else()
     set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
   endif()
+
   file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
 
   foreach(var ${CCF_PATH_VARS})
@@ -188,11 +189,31 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
     endif()
   endforeach()
 
+  get_filename_component(inputFileName "${_inputFile}" NAME)
+
   set(PACKAGE_INIT "
 ####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was ${inputFileName}                            ########
+
 get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
 ")
 
+  if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
+    # Handle "/usr move" symlinks created by some Linux distros.
+    set(PACKAGE_INIT "${PACKAGE_INIT}
+# Use original install prefix when loaded through a \"/usr move\"
+# cross-prefix symbolic link such as /lib -> /usr/lib.
+get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
+get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
+if(_realCurr STREQUAL _realOrig)
+  set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\")
+endif()
+unset(_realOrig)
+unset(_realCurr)
+")
+  endif()
+
   if(NOT CCF_NO_SET_AND_CHECK_MACRO)
     set(PACKAGE_INIT "${PACKAGE_INIT}
 macro(set_and_check _var _file)
index ecb20dc..80e0218 100644 (file)
 # This is used internally by CMake and should not be included by user
 # code.
 
-function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
+function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj_regex)
   set(implicit_libs_tmp "")
   set(implicit_dirs_tmp)
+  set(implicit_fwks_tmp)
   set(log "")
 
   # Parse implicit linker arguments.
@@ -36,6 +37,16 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
     set(cmd)
     if("${line}" MATCHES "${linker_regex}" AND
         NOT "${line}" MATCHES "${linker_exclude_regex}")
+      if(XCODE)
+        # Xcode unconditionally adds a path under the project build tree and
+        # on older versions it is not reported with proper quotes.  Remove it.
+        string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" _dir_regex "${CMAKE_BINARY_DIR}")
+        string(REGEX REPLACE " -[FL]${_dir_regex}/([^ ]| [^-])+( |$)" " " xline "${line}")
+        if(NOT "x${xline}" STREQUAL "x${line}")
+          set(log "${log}  reduced line: [${line}]\n            to: [${xline}]\n")
+          set(line "${xline}")
+        endif()
+      endif()
       if(UNIX)
         separate_arguments(args UNIX_COMMAND "${line}")
       else()
@@ -97,32 +108,62 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
     endif()
   endforeach()
 
+  # Look for library search paths reported by linker.
+  if("${output_lines}" MATCHES ";Library search paths:((;\t[^;]+)+)")
+    string(REPLACE ";\t" ";" implicit_dirs_match "${CMAKE_MATCH_1}")
+    set(log "${log}  Library search paths: [${implicit_dirs_match}]\n")
+    list(APPEND implicit_dirs_tmp ${implicit_dirs_match})
+  endif()
+  if("${output_lines}" MATCHES ";Framework search paths:((;\t[^;]+)+)")
+    string(REPLACE ";\t" ";" implicit_fwks_match "${CMAKE_MATCH_1}")
+    set(log "${log}  Framework search paths: [${implicit_fwks_match}]\n")
+    list(APPEND implicit_fwks_tmp ${implicit_fwks_match})
+  endif()
+
   # Cleanup list of libraries and flags.
   # We remove items that are not language-specific.
   set(implicit_libs "")
   foreach(lib IN LISTS implicit_libs_tmp)
     if("${lib}" MATCHES "^(crt.*\\.o|gcc.*|System.*)$")
       set(log "${log}  remove lib [${lib}]\n")
+    elseif(IS_ABSOLUTE "${lib}")
+      get_filename_component(abs "${lib}" ABSOLUTE)
+      if(NOT "x${lib}" STREQUAL "x${abs}")
+        set(log "${log}  collapse lib [${lib}] ==> [${abs}]\n")
+      endif()
+      list(APPEND implicit_libs "${abs}")
     else()
       list(APPEND implicit_libs "${lib}")
     endif()
   endforeach()
 
-  # Cleanup list of directories.
-  set(implicit_dirs "")
-  foreach(d IN LISTS implicit_dirs_tmp)
-    get_filename_component(dir "${d}" ABSOLUTE)
-    list(APPEND implicit_dirs "${dir}")
-    set(log "${log}  collapse dir [${d}] ==> [${dir}]\n")
+  # Cleanup list of library and framework directories.
+  set(desc_dirs "library")
+  set(desc_fwks "framework")
+  foreach(t dirs fwks)
+    set(implicit_${t} "")
+    foreach(d IN LISTS implicit_${t}_tmp)
+      get_filename_component(dir "${d}" ABSOLUTE)
+      string(FIND "${dir}" "${CMAKE_FILES_DIRECTORY}/" pos)
+      if(NOT pos LESS 0)
+        set(msg ", skipping non-system directory")
+      else()
+        set(msg "")
+        list(APPEND implicit_${t} "${dir}")
+      endif()
+      set(log "${log}  collapse ${desc_${t}} dir [${d}] ==> [${dir}]${msg}\n")
+    endforeach()
+    list(REMOVE_DUPLICATES implicit_${t})
   endforeach()
-  list(REMOVE_DUPLICATES implicit_dirs)
 
   # Log results.
   set(log "${log}  implicit libs: [${implicit_libs}]\n")
   set(log "${log}  implicit dirs: [${implicit_dirs}]\n")
+  set(log "${log}  implicit fwks: [${implicit_fwks}]\n")
 
   # Return results.
   set(${lib_var} "${implicit_libs}" PARENT_SCOPE)
   set(${dir_var} "${implicit_dirs}" PARENT_SCOPE)
+  set(${fwk_var} "${implicit_fwks}" PARENT_SCOPE)
   set(${log_var} "${log}" PARENT_SCOPE)
 endfunction()
index c373414..69171c2 100644 (file)
 #elif defined(__hpux) || defined(__hpux__)
 # define PLATFORM_ID "HP-UX"
 
-#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+#elif defined(__HAIKU__)
 # define PLATFORM_ID "Haiku"
-/* Haiku also defines __BEOS__ so we must
-   put it prior to the check for __BEOS__
-*/
 
 #elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
 # define PLATFORM_ID "BeOS"
diff --git a/Modules/CMakeVS12FindMake.cmake b/Modules/CMakeVS12FindMake.cmake
new file mode 100644 (file)
index 0000000..338d9a2
--- /dev/null
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2007-2013 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# Always use MSBuild because:
+# - devenv treats command-line builds as recently-loaded projects in the IDE
+# - devenv does not appear to support non-standard platform toolsets
+# If we need devenv for Intel Fortran in the future we should add
+# a special case when Fortran is enabled.
+find_program(CMAKE_MAKE_PROGRAM
+  NAMES MSBuild
+  HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\12.0;MSBuildToolsPath]"
+  )
+
+mark_as_advanced(CMAKE_MAKE_PROGRAM)
+set(MSVC12 1)
+set(MSVC_VERSION 1800)
index 6886ed9..42d3c0c 100644 (file)
@@ -438,6 +438,7 @@ if(NOT CPACK_GENERATOR)
     endif()
   else()
     option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
+    option(CPACK_BINARY_WIX  "Enable to build WiX packages" OFF)
     option(CPACK_BINARY_ZIP  "Enable to build ZIP packages" OFF)
   endif()
 
@@ -453,6 +454,7 @@ if(NOT CPACK_GENERATOR)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TGZ          TGZ)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TBZ2         TBZ2)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TZ           TZ)
+  cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_WIX          WIX)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_ZIP          ZIP)
 
 endif()
@@ -483,7 +485,7 @@ endif()
 mark_as_advanced(CPACK_BINARY_CYGWIN CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_OSXX11
                  CPACK_BINARY_STGZ   CPACK_BINARY_TGZ          CPACK_BINARY_TBZ2
                  CPACK_BINARY_DEB    CPACK_BINARY_RPM          CPACK_BINARY_TZ
-                 CPACK_BINARY_NSIS CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE
+                 CPACK_BINARY_NSIS CPACK_BINARY_WIX CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE
                  CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ
                  CPACK_SOURCE_TZ CPACK_SOURCE_ZIP CPACK_BINARY_DRAGNDROP)
 
@@ -522,6 +524,9 @@ cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
 
+# WiX specific variables
+cpack_set_if_not_set(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
+
 if(DEFINED CPACK_COMPONENTS_ALL)
   if(CPACK_MONOLITHIC_INSTALL)
     message("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.")
index 106b44c..75ff3be 100644 (file)
@@ -385,15 +385,13 @@ endif()
 # Are we packaging components ?
 if(CPACK_DEB_PACKAGE_COMPONENT)
   set(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "-${CPACK_DEB_PACKAGE_COMPONENT}")
-  set(CPACK_DEB_PACKAGE_COMPONENT_PART_PATH "/${CPACK_DEB_PACKAGE_COMPONENT}")
-  set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${CPACK_DEB_PACKAGE_COMPONENT}")
   string(TOLOWER "${CPACK_PACKAGE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
 else()
   set(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "")
-  set(CPACK_DEB_PACKAGE_COMPONENT_PART_PATH "")
-  set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}")
 endif()
 
+set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
+
 # Print out some debug information if we were asked for that
 if(CPACK_DEBIAN_PACKAGE_DEBUG)
    message("CPackDeb:Debug: CPACK_TOPLEVEL_DIRECTORY          = ${CPACK_TOPLEVEL_DIRECTORY}")
index 0cec897..fa79e1b 100644 (file)
@@ -311,14 +311,12 @@ endif()
 # Are we packaging components ?
 if(CPACK_RPM_PACKAGE_COMPONENT)
   set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
-  set(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "/${CPACK_RPM_PACKAGE_COMPONENT}")
-  set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${CPACK_RPM_PACKAGE_COMPONENT}")
 else()
   set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "")
-  set(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "")
-  set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}")
 endif()
 
+set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}")
+
 #
 # Use user-defined RPM specific variables value
 # or generate reasonable default value from
@@ -453,31 +451,41 @@ endif()
 
 # Check if additional fields for RPM spec header are given
 # There may be some COMPONENT specific variables as well
+# If component specific var is not provided we use the global one
+# for each component
 foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV)
     if(CPACK_RPM_PACKAGE_DEBUG)
       message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
     endif()
     if(CPACK_RPM_PACKAGE_COMPONENT)
-        if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER})
+        if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER})
             if(CPACK_RPM_PACKAGE_DEBUG)
               message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}")
             endif()
             set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}})
         else()
-            if(CPACK_RPM_PACKAGE_DEBUG)
-              message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined")
-              message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+            if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
+              if(CPACK_RPM_PACKAGE_DEBUG)
+                message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined")
+                message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+              endif()
+              set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
             endif()
-            set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
         endif()
     else()
-        if(CPACK_RPM_PACKAGE_DEBUG)
-          message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+        if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER})
+          if(CPACK_RPM_PACKAGE_DEBUG)
+            message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+          endif()
+          set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
         endif()
-        set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
     endif()
 
-  if(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+  # Treat the RPM Spec keyword iff it has been properly defined
+  if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+    # Transform NAME --> Name e.g. PROVIDES --> Provides
+    # The Upper-case first letter and lowercase tail is the
+    # appropriate value required in the final RPM spec file.
     string(LENGTH ${_RPM_SPEC_HEADER} _PACKAGE_HEADER_STRLENGTH)
     math(EXPR _PACKAGE_HEADER_STRLENGTH "${_PACKAGE_HEADER_STRLENGTH} - 1")
     string(SUBSTRING ${_RPM_SPEC_HEADER} 1 ${_PACKAGE_HEADER_STRLENGTH} _PACKAGE_HEADER_TAIL)
diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake
new file mode 100644 (file)
index 0000000..0c0a8f1
--- /dev/null
@@ -0,0 +1,109 @@
+##section Variables specific to CPack WiX generator
+##end
+##module
+# - CPack WiX generator specific options
+#
+# The following variables are specific to the installers built
+# on Windows using WiX.
+##end
+##variable
+#  CPACK_WIX_UPGRADE_GUID - Upgrade GUID (Product/@UpgradeCode)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# It should be explicitly set to a constant generated
+# gloabally unique identifier (GUID) to allow your installers
+# to replace existing installations that use the same GUID.
+#
+# You may for example explicitly set this variable in
+# your CMakeLists.txt to the value that has been generated per default.
+# You should not use GUIDs that you did not generate yourself or which may
+# belong to other projects.
+#
+# A GUID shall have the following fixed length syntax:
+# XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+#  (each X represents an uppercase hexadecimal digit)
+##end
+##variable
+#  CPACK_WIX_PRODUCT_GUID - Product GUID (Product/@Id)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# If explicitly provided this will set the Product Id of your installer.
+#
+# The installer will abort if it detects a pre-existing installation that uses
+# the same GUID.
+#
+# The GUID shall use the syntax described for CPACK_WIX_UPGRADE_GUID.
+##end
+##variable
+#  CPACK_WIX_LICENSE_RTF - RTF License File
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .rtf extension
+# it is used as-is.
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .txt extension
+# it is implicitly converted to RTF by the WiX Generator.
+#
+# With CPACK_WIX_LICENSE_RTF you can override the license file used
+# by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE
+# is in an unsupported format or the .txt -> .rtf
+# conversion does not work as expected.
+#
+##end
+#
+##variable
+# CPACK_WIX_PRODUCT_ICON - The Icon shown next to the program name in Add/Remove programs.
+#
+# If set, this icon is used in place of the default icon.
+#
+##end
+#
+##variable
+# CPACK_WIX_UI_BANNER - The bitmap will appear at the top of all installer pages other than the welcome and completion dialogs.
+#
+# If set, this image will replace the default banner image.
+#
+# This image must be 493 by 58 pixels.
+#
+##end
+#
+##variable
+# CPACK_WIX_UI_DIALOG - Background bitmap used on the welcome and completion dialogs.
+#
+# If this variable is set, the installer will replace the default dialog image.
+#
+# This image must be 493 by 312 pixels.
+#
+##end
+
+#=============================================================================
+# Copyright 2012 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT CPACK_WIX_ROOT)
+  file(TO_CMAKE_PATH "$ENV{WIX}" CPACK_WIX_ROOT)
+endif()
+
+find_program(CPACK_WIX_CANDLE_EXECUTABLE candle
+  PATHS "${CPACK_WIX_ROOT}/bin")
+
+if(NOT CPACK_WIX_CANDLE_EXECUTABLE)
+  message(FATAL_ERROR "Could not find the WiX candle executable.")
+endif()
+
+find_program(CPACK_WIX_LIGHT_EXECUTABLE light
+  PATHS "${CPACK_WIX_ROOT}/bin")
+
+if(NOT CPACK_WIX_LIGHT_EXECUTABLE)
+  message(FATAL_ERROR "Could not find the WiX light executable.")
+endif()
index fd4bd80..5b6e062 100644 (file)
@@ -16,6 +16,10 @@ if(NOT RUN_FROM_CTEST_OR_DART)
   message(FATAL_ERROR "Do not incldue CTestTargets.cmake directly")
 endif()
 
+if(NOT PROJECT_BINARY_DIR)
+  message(FATAL_ERROR "Do not include(CTest) before calling project().")
+endif()
+
 # make directories in the binary tree
 file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Testing/Temporary)
 get_filename_component(CMAKE_HOST_PATH ${CMAKE_COMMAND} PATH)
index 6731d37..24f5f2e 100644 (file)
@@ -35,7 +35,7 @@ if(NOT DEFINED CTEST_USE_LAUNCHERS AND DEFINED ENV{CTEST_USE_LAUNCHERS_DEFAULT})
     CACHE INTERNAL "CTEST_USE_LAUNCHERS initial value from ENV")
 endif()
 
-if(NOT "${CMAKE_GENERATOR}" MATCHES "Make")
+if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
   set(CTEST_USE_LAUNCHERS 0)
 endif()
 
index b457754..86a4565 100644 (file)
@@ -24,7 +24,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
@@ -43,10 +42,8 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
     endif()
@@ -64,8 +61,8 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
       "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
 
index bc64acd..e3a091f 100644 (file)
@@ -24,7 +24,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
@@ -32,10 +31,8 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
     endif()
@@ -53,9 +50,9 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
       -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
-      "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
       "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
       COMPILE_OUTPUT_VARIABLE OUTPUT)
     # if it did not compile make the return value fail code of 1
index c0be1f7..734c083 100644 (file)
@@ -24,7 +24,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
@@ -44,10 +43,8 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
     endif()
@@ -65,8 +62,8 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
       "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
 
index 47ab161..9e401f1 100644 (file)
@@ -24,7 +24,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
@@ -32,10 +31,8 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
     set(MACRO_CHECK_FUNCTION_DEFINITIONS
       "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
     endif()
@@ -53,9 +50,9 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
       -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
-      "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
       "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
       COMPILE_OUTPUT_VARIABLE OUTPUT)
 
index 882dc21..7250fbf 100644 (file)
@@ -16,7 +16,7 @@ int main(int ac, char*av[]){
   pthread_create(&tid[0], 0, runner, (void*)1);
   pthread_create(&tid[1], 0, runner, (void*)2);
 
-#if defined(__BEOS__) && !defined(__ZETA__)  && !defined(__HAIKU__) // (no usleep on BeOS 5.)
+#if defined(__BEOS__) && !defined(__ZETA__) // (no usleep on BeOS 5.)
   usleep(1); // for strange behavior on single-processor sun
 #endif
 
index 4b9f9b7..45dd7be 100644 (file)
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
   if(NOT DEFINED ${VARIABLE})
     message(STATUS "Looking for Fortran ${FUNCTION}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
     endif()
@@ -48,7 +45,7 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
     try_compile(${VARIABLE}
     ${CMAKE_BINARY_DIR}
     ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
-    CMAKE_FLAGS "${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}"
+    ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
     OUTPUT_VARIABLE OUTPUT
     )
 #    message(STATUS "${OUTPUT}")
index 3f952e0..7aa1748 100644 (file)
@@ -27,7 +27,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
@@ -36,10 +35,8 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
       "-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
     message(STATUS "Looking for ${FUNCTION}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
     endif()
@@ -53,8 +50,8 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
-      "${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}"
       "${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
     if(${VARIABLE})
index 697f8a4..fb7d0ec 100644 (file)
@@ -26,7 +26,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
@@ -36,19 +35,17 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
     message(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
     set(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY})
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_LIBRARY_EXISTS_LIBRARIES
-        ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES})
+        ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})
     endif()
     try_compile(${VARIABLE}
       ${CMAKE_BINARY_DIR}
       ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}
       -DLINK_DIRECTORIES:STRING=${LOCATION}
-      "-DLINK_LIBRARIES:STRING=${CHECK_LIBRARY_EXISTS_LIBRARIES}"
       OUTPUT_VARIABLE OUTPUT)
 
     if(${VARIABLE})
index 74b94b8..2342b3c 100644 (file)
@@ -34,7 +34,6 @@
 #  License text for the above reference.)
 #
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
 
@@ -46,10 +45,8 @@ function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB
 
     set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
     if (CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_PROTOTYPE_DEFINITION_LIBS
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_PROTOTYPE_DEFINITION_LIBS)
     endif()
@@ -78,8 +75,8 @@ function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_PROTOTYPE_DEFINITION_LIBS}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
-      "${CHECK_PROTOTYPE_DEFINITION_LIBS}"
       "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
 
index 5a8597f..0969bc5 100644 (file)
@@ -35,7 +35,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
@@ -47,10 +46,8 @@ macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
     set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
     set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_SYMBOL_EXISTS_LIBS
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_SYMBOL_EXISTS_LIBS)
     endif()
@@ -75,9 +72,9 @@ macro(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
       ${CMAKE_BINARY_DIR}
       "${SOURCEFILE}"
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_SYMBOL_EXISTS_LIBS}
       CMAKE_FLAGS
       -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
-      "${CHECK_SYMBOL_EXISTS_LIBS}"
       "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
     if(${VARIABLE})
index 7285b8a..2d0eab5 100644 (file)
@@ -52,7 +52,6 @@
 #  License text for the above reference.)
 
 include(CheckIncludeFile)
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 cmake_policy(PUSH)
 cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
@@ -83,18 +82,16 @@ function(__check_type_size_impl type var map builtin)
 
   # Perform the check.
 
-  # this one translates potentially used imported library targets to their files on disk
-  cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
 
   set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
   configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
   try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
     COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+    LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
     CMAKE_FLAGS
       "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}"
       "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}"
-      "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}"
     OUTPUT_VARIABLE output
     COPY_FILE ${bin}
     )
index f9155a0..a21e65f 100644 (file)
@@ -26,7 +26,6 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
 
 
 macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
@@ -35,10 +34,8 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
       "-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}")
     message(STATUS "Looking for ${VAR}")
     if(CMAKE_REQUIRED_LIBRARIES)
-      # this one translates potentially used imported library targets to their files on disk
-      CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES  LIBRARIES  ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
       set(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES
-        "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
     else()
       set(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES)
     endif()
@@ -46,8 +43,8 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
       ${CMAKE_BINARY_DIR}
       ${CMAKE_ROOT}/Modules/CheckVariableExists.c
       COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_VARIABLE_EXISTS_ADD_LIBRARIES}
       CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_VARIABLE_DEFINITIONS}
-      "${CHECK_VARIABLE_EXISTS_ADD_LIBRARIES}"
       OUTPUT_VARIABLE OUTPUT)
     if(${VARIABLE})
       set(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}")
index 75a971d..c6cd8f8 100644 (file)
@@ -23,4 +23,5 @@ include(Compiler/GNU)
 macro(__compiler_clang lang)
   __compiler_gnu(${lang})
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+  set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
 endmacro()
index 9a89746..18f141e 100644 (file)
@@ -32,3 +32,4 @@ set(CMAKE_Fortran_MODDIR_FLAG "-mdir ")
 set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-PIC")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-PIC")
diff --git a/Modules/Compiler/TI-ASM.cmake b/Modules/Compiler/TI-ASM.cmake
new file mode 100644 (file)
index 0000000..e097626
--- /dev/null
@@ -0,0 +1,8 @@
+set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
+set(CMAKE_LINK_LIBRARY_FLAG "--library=")
+set(CMAKE_INCLUDE_FLAG_ASM "--include_path=")
+
+set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <OBJECTS> --run_linker --output_file=<TARGET> <CMAKE_ASM_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
+
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm;s;abs)
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
new file mode 100644 (file)
index 0000000..b580994
--- /dev/null
@@ -0,0 +1,10 @@
+set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
+set(CMAKE_LINK_LIBRARY_FLAG "--library=")
+set(CMAKE_INCLUDE_FLAG_C "--include_path=")
+
+set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+
+set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
+set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
new file mode 100644 (file)
index 0000000..8cf5ac3
--- /dev/null
@@ -0,0 +1,10 @@
+set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
+set(CMAKE_LINK_LIBRARY_FLAG "--library=")
+set(CMAKE_INCLUDE_FLAG_CXX "--include_path=")
+
+set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+
+set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <FLAGS> --output_file=<OBJECT>")
+set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
+set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
index d293610..7bf5020 100644 (file)
@@ -27,6 +27,7 @@ find_program(CMAKE_XL_CreateExportList
 macro(__compiler_xl lang)
   # Feature flags.
   set(CMAKE_${lang}_VERBOSE_FLAG "-V")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-qpic")
 
   set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g")
   set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O")
index 71bf64d..fa48cad 100644 (file)
@@ -24,7 +24,6 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               PreprocessorDefinitions=""
                                MinimalRebuild="false"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="3"
                        <Tool
                                Name="VCLinkerTool"
                                LinkIncremental="1"
+                               IgnoreDefaultLibraryNames="libc"
                                GenerateDebugInformation="false"
-                               SubSystem="1"
-                               TargetMachine="@id_machine_7@"
+                               SubSystem="@id_subsystem@"
+                               EntryPointSymbol="@id_entrypoint@"
                        />
                        <Tool
                                Name="VCPostBuildEventTool"
index 41ca7db..d94a803 100644 (file)
@@ -83,6 +83,7 @@
                                ONLY_ACTIVE_ARCH = YES;
                                CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
                                SYMROOT = .;
+                               @id_toolset@
                        };
                        name = Debug;
                };
index 309fce3..5f8a9fb 100644 (file)
@@ -80,7 +80,7 @@
 # The functions defined in this file depend on the fixup_bundle function
 # (and others) found in BundleUtilities.cmake
 
-include(BundleUtilities)
+include("${CMAKE_CURRENT_LIST_DIR}/BundleUtilities.cmake")
 set(DeployQt4_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
 set(DeployQt4_apple_plugins_dir "PlugIns")
 
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
new file mode 100644 (file)
index 0000000..8332725
--- /dev/null
@@ -0,0 +1,771 @@
+# - Manage data files stored outside source tree
+# Use this module to unambiguously reference data files stored outside the
+# source tree and fetch them at build time from arbitrary local and remote
+# content-addressed locations.  Functions provided by this module recognize
+# arguments with the syntax "DATA{<name>}" as references to external data,
+# replace them with full paths to local copies of those data, and create build
+# rules to fetch and update the local copies.
+#
+# The DATA{} syntax is literal and the <name> is a full or relative path
+# within the source tree.  The source tree must contain either a real data
+# file at <name> or a "content link" at <name><ext> containing a hash of the
+# real file using a hash algorithm corresponding to <ext>.  For example, the
+# argument "DATA{img.png}" may be satisfied by either a real "img.png" file in
+# the current source directory or a "img.png.md5" file containing its MD5 sum.
+#
+# The 'ExternalData_Expand_Arguments' function evaluates DATA{} references
+# in its arguments and constructs a new list of arguments:
+#  ExternalData_Expand_Arguments(
+#    <target>   # Name of data management target
+#    <outVar>   # Output variable
+#    [args...]  # Input arguments, DATA{} allowed
+#    )
+# It replaces each DATA{} reference in an argument with the full path of a
+# real data file on disk that will exist after the <target> builds.
+#
+# The 'ExternalData_Add_Test' function wraps around the CMake add_test()
+# command but supports DATA{} references in its arguments:
+#  ExternalData_Add_Test(
+#    <target>   # Name of data management target
+#    ...        # Arguments of add_test(), DATA{} allowed
+#    )
+# It passes its arguments through ExternalData_Expand_Arguments and then
+# invokes add_test() using the results.
+#
+# The 'ExternalData_Add_Target' function creates a custom target to manage
+# local instances of data files stored externally:
+#  ExternalData_Add_Target(
+#    <target>   # Name of data management target
+#    )
+# It creates custom commands in the target as necessary to make data files
+# available for each DATA{} reference previously evaluated by other functions
+# provided by this module.  A list of URL templates must be provided in the
+# variable ExternalData_URL_TEMPLATES using the placeholders "%(algo)" and
+# "%(hash)" in each template.  Data fetch rules try each URL template in order
+# by substituting the hash algorithm name for "%(algo)" and the hash value for
+# "%(hash)".
+#
+# The following hash algorithms are supported:
+#    %(algo)     <ext>     Description
+#    -------     -----     -----------
+#    MD5         .md5      Message-Digest Algorithm 5, RFC 1321
+#    SHA1        .sha1     US Secure Hash Algorithm 1, RFC 3174
+#    SHA224      .sha224   US Secure Hash Algorithms, RFC 4634
+#    SHA256      .sha256   US Secure Hash Algorithms, RFC 4634
+#    SHA384      .sha384   US Secure Hash Algorithms, RFC 4634
+#    SHA512      .sha512   US Secure Hash Algorithms, RFC 4634
+# Note that the hashes are used only for unique data identification and
+# download verification.  This is not security software.
+#
+# Example usage:
+#   include(ExternalData)
+#   set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
+#                                  "http://data.org/%(algo)/%(hash)")
+#   ExternalData_Add_Test(MyData
+#     NAME MyTest
+#     COMMAND MyExe DATA{MyInput.png}
+#     )
+#   ExternalData_Add_Target(MyData)
+# When test "MyTest" runs the "DATA{MyInput.png}" argument will be replaced by
+# the full path to a real instance of the data file "MyInput.png" on disk.  If
+# the source tree contains a content link such as "MyInput.png.md5" then the
+# "MyData" target creates a real "MyInput.png" in the build tree.
+#
+# The DATA{} syntax can be told to fetch a file series using the form
+# "DATA{<name>,:}", where the ":" is literal.  If the source tree contains a
+# group of files or content links named like a series then a reference to one
+# member adds rules to fetch all of them.  Although all members of a series
+# are fetched, only the file originally named by the DATA{} argument is
+# substituted for it.  The default configuration recognizes file series names
+# ending with "#.ext", "_#.ext", ".#.ext", or "-#.ext" where "#" is a sequence
+# of decimal digits and ".ext" is any single extension.  Configure it with a
+# regex that parses <number> and <suffix> parts from the end of <name>:
+#  ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$
+# For more complicated cases set:
+#  ExternalData_SERIES_PARSE = regex with at least two () groups
+#  ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
+#  ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
+#  ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number
+# Configure series number matching with a regex that matches the
+# <number> part of series members named <prefix><number><suffix>:
+#  ExternalData_SERIES_MATCH = regex matching <number> in all series members
+# Note that the <suffix> of a series does not include a hash-algorithm
+# extension.
+#
+# The DATA{} syntax can alternatively match files associated with the named
+# file and contained in the same directory.  Associated files may be specified
+# by options using the syntax DATA{<name>,<opt1>,<opt2>,...}.  Each option may
+# specify one file by name or specify a regular expression to match file names
+# using the syntax REGEX:<regex>.  For example, the arguments
+#   DATA{MyData/MyInput.mhd,MyInput.img}                   # File pair
+#   DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series
+# will pass MyInput.mha and MyFrames00.png on the command line but ensure
+# that the associated files are present next to them.
+#
+# The DATA{} syntax may reference a directory using a trailing slash and a
+# list of associated files.  The form DATA{<name>/,<opt1>,<opt2>,...} adds
+# rules to fetch any files in the directory that match one of the associated
+# file options.  For example, the argument DATA{MyDataDir/,REGEX:.*} will pass
+# the full path to a MyDataDir directory on the command line and ensure that
+# the directory contains files corresponding to every file or content link in
+# the MyDataDir source directory.
+#
+# The variable ExternalData_LINK_CONTENT may be set to the name of a supported
+# hash algorithm to enable automatic conversion of real data files referenced
+# by the DATA{} syntax into content links.  For each such <file> a content
+# link named "<file><ext>" is created.  The original file is renamed to the
+# form ".ExternalData_<algo>_<hash>" to stage it for future transmission to
+# one of the locations in the list of URL templates (by means outside the
+# scope of this module).  The data fetch rule created for the content link
+# will use the staged object if it cannot be found using any URL template.
+#
+# The variable ExternalData_OBJECT_STORES may be set to a list of local
+# directories that store objects using the layout <dir>/%(algo)/%(hash).
+# These directories will be searched first for a needed object.  If the object
+# is not available in any store then it will be fetched remotely using the URL
+# templates and added to the first local store listed.  If no stores are
+# specified the default is a location inside the build tree.
+#
+# The variable ExternalData_SOURCE_ROOT may be set to the highest source
+# directory containing any path named by a DATA{} reference.  The default is
+# CMAKE_SOURCE_DIR.  ExternalData_SOURCE_ROOT and CMAKE_SOURCE_DIR must refer
+# to directories within a single source distribution (e.g. they come together
+# in one tarball).
+#
+# The variable ExternalData_BINARY_ROOT may be set to the directory to hold
+# the real data files named by expanded DATA{} references.  The default is
+# CMAKE_BINARY_DIR.  The directory layout will mirror that of content links
+# under ExternalData_SOURCE_ROOT.
+#
+# Variables ExternalData_TIMEOUT_INACTIVITY and ExternalData_TIMEOUT_ABSOLUTE
+# set the download inactivity and absolute timeouts, in seconds.  The defaults
+# are 60 seconds and 300 seconds, respectively.  Set either timeout to 0
+# seconds to disable enforcement.
+
+#=============================================================================
+# Copyright 2010-2013 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+function(ExternalData_add_test target)
+  # Expand all arguments as a single string to preserve escaped semicolons.
+  ExternalData_expand_arguments("${target}" testArgs "${ARGN}")
+  add_test(${testArgs})
+endfunction()
+
+function(ExternalData_add_target target)
+  if(NOT ExternalData_URL_TEMPLATES)
+    message(FATAL_ERROR "ExternalData_URL_TEMPLATES is not set!")
+  endif()
+  if(NOT ExternalData_OBJECT_STORES)
+    set(ExternalData_OBJECT_STORES ${CMAKE_BINARY_DIR}/ExternalData/Objects)
+  endif()
+  set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake)
+  configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY)
+
+  set(files "")
+
+  # Set "_ExternalData_FILE_${file}" for each output file to avoid duplicate
+  # rules.  Use local data first to prefer real files over content links.
+
+  # Custom commands to copy or link local data.
+  get_property(data_local GLOBAL PROPERTY _ExternalData_${target}_LOCAL)
+  foreach(entry IN LISTS data_local)
+    string(REPLACE "|" ";" tuple "${entry}")
+    list(GET tuple 0 file)
+    list(GET tuple 1 name)
+    if(NOT DEFINED "_ExternalData_FILE_${file}")
+      set("_ExternalData_FILE_${file}" 1)
+      add_custom_command(
+        COMMENT "Generating ${file}"
+        OUTPUT "${file}"
+        COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
+                                 -Dfile=${file} -Dname=${name}
+                                 -DExternalData_ACTION=local
+                                 -DExternalData_CONFIG=${config}
+                                 -P ${_ExternalData_SELF}
+        MAIN_DEPENDENCY "${name}"
+        )
+      list(APPEND files "${file}")
+    endif()
+  endforeach()
+
+  # Custom commands to fetch remote data.
+  get_property(data_fetch GLOBAL PROPERTY _ExternalData_${target}_FETCH)
+  foreach(entry IN LISTS data_fetch)
+    string(REPLACE "|" ";" tuple "${entry}")
+    list(GET tuple 0 file)
+    list(GET tuple 1 name)
+    list(GET tuple 2 ext)
+    set(stamp "${ext}-stamp")
+    if(NOT DEFINED "_ExternalData_FILE_${file}")
+      set("_ExternalData_FILE_${file}" 1)
+      add_custom_command(
+        # Users care about the data file, so hide the hash/timestamp file.
+        COMMENT "Generating ${file}"
+        # The hash/timestamp file is the output from the build perspective.
+        # List the real file as a second output in case it is a broken link.
+        # The files must be listed in this order so CMake can hide from the
+        # make tool that a symlink target may not be newer than the input.
+        OUTPUT "${file}${stamp}" "${file}"
+        # Run the data fetch/update script.
+        COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
+                                 -Dfile=${file} -Dname=${name} -Dext=${ext}
+                                 -DExternalData_ACTION=fetch
+                                 -DExternalData_CONFIG=${config}
+                                 -P ${_ExternalData_SELF}
+        # Update whenever the object hash changes.
+        MAIN_DEPENDENCY "${name}${ext}"
+        )
+      list(APPEND files "${file}${stamp}")
+    endif()
+  endforeach()
+
+  # Custom target to drive all update commands.
+  add_custom_target(${target} ALL DEPENDS ${files})
+endfunction()
+
+function(ExternalData_expand_arguments target outArgsVar)
+  # Replace DATA{} references with real arguments.
+  set(data_regex "DATA{([^;{}\r\n]*)}")
+  set(other_regex "([^D]|D[^A]|DA[^T]|DAT[^A]|DATA[^{])+|.")
+  set(outArgs "")
+  # This list expansion un-escapes semicolons in list element values so we
+  # must re-escape them below anywhere a new list expansion will occur.
+  foreach(arg IN LISTS ARGN)
+    if("x${arg}" MATCHES "${data_regex}")
+      # Re-escape in-value semicolons before expansion in foreach below.
+      string(REPLACE ";" "\\;" tmp "${arg}")
+      # Split argument into DATA{}-pieces and other pieces.
+      string(REGEX MATCHALL "${data_regex}|${other_regex}" pieces "${tmp}")
+      # Compose output argument with DATA{}-pieces replaced.
+      set(outArg "")
+      foreach(piece IN LISTS pieces)
+        if("x${piece}" MATCHES "^x${data_regex}$")
+          # Replace this DATA{}-piece with a file path.
+          string(REGEX REPLACE "${data_regex}" "\\1" data "${piece}")
+          _ExternalData_arg("${target}" "${piece}" "${data}" file)
+          set(outArg "${outArg}${file}")
+        else()
+          # No replacement needed for this piece.
+          set(outArg "${outArg}${piece}")
+        endif()
+      endforeach()
+    else()
+      # No replacements needed in this argument.
+      set(outArg "${arg}")
+    endif()
+    # Re-escape in-value semicolons in resulting list.
+    string(REPLACE ";" "\\;" outArg "${outArg}")
+    list(APPEND outArgs "${outArg}")
+  endforeach()
+  set("${outArgsVar}" "${outArgs}" PARENT_SCOPE)
+endfunction()
+
+#-----------------------------------------------------------------------------
+# Private helper interface
+
+set(_ExternalData_REGEX_ALGO "MD5|SHA1|SHA224|SHA256|SHA384|SHA512")
+set(_ExternalData_REGEX_EXT "md5|sha1|sha224|sha256|sha384|sha512")
+set(_ExternalData_SELF "${CMAKE_CURRENT_LIST_FILE}")
+get_filename_component(_ExternalData_SELF_DIR "${_ExternalData_SELF}" PATH)
+
+function(_ExternalData_compute_hash var_hash algo file)
+  if("${algo}" MATCHES "^${_ExternalData_REGEX_ALGO}$")
+    file("${algo}" "${file}" hash)
+    set("${var_hash}" "${hash}" PARENT_SCOPE)
+  else()
+    message(FATAL_ERROR "Hash algorithm ${algo} unimplemented.")
+  endif()
+endfunction()
+
+function(_ExternalData_random var)
+  string(RANDOM LENGTH 6 random)
+  set("${var}" "${random}" PARENT_SCOPE)
+endfunction()
+
+function(_ExternalData_exact_regex regex_var string)
+  string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" regex "${string}")
+  set("${regex_var}" "${regex}" PARENT_SCOPE)
+endfunction()
+
+function(_ExternalData_atomic_write file content)
+  _ExternalData_random(random)
+  set(tmp "${file}.tmp${random}")
+  file(WRITE "${tmp}" "${content}")
+  file(RENAME "${tmp}" "${file}")
+endfunction()
+
+function(_ExternalData_link_content name var_ext)
+  if("${ExternalData_LINK_CONTENT}" MATCHES "^(${_ExternalData_REGEX_ALGO})$")
+    set(algo "${ExternalData_LINK_CONTENT}")
+  else()
+    message(FATAL_ERROR
+      "Unknown hash algorithm specified by ExternalData_LINK_CONTENT:\n"
+      "  ${ExternalData_LINK_CONTENT}")
+  endif()
+  _ExternalData_compute_hash(hash "${algo}" "${name}")
+  get_filename_component(dir "${name}" PATH)
+  set(staged "${dir}/.ExternalData_${algo}_${hash}")
+  string(TOLOWER ".${algo}" ext)
+  _ExternalData_atomic_write("${name}${ext}" "${hash}\n")
+  file(RENAME "${name}" "${staged}")
+  set("${var_ext}" "${ext}" PARENT_SCOPE)
+
+  file(RELATIVE_PATH relname "${ExternalData_SOURCE_ROOT}" "${name}${ext}")
+  message(STATUS "Linked ${relname} to ExternalData ${algo}/${hash}")
+endfunction()
+
+function(_ExternalData_arg target arg options var_file)
+  # Separate data path from the options.
+  string(REPLACE "," ";" options "${options}")
+  list(GET options 0 data)
+  list(REMOVE_AT options 0)
+
+  # Interpret trailing slashes as directories.
+  set(data_is_directory 0)
+  if("x${data}" MATCHES "^x(.*)([/\\])$")
+    set(data_is_directory 1)
+    set(data "${CMAKE_MATCH_1}")
+  endif()
+
+  # Convert to full path.
+  if(IS_ABSOLUTE "${data}")
+    set(absdata "${data}")
+  else()
+    set(absdata "${CMAKE_CURRENT_SOURCE_DIR}/${data}")
+  endif()
+  get_filename_component(absdata "${absdata}" ABSOLUTE)
+
+  # Convert to relative path under the source tree.
+  if(NOT ExternalData_SOURCE_ROOT)
+    set(ExternalData_SOURCE_ROOT "${CMAKE_SOURCE_DIR}")
+  endif()
+  set(top_src "${ExternalData_SOURCE_ROOT}")
+  file(RELATIVE_PATH reldata "${top_src}" "${absdata}")
+  if(IS_ABSOLUTE "${reldata}" OR "${reldata}" MATCHES "^\\.\\./")
+    message(FATAL_ERROR "Data file referenced by argument\n"
+      "  ${arg}\n"
+      "does not lie under the top-level source directory\n"
+      "  ${top_src}\n")
+  endif()
+  if(data_is_directory AND NOT IS_DIRECTORY "${top_src}/${reldata}")
+    message(FATAL_ERROR "Data directory referenced by argument\n"
+      "  ${arg}\n"
+      "corresponds to source tree path\n"
+      "  ${reldata}\n"
+      "that does not exist as a directory!")
+  endif()
+  if(NOT ExternalData_BINARY_ROOT)
+    set(ExternalData_BINARY_ROOT "${CMAKE_BINARY_DIR}")
+  endif()
+  set(top_bin "${ExternalData_BINARY_ROOT}")
+
+  # Handle in-source builds gracefully.
+  if("${top_src}" STREQUAL "${top_bin}")
+    if(ExternalData_LINK_CONTENT)
+      message(WARNING "ExternalData_LINK_CONTENT cannot be used in-source")
+      set(ExternalData_LINK_CONTENT 0)
+    endif()
+    set(top_same 1)
+  endif()
+
+  set(external "") # Entries external to the source tree.
+  set(internal "") # Entries internal to the source tree.
+  set(have_original ${data_is_directory})
+
+  # Process options.
+  set(series_option "")
+  set(associated_files "")
+  set(associated_regex "")
+  foreach(opt ${options})
+    if("x${opt}" MATCHES "^xREGEX:[^:/]+$")
+      # Regular expression to match associated files.
+      string(REGEX REPLACE "^REGEX:" "" regex "${opt}")
+      list(APPEND associated_regex "${regex}")
+    elseif("x${opt}" MATCHES "^x:$")
+      # Activate series matching.
+      set(series_option "${opt}")
+    elseif("x${opt}" MATCHES "^[^][:/*?]+$")
+      # Specific associated file.
+      list(APPEND associated_files "${opt}")
+    else()
+      message(FATAL_ERROR "Unknown option \"${opt}\" in argument\n"
+        "  ${arg}\n")
+    endif()
+  endforeach()
+
+  if(series_option)
+    if(data_is_directory)
+      message(FATAL_ERROR "Series option \"${series_option}\" not allowed with directories.")
+    endif()
+    if(associated_files OR associated_regex)
+      message(FATAL_ERROR "Series option \"${series_option}\" not allowed with associated files.")
+    endif()
+    # Load a whole file series.
+    _ExternalData_arg_series()
+  elseif(data_is_directory)
+    if(associated_files OR associated_regex)
+      # Load listed/matching associated files in the directory.
+      _ExternalData_arg_associated()
+    else()
+      message(FATAL_ERROR "Data directory referenced by argument\n"
+        "  ${arg}\n"
+        "must list associated files.")
+    endif()
+  else()
+    # Load the named data file.
+    _ExternalData_arg_single()
+    if(associated_files OR associated_regex)
+      # Load listed/matching associated files.
+      _ExternalData_arg_associated()
+    endif()
+  endif()
+
+  if(NOT have_original)
+    message(FATAL_ERROR "Data file referenced by argument\n"
+      "  ${arg}\n"
+      "corresponds to source tree path\n"
+      "  ${reldata}\n"
+      "that does not exist as a file (with or without an extension)!")
+  endif()
+
+  if(external)
+    # Make the series available in the build tree.
+    set_property(GLOBAL APPEND PROPERTY
+      _ExternalData_${target}_FETCH "${external}")
+    set_property(GLOBAL APPEND PROPERTY
+      _ExternalData_${target}_LOCAL "${internal}")
+    set("${var_file}" "${top_bin}/${reldata}" PARENT_SCOPE)
+  else()
+    # The whole series is in the source tree.
+    set("${var_file}" "${top_src}/${reldata}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+macro(_ExternalData_arg_associated)
+  # Associated files lie in the same directory.
+  if(data_is_directory)
+    set(reldir "${reldata}")
+  else()
+    get_filename_component(reldir "${reldata}" PATH)
+  endif()
+  if(reldir)
+    set(reldir "${reldir}/")
+  endif()
+  _ExternalData_exact_regex(reldir_regex "${reldir}")
+
+  # Find files named explicitly.
+  foreach(file ${associated_files})
+    _ExternalData_exact_regex(file_regex "${file}")
+    _ExternalData_arg_find_files("${reldir}${file}" "${reldir_regex}${file_regex}")
+  endforeach()
+
+  # Find files matching the given regular expressions.
+  set(all "")
+  set(sep "")
+  foreach(regex ${associated_regex})
+    set(all "${all}${sep}${reldir_regex}${regex}")
+    set(sep "|")
+  endforeach()
+  _ExternalData_arg_find_files("${reldir}" "${all}")
+endmacro()
+
+macro(_ExternalData_arg_single)
+  # Match only the named data by itself.
+  _ExternalData_exact_regex(data_regex "${reldata}")
+  _ExternalData_arg_find_files("${reldata}" "${data_regex}")
+endmacro()
+
+macro(_ExternalData_arg_series)
+  # Configure series parsing and matching.
+  set(series_parse_prefix "")
+  set(series_parse_number "\\1")
+  set(series_parse_suffix "\\2")
+  if(ExternalData_SERIES_PARSE)
+    if(ExternalData_SERIES_PARSE_NUMBER AND ExternalData_SERIES_PARSE_SUFFIX)
+      if(ExternalData_SERIES_PARSE_PREFIX)
+        set(series_parse_prefix "\\${ExternalData_SERIES_PARSE_PREFIX}")
+      endif()
+      set(series_parse_number "\\${ExternalData_SERIES_PARSE_NUMBER}")
+      set(series_parse_suffix "\\${ExternalData_SERIES_PARSE_SUFFIX}")
+    elseif(NOT "x${ExternalData_SERIES_PARSE}" MATCHES "^x\\([^()]*\\)\\([^()]*\\)\\$$")
+      message(FATAL_ERROR
+        "ExternalData_SERIES_PARSE is set to\n"
+        "  ${ExternalData_SERIES_PARSE}\n"
+        "which is not of the form\n"
+        "  (<number>)(<suffix>)$\n"
+        "Fix the regular expression or set variables\n"
+        "  ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any\n"
+        "  ExternalData_SERIES_PARSE_NUMBER = <number> regex group number\n"
+        "  ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number\n"
+        )
+    endif()
+    set(series_parse "${ExternalData_SERIES_PARSE}")
+  else()
+    set(series_parse "([0-9]*)(\\.[^./]*)$")
+  endif()
+  if(ExternalData_SERIES_MATCH)
+    set(series_match "${ExternalData_SERIES_MATCH}")
+  else()
+    set(series_match "[_.-]?[0-9]*")
+  endif()
+
+  # Parse the base, number, and extension components of the series.
+  string(REGEX REPLACE "${series_parse}" "${series_parse_prefix};${series_parse_number};${series_parse_suffix}" tuple "${reldata}")
+  list(LENGTH tuple len)
+  if(NOT "${len}" EQUAL 3)
+    message(FATAL_ERROR "Data file referenced by argument\n"
+      "  ${arg}\n"
+      "corresponds to path\n"
+      "  ${reldata}\n"
+      "that does not match regular expression\n"
+      "  ${series_parse}")
+  endif()
+  list(GET tuple 0 relbase)
+  list(GET tuple 2 ext)
+
+  # Glob files that might match the series.
+  # Then match base, number, and extension.
+  _ExternalData_exact_regex(series_base "${relbase}")
+  _ExternalData_exact_regex(series_ext "${ext}")
+  _ExternalData_arg_find_files("${relbase}*${ext}"
+    "${series_base}${series_match}${series_ext}")
+endmacro()
+
+function(_ExternalData_arg_find_files pattern regex)
+  file(GLOB globbed RELATIVE "${top_src}" "${top_src}/${pattern}*")
+  foreach(entry IN LISTS globbed)
+    if("x${entry}" MATCHES "^x(.*)(\\.(${_ExternalData_REGEX_EXT}))$")
+      set(relname "${CMAKE_MATCH_1}")
+      set(alg "${CMAKE_MATCH_2}")
+    else()
+      set(relname "${entry}")
+      set(alg "")
+    endif()
+    if("x${relname}" MATCHES "^x${regex}$" # matches
+        AND NOT IS_DIRECTORY "${top_src}/${entry}" # not a directory
+        AND NOT "x${relname}" MATCHES "(^x|/)\\.ExternalData_" # not staged obj
+        )
+      set(name "${top_src}/${relname}")
+      set(file "${top_bin}/${relname}")
+      if(alg)
+        list(APPEND external "${file}|${name}|${alg}")
+      elseif(ExternalData_LINK_CONTENT)
+        _ExternalData_link_content("${name}" alg)
+        list(APPEND external "${file}|${name}|${alg}")
+      elseif(NOT top_same)
+        list(APPEND internal "${file}|${name}")
+      endif()
+      if("${relname}" STREQUAL "${reldata}")
+        set(have_original 1)
+      endif()
+    endif()
+  endforeach()
+  set(external "${external}" PARENT_SCOPE)
+  set(internal "${internal}" PARENT_SCOPE)
+  set(have_original "${have_original}" PARENT_SCOPE)
+endfunction()
+
+#-----------------------------------------------------------------------------
+# Private script mode interface
+
+if(CMAKE_GENERATOR OR NOT ExternalData_ACTION)
+  return()
+endif()
+
+if(ExternalData_CONFIG)
+  include(${ExternalData_CONFIG})
+endif()
+if(NOT ExternalData_URL_TEMPLATES)
+  message(FATAL_ERROR "No ExternalData_URL_TEMPLATES set!")
+endif()
+
+function(_ExternalData_link_or_copy src dst)
+  # Create a temporary file first.
+  get_filename_component(dst_dir "${dst}" PATH)
+  file(MAKE_DIRECTORY "${dst_dir}")
+  _ExternalData_random(random)
+  set(tmp "${dst}.tmp${random}")
+  if(UNIX)
+    # Create a symbolic link.
+    set(tgt "${src}")
+    if(relative_top)
+      # Use relative path if files are close enough.
+      file(RELATIVE_PATH relsrc "${relative_top}" "${src}")
+      file(RELATIVE_PATH relfile "${relative_top}" "${dst}")
+      if(NOT IS_ABSOLUTE "${relsrc}" AND NOT "${relsrc}" MATCHES "^\\.\\./" AND
+          NOT IS_ABSOLUTE "${reldst}" AND NOT "${reldst}" MATCHES "^\\.\\./")
+        file(RELATIVE_PATH tgt "${dst_dir}" "${src}")
+      endif()
+    endif()
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${tgt}" "${tmp}" RESULT_VARIABLE result)
+  else()
+    # Create a copy.
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${src}" "${tmp}" RESULT_VARIABLE result)
+  endif()
+  if(result)
+    file(REMOVE "${tmp}")
+    message(FATAL_ERROR "Failed to create\n  ${tmp}\nfrom\n  ${obj}")
+  endif()
+
+  # Atomically create/replace the real destination.
+  file(RENAME "${tmp}" "${dst}")
+endfunction()
+
+function(_ExternalData_download_file url file err_var msg_var)
+  set(retry 3)
+  while(retry)
+    math(EXPR retry "${retry} - 1")
+    if(ExternalData_TIMEOUT_INACTIVITY)
+      set(inactivity_timeout INACTIVITY_TIMEOUT ${ExternalData_TIMEOUT_INACTIVITY})
+    elseif(NOT "${ExternalData_TIMEOUT_INACTIVITY}" EQUAL 0)
+      set(inactivity_timeout INACTIVITY_TIMEOUT 60)
+    else()
+      set(inactivity_timeout "")
+    endif()
+    if(ExternalData_TIMEOUT_ABSOLUTE)
+      set(absolute_timeout TIMEOUT ${ExternalData_TIMEOUT_ABSOLUTE})
+    elseif(NOT "${ExternalData_TIMEOUT_ABSOLUTE}" EQUAL 0)
+      set(absolute_timeout TIMEOUT 300)
+    else()
+      set(absolute_timeout "")
+    endif()
+    file(DOWNLOAD "${url}" "${file}" STATUS status LOG log ${inactivity_timeout} ${absolute_timeout} SHOW_PROGRESS)
+    list(GET status 0 err)
+    list(GET status 1 msg)
+    if(err)
+      if("${msg}" MATCHES "HTTP response code said error" AND
+          "${log}" MATCHES "error: 503")
+        set(msg "temporarily unavailable")
+      endif()
+    elseif("${log}" MATCHES "\nHTTP[^\n]* 503")
+      set(err TRUE)
+      set(msg "temporarily unavailable")
+    endif()
+    if(NOT err OR NOT "${msg}" MATCHES "partial|timeout|temporarily")
+      break()
+    elseif(retry)
+      message(STATUS "[download terminated: ${msg}, retries left: ${retry}]")
+    endif()
+  endwhile()
+  set("${err_var}" "${err}" PARENT_SCOPE)
+  set("${msg_var}" "${msg}" PARENT_SCOPE)
+endfunction()
+
+function(_ExternalData_download_object name hash algo var_obj)
+  # Search all object stores for an existing object.
+  foreach(dir ${ExternalData_OBJECT_STORES})
+    set(obj "${dir}/${algo}/${hash}")
+    if(EXISTS "${obj}")
+      message(STATUS "Found object: \"${obj}\"")
+      set("${var_obj}" "${obj}" PARENT_SCOPE)
+      return()
+    endif()
+  endforeach()
+
+  # Download object to the first store.
+  list(GET ExternalData_OBJECT_STORES 0 store)
+  set(obj "${store}/${algo}/${hash}")
+
+  _ExternalData_random(random)
+  set(tmp "${obj}.tmp${random}")
+  set(found 0)
+  set(tried "")
+  foreach(url_template IN LISTS ExternalData_URL_TEMPLATES)
+    string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}")
+    string(REPLACE "%(algo)" "${algo}" url "${url_tmp}")
+    message(STATUS "Fetching \"${url}\"")
+    _ExternalData_download_file("${url}" "${tmp}" err errMsg)
+    set(tried "${tried}\n  ${url}")
+    if(err)
+      set(tried "${tried} (${errMsg})")
+    else()
+      # Verify downloaded object.
+      _ExternalData_compute_hash(dl_hash "${algo}" "${tmp}")
+      if("${dl_hash}" STREQUAL "${hash}")
+        set(found 1)
+        break()
+      else()
+        set(tried "${tried} (wrong hash ${algo}=${dl_hash})")
+        if("$ENV{ExternalData_DEBUG_DOWNLOAD}" MATCHES ".")
+          file(RENAME "${tmp}" "${store}/${algo}/${dl_hash}")
+        endif()
+      endif()
+    endif()
+    file(REMOVE "${tmp}")
+  endforeach()
+
+  get_filename_component(dir "${name}" PATH)
+  set(staged "${dir}/.ExternalData_${algo}_${hash}")
+
+  if(found)
+    file(RENAME "${tmp}" "${obj}")
+    message(STATUS "Downloaded object: \"${obj}\"")
+  elseif(EXISTS "${staged}")
+    set(obj "${staged}")
+    message(STATUS "Staged object: \"${obj}\"")
+  else()
+    message(FATAL_ERROR "Object ${algo}=${hash} not found at:${tried}")
+  endif()
+
+  set("${var_obj}" "${obj}" PARENT_SCOPE)
+endfunction()
+
+if("${ExternalData_ACTION}" STREQUAL "fetch")
+  foreach(v ExternalData_OBJECT_STORES file name ext)
+    if(NOT DEFINED "${v}")
+      message(FATAL_ERROR "No \"-D${v}=\" value provided!")
+    endif()
+  endforeach()
+
+  file(READ "${name}${ext}" hash)
+  string(STRIP "${hash}" hash)
+
+  if("${ext}" MATCHES "^\\.(${_ExternalData_REGEX_EXT})$")
+    string(TOUPPER "${CMAKE_MATCH_1}" algo)
+  else()
+    message(FATAL_ERROR "Unknown hash algorithm extension \"${ext}\"")
+  endif()
+
+  _ExternalData_download_object("${name}" "${hash}" "${algo}" obj)
+
+  # Check if file already corresponds to the object.
+  set(stamp "${ext}-stamp")
+  set(file_up_to_date 0)
+  if(EXISTS "${file}" AND EXISTS "${file}${stamp}")
+    file(READ "${file}${stamp}" f_hash)
+    string(STRIP "${f_hash}" f_hash)
+    if("${f_hash}" STREQUAL "${hash}")
+      #message(STATUS "File already corresponds to object")
+      set(file_up_to_date 1)
+    endif()
+  endif()
+
+  if(file_up_to_date)
+    # Touch the file to convince the build system it is up to date.
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${file}")
+  else()
+    _ExternalData_link_or_copy("${obj}" "${file}")
+  endif()
+
+  # Atomically update the hash/timestamp file to record the object referenced.
+  _ExternalData_atomic_write("${file}${stamp}" "${hash}\n")
+elseif("${ExternalData_ACTION}" STREQUAL "local")
+  foreach(v file name)
+    if(NOT DEFINED "${v}")
+      message(FATAL_ERROR "No \"-D${v}=\" value provided!")
+    endif()
+  endforeach()
+  _ExternalData_link_or_copy("${name}" "${file}")
+else()
+  message(FATAL_ERROR "Unknown ExternalData_ACTION=[${ExternalData_ACTION}]")
+endif()
diff --git a/Modules/ExternalData_config.cmake.in b/Modules/ExternalData_config.cmake.in
new file mode 100644 (file)
index 0000000..0858f53
--- /dev/null
@@ -0,0 +1,4 @@
+set(ExternalData_OBJECT_STORES "@ExternalData_OBJECT_STORES@")
+set(ExternalData_URL_TEMPLATES "@ExternalData_URL_TEMPLATES@")
+set(ExternalData_TIMEOUT_INACTIVITY "@ExternalData_TIMEOUT_INACTIVITY@")
+set(ExternalData_TIMEOUT_ABSOLUTE "@ExternalData_TIMEOUT_ABSOLUTE@")
index 8d57860..40e14d5 100644 (file)
@@ -38,6 +38,7 @@
 #    [CONFIGURE_COMMAND cmd...]  # Build tree configuration command
 #    [CMAKE_COMMAND /.../cmake]  # Specify alternative cmake executable
 #    [CMAKE_GENERATOR gen]       # Specify generator for native build
+#    [CMAKE_GENERATOR_TOOLSET t] # Generator-specific toolset name
 #    [CMAKE_ARGS args...]        # Arguments to CMake command line
 #    [CMAKE_CACHE_ARGS args...]  # Initial cache arguments, of the form -Dvar:string=on
 #   #--Build step-----------------
@@ -286,11 +287,21 @@ if(error_code)
   message(FATAL_ERROR \"Failed to remove directory: '${source_dir}'\")
 endif()
 
-execute_process(
-  COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\"
-  WORKING_DIRECTORY \"${work_dir}\"
-  RESULT_VARIABLE error_code
-  )
+# try the clone 3 times incase there is an odd git clone issue
+set(error_code 1)
+set(number_of_tries 0)
+while(error_code AND number_of_tries LESS 3)
+  execute_process(
+    COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\"
+    WORKING_DIRECTORY \"${work_dir}\"
+    RESULT_VARIABLE error_code
+    )
+  math(EXPR number_of_tries \"\${number_of_tries} + 1\")
+endwhile()
+if(number_of_tries GREATER 1)
+  message(STATUS \"Had to git clone more than once:
+          \${number_of_tries} times.\")
+endif()
 if(error_code)
   message(FATAL_ERROR \"Failed to clone repository: '${git_repository}'\")
 endif()
@@ -402,6 +413,79 @@ endif()
 endfunction()
 
 
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_repository work_dir)
+  file(WRITE ${script_filename}
+"if(\"${git_tag}\" STREQUAL \"\")
+  message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
+endif()
+
+execute_process(
+  COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD
+  WORKING_DIRECTORY \"${work_dir}\"
+  RESULT_VARIABLE error_code
+  OUTPUT_VARIABLE head_sha
+  )
+if(error_code)
+  message(FATAL_ERROR \"Failed to get the hash for HEAD\")
+endif()
+
+execute_process(
+  COMMAND \"${git_EXECUTABLE}\" show-ref ${git_tag}
+  WORKING_DIRECTORY \"${work_dir}\"
+  OUTPUT_VARIABLE show_ref_output
+  )
+# If a remote ref is asked for, which can possibly move around,
+# we must always do a fetch and checkout.
+if(\"\${show_ref_output}\" MATCHES \"remotes\")
+  set(is_remote_ref 1)
+else()
+  set(is_remote_ref 0)
+endif()
+
+# This will fail if the tag does not exist (it probably has not been fetched
+# yet).
+execute_process(
+  COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 ${git_tag}
+  WORKING_DIRECTORY \"${work_dir}\"
+  RESULT_VARIABLE error_code
+  OUTPUT_VARIABLE tag_sha
+  )
+
+# Is the hash checkout out that we want?
+if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"))
+  execute_process(
+    COMMAND \"${git_EXECUTABLE}\" fetch
+    WORKING_DIRECTORY \"${work_dir}\"
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\")
+  endif()
+
+  execute_process(
+    COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
+    WORKING_DIRECTORY \"${work_dir}\"
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
+  endif()
+
+  execute_process(
+    COMMAND \"${git_EXECUTABLE}\" submodule update --recursive
+    WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
+  endif()
+endif()
+
+"
+)
+
+endfunction(_ep_write_gitupdate_script)
+
 function(_ep_write_downloadfile_script script_filename remote local timeout hash tls_verify tls_cainfo)
   if(timeout)
     set(timeout_args TIMEOUT ${timeout})
@@ -1354,7 +1438,7 @@ endfunction()
 
 
 function(_ep_add_update_command name)
-  ExternalProject_Get_Property(${name} source_dir)
+  ExternalProject_Get_Property(${name} source_dir tmp_dir)
 
   get_property(cmd_set TARGET ${name} PROPERTY _EP_UPDATE_COMMAND SET)
   get_property(cmd TARGET ${name} PROPERTY _EP_UPDATE_COMMAND)
@@ -1406,15 +1490,15 @@ function(_ep_add_update_command name)
       message(FATAL_ERROR "error: could not find git for fetch of ${name}")
     endif()
     set(work_dir ${source_dir})
-    set(comment "Performing update step (git fetch) for '${name}'")
+    set(comment "Performing update step for '${name}'")
     get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
     if(NOT git_tag)
       set(git_tag "master")
     endif()
-    set(cmd ${GIT_EXECUTABLE} fetch
-      COMMAND ${GIT_EXECUTABLE} checkout ${git_tag}
-      COMMAND ${GIT_EXECUTABLE} submodule update --recursive
+    _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
+      ${GIT_EXECUTABLE} ${git_tag} ${git_repository} ${work_dir}
       )
+    set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
     set(always 1)
   elseif(hg_repository)
     if(NOT HG_EXECUTABLE)
@@ -1485,8 +1569,11 @@ function(_ep_add_configure_command name)
   set(file_deps)
   get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
   foreach(dep IN LISTS deps)
-    _ep_get_step_stampfile(${dep} "done" done_stamp_file)
-    list(APPEND file_deps ${done_stamp_file})
+    get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
+    if(is_ep)
+      _ep_get_step_stampfile(${dep} "done" done_stamp_file)
+      list(APPEND file_deps ${done_stamp_file})
+    endif()
   endforeach()
 
   get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
@@ -1512,16 +1599,27 @@ function(_ep_add_configure_command name)
     endif()
 
     get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
+    get_target_property(cmake_generator_toolset ${name} _EP_CMAKE_GENERATOR_TOOLSET)
     if(cmake_generator)
-      list(APPEND cmd "-G${cmake_generator}" "${source_dir}")
+      list(APPEND cmd "-G${cmake_generator}")
+      if(cmake_generator_toolset)
+        list(APPEND cmd "-T${cmake_generator_toolset}")
+      endif()
     else()
       if(CMAKE_EXTRA_GENERATOR)
-        list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}"
-          "${source_dir}")
+        list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
       else()
-        list(APPEND cmd "-G${CMAKE_GENERATOR}" "${source_dir}")
+        list(APPEND cmd "-G${CMAKE_GENERATOR}")
+      endif()
+      if(cmake_generator_toolset)
+        message(FATAL_ERROR "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR.")
+      endif()
+      if(CMAKE_GENERATOR_TOOLSET)
+        list(APPEND cmd "-T${CMAKE_GENERATOR_TOOLSET}")
       endif()
     endif()
+
+    list(APPEND cmd "${source_dir}")
   endif()
 
   # If anything about the configure command changes, (command itself, cmake
index 41bce1e..5d98ac3 100644 (file)
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CMakeParseArguments)
+include("${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake")
 
 
 function(ADD_FEATURE_INFO _name _enabled _desc)
index a0afd34..4a3e68c 100644 (file)
@@ -47,7 +47,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-find_program(BISON_EXECUTABLE bison DOC "path to the bison executable")
+find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable")
 mark_as_advanced(BISON_EXECUTABLE)
 
 if(BISON_EXECUTABLE)
index d9b3c61..f8a284d 100644 (file)
@@ -40,8 +40,8 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CheckFunctionExists)
-include(CheckFortranFunctionExists)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
 
 set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
 
index 8b9d235..9fb29d0 100644 (file)
@@ -49,7 +49,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
                                   VERSION_VAR BZIP2_VERSION_STRING)
 
 if (BZIP2_FOUND)
-   include(CheckLibraryExists)
+   include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
    CHECK_LIBRARY_EXISTS("${BZIP2_LIBRARIES}" BZ2_bzCompressInit "" BZIP2_NEED_PREFIX)
 endif ()
 
index 17aba1b..f2c2ce3 100644 (file)
-# - Try to find Boost include dirs and libraries
-# Usage of this module as follows:
-#
-# NOTE: Take note of the Boost_ADDITIONAL_VERSIONS variable below.
-# Due to Boost naming conventions and limitations in CMake this find
-# module is NOT future safe with respect to Boost version numbers,
-# and may break.
-#
-# == Using Header-Only libraries from within Boost: ==
-#
-#   find_package( Boost 1.36.0 )
-#   if(Boost_FOUND)
-#      include_directories(${Boost_INCLUDE_DIRS})
-#      add_executable(foo foo.cc)
-#   endif()
-#
-#
-# == Using actual libraries from within Boost: ==
-#
-#   set(Boost_USE_STATIC_LIBS        ON)
-#   set(Boost_USE_MULTITHREADED      ON)
-#   set(Boost_USE_STATIC_RUNTIME    OFF)
-#   find_package( Boost 1.36.0 COMPONENTS date_time filesystem system ... )
-#
-#   if(Boost_FOUND)
-#      include_directories(${Boost_INCLUDE_DIRS})
-#      add_executable(foo foo.cc)
-#      target_link_libraries(foo ${Boost_LIBRARIES})
-#   endif()
-#
-#
-# The components list needs to contain actual names of boost libraries only,
-# such as "date_time" for "libboost_date_time".  If you're using parts of
-# Boost that contain header files only (e.g. foreach) you do not need to
-# specify COMPONENTS.
-#
-# You should provide a minimum version number that should be used. If you provide this
-# version number and specify the REQUIRED attribute, this module will fail if it
-# can't find the specified or a later version. If you specify a version number this is
-# automatically put into the considered list of version numbers and thus doesn't need
-# to be specified in the Boost_ADDITIONAL_VERSIONS variable (see below).
-#
-# NOTE for Visual Studio Users:
-#     Automatic linking is used on MSVC & Borland compilers by default when
-#     #including things in Boost.  It's important to note that setting
-#     Boost_USE_STATIC_LIBS to OFF is NOT enough to get you dynamic linking,
-#     should you need this feature.  Automatic linking typically uses static
-#     libraries with a few exceptions (Boost.Python is one).
-#
-#     Please see the section below near Boost_LIB_DIAGNOSTIC_DEFINITIONS for
-#     more details.  Adding a target_link_libraries() as shown in the example
-#     above appears to cause VS to link dynamically if Boost_USE_STATIC_LIBS
-#     gets set to OFF.  It is suggested you avoid automatic linking since it
-#     will make your application less portable.
-#
-# =========== The mess that is Boost_ADDITIONAL_VERSIONS (sorry?) ============
-#
-# OK, so the Boost_ADDITIONAL_VERSIONS variable can be used to specify a list of
-# boost version numbers that should be taken into account when searching
-# for Boost. Unfortunately boost puts the version number into the
-# actual filename for the libraries, so this variable will certainly be needed
-# in the future when new Boost versions are released.
-#
-# Currently this module searches for the following version numbers:
-# 1.33, 1.33.0, 1.33.1, 1.34, 1.34.0, 1.34.1, 1.35, 1.35.0, 1.35.1,
-# 1.36, 1.36.0, 1.36.1, 1.37, 1.37.0, 1.38, 1.38.0, 1.39, 1.39.0,
-# 1.40, 1.40.0, 1.41, 1.41.0, 1.42, 1.42.0, 1.43, 1.43.0, 1.44, 1.44.0,
-# 1.45, 1.45.0, 1.46, 1.46.0, 1.46.1, 1.47, 1.47.0, 1.48, 1.48.0,
-# 1.49, 1.49.0, 1.50, 1.50.0, 1.51, 1.51.0, 1.52, 1.52.0,
-# 1.53, 1.53.0, 1.54, 1.54.0, 1.55, 1.55.0, 1.56, 1.56.0
-#
-# NOTE: If you add a new major 1.x version in Boost_ADDITIONAL_VERSIONS you should
-# add both 1.x and 1.x.0 as shown above.  Official Boost include directories
-# omit the 3rd version number from include paths if it is 0 although not all
-# binary Boost releases do so.
-#
-# set(Boost_ADDITIONAL_VERSIONS "1.78" "1.78.0" "1.79" "1.79.0")
-#
-# ===================================== ============= ========================
-#
-# Variables used by this module, they can change the default behaviour and
-# need to be set before calling find_package:
-#
-#   Boost_USE_MULTITHREADED      Can be set to OFF to use the non-multithreaded
-#                                boost libraries.  If not specified, defaults
-#                                to ON.
-#
-#   Boost_USE_STATIC_LIBS        Can be set to ON to force the use of the static
-#                                boost libraries. Defaults to OFF.
-#
-#   Boost_NO_SYSTEM_PATHS        Set to TRUE to suppress searching in system
-#                                paths (or other locations outside of BOOST_ROOT
-#                                or BOOST_INCLUDEDIR).  Useful when specifying
-#                                BOOST_ROOT. Defaults to OFF.
-#                                  [Since CMake 2.8.3]
-#
-#   Boost_NO_BOOST_CMAKE         Do not do a find_package call in config mode
-#                                before searching for a regular boost install.
-#                                This will avoid finding boost-cmake installs.
-#                                Defaults to OFF.
-#                                  [Since CMake 2.8.6]
-#
-#   Boost_USE_STATIC_RUNTIME     If enabled, searches for boost libraries
-#                                linked against a static C++ standard library
-#                                ('s' ABI tag). This option should be set to
-#                                ON or OFF because the default behavior
-#                                if not specified is platform dependent
-#                                for backwards compatibility.
-#                                  [Since CMake 2.8.3]
-#
-#   Boost_USE_DEBUG_PYTHON       If enabled, searches for boost libraries
-#                                compiled against a special debug build of
-#                                Python ('y' ABI tag). Defaults to OFF.
-#                                  [Since CMake 2.8.3]
-#
-#   Boost_USE_STLPORT            If enabled, searches for boost libraries
-#                                compiled against the STLPort standard
-#                                library ('p' ABI tag). Defaults to OFF.
-#                                  [Since CMake 2.8.3]
-#
-#   Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
-#                                If enabled, searches for boost libraries
-#                                compiled against the deprecated STLPort
-#                                "native iostreams" feature ('n' ABI tag).
-#                                Defaults to OFF.
-#                                  [Since CMake 2.8.3]
-#
-# Other Variables used by this module which you may want to set.
-#
-#   Boost_ADDITIONAL_VERSIONS    A list of version numbers to use for searching
-#                                the boost include directory.  Please see
-#                                the documentation above regarding this
-#                                annoying, but necessary variable :(
-#
-#   Boost_DEBUG                  Set this to TRUE to enable debugging output
-#                                of FindBoost.cmake if you are having problems.
-#                                Please enable this before filing any bug
-#                                reports.
-#
-#   Boost_DETAILED_FAILURE_MSG   FindBoost doesn't output detailed information
-#                                about why it failed or how to fix the problem
-#                                unless this is set to TRUE or the REQUIRED
-#                                keyword is specified in find_package().
-#                                  [Since CMake 2.8.0]
-#
-#   Boost_COMPILER               Set this to the compiler suffix used by Boost
-#                                (e.g. "-gcc43") if FindBoost has problems finding
-#                                the proper Boost installation
-#
-#   Boost_THREADAPI                When building boost.thread, sometimes the name of the
-#                                library contains an additional "pthread" or "win32"
-#                                string known as the threadapi.  This can happen when
-#                                compiling against pthreads on Windows or win32 threads
-#                                on Cygwin.  You may specify this variable and if set
-#                                when FindBoost searches for the Boost threading library
-#                                it will first try to match the threadapi you specify.
-#                                  For Example: libboost_thread_win32-mgw45-mt-1_43.a
-#                                might be found if you specified "win32" here before
-#                                falling back on libboost_thread-mgw45-mt-1_43.a.
-#                                  [Since CMake 2.8.3]
-#
-#   Boost_REALPATH               Resolves symbolic links for discovered boost libraries
-#                                to assist with packaging.  For example, instead of
-#                                Boost_SYSTEM_LIBRARY_RELEASE being resolved to
-#                                "/usr/lib/libboost_system.so" it would be
-#                                "/usr/lib/libboost_system.so.1.42.0" instead.
-#                                This does not affect linking and should not be
-#                                enabled unless the user needs this information.
-#                                  [Since CMake 2.8.3]
-#
-
-
-#
-# These last three variables are available also as environment variables:
-# Also, note they are completely UPPERCASE, except Boost_DIR.
-#
-#   Boost_DIR or                 The preferred installation prefix for searching for
-#   BOOST_ROOT or BOOSTROOT      Boost.  Set this if the module has problems finding
-#                                the proper Boost installation.
-#
-#                                Note that Boost_DIR behaves exactly as <package>_DIR
-#                                variables are documented to behave in find_package's
-#                                Config mode.  That is, if it is set as a -D argument
-#                                to CMake, it must point to the location of the
-#                                BoostConfig.cmake or Boost-config.cmake file.  If it
-#                                is set as an environment variable, it must point to
-#                                the root of the boost installation.  BOOST_ROOT and
-#                                BOOSTROOT, on the other hand, will point to the root
-#                                in either case.
-#
-#                                To prevent falling back on the system paths, set
-#                                Boost_NO_SYSTEM_PATHS to true.
-#
-#                                To avoid finding boost-cmake installations, set
-#                                Boost_NO_BOOST_CMAKE to true.
-#
-#   BOOST_INCLUDEDIR             Set this to the include directory of Boost, if the
-#                                module has problems finding the proper Boost installation
-#
-#   BOOST_LIBRARYDIR             Set this to the lib directory of Boost, if the
-#                                module has problems finding the proper Boost installation
-#
-# Variables defined by this module:
-#
-#   Boost_FOUND                         System has Boost, this means the include dir was
-#                                       found, as well as all the libraries specified in
-#                                       the COMPONENTS list.
-#
-#   Boost_INCLUDE_DIRS                  Boost include directories: not cached
-#
-#   Boost_INCLUDE_DIR                   This is almost the same as above, but this one is
-#                                       cached and may be modified by advanced users
-#
-#   Boost_LIBRARIES                     Link to these to use the Boost libraries that you
-#                                       specified: not cached
-#
-#   Boost_LIBRARY_DIRS                  The path to where the Boost library files are.
-#
-#   Boost_VERSION                       The version number of the boost libraries that
-#                                       have been found, same as in version.hpp from Boost
-#
-#   Boost_LIB_VERSION                   The version number in filename form as
-#                                       it's appended to the library filenames
-#
-#   Boost_MAJOR_VERSION                 major version number of boost
-#   Boost_MINOR_VERSION                 minor version number of boost
-#   Boost_SUBMINOR_VERSION              subminor version number of boost
-#
-#   Boost_LIB_DIAGNOSTIC_DEFINITIONS    [WIN32 Only] You can call
-#                                       add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
-#                                       to have diagnostic information about Boost's
-#                                       automatic linking outputted during compilation time.
-#
-# For each component you specify in find_package(), the following (UPPER-CASE)
-# variables are set.  You can use these variables if you would like to pick and
-# choose components for your targets instead of just using Boost_LIBRARIES.
-#
-#   Boost_${COMPONENT}_FOUND            True IF the Boost library "component" was found.
-#
-#   Boost_${COMPONENT}_LIBRARY          Contains the libraries for the specified Boost
-#                                       "component" (includes debug and optimized keywords
-#                                       when needed).
+# - Find Boost include dirs and libraries
+# Use this module by invoking find_package with the form:
+#  find_package(Boost
+#    [version] [EXACT]      # Minimum or EXACT version e.g. 1.36.0
+#    [REQUIRED]             # Fail with error if Boost is not found
+#    [COMPONENTS <libs>...] # Boost libraries by their canonical name
+#    )                      # e.g. "date_time" for "libboost_date_time"
+# This module finds headers and requested component libraries OR a CMake
+# package configuration file provided by a "Boost CMake" build.  For the
+# latter case skip to the "Boost CMake" section below.  For the former
+# case results are reported in variables:
+#  Boost_FOUND            - True if headers and requested libraries were found
+#  Boost_INCLUDE_DIRS     - Boost include directories
+#  Boost_LIBRARY_DIRS     - Link directories for Boost libraries
+#  Boost_LIBRARIES        - Boost component libraries to be linked
+#  Boost_<C>_FOUND        - True if component <C> was found (<C> is upper-case)
+#  Boost_<C>_LIBRARY      - Libraries to link for component <C> (may include
+#                           target_link_libraries debug/optimized keywords)
+#  Boost_VERSION          - BOOST_VERSION value from boost/version.hpp
+#  Boost_LIB_VERSION      - Version string appended to library filenames
+#  Boost_MAJOR_VERSION    - Boost major version number (X in X.y.z)
+#  Boost_MINOR_VERSION    - Boost minor version number (Y in x.Y.z)
+#  Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z)
+#  Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows)
+#                         - Pass to add_definitions() to have diagnostic
+#                           information about Boost's automatic linking
+#                           displayed during compilation
+#
+# This module reads hints about search locations from variables:
+#  BOOST_ROOT             - Preferred installation prefix
+#   (or BOOSTROOT)
+#  BOOST_INCLUDEDIR       - Preferred include directory e.g. <prefix>/include
+#  BOOST_LIBRARYDIR       - Preferred library directory e.g. <prefix>/lib
+#  Boost_NO_SYSTEM_PATHS  - Set to ON to disable searching in locations not
+#                           specified by these hint variables. Default is OFF.
+#  Boost_ADDITIONAL_VERSIONS
+#                         - List of Boost versions not known to this module
+#                           (Boost install locations may contain the version)
+# and saves search results persistently in CMake cache entries:
+#  Boost_INCLUDE_DIR         - Directory containing Boost headers
+#  Boost_LIBRARY_DIR         - Directory containing Boost libraries
+#  Boost_<C>_LIBRARY_DEBUG   - Component <C> library debug variant
+#  Boost_<C>_LIBRARY_RELEASE - Component <C> library release variant
+# Users may set the these hints or results as cache entries.  Projects should
+# not read these entries directly but instead use the above result variables.
+# Note that some hint names start in upper-case "BOOST".  One may specify
+# these as environment variables if they are not specified as CMake variables
+# or cache entries.
+#
+# This module first searches for the Boost header files using the above hint
+# variables (excluding BOOST_LIBRARYDIR) and saves the result in
+# Boost_INCLUDE_DIR.  Then it searches for requested component libraries using
+# the above hints (excluding BOOST_INCLUDEDIR and Boost_ADDITIONAL_VERSIONS),
+# "lib" directories near Boost_INCLUDE_DIR, and the library name configuration
+# settings below.  It saves the library directory in Boost_LIBRARY_DIR and
+# individual library locations in Boost_<C>_LIBRARY_DEBUG and
+# Boost_<C>_LIBRARY_RELEASE.  When one changes settings used by previous
+# searches in the same build tree (excluding environment variables) this
+# module discards previous search results affected by the changes and searches
+# again.
+#
+# Boost libraries come in many variants encoded in their file name.  Users or
+# projects may tell this module which variant to find by setting variables:
+#  Boost_USE_MULTITHREADED  - Set to OFF to use the non-multithreaded
+#                             libraries ('mt' tag).  Default is ON.
+#  Boost_USE_STATIC_LIBS    - Set to ON to force the use of the static
+#                             libraries.  Default is OFF.
+#  Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use
+#                             libraries linked statically to the C++ runtime
+#                             ('s' tag).  Default is platform dependent.
+#  Boost_USE_DEBUG_PYTHON   - Set to ON to use libraries compiled with a
+#                             debug Python build ('y' tag). Default is OFF.
+#  Boost_USE_STLPORT        - Set to ON to use libraries compiled with
+#                             STLPort ('p' tag).  Default is OFF.
+#  Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
+#                           - Set to ON to use libraries compiled with
+#                             STLPort deprecated "native iostreams"
+#                             ('n' tag).  Default is OFF.
+#  Boost_COMPILER           - Set to the compiler-specific library suffix
+#                             (e.g. "-gcc43").  Default is auto-computed
+#                             for the C++ compiler in use.
+#  Boost_THREADAPI          - Suffix for "thread" component library name,
+#                             such as "pthread" or "win32".  Names with
+#                             and without this suffix will both be tried.
+# Other variables one may set to control this module are:
+#  Boost_DEBUG              - Set to ON to enable debug output from FindBoost.
+#                             Please enable this before filing any bug report.
+#  Boost_DETAILED_FAILURE_MSG
+#                           - Set to ON to add detailed information to the
+#                             failure message even when the REQUIRED option
+#                             is not given to the find_package call.
+#  Boost_REALPATH           - Set to ON to resolve symlinks for discovered
+#                             libraries to assist with packaging.  For example,
+#                             the "system" component library may be resolved to
+#                             "/usr/lib/libboost_system.so.1.42.0" instead of
+#                             "/usr/lib/libboost_system.so".  This does not
+#                             affect linking and should not be enabled unless
+#                             the user needs this information.
+# On Visual Studio and Borland compilers Boost headers request automatic
+# linking to corresponding libraries.  This requires matching libraries to be
+# linked explicitly or available in the link library search path.  In this
+# case setting Boost_USE_STATIC_LIBS to OFF may not achieve dynamic linking.
+# Boost automatic linking typically requests static libraries with a few
+# exceptions (such as Boost.Python).  Use
+#  add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
+# to ask Boost to report information about automatic linking requests.
+#
+# Example to find Boost headers only:
+#  find_package(Boost 1.36.0)
+#  if(Boost_FOUND)
+#    include_directories(${Boost_INCLUDE_DIRS})
+#    add_executable(foo foo.cc)
+#  endif()
+# Example to find Boost headers and some libraries:
+#  set(Boost_USE_STATIC_LIBS        ON)
+#  set(Boost_USE_MULTITHREADED      ON)
+#  set(Boost_USE_STATIC_RUNTIME    OFF)
+#  find_package(Boost 1.36.0 COMPONENTS date_time filesystem system ...)
+#  if(Boost_FOUND)
+#    include_directories(${Boost_INCLUDE_DIRS})
+#    add_executable(foo foo.cc)
+#    target_link_libraries(foo ${Boost_LIBRARIES})
+#  endif()
+#
+# Boost CMake ----------------------------------------------------------
+#
+# If Boost was built using the boost-cmake project it provides a package
+# configuration file for use with find_package's Config mode.  This module
+# looks for the package configuration file called BoostConfig.cmake or
+# boost-config.cmake and stores the result in cache entry "Boost_DIR".  If
+# found, the package configuration file is loaded and this module returns with
+# no further action.  See documentation of the Boost CMake package
+# configuration for details on what it provides.
+#
+# Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake.
 
 #=============================================================================
-# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006-2012 Kitware, Inc.
 # Copyright 2006-2008 Andreas Schneider <mail@cynapses.org>
 # Copyright 2007      Wengo
 # Copyright 2007      Mike Jackson
@@ -282,6 +175,7 @@ if (NOT Boost_NO_BOOST_CMAKE)
   # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
   # need to delegate them to this find_package call.
   find_package(Boost QUIET NO_MODULE)
+  mark_as_advanced(Boost_DIR)
 
   # If we found boost-cmake, then we're done.  Print out what we found.
   # Otherwise let the rest of the module try to find it.
@@ -349,29 +243,54 @@ macro(_Boost_ADJUST_LIB_VARS basename)
     endif()
 
     if(Boost_${basename}_LIBRARY)
-      set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY} CACHE FILEPATH "The Boost ${basename} library")
-
-      # Remove superfluous "debug" / "optimized" keywords from
-      # Boost_LIBRARY_DIRS
-      foreach(_boost_my_lib ${Boost_${basename}_LIBRARY})
-        get_filename_component(_boost_my_lib_path "${_boost_my_lib}" PATH)
-        list(APPEND Boost_LIBRARY_DIRS ${_boost_my_lib_path})
-      endforeach()
-      list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
-
-      set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIRS} CACHE FILEPATH "Boost library directory")
-      set(Boost_${basename}_FOUND ON CACHE INTERNAL "Whether the Boost ${basename} library found")
+      set(Boost_${basename}_FOUND ON)
     endif()
 
   endif()
   # Make variables changeble to the advanced user
   mark_as_advanced(
-      Boost_${basename}_LIBRARY
       Boost_${basename}_LIBRARY_RELEASE
       Boost_${basename}_LIBRARY_DEBUG
   )
 endmacro()
 
+macro(_Boost_CHANGE_DETECT changed_var)
+  set(${changed_var} 0)
+  foreach(v ${ARGN})
+    if(DEFINED _Boost_COMPONENTS_SEARCHED)
+      if(${v})
+        if(_${v}_LAST)
+          string(COMPARE NOTEQUAL "${${v}}" "${_${v}_LAST}" _${v}_CHANGED)
+        else()
+          set(_${v}_CHANGED 1)
+        endif()
+      elseif(_${v}_LAST)
+        set(_${v}_CHANGED 1)
+      endif()
+      if(_${v}_CHANGED)
+        set(${changed_var} 1)
+      endif()
+    else()
+      set(_${v}_CHANGED 0)
+    endif()
+  endforeach()
+endmacro()
+
+macro(_Boost_FIND_LIBRARY var)
+  find_library(${var} ${ARGN})
+
+  # If we found the first library save Boost_LIBRARY_DIR.
+  if(${var} AND NOT Boost_LIBRARY_DIR)
+    get_filename_component(_dir "${${var}}" PATH)
+    set(Boost_LIBRARY_DIR "${_dir}" CACHE PATH "Boost library directory" FORCE)
+  endif()
+
+  # If Boost_LIBRARY_DIR is known then search only there.
+  if(Boost_LIBRARY_DIR)
+    set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH)
+  endif()
+endmacro()
+
 #-------------------------------------------------------------------------------
 
 #
@@ -391,17 +310,6 @@ function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION)
 endfunction()
 
 #
-# A convenience function for marking desired components
-# as found or not
-#
-function(_Boost_MARK_COMPONENTS_FOUND _yes_or_no)
-  foreach(COMPONENT ${Boost_FIND_COMPONENTS})
-    string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
-    set(Boost_${UPPERCOMPONENT}_FOUND ${_yes_or_no} CACHE INTERNAL "Whether the Boost ${COMPONENT} library found" FORCE)
-  endforeach()
-endfunction()
-
-#
 # Take a list of libraries with "thread" in it
 # and prepend duplicates with "thread_${Boost_THREADAPI}"
 # at the front of the list
@@ -441,6 +349,8 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
     else()
       set (_boost_COMPILER "-il")
     endif()
+  elseif (MSVC12)
+    set(_boost_COMPILER "-vc120")
   elseif (MSVC11)
     set(_boost_COMPILER "-vc110")
   elseif (MSVC10)
@@ -561,652 +471,687 @@ endif()
 # Boost.
 set(Boost_ERROR_REASON)
 
-  if(Boost_DEBUG)
-    # Output some of their choices
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}")
-  endif()
-
-  if(WIN32)
-    # In windows, automatic linking is performed, so you do not have
-    # to specify the libraries.  If you are linking to a dynamic
-    # runtime, then you can choose to link to either a static or a
-    # dynamic Boost library, the default is to do a static link.  You
-    # can alter this for a specific library "whatever" by defining
-    # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
-    # linked dynamically.  Alternatively you can force all Boost
-    # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
-
-    # This feature can be disabled for Boost library "whatever" by
-    # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
-    # BOOST_ALL_NO_LIB.
-
-    # If you want to observe which libraries are being linked against
-    # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
-    # code to emit a #pragma message each time a library is selected
-    # for linking.
-    set(Boost_LIB_DIAGNOSTIC_DEFINITIONS
-      "-DBOOST_LIB_DIAGNOSTIC" CACHE STRING "Boost diagnostic define")
-  endif()
+if(Boost_DEBUG)
+  # Output some of their choices
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}")
+endif()
 
-  set(_boost_INCLUDE_SEARCH_DIRS_SYSTEM
-    C:/boost/include
-    C:/boost
-    "$ENV{ProgramFiles}/boost/include"
-    "$ENV{ProgramFiles}/boost"
-    /sw/local/include
-  )
+if(WIN32)
+  # In windows, automatic linking is performed, so you do not have
+  # to specify the libraries.  If you are linking to a dynamic
+  # runtime, then you can choose to link to either a static or a
+  # dynamic Boost library, the default is to do a static link.  You
+  # can alter this for a specific library "whatever" by defining
+  # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
+  # linked dynamically.  Alternatively you can force all Boost
+  # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
+
+  # This feature can be disabled for Boost library "whatever" by
+  # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
+  # BOOST_ALL_NO_LIB.
+
+  # If you want to observe which libraries are being linked against
+  # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
+  # code to emit a #pragma message each time a library is selected
+  # for linking.
+  set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC")
+endif()
 
-  _Boost_CHECK_SPELLING(Boost_ROOT)
-  _Boost_CHECK_SPELLING(Boost_LIBRARYDIR)
-  _Boost_CHECK_SPELLING(Boost_INCLUDEDIR)
+_Boost_CHECK_SPELLING(Boost_ROOT)
+_Boost_CHECK_SPELLING(Boost_LIBRARYDIR)
+_Boost_CHECK_SPELLING(Boost_INCLUDEDIR)
 
-  # If BOOST_ROOT was defined in the environment, use it.
-  if (NOT BOOST_ROOT AND NOT $ENV{Boost_DIR} STREQUAL "")
-    set(BOOST_ROOT $ENV{Boost_DIR})
+# Collect environment variable inputs as hints.  Do not consider changes.
+foreach(v BOOSTROOT BOOST_ROOT BOOST_INCLUDEDIR BOOST_LIBRARYDIR)
+  set(_env $ENV{${v}})
+  if(_env)
+    file(TO_CMAKE_PATH "${_env}" _ENV_${v})
+  else()
+    set(_ENV_${v} "")
   endif()
+endforeach()
+if(NOT _ENV_BOOST_ROOT AND _ENV_BOOSTROOT)
+  set(_ENV_BOOST_ROOT "${_ENV_BOOSTROOT}")
+endif()
 
-  # If BOOST_ROOT was defined in the environment, use it.
-  if (NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
-    set(BOOST_ROOT $ENV{BOOST_ROOT})
-  endif()
+# Collect inputs and cached results.  Detect changes since the last run.
+if(NOT BOOST_ROOT AND BOOSTROOT)
+  set(BOOST_ROOT "${BOOSTROOT}")
+endif()
+set(_Boost_VARS_DIR
+  BOOST_ROOT
+  Boost_NO_SYSTEM_PATHS
+  )
 
-  # If BOOSTROOT was defined in the environment, use it.
-  if (NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
-    set(BOOST_ROOT $ENV{BOOSTROOT})
-  endif()
+if(Boost_DEBUG)
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "Declared as CMake or Environmental Variables:")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "  BOOST_ROOT = ${BOOST_ROOT}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "  BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "  BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                 "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
+endif()
 
-  # If BOOST_INCLUDEDIR was defined in the environment, use it.
-  if( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
-    set(BOOST_INCLUDEDIR $ENV{BOOST_INCLUDEDIR})
-  endif()
+# ------------------------------------------------------------------------
+#  Search for Boost include DIR
+# ------------------------------------------------------------------------
 
-  # If BOOST_LIBRARYDIR was defined in the environment, use it.
-  if( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
-    set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
-  endif()
+set(_Boost_VARS_INC BOOST_INCLUDEDIR Boost_INCLUDE_DIR Boost_ADDITIONAL_VERSIONS)
+_Boost_CHANGE_DETECT(_Boost_CHANGE_INCDIR ${_Boost_VARS_DIR} ${_Boost_VARS_INC})
+# Clear Boost_INCLUDE_DIR if it did not change but other input affecting the
+# location did.  We will find a new one based on the new inputs.
+if(_Boost_CHANGE_INCDIR AND NOT _Boost_INCLUDE_DIR_CHANGED)
+  unset(Boost_INCLUDE_DIR CACHE)
+endif()
 
-  if( BOOST_ROOT )
-    file(TO_CMAKE_PATH ${BOOST_ROOT} BOOST_ROOT)
+if(NOT Boost_INCLUDE_DIR)
+  set(_boost_INCLUDE_SEARCH_DIRS "")
+  if(BOOST_INCLUDEDIR)
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_INCLUDEDIR})
+  elseif(_ENV_BOOST_INCLUDEDIR)
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_INCLUDEDIR})
   endif()
 
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "Declared as CMake or Environmental Variables:")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_ROOT = ${BOOST_ROOT}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "  BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                   "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
+  if( BOOST_ROOT )
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_ROOT}/include ${BOOST_ROOT})
+  elseif( _ENV_BOOST_ROOT )
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_ROOT}/include ${_ENV_BOOST_ROOT})
   endif()
 
   if( Boost_NO_SYSTEM_PATHS)
-    set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH)
   else()
-    set(_boost_INCLUDE_SEARCH_DIRS ${_boost_INCLUDE_SEARCH_DIRS_SYSTEM})
-  endif()
-
-  if( BOOST_ROOT )
-    set(_boost_INCLUDE_SEARCH_DIRS
-      ${BOOST_ROOT}/include
-      ${BOOST_ROOT}
-      ${_boost_INCLUDE_SEARCH_DIRS})
-  endif()
-
-  # prepend BOOST_INCLUDEDIR to search path if specified
-  if( BOOST_INCLUDEDIR )
-    file(TO_CMAKE_PATH ${BOOST_INCLUDEDIR} BOOST_INCLUDEDIR)
-    set(_boost_INCLUDE_SEARCH_DIRS
-      ${BOOST_INCLUDEDIR} ${_boost_INCLUDE_SEARCH_DIRS})
+    list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS
+      C:/boost/include
+      C:/boost
+      /sw/local/include
+      )
   endif()
 
-  # ------------------------------------------------------------------------
-  #  Search for Boost include DIR
-  # ------------------------------------------------------------------------
   # Try to find Boost by stepping backwards through the Boost versions
   # we know about.
-  if( NOT Boost_INCLUDE_DIR )
-    # Build a list of path suffixes for each version.
-    set(_boost_PATH_SUFFIXES)
-    foreach(_boost_VER ${_boost_TEST_VERSIONS})
-      # Add in a path suffix, based on the required version, ideally
-      # we could read this from version.hpp, but for that to work we'd
-      # need to know the include dir already
-      set(_boost_BOOSTIFIED_VERSION)
-
-      # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0
-      if(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
-          string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3"
-            _boost_BOOSTIFIED_VERSION ${_boost_VER})
-      elseif(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
-          string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2"
-            _boost_BOOSTIFIED_VERSION ${_boost_VER})
-      endif()
-
-      list(APPEND _boost_PATH_SUFFIXES "boost-${_boost_BOOSTIFIED_VERSION}")
-      list(APPEND _boost_PATH_SUFFIXES "boost_${_boost_BOOSTIFIED_VERSION}")
-
-    endforeach()
-
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "Include debugging info:")
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "  _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}")
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "  _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}")
+  # Build a list of path suffixes for each version.
+  set(_boost_PATH_SUFFIXES)
+  foreach(_boost_VER ${_boost_TEST_VERSIONS})
+    # Add in a path suffix, based on the required version, ideally
+    # we could read this from version.hpp, but for that to work we'd
+    # need to know the include dir already
+    set(_boost_BOOSTIFIED_VERSION)
+
+    # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0
+    if(_boost_VER MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+")
+        string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1_\\2_\\3"
+          _boost_BOOSTIFIED_VERSION ${_boost_VER})
+    elseif(_boost_VER MATCHES "[0-9]+\\.[0-9]+")
+        string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1_\\2"
+          _boost_BOOSTIFIED_VERSION ${_boost_VER})
     endif()
 
-    # Look for a standard boost header file.
-    find_path(Boost_INCLUDE_DIR
-      NAMES         boost/config.hpp
-      HINTS         ${_boost_INCLUDE_SEARCH_DIRS}
-      PATH_SUFFIXES ${_boost_PATH_SUFFIXES}
-      ${_boost_FIND_OPTIONS}
+    list(APPEND _boost_PATH_SUFFIXES
+      "boost-${_boost_BOOSTIFIED_VERSION}"
+      "boost_${_boost_BOOSTIFIED_VERSION}"
+      "boost/boost-${_boost_BOOSTIFIED_VERSION}"
+      "boost/boost_${_boost_BOOSTIFIED_VERSION}"
       )
-  endif()
 
-  # ------------------------------------------------------------------------
-  #  Extract version information from version.hpp
-  # ------------------------------------------------------------------------
-
-  if(Boost_INCLUDE_DIR)
-    # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp
-    # Read the whole file:
-    #
-    set(BOOST_VERSION 0)
-    set(BOOST_LIB_VERSION "")
-    file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ")
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp")
-    endif()
+  endforeach()
 
-    string(REGEX REPLACE ".*#define BOOST_VERSION ([0-9]+).*" "\\1" Boost_VERSION "${_boost_VERSION_HPP_CONTENTS}")
-    string(REGEX REPLACE ".*#define BOOST_LIB_VERSION \"([0-9_]+)\".*" "\\1" Boost_LIB_VERSION "${_boost_VERSION_HPP_CONTENTS}")
-    unset(_boost_VERSION_HPP_CONTENTS)
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "Include debugging info:")
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "  _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}")
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "  _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}")
+  endif()
 
-    set(Boost_LIB_VERSION ${Boost_LIB_VERSION} CACHE INTERNAL "The library version string for boost libraries")
-    set(Boost_VERSION ${Boost_VERSION} CACHE INTERNAL "The version number for boost libraries")
+  # Look for a standard boost header file.
+  find_path(Boost_INCLUDE_DIR
+    NAMES         boost/config.hpp
+    HINTS         ${_boost_INCLUDE_SEARCH_DIRS}
+    PATH_SUFFIXES ${_boost_PATH_SUFFIXES}
+    )
+endif()
 
-    if(NOT "${Boost_VERSION}" STREQUAL "0")
-      math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
-      math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
-      math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
+# ------------------------------------------------------------------------
+#  Extract version information from version.hpp
+# ------------------------------------------------------------------------
 
-      set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}")
-    endif()
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "version.hpp reveals boost "
-                     "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
-    endif()
-  else()
-    set(Boost_ERROR_REASON
-      "${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.")
+# Set Boost_FOUND based only on header location and version.
+# It will be updated below for component libraries.
+if(Boost_INCLUDE_DIR)
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp")
   endif()
 
-  # ------------------------------------------------------------------------
-  #  Suffix initialization and compiler suffix detection.
-  # ------------------------------------------------------------------------
+  # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp
+  set(Boost_VERSION 0)
+  set(Boost_LIB_VERSION "")
+  file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ")
+  set(_Boost_VERSION_REGEX "([0-9]+)")
+  set(_Boost_LIB_VERSION_REGEX "\"([0-9_]+)\"")
+  foreach(v VERSION LIB_VERSION)
+    if("${_boost_VERSION_HPP_CONTENTS}" MATCHES ".*#define BOOST_${v} ${_Boost_${v}_REGEX}.*")
+      set(Boost_${v} "${CMAKE_MATCH_1}")
+    endif()
+  endforeach()
+  unset(_boost_VERSION_HPP_CONTENTS)
+
+  math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
+  math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
+  math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
 
-  # Setting some more suffixes for the library
-  set(Boost_LIB_PREFIX "")
-  if ( WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN)
-    set(Boost_LIB_PREFIX "lib")
+  set(Boost_ERROR_REASON
+    "${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}")
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "version.hpp reveals boost "
+                   "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
   endif()
 
-  if (Boost_COMPILER)
-    set(_boost_COMPILER ${Boost_COMPILER})
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "using user-specified Boost_COMPILER = ${_boost_COMPILER}")
+  if(Boost_FIND_VERSION)
+    # Set Boost_FOUND based on requested version.
+    set(_Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
+    if("${_Boost_VERSION}" VERSION_LESS "${Boost_FIND_VERSION}")
+      set(Boost_FOUND 0)
+      set(_Boost_VERSION_AGE "old")
+    elseif(Boost_FIND_VERSION_EXACT AND
+        NOT "${_Boost_VERSION}" VERSION_EQUAL "${Boost_FIND_VERSION}")
+      set(Boost_FOUND 0)
+      set(_Boost_VERSION_AGE "new")
+    else()
+      set(Boost_FOUND 1)
     endif()
+    if(NOT Boost_FOUND)
+      # State that we found a version of Boost that is too new or too old.
+      set(Boost_ERROR_REASON
+        "${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
+      if (Boost_FIND_VERSION_PATCH)
+        set(Boost_ERROR_REASON
+          "${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}")
+      endif ()
+      if (NOT Boost_FIND_VERSION_EXACT)
+        set(Boost_ERROR_REASON "${Boost_ERROR_REASON} (or newer)")
+      endif ()
+      set(Boost_ERROR_REASON "${Boost_ERROR_REASON}.")
+    endif ()
   else()
-    # Attempt to guess the compiler suffix
-    # NOTE: this is not perfect yet, if you experience any issues
-    # please report them and use the Boost_COMPILER variable
-    # to work around the problems.
-    _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER)
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-        "guessed _boost_COMPILER = ${_boost_COMPILER}")
-    endif()
+    # Caller will accept any Boost version.
+    set(Boost_FOUND 1)
   endif()
+else()
+  set(Boost_FOUND 0)
+  set(Boost_ERROR_REASON
+    "${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.")
+endif()
 
-  set (_boost_MULTITHREADED "-mt")
-  if( NOT Boost_USE_MULTITHREADED )
-    set (_boost_MULTITHREADED "")
+# ------------------------------------------------------------------------
+#  Suffix initialization and compiler suffix detection.
+# ------------------------------------------------------------------------
+
+set(_Boost_VARS_NAME
+  Boost_COMPILER
+  Boost_THREADAPI
+  Boost_USE_DEBUG_PYTHON
+  Boost_USE_MULTITHREADED
+  Boost_USE_STATIC_LIBS
+  Boost_USE_STATIC_RUNTIME
+  Boost_USE_STLPORT
+  Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
+  )
+_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME})
+
+# Setting some more suffixes for the library
+set(Boost_LIB_PREFIX "")
+if ( WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN)
+  set(Boost_LIB_PREFIX "lib")
+endif()
+
+if (Boost_COMPILER)
+  set(_boost_COMPILER ${Boost_COMPILER})
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "using user-specified Boost_COMPILER = ${_boost_COMPILER}")
   endif()
+else()
+  # Attempt to guess the compiler suffix
+  # NOTE: this is not perfect yet, if you experience any issues
+  # please report them and use the Boost_COMPILER variable
+  # to work around the problems.
+  _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER)
   if(Boost_DEBUG)
     message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_MULTITHREADED = ${_boost_MULTITHREADED}")
+      "guessed _boost_COMPILER = ${_boost_COMPILER}")
   endif()
+endif()
 
-  #======================
-  # Systematically build up the Boost ABI tag
-  # http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming
-  set( _boost_RELEASE_ABI_TAG "-")
-  set( _boost_DEBUG_ABI_TAG   "-")
-  # Key       Use this library when:
-  #  s        linking statically to the C++ standard library and
-  #           compiler runtime support libraries.
-  if(Boost_USE_STATIC_RUNTIME)
-    set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s")
-    set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}s")
-  endif()
-  #  g        using debug versions of the standard and runtime
-  #           support libraries
-  if(WIN32)
-    if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
-            OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
-      set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g")
-    endif()
-  endif()
-  #  y        using special debug build of python
-  if(Boost_USE_DEBUG_PYTHON)
-    set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}y")
-  endif()
-  #  d        using a debug version of your code
-  set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}d")
-  #  p        using the STLport standard library rather than the
-  #           default one supplied with your compiler
-  if(Boost_USE_STLPORT)
-    set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}p")
-    set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}p")
-  endif()
-  #  n        using the STLport deprecated "native iostreams" feature
-  if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS)
-    set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}n")
-    set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}n")
-  endif()
+set (_boost_MULTITHREADED "-mt")
+if( NOT Boost_USE_MULTITHREADED )
+  set (_boost_MULTITHREADED "")
+endif()
+if(Boost_DEBUG)
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+    "_boost_MULTITHREADED = ${_boost_MULTITHREADED}")
+endif()
 
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}")
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}")
+#======================
+# Systematically build up the Boost ABI tag
+# http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming
+set( _boost_RELEASE_ABI_TAG "-")
+set( _boost_DEBUG_ABI_TAG   "-")
+# Key       Use this library when:
+#  s        linking statically to the C++ standard library and
+#           compiler runtime support libraries.
+if(Boost_USE_STATIC_RUNTIME)
+  set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s")
+  set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}s")
+endif()
+#  g        using debug versions of the standard and runtime
+#           support libraries
+if(WIN32)
+  if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
+          OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
+    set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g")
   endif()
+endif()
+#  y        using special debug build of python
+if(Boost_USE_DEBUG_PYTHON)
+  set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}y")
+endif()
+#  d        using a debug version of your code
+set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}d")
+#  p        using the STLport standard library rather than the
+#           default one supplied with your compiler
+if(Boost_USE_STLPORT)
+  set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}p")
+  set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}p")
+endif()
+#  n        using the STLport deprecated "native iostreams" feature
+if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS)
+  set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}n")
+  set( _boost_DEBUG_ABI_TAG   "${_boost_DEBUG_ABI_TAG}n")
+endif()
+
+if(Boost_DEBUG)
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+    "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}")
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+    "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}")
+endif()
+
+# ------------------------------------------------------------------------
+#  Begin finding boost libraries
+# ------------------------------------------------------------------------
+set(_Boost_VARS_LIB BOOST_LIBRARYDIR Boost_LIBRARY_DIR)
+_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR ${_Boost_VARS_DIR} ${_Boost_VARS_LIB} Boost_INCLUDE_DIR)
+# Clear Boost_LIBRARY_DIR if it did not change but other input affecting the
+# location did.  We will find a new one based on the new inputs.
+if(_Boost_CHANGE_LIBDIR AND NOT _Boost_LIBRARY_DIR_CHANGED)
+  unset(Boost_LIBRARY_DIR CACHE)
+endif()
 
-  # ------------------------------------------------------------------------
-  #  Begin finding boost libraries
-  # ------------------------------------------------------------------------
+if(Boost_LIBRARY_DIR)
+  set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH)
+else()
+  set(_boost_LIBRARY_SEARCH_DIRS "")
+  if(BOOST_LIBRARYDIR)
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_LIBRARYDIR})
+  elseif(_ENV_BOOST_LIBRARYDIR)
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_LIBRARYDIR})
+  endif()
 
   if(BOOST_ROOT)
-    set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
-      ${BOOST_ROOT}/lib
-      ${BOOST_ROOT}/stage/lib)
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib)
+  elseif(_ENV_BOOST_ROOT)
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib)
   endif()
-  set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
-    ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS}
+
+  list(APPEND _boost_LIBRARY_SEARCH_DIRS
     ${Boost_INCLUDE_DIR}/lib
     ${Boost_INCLUDE_DIR}/../lib
     ${Boost_INCLUDE_DIR}/stage/lib
-  )
-  set(_boost_LIBRARY_SEARCH_DIRS_SYSTEM
-    C:/boost/lib
-    C:/boost
-    "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}_${Boost_SUBMINOR_VERSION}/lib"
-    "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}/lib"
-    "$ENV{ProgramFiles}/boost/lib"
-    "$ENV{ProgramFiles}/boost"
-    /sw/local/lib
-  )
-  set(_boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS})
+    )
   if( Boost_NO_SYSTEM_PATHS )
-    set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH)
   else()
-    list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_SYSTEM})
-  endif()
-
-  # prepend BOOST_LIBRARYDIR to search path if specified
-  if( BOOST_LIBRARYDIR )
-    file(TO_CMAKE_PATH ${BOOST_LIBRARYDIR} BOOST_LIBRARYDIR)
-    set(_boost_LIBRARY_SEARCH_DIRS
-      ${BOOST_LIBRARYDIR} ${_boost_LIBRARY_SEARCH_DIRS})
+    list(APPEND _boost_LIBRARY_SEARCH_DIRS PATHS
+      C:/boost/lib
+      C:/boost
+      /sw/local/lib
+      )
   endif()
+endif()
 
-  if(Boost_DEBUG)
-    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-      "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}")
-  endif()
+if(Boost_DEBUG)
+  message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+    "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}")
+endif()
 
-  # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
-  if( Boost_USE_STATIC_LIBS )
-    set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-    if(WIN32)
-      set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
-    else()
-      set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
-    endif()
+# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+if( Boost_USE_STATIC_LIBS )
+  set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  if(WIN32)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
   endif()
+endif()
 
-  # We want to use the tag inline below without risking double dashes
-  if(_boost_RELEASE_ABI_TAG)
-    if(${_boost_RELEASE_ABI_TAG} STREQUAL "-")
-      set(_boost_RELEASE_ABI_TAG "")
-    endif()
+# We want to use the tag inline below without risking double dashes
+if(_boost_RELEASE_ABI_TAG)
+  if(${_boost_RELEASE_ABI_TAG} STREQUAL "-")
+    set(_boost_RELEASE_ABI_TAG "")
   endif()
-  if(_boost_DEBUG_ABI_TAG)
-    if(${_boost_DEBUG_ABI_TAG} STREQUAL "-")
-      set(_boost_DEBUG_ABI_TAG "")
-    endif()
+endif()
+if(_boost_DEBUG_ABI_TAG)
+  if(${_boost_DEBUG_ABI_TAG} STREQUAL "-")
+    set(_boost_DEBUG_ABI_TAG "")
   endif()
+endif()
 
-  # The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled
-  # on WIN32 was to:
-  #  1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found)
-  #  2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found)
-  # We maintain this behavior since changing it could break people's builds.
-  # To disable the ambiguous behavior, the user need only
-  # set Boost_USE_STATIC_RUNTIME either ON or OFF.
-  set(_boost_STATIC_RUNTIME_WORKAROUND false)
-  if(WIN32 AND Boost_USE_STATIC_LIBS)
-    if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
-      set(_boost_STATIC_RUNTIME_WORKAROUND true)
-    endif()
+# The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled
+# on WIN32 was to:
+#  1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found)
+#  2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found)
+# We maintain this behavior since changing it could break people's builds.
+# To disable the ambiguous behavior, the user need only
+# set Boost_USE_STATIC_RUNTIME either ON or OFF.
+set(_boost_STATIC_RUNTIME_WORKAROUND false)
+if(WIN32 AND Boost_USE_STATIC_LIBS)
+  if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
+    set(_boost_STATIC_RUNTIME_WORKAROUND true)
   endif()
+endif()
 
-  # On versions < 1.35, remove the System library from the considered list
-  # since it wasn't added until 1.35.
-  if(Boost_VERSION AND Boost_FIND_COMPONENTS)
-     if(Boost_VERSION LESS 103500)
-       list(REMOVE_ITEM Boost_FIND_COMPONENTS system)
-     endif()
-  endif()
+# On versions < 1.35, remove the System library from the considered list
+# since it wasn't added until 1.35.
+if(Boost_VERSION AND Boost_FIND_COMPONENTS)
+   if(Boost_VERSION LESS 103500)
+     list(REMOVE_ITEM Boost_FIND_COMPONENTS system)
+   endif()
+endif()
 
-  foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+# If the user changed any of our control inputs flush previous results.
+if(_Boost_CHANGE_LIBDIR OR _Boost_CHANGE_LIBNAME)
+  foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED})
     string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
-    set( Boost_${UPPERCOMPONENT}_LIBRARY "Boost_${UPPERCOMPONENT}_LIBRARY-NOTFOUND" )
-    set( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
-    set( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
-
-    set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
-    set( _boost_docstring_debug   "Boost ${COMPONENT} library (debug)")
-
-    #
-    # Find RELEASE libraries
-    #
-    set(_boost_RELEASE_NAMES
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT} )
-    if(_boost_STATIC_RUNTIME_WORKAROUND)
-      set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}")
-      list(APPEND _boost_RELEASE_NAMES
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
-    endif()
-    if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
-       _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})
-    endif()
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}")
-    endif()
-    find_library(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
-        NAMES ${_boost_RELEASE_NAMES}
-        HINTS ${_boost_LIBRARY_SEARCH_DIRS}
-        ${_boost_FIND_OPTIONS}
-        DOC "${_boost_docstring_release}"
-    )
+    foreach(c DEBUG RELEASE)
+      set(_var Boost_${UPPERCOMPONENT}_LIBRARY_${c})
+      unset(${_var} CACHE)
+      set(${_var} "${_var}-NOTFOUND")
+    endforeach()
+  endforeach()
+  set(_Boost_COMPONENTS_SEARCHED "")
+endif()
 
-    #
-    # Find DEBUG libraries
-    #
-    set(_boost_DEBUG_NAMES
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
-      ${Boost_LIB_PREFIX}boost_${COMPONENT} )
-    if(_boost_STATIC_RUNTIME_WORKAROUND)
-      set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}")
-      list(APPEND _boost_DEBUG_NAMES
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
-        ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
-    endif()
-    if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
-       _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES})
-    endif()
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
-                     "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}")
-    endif()
-    find_library(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
-        NAMES ${_boost_DEBUG_NAMES}
-        HINTS ${_boost_LIBRARY_SEARCH_DIRS}
-        ${_boost_FIND_OPTIONS}
-        DOC "${_boost_docstring_debug}"
+foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+  string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+
+  set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
+  set( _boost_docstring_debug   "Boost ${COMPONENT} library (debug)")
+
+  #
+  # Find RELEASE libraries
+  #
+  set(_boost_RELEASE_NAMES
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+  if(_boost_STATIC_RUNTIME_WORKAROUND)
+    set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}")
+    list(APPEND _boost_RELEASE_NAMES
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} )
+  endif()
+  if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+     _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})
+  endif()
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}")
+  endif()
+
+  # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing.
+  string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}")
+
+  _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
+    NAMES ${_boost_RELEASE_NAMES}
+    HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp}
+    NAMES_PER_DIR
+    DOC "${_boost_docstring_release}"
     )
 
-    if(Boost_REALPATH)
-      _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")
-      _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG   "${_boost_docstring_debug}"  )
-    endif()
+  #
+  # Find DEBUG libraries
+  #
+  set(_boost_DEBUG_NAMES
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}
+    ${Boost_LIB_PREFIX}boost_${COMPONENT} )
+  if(_boost_STATIC_RUNTIME_WORKAROUND)
+    set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}")
+    list(APPEND _boost_DEBUG_NAMES
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION}
+      ${Boost_LIB_PREFIX}boost_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} )
+  endif()
+  if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+     _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES})
+  endif()
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+                   "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}")
+  endif()
 
-    _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
+  # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing.
+  string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}")
 
-  endforeach()
+  _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
+    NAMES ${_boost_DEBUG_NAMES}
+    HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp}
+    NAMES_PER_DIR
+    DOC "${_boost_docstring_debug}"
+    )
 
-  # Restore the original find library ordering
-  if( Boost_USE_STATIC_LIBS )
-    set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+  if(Boost_REALPATH)
+    _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")
+    _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG   "${_boost_docstring_debug}"  )
   endif()
 
-  # ------------------------------------------------------------------------
-  #  End finding boost libraries
-  # ------------------------------------------------------------------------
+  _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
 
-  # ------------------------------------------------------------------------
-  #  Begin long process of determining Boost_FOUND, starting with version
-  #  number checks, followed by
-  #  TODO: Ideally the version check logic should happen prior to searching
-  #        for libraries...
-  # ------------------------------------------------------------------------
+endforeach()
 
-  set(Boost_INCLUDE_DIRS
-    ${Boost_INCLUDE_DIR}
-  )
+# Restore the original find library ordering
+if( Boost_USE_STATIC_LIBS )
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
 
-  set(Boost_FOUND FALSE)
-  if(Boost_INCLUDE_DIR)
-    set( Boost_FOUND TRUE )
+# ------------------------------------------------------------------------
+#  End finding boost libraries
+# ------------------------------------------------------------------------
 
-    if(Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" )
-      set( Boost_FOUND FALSE )
-      set(_Boost_VERSION_AGE "old")
-    elseif(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
-      if(Boost_MINOR_VERSION LESS "${Boost_FIND_VERSION_MINOR}" )
-        set( Boost_FOUND FALSE )
-        set(_Boost_VERSION_AGE "old")
-      elseif(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
-        if( Boost_FIND_VERSION_PATCH AND Boost_SUBMINOR_VERSION LESS "${Boost_FIND_VERSION_PATCH}" )
-          set( Boost_FOUND FALSE )
-          set(_Boost_VERSION_AGE "old")
-        endif()
-      endif()
-    endif()
+set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR})
+set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR})
 
-    if (NOT Boost_FOUND)
-      _Boost_MARK_COMPONENTS_FOUND(OFF)
+# The above setting of Boost_FOUND was based only on the header files.
+# Update it for the requested component libraries.
+if(Boost_FOUND)
+  # The headers were found.  Check for requested component libs.
+  set(_boost_CHECKED_COMPONENT FALSE)
+  set(_Boost_MISSING_COMPONENTS "")
+  foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+    string(TOUPPER ${COMPONENT} COMPONENT)
+    set(_boost_CHECKED_COMPONENT TRUE)
+    if(NOT Boost_${COMPONENT}_FOUND)
+      string(TOLOWER ${COMPONENT} COMPONENT)
+      list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
     endif()
+  endforeach()
 
-    if (Boost_FOUND AND Boost_FIND_VERSION_EXACT)
-      # If the user requested an exact version of Boost, check
-      # that. We already know that the Boost version we have is >= the
-      # requested version.
-      set(_Boost_VERSION_AGE "new")
-
-      # If the user didn't specify a patchlevel, it's 0.
-      if (NOT Boost_FIND_VERSION_PATCH)
-        set(Boost_FIND_VERSION_PATCH 0)
-      endif ()
-
-      # We'll set Boost_FOUND true again if we have an exact version match.
-      set(Boost_FOUND FALSE)
-      _Boost_MARK_COMPONENTS_FOUND(OFF)
-      if(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
-        if(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
-          if(Boost_SUBMINOR_VERSION EQUAL "${Boost_FIND_VERSION_PATCH}" )
-            set( Boost_FOUND TRUE )
-            _Boost_MARK_COMPONENTS_FOUND(ON)
-          endif()
-        endif()
-      endif()
-    endif ()
+  if(Boost_DEBUG)
+    message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}")
+  endif()
 
-    if(NOT Boost_FOUND)
-      # State that we found a version of Boost that is too new or too old.
+  if (_Boost_MISSING_COMPONENTS)
+    set(Boost_FOUND 0)
+    # We were unable to find some libraries, so generate a sensible
+    # error message that lists the libraries we were unable to find.
+    set(Boost_ERROR_REASON
+      "${Boost_ERROR_REASON}\nThe following Boost libraries could not be found:\n")
+    foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
       set(Boost_ERROR_REASON
-        "${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
-      if (Boost_FIND_VERSION_PATCH)
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}")
-      endif ()
-      if (NOT Boost_FIND_VERSION_EXACT)
-        set(Boost_ERROR_REASON "${Boost_ERROR_REASON} (or newer)")
-      endif ()
-      set(Boost_ERROR_REASON "${Boost_ERROR_REASON}.")
-    endif ()
-
-    # Always check for missing components
-    set(_boost_CHECKED_COMPONENT FALSE)
-    set(_Boost_MISSING_COMPONENTS "")
-    foreach(COMPONENT ${Boost_FIND_COMPONENTS})
-      string(TOUPPER ${COMPONENT} COMPONENT)
-      set(_boost_CHECKED_COMPONENT TRUE)
-      if(NOT Boost_${COMPONENT}_FOUND)
-        string(TOLOWER ${COMPONENT} COMPONENT)
-        list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
-        set( Boost_FOUND FALSE)
-      endif()
+        "${Boost_ERROR_REASON}        boost_${COMPONENT}\n")
     endforeach()
 
-    if(Boost_DEBUG)
-      message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}")
-    endif()
-
-    if (_Boost_MISSING_COMPONENTS)
-      # We were unable to find some libraries, so generate a sensible
-      # error message that lists the libraries we were unable to find.
+    list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
+    list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS)
+    if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
       set(Boost_ERROR_REASON
-        "${Boost_ERROR_REASON}\nThe following Boost libraries could not be found:\n")
-      foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}        boost_${COMPONENT}\n")
-      endforeach()
-
-      list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
-      list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS)
-      if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
-      else ()
-        set(Boost_ERROR_REASON
-          "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
-      endif ()
+        "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
+    else ()
+      set(Boost_ERROR_REASON
+        "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
     endif ()
+  endif ()
 
-    if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
-      # Compatibility Code for backwards compatibility with CMake
-      # 2.4's FindBoost module.
+  if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
+    # Compatibility Code for backwards compatibility with CMake
+    # 2.4's FindBoost module.
 
-      # Look for the boost library path.
-      # Note that the user may not have installed any libraries
-      # so it is quite possible the Boost_LIBRARY_DIRS may not exist.
-      set(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
+    # Look for the boost library path.
+    # Note that the user may not have installed any libraries
+    # so it is quite possible the Boost_LIBRARY_DIRS may not exist.
+    set(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
 
-      if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
-        get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
-      endif()
+    if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
+      get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+    endif()
 
-      if("${_boost_LIB_DIR}" MATCHES "/include$")
-        # Strip off the trailing "/include" in the path.
-        get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
-      endif()
+    if("${_boost_LIB_DIR}" MATCHES "/include$")
+      # Strip off the trailing "/include" in the path.
+      get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+    endif()
 
-      if(EXISTS "${_boost_LIB_DIR}/lib")
-        set(_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
+    if(EXISTS "${_boost_LIB_DIR}/lib")
+      set(_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
+    else()
+      if(EXISTS "${_boost_LIB_DIR}/stage/lib")
+        set(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
       else()
-        if(EXISTS "${_boost_LIB_DIR}/stage/lib")
-          set(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
-        else()
-          set(_boost_LIB_DIR "")
-        endif()
-      endif()
-
-      if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
-        set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR} CACHE FILEPATH "Boost library directory")
+        set(_boost_LIB_DIR "")
       endif()
+    endif()
 
+    if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
+      set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR})
     endif()
 
-  else()
-    set( Boost_FOUND FALSE)
   endif()
+else()
+  # Boost headers were not found so no components were found.
+  foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+    string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+    set(Boost_${UPPERCOMPONENT}_FOUND 0)
+  endforeach()
+endif()
 
-  # ------------------------------------------------------------------------
-  #  Notification to end user about what was found
-  # ------------------------------------------------------------------------
+# ------------------------------------------------------------------------
+#  Notification to end user about what was found
+# ------------------------------------------------------------------------
 
-  if(Boost_FOUND)
+set(Boost_LIBRARIES "")
+if(Boost_FOUND)
+  if(NOT Boost_FIND_QUIETLY)
+    message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
+    if(Boost_FIND_COMPONENTS)
+      message(STATUS "Found the following Boost libraries:")
+    endif()
+  endif()
+  foreach( COMPONENT  ${Boost_FIND_COMPONENTS} )
+    string( TOUPPER ${COMPONENT} UPPERCOMPONENT )
+    if( Boost_${UPPERCOMPONENT}_FOUND )
       if(NOT Boost_FIND_QUIETLY)
-        message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
-        if(Boost_FIND_COMPONENTS)
-          message(STATUS "Found the following Boost libraries:")
-        endif()
+        message (STATUS "  ${COMPONENT}")
       endif()
-      foreach( COMPONENT  ${Boost_FIND_COMPONENTS} )
-        string( TOUPPER ${COMPONENT} UPPERCOMPONENT )
-        if( Boost_${UPPERCOMPONENT}_FOUND )
-          if(NOT Boost_FIND_QUIETLY)
-            message (STATUS "  ${COMPONENT}")
-          endif()
-          set(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${UPPERCOMPONENT}_LIBRARY})
-        endif()
-      endforeach()
+      list(APPEND Boost_LIBRARIES ${Boost_${UPPERCOMPONENT}_LIBRARY})
+    endif()
+  endforeach()
+else()
+  if(Boost_FIND_REQUIRED)
+    message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}")
   else()
-    if(Boost_FIND_REQUIRED)
-      message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}")
-    else()
-      if(NOT Boost_FIND_QUIETLY)
-        # we opt not to automatically output Boost_ERROR_REASON here as
-        # it could be quite lengthy and somewhat imposing in its requests
-        # Since Boost is not always a required dependency we'll leave this
-        # up to the end-user.
-        if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG)
-          message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}")
-        else()
-          message(STATUS "Could NOT find Boost")
-        endif()
+    if(NOT Boost_FIND_QUIETLY)
+      # we opt not to automatically output Boost_ERROR_REASON here as
+      # it could be quite lengthy and somewhat imposing in its requests
+      # Since Boost is not always a required dependency we'll leave this
+      # up to the end-user.
+      if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG)
+        message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}")
+      else()
+        message(STATUS "Could NOT find Boost")
       endif()
     endif()
   endif()
+endif()
 
-  # show the Boost_INCLUDE_DIRS AND Boost_LIBRARIES variables only in the advanced view
-  mark_as_advanced(Boost_INCLUDE_DIR
-      Boost_INCLUDE_DIRS
-      Boost_LIBRARY_DIRS
-  )
+# Configure display of cache entries in GUI.
+foreach(v BOOSTROOT BOOST_ROOT ${_Boost_VARS_INC} ${_Boost_VARS_LIB})
+  get_property(_type CACHE ${v} PROPERTY TYPE)
+  if(_type)
+    set_property(CACHE ${v} PROPERTY ADVANCED 1)
+    if("x${_type}" STREQUAL "xUNINITIALIZED")
+      if("x${v}" STREQUAL "xBoost_ADDITIONAL_VERSIONS")
+        set_property(CACHE ${v} PROPERTY TYPE STRING)
+      else()
+        set_property(CACHE ${v} PROPERTY TYPE PATH)
+      endif()
+    endif()
+  endif()
+endforeach()
+
+# Record last used values of input variables so we can
+# detect on the next run if the user changed them.
+foreach(v
+    ${_Boost_VARS_INC} ${_Boost_VARS_LIB}
+    ${_Boost_VARS_DIR} ${_Boost_VARS_NAME}
+    )
+  if(DEFINED ${v})
+    set(_${v}_LAST "${${v}}" CACHE INTERNAL "Last used ${v} value.")
+  else()
+    unset(_${v}_LAST CACHE)
+  endif()
+endforeach()
+
+# Maintain a persistent list of components requested anywhere since
+# the last flush.
+set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}")
+list(APPEND _Boost_COMPONENTS_SEARCHED ${Boost_FIND_COMPONENTS})
+list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED)
+list(SORT _Boost_COMPONENTS_SEARCHED)
+set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}"
+  CACHE INTERNAL "Components requested for this build tree.")
index 1c4a9de..1a27fc3 100644 (file)
@@ -33,6 +33,8 @@ macro(_FIND_BULLET_LIBRARY _var)
         ${ARGN}
      HINTS
         ${BULLET_ROOT}
+        ${BULLET_ROOT}/lib/Release
+        ${BULLET_ROOT}/lib/Debug
         ${BULLET_ROOT}/out/release8/libs
         ${BULLET_ROOT}/out/debug8/libs
      PATH_SUFFIXES lib
index 5a834b1..423ad3d 100644 (file)
 #     CUDA_ADD_LIBRARY, CUDA_ADD_EXECUTABLE, or CUDA_WRAP_SRCS.  Flags used for
 #     shared library compilation are not affected by this flag.
 #
+#  CUDA_SEPARABLE_COMPILATION (Default OFF)
+#  -- If set this will enable separable compilation for all CUDA runtime object
+#     files.  If used outside of CUDA_ADD_EXECUTABLE and CUDA_ADD_LIBRARY
+#     (e.g. calling CUDA_WRAP_SRCS directly),
+#     CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME and
+#     CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS should be called.
+#
 #  CUDA_VERBOSE_BUILD (Default OFF)
 #  -- Set to ON to see all the commands used when building the CUDA file.  When
 #     using a Makefile generator the value defaults to VERBOSE (run make
 #  CUDA_COMPILE_PTX( generated_files file0 file1 ... [OPTIONS ...] )
 #  -- Returns a list of PTX files generated from the input source files.
 #
+#  CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME( output_file_var
+#                                                       cuda_target
+#                                                       object_files )
+#  -- Compute the name of the intermediate link file used for separable
+#     compilation.  This file name is typically passed into
+#     CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS.  output_file_var is produced
+#     based on cuda_target the list of objects files that need separable
+#     compilation as specified by object_files.  If the object_files list is
+#     empty, then output_file_var will be empty.  This function is called
+#     automatically for CUDA_ADD_LIBRARY and CUDA_ADD_EXECUTABLE.  Note that
+#     this is a function and not a macro.
+#
 #  CUDA_INCLUDE_DIRECTORIES( path0 path1 ... )
 #  -- Sets the directories that should be passed to nvcc
 #     (e.g. nvcc -Ipath0 -Ipath1 ... ). These paths usually contain other .cu
 #     files.
 #
+#
+#  CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS( output_file_var cuda_target
+#                                           nvcc_flags object_files)
+#
+#  -- Generates the link object required by separable compilation from the given
+#     object files.  This is called automatically for CUDA_ADD_EXECUTABLE and
+#     CUDA_ADD_LIBRARY, but can be called manually when using CUDA_WRAP_SRCS
+#     directly.  When called from CUDA_ADD_LIBRARY or CUDA_ADD_EXECUTABLE the
+#     nvcc_flags passed in are the same as the flags passed in via the OPTIONS
+#     argument.  The only nvcc flag added automatically is the bitness flag as
+#     specified by CUDA_64_BIT_DEVICE_CODE.  Note that this is a function
+#     instead of a macro.
+#
 #  CUDA_WRAP_SRCS ( cuda_target format generated_files file0 file1 ...
 #                   [STATIC | SHARED | MODULE] [OPTIONS ...] )
 #  -- This is where all the magic happens.  CUDA_ADD_EXECUTABLE,
 #  CUDA_CUBLAS_LIBRARIES -- Device or emulation library for the Cuda BLAS
 #                           implementation (alterative to:
 #                           CUDA_ADD_CUBLAS_TO_TARGET macro).
+#  CUDA_cupti_LIBRARY    -- CUDA Profiling Tools Interface library.
+#                           Only available for CUDA version 4.0+.
 #  CUDA_curand_LIBRARY   -- CUDA Random Number Generation library.
 #                           Only available for CUDA version 3.2+.
 #  CUDA_cusparse_LIBRARY -- CUDA Sparse Matrix library.
@@ -406,6 +440,9 @@ endif()
 # Propagate the host flags to the host compiler via -Xcompiler
 option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON)
 
+# Enable CUDA_SEPARABLE_COMPILATION
+option(CUDA_SEPARABLE_COMPILATION "Compile CUDA objects with separable compilation enabled.  Requires CUDA 5.0+" OFF)
+
 # Specifies whether the commands used when compiling the .cu file will be printed out.
 option(CUDA_VERBOSE_BUILD "Print out the commands run while compiling the CUDA source file.  With the Makefile generator this defaults to VERBOSE variable specified on the command line, but can be forced on with this option." OFF)
 
@@ -451,6 +488,7 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}")
   endif()
   unset(CUDA_VERSION CACHE)
   unset(CUDA_CUDA_LIBRARY CACHE)
+  unset(CUDA_cupti_LIBRARY CACHE)
   unset(CUDA_cublas_LIBRARY CACHE)
   unset(CUDA_cublasemu_LIBRARY CACHE)
   unset(CUDA_cufft_LIBRARY CACHE)
@@ -551,11 +589,11 @@ mark_as_advanced(CUDA_TOOLKIT_INCLUDE)
 set (CUDA_NVCC_INCLUDE_ARGS_USER "")
 set (CUDA_INCLUDE_DIRS ${CUDA_TOOLKIT_INCLUDE})
 
-macro(FIND_LIBRARY_LOCAL_FIRST _var _names _doc)
+macro(cuda_find_library_local_first_with_path_ext _var _names _doc _path_ext )
   if(CMAKE_SIZEOF_VOID_P EQUAL 8)
     # CUDA 3.2+ on Windows moved the library directories, so we need the new
     # and old paths.
-    set(_cuda_64bit_lib_dir "lib/x64" "lib64" )
+    set(_cuda_64bit_lib_dir "${_path_ext}lib/x64" "${_path_ext}lib64" "${_path_ext}libx64" )
   endif()
   # CUDA 3.2+ on Windows moved the library directories, so we need to new
   # (lib/Win32) and the old path (lib).
@@ -564,7 +602,7 @@ macro(FIND_LIBRARY_LOCAL_FIRST _var _names _doc)
     PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
     ENV CUDA_PATH
     ENV CUDA_LIB_PATH
-    PATH_SUFFIXES ${_cuda_64bit_lib_dir} "lib/Win32" "lib"
+    PATH_SUFFIXES ${_cuda_64bit_lib_dir} "${_path_ext}lib/Win32" "${_path_ext}lib" "${_path_ext}libWin32"
     DOC ${_doc}
     NO_DEFAULT_PATH
     )
@@ -572,15 +610,31 @@ macro(FIND_LIBRARY_LOCAL_FIRST _var _names _doc)
   find_library(${_var} NAMES ${_names} DOC ${_doc})
 endmacro()
 
+macro(cuda_find_library_local_first _var _names _doc)
+  cuda_find_library_local_first_with_path_ext( "${_var}" "${_names}" "${_doc}" "" )
+endmacro()
+
+macro(find_library_local_first _var _names _doc )
+  cuda_find_library_local_first( "${_var}" "${_names}" "${_doc}" "" )
+endmacro()
+
+
 # CUDA_LIBRARIES
-find_library_local_first(CUDA_CUDART_LIBRARY cudart "\"cudart\" library")
+cuda_find_library_local_first(CUDA_CUDART_LIBRARY cudart "\"cudart\" library")
 if(CUDA_VERSION VERSION_EQUAL "3.0")
   # The cudartemu library only existed for the 3.0 version of CUDA.
-  find_library_local_first(CUDA_CUDARTEMU_LIBRARY cudartemu "\"cudartemu\" library")
+  cuda_find_library_local_first(CUDA_CUDARTEMU_LIBRARY cudartemu "\"cudartemu\" library")
   mark_as_advanced(
     CUDA_CUDARTEMU_LIBRARY
     )
 endif()
+
+# CUPTI library showed up in cuda toolkit 4.0
+if(NOT CUDA_VERSION VERSION_LESS "4.0")
+  cuda_find_library_local_first_with_path_ext(CUDA_cupti_LIBRARY cupti "\"cupti\" library" "extras/CUPTI/")
+  mark_as_advanced(CUDA_cupti_LIBRARY)
+endif()
+
 # If we are using emulation mode and we found the cudartemu library then use
 # that one instead of cudart.
 if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY)
@@ -603,12 +657,7 @@ endif()
 
 # 1.1 toolkit on linux doesn't appear to have a separate library on
 # some platforms.
-find_library_local_first(CUDA_CUDA_LIBRARY cuda "\"cuda\" library (older versions only).")
-
-# Add cuda library to the link line only if it is found.
-if (CUDA_CUDA_LIBRARY)
-  set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY})
-endif()
+cuda_find_library_local_first(CUDA_CUDA_LIBRARY cuda "\"cuda\" library (older versions only).")
 
 mark_as_advanced(
   CUDA_CUDA_LIBRARY
@@ -618,7 +667,7 @@ mark_as_advanced(
 #######################
 # Look for some of the toolkit helper libraries
 macro(FIND_CUDA_HELPER_LIBS _name)
-  find_library_local_first(CUDA_${_name}_LIBRARY ${_name} "\"${_name}\" library")
+  cuda_find_library_local_first(CUDA_${_name}_LIBRARY ${_name} "\"${_name}\" library")
   mark_as_advanced(CUDA_${_name}_LIBRARY)
 endmacro()
 
@@ -913,6 +962,11 @@ endfunction()
 
 macro(CUDA_WRAP_SRCS cuda_target format generated_files)
 
+  # If CMake doesn't support separable compilation, complain
+  if(CUDA_SEPARABLE_COMPILATION AND CMAKE_VERSION VERSION_LESS "2.8.10.1")
+    message(SEND_ERROR "CUDA_SEPARABLE_COMPILATION isn't supported for CMake versions less than 2.8.10.1")
+  endif()
+
   # Set up all the command line flags here, so that they can be overridden on a per target basis.
 
   set(nvcc_flags "")
@@ -950,6 +1004,8 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
   # $(VCInstallDir)/bin.
   if(CMAKE_GENERATOR MATCHES "Visual Studio")
     set(ccbin_flags -D "\"CCBIN:PATH=$(VCInstallDir)bin\"" )
+  else()
+    set(ccbin_flags)
   endif()
 
   # Figure out which configure we will use and pass that in as an argument to
@@ -1117,7 +1173,11 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
       else()
         set(generated_file_path "${cuda_compile_output_dir}/${CMAKE_CFG_INTDIR}")
         set(generated_file_basename "${cuda_target}_generated_${basename}${generated_extension}")
-        set(format_flag "-c")
+        if(CUDA_SEPARABLE_COMPILATION)
+          set(format_flag "-dc")
+        else()
+          set(format_flag "-c")
+        endif()
       endif()
 
       # Set all of our file names.  Make sure that whatever filenames that have
@@ -1146,6 +1206,10 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
         set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
       endif()
 
+      if( NOT compile_to_ptx AND CUDA_SEPARABLE_COMPILATION)
+        list(APPEND ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS "${generated_file}")
+      endif()
+
       # Bring in the dependencies.  Creates a variable CUDA_NVCC_DEPEND #######
       cuda_include_nvcc_dependencies(${cmake_dependency_file})
 
@@ -1244,6 +1308,100 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
   set(${generated_files} ${_cuda_wrap_generated_files})
 endmacro()
 
+function(_cuda_get_important_host_flags important_flags flag_string)
+  if(CMAKE_GENERATOR MATCHES "Visual Studio")
+    string(REGEX MATCHALL "/M[DT][d]?" flags ${flag_string})
+    list(APPEND ${important_flags} ${flags})
+  else()
+    string(REGEX MATCHALL "-fPIC" flags ${flag_string})
+    list(APPEND ${important_flags} ${flags})
+  endif()
+  set(${important_flags} ${${important_flags}} PARENT_SCOPE)
+endfunction()
+
+###############################################################################
+###############################################################################
+# Separable Compilation Link
+###############################################################################
+###############################################################################
+
+# Compute the filename to be used by CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS
+function(CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME output_file_var cuda_target object_files)
+  if (object_files)
+    set(generated_extension ${CMAKE_${CUDA_C_OR_CXX}_OUTPUT_EXTENSION})
+    set(output_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${cuda_target}.dir/${CMAKE_CFG_INTDIR}/${cuda_target}_intermediate_link${generated_extension}")
+  else()
+    set(output_file)
+  endif()
+
+  set(${output_file_var} "${output_file}" PARENT_SCOPE)
+endfunction()
+
+# Setup the build rule for the separable compilation intermediate link file.
+function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options object_files)
+  if (object_files)
+
+    set_source_files_properties("${output_file}"
+      PROPERTIES
+      EXTERNAL_OBJECT TRUE # This is an object file not to be compiled, but only
+                           # be linked.
+      GENERATED TRUE       # This file is generated during the build
+      )
+
+    # For now we are ignoring all the configuration specific flags.
+    set(nvcc_flags)
+    CUDA_PARSE_NVCC_OPTIONS(nvcc_flags ${options})
+    if(CUDA_64_BIT_DEVICE_CODE)
+      list(APPEND nvcc_flags -m64)
+    else()
+      list(APPEND nvcc_flags -m32)
+    endif()
+    # If -ccbin, --compiler-bindir has been specified, don't do anything.  Otherwise add it here.
+    list( FIND nvcc_flags "-ccbin" ccbin_found0 )
+    list( FIND nvcc_flags "--compiler-bindir" ccbin_found1 )
+    if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 )
+      list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"")
+    endif()
+    set(flags)
+    foreach(config ${CUDA_configuration_types})
+      string(TOUPPER ${config} config_upper)
+      set(important_host_flags)
+      _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}})
+      foreach(f ${important_host_flags})
+        list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>)
+      endforeach()
+    endforeach()
+    file(RELATIVE_PATH output_file_relative_path "${CMAKE_BINARY_DIR}" "${output_file}")
+
+    # Some generators don't handle the multiple levels of custom command
+    # dependencies correctly (obj1 depends on file1, obj2 depends on obj1), so
+    # we work around that issue by compiling the intermediate link object as a
+    # pre-link custom command in that situation.
+    set(do_obj_build_rule TRUE)
+    if (MSVC_VERSION GREATER 1599)
+      # VS 2010 and 2012 have this problem.  If future versions fix this issue,
+      # it should still work, it just won't be as nice as the other method.
+      set(do_obj_build_rule FALSE)
+    endif()
+
+    if (do_obj_build_rule)
+      add_custom_command(
+        OUTPUT ${output_file}
+        DEPENDS ${object_files}
+        COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file}
+        ${flags}
+        COMMENT "Building NVCC intermediate link file ${output_file_relative_path}"
+        )
+    else()
+      add_custom_command(
+        TARGET ${cuda_target}
+        PRE_LINK
+        COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}"
+        COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}"
+        )
+    endif()
+ endif()
+endfunction()
 
 ###############################################################################
 ###############################################################################
@@ -1262,12 +1420,22 @@ macro(CUDA_ADD_LIBRARY cuda_target)
     ${_cmake_options} ${_cuda_shared_flag}
     OPTIONS ${_options} )
 
+  # Compute the file name of the intermedate link file used for separable
+  # compilation.
+  CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${cuda_target} "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}")
+
   # Add the library.
   add_library(${cuda_target} ${_cmake_options}
     ${_generated_files}
     ${_sources}
+    ${link_file}
     )
 
+  # Add a link phase for the separable compilation if it has been enabled.  If
+  # it has been enabled then the ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS
+  # variable will have been defined.
+  CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${cuda_target} "${_options}" "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}")
+
   target_link_libraries(${cuda_target}
     ${CUDA_LIBRARIES}
     )
@@ -1296,12 +1464,22 @@ macro(CUDA_ADD_EXECUTABLE cuda_target)
   # Create custom commands and targets for each file.
   CUDA_WRAP_SRCS( ${cuda_target} OBJ _generated_files ${_sources} OPTIONS ${_options} )
 
+  # Compute the file name of the intermedate link file used for separable
+  # compilation.
+  CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME(link_file ${cuda_target} "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}")
+
   # Add the library.
   add_executable(${cuda_target} ${_cmake_options}
     ${_generated_files}
     ${_sources}
+    ${link_file}
     )
 
+  # Add a link phase for the separable compilation if it has been enabled.  If
+  # it has been enabled then the ${cuda_target}_SEPARABLE_COMPILATION_OBJECTS
+  # variable will have been defined.
+  CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS("${link_file}" ${cuda_target} "${_options}" "${${cuda_target}_SEPARABLE_COMPILATION_OBJECTS}")
+
   target_link_libraries(${cuda_target}
     ${CUDA_LIBRARIES}
     )
index f74366b..53ab031 100644 (file)
@@ -28,7 +28,7 @@ find_path(CUPS_INCLUDE_DIR cups/cups.h )
 find_library(CUPS_LIBRARIES NAMES cups )
 
 if (CUPS_INCLUDE_DIR AND CUPS_LIBRARIES AND CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
-    include(CheckLibraryExists)
+    include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
 
     # ippDeleteAttribute is new in cups-1.1.19 (and used by kdeprint)
     CHECK_LIBRARY_EXISTS(cups ippDeleteAttribute "" CUPS_HAS_IPP_DELETE_ATTRIBUTE)
index 6acf421..09d1ba4 100644 (file)
@@ -56,7 +56,7 @@ endif()
 # prefix as the library was found, if still not found, try curses.h with the
 # default search paths.
 if(CURSES_CURSES_LIBRARY  AND  CURSES_NEED_NCURSES)
-  include(CheckLibraryExists)
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
   CHECK_LIBRARY_EXISTS("${CURSES_CURSES_LIBRARY}"
     wsyncup "" CURSES_CURSES_HAS_WSYNCUP)
 
index daae94f..79a3a1e 100644 (file)
@@ -63,7 +63,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-find_program(FLEX_EXECUTABLE flex DOC "path to the flex executable")
+find_program(FLEX_EXECUTABLE NAMES flex win_flex DOC "path to the flex executable")
 mark_as_advanced(FLEX_EXECUTABLE)
 
 find_library(FL_LIBRARY NAMES fl
@@ -93,10 +93,12 @@ if(FLEX_EXECUTABLE)
   else()
     # older versions of flex printed "/full/path/to/executable version X.Y"
     # newer versions use "basename(executable) X.Y"
-    get_filename_component(FLEX_EXE_NAME "${FLEX_EXECUTABLE}" NAME)
-    string(REGEX REPLACE "^.*${FLEX_EXE_NAME}\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\2"
+    get_filename_component(FLEX_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE)
+    get_filename_component(FLEX_EXE_EXT "${FLEX_EXECUTABLE}" EXT)
+    string(REGEX REPLACE "^.*${FLEX_EXE_NAME_WE}(${FLEX_EXE_EXT})?\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\3"
       FLEX_VERSION "${FLEX_version_output}")
-    unset(FLEX_EXE_NAME)
+    unset(FLEX_EXE_EXT)
+    unset(FLEX_EXE_NAME_WE)
   endif()
 
   #============================================================
index 24cfb87..92c14da 100644 (file)
@@ -58,7 +58,7 @@ if(WIN32)
 endif()
 
 if(UNIX)
-  include(FindX11)
+  include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake)
   find_library(FLTK_MATH_LIBRARY m)
   set( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} ${FLTK_MATH_LIBRARY})
 endif()
index cdb46be..1df2399 100644 (file)
@@ -46,6 +46,7 @@ find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
   HINTS
     ENV FREETYPE_DIR
   PATHS
+    /usr/X11R6
     /usr/local/X11R6
     /usr/local/X11
     /usr/freeware
@@ -56,6 +57,7 @@ find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
   HINTS
     ENV FREETYPE_DIR
   PATHS
+    /usr/X11R6
     /usr/local/X11R6
     /usr/local/X11
     /usr/freeware
@@ -68,6 +70,7 @@ find_library(FREETYPE_LIBRARY
     ENV FREETYPE_DIR
   PATH_SUFFIXES lib
   PATHS
+  /usr/X11R6
   /usr/local/X11R6
   /usr/local/X11
   /usr/freeware
index 6a665ad..90ff737 100644 (file)
@@ -58,8 +58,8 @@ set(GIF_LIBRARIES ${GIF_LIBRARY})
 # one.
 # http://giflib.sourcearchive.com/documentation/4.1.4/files.html
 if(GIF_INCLUDE_DIR)
-  include(CMakePushCheckState)
-  include(CheckStructHasMember)
+  include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+  include(${CMAKE_CURRENT_LIST_DIR}/CheckStructHasMember.cmake)
   CMAKE_PUSH_CHECK_STATE()
   set(GIF_VERSION 3)
   set(CMAKE_REQUIRED_INCLUDES "${GIF_INCLUDE_DIR}")
index d87945a..0d36fad 100644 (file)
@@ -19,7 +19,7 @@
 message(STATUS
   "WARNING: you are using the obsolete 'GLU' package, please use 'OpenGL' instead")
 
-include(FindOpenGL)
+include(${CMAKE_CURRENT_LIST_DIR}/FindOpenGL.cmake)
 
 if (OPENGL_GLU_FOUND)
   set (GLU_LIBRARY ${OPENGL_LIBRARIES})
index 55790ae..843d138 100644 (file)
@@ -40,25 +40,39 @@ else ()
     set(GLUT_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX")
   else ()
 
+    if (BEOS)
+
+      set(_GLUT_INC_DIR /boot/develop/headers/os/opengl)
+      set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86)
+
+    else()
+
+      find_library( GLUT_Xi_LIBRARY Xi
+        /usr/openwin/lib
+        )
+
+      find_library( GLUT_Xmu_LIBRARY Xmu
+        /usr/openwin/lib
+        )
+
+    endif ()
+
     find_path( GLUT_INCLUDE_DIR GL/glut.h
       /usr/include/GL
       /usr/openwin/share/include
       /usr/openwin/include
       /opt/graphics/OpenGL/include
       /opt/graphics/OpenGL/contrib/libglut
+      ${_GLUT_INC_DIR}
       )
 
     find_library( GLUT_glut_LIBRARY glut
       /usr/openwin/lib
+      ${_GLUT_glut_LIB_DIR}
       )
 
-    find_library( GLUT_Xi_LIBRARY Xi
-      /usr/openwin/lib
-      )
-
-    find_library( GLUT_Xmu_LIBRARY Xmu
-      /usr/openwin/lib
-      )
+    unset(_GLUT_INC_DIR)
+    unset(_GLUT_glut_LIB_DIR)
 
   endif ()
 
index 517a9ac..06cf962 100644 (file)
@@ -439,28 +439,19 @@ list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})
 
 foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
     if(_GTK2_component STREQUAL "gtk")
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
-        _GTK2_FIND_LIBRARY    (GTK2_GLIB_LIBRARY glib false true)
-
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
-        _GTK2_FIND_LIBRARY    (GTK2_GOBJECT_LIBRARY gobject false true)
-
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
-        _GTK2_FIND_LIBRARY    (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
-
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
         _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
 
         if(UNIX)
-            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-x11 false true)
             _GTK2_FIND_LIBRARY    (GTK2_GTK_LIBRARY gtk-x11 false true)
+            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-x11 false true)
         else()
-            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-win32 false true)
             _GTK2_FIND_LIBRARY    (GTK2_GTK_LIBRARY gtk-win32 false true)
+            _GTK2_FIND_LIBRARY    (GTK2_GDK_LIBRARY gdk-win32 false true)
         endif()
 
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
+
         _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
         _GTK2_FIND_LIBRARY    (GTK2_CAIRO_LIBRARY cairo false false)
 
@@ -469,35 +460,40 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
         _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
         _GTK2_FIND_LIBRARY    (GTK2_PANGO_LIBRARY pango false true)
 
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
+        _GTK2_FIND_LIBRARY    (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
+
+        _GTK2_FIND_LIBRARY    (GTK2_GIO_LIBRARY gio false true)
+
         _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
         _GTK2_FIND_LIBRARY    (GTK2_ATK_LIBRARY atk false true)
 
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
+        _GTK2_FIND_LIBRARY    (GTK2_GOBJECT_LIBRARY gobject false true)
 
-    elseif(_GTK2_component STREQUAL "gtkmm")
-
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
-        _GTK2_FIND_LIBRARY    (GTK2_GLIBMM_LIBRARY glibmm true true)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
+        _GTK2_FIND_LIBRARY    (GTK2_GLIB_LIBRARY glib false true)
 
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
-        _GTK2_FIND_LIBRARY    (GTK2_GDKMM_LIBRARY gdkmm true true)
+    elseif(_GTK2_component STREQUAL "gtkmm")
 
         _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
         _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
         _GTK2_FIND_LIBRARY    (GTK2_GTKMM_LIBRARY gtkmm true true)
 
-        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h)
-        _GTK2_FIND_LIBRARY    (GTK2_CAIROMM_LIBRARY cairomm true true)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
+        _GTK2_FIND_LIBRARY    (GTK2_GDKMM_LIBRARY gdkmm true true)
 
         _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
         _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h)
         _GTK2_FIND_LIBRARY    (GTK2_PANGOMM_LIBRARY pangomm true true)
 
-        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
-        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
-        _GTK2_FIND_LIBRARY    (GTK2_SIGC++_LIBRARY sigc true true)
+        _GTK2_FIND_LIBRARY    (GTK2_PANGOCAIRO_LIBRARY pangocairo true true)
+
+        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h)
+        _GTK2_FIND_LIBRARY    (GTK2_CAIROMM_LIBRARY cairomm true true)
 
         _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
         _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
@@ -506,6 +502,15 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
         _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
         _GTK2_FIND_LIBRARY    (GTK2_ATKMM_LIBRARY atkmm true true)
 
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
+        _GTK2_FIND_LIBRARY    (GTK2_GLIBMM_LIBRARY glibmm true true)
+
+        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
+        _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
+        _GTK2_FIND_LIBRARY    (GTK2_SIGC++_LIBRARY sigc true true)
+
+
     elseif(_GTK2_component STREQUAL "glade")
 
         _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
@@ -549,13 +554,13 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
             GTK2_GTK_LIBRARY
             GTK2_GTK_INCLUDE_DIR
 
-            GTK2_GLIB_INCLUDE_DIR
-            GTK2_GLIBCONFIG_INCLUDE_DIR
-            GTK2_GLIB_LIBRARY
-
             GTK2_GDK_INCLUDE_DIR
             GTK2_GDKCONFIG_INCLUDE_DIR
             GTK2_GDK_LIBRARY
+
+            GTK2_GLIB_INCLUDE_DIR
+            GTK2_GLIBCONFIG_INCLUDE_DIR
+            GTK2_GLIB_LIBRARY
         )
     elseif(_GTK2_component STREQUAL "gtkmm")
         FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
@@ -563,13 +568,14 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
             GTK2_GTKMM_INCLUDE_DIR
             GTK2_GTKMMCONFIG_INCLUDE_DIR
 
+            GTK2_GDKMM_INCLUDE_DIR
+            GTK2_GDKMMCONFIG_INCLUDE_DIR
+            GTK2_GDKMM_LIBRARY
+
             GTK2_GLIBMM_INCLUDE_DIR
             GTK2_GLIBMMCONFIG_INCLUDE_DIR
             GTK2_GLIBMM_LIBRARY
 
-            GTK2_GDKMM_INCLUDE_DIR
-            GTK2_GDKMMCONFIG_INCLUDE_DIR
-            GTK2_GDKMM_LIBRARY
         )
     elseif(_GTK2_component STREQUAL "glade")
         FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
index 07af0bf..f2f9dd0 100644 (file)
@@ -21,7 +21,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindCygwin)
+include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
 
 find_program(GNUPLOT_EXECUTABLE
   NAMES
index 33599be..8514164 100644 (file)
@@ -60,7 +60,7 @@
 
 # This module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
 
-include(SelectLibraryConfigurations)
+include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
 # List of the valid HDF5 components
diff --git a/Modules/FindIcotool.cmake b/Modules/FindIcotool.cmake
new file mode 100644 (file)
index 0000000..8c10177
--- /dev/null
@@ -0,0 +1,56 @@
+# - Find icotool
+# This module looks for icotool. This module defines the
+# following values:
+#  ICOTOOL_EXECUTABLE: the full path to the icotool tool.
+#  ICOTOOL_FOUND: True if icotool has been found.
+#  ICOTOOL_VERSION_STRING: the version of icotool found.
+#
+
+#=============================================================================
+# Copyright 2012 Aleksey Avdeev <solo@altlinux.ru>
+#
+# 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+find_program(ICOTOOL_EXECUTABLE
+  icotool
+)
+
+if(ICOTOOL_EXECUTABLE)
+  execute_process(
+    COMMAND ${ICOTOOL_EXECUTABLE} --version
+    OUTPUT_VARIABLE _icotool_version
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  if("${_icotool_version}" MATCHES "^icotool \\([^\\)]*\\) ([0-9\\.]+[^ \n]*).*")
+    set( ICOTOOL_VERSION_STRING
+      "${CMAKE_MATCH_1}"
+    )
+  else()
+    set( ICOTOOL_VERSION_STRING
+      ""
+    )
+  endif()
+  unset(_icotool_version)
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set ICOTOOL_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(
+  Icotool
+  REQUIRED_VARS ICOTOOL_EXECUTABLE
+  VERSION_VAR ICOTOOL_VERSION_STRING
+)
+
+mark_as_advanced(
+  ICOTOOL_EXECUTABLE
+)
index bf09616..cd97b38 100644 (file)
@@ -147,17 +147,17 @@ foreach(component ${ImageMagick_FIND_COMPONENTS}
     )
   if(component STREQUAL "Magick++")
     FIND_IMAGEMAGICK_API(Magick++ Magick++.h
-      Magick++ CORE_RL_Magick++_
+      Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8
       )
     list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
   elseif(component STREQUAL "MagickWand")
     FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
-      Wand MagickWand CORE_RL_wand_
+      Wand MagickWand CORE_RL_wand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8
       )
     list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
   elseif(component STREQUAL "MagickCore")
     FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
-      Magick MagickCore CORE_RL_magick_
+      Magick MagickCore CORE_RL_magick_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8
       )
     list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
   else()
index 0de3f79..9d708ca 100644 (file)
@@ -120,6 +120,11 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
   /usr/lib/jvm/default-java/jre/lib/{libarch}
   /usr/lib/jvm/default-java/jre/lib
   /usr/lib/jvm/default-java/lib
+  # OpenBSD specific paths for default JVM
+  /usr/local/jdk-1.7.0/jre/lib/{libarch}
+  /usr/local/jre-1.7.0/lib/{libarch}
+  /usr/local/jdk-1.6.0/jre/lib/{libarch}
+  /usr/local/jre-1.6.0/lib/{libarch}
   )
 
 set(JAVA_JVM_LIBRARY_DIRECTORIES)
@@ -153,6 +158,9 @@ set(JAVA_AWT_INCLUDE_DIRECTORIES
   /opt/sun-jdk-1.5.0.04/include
   # Debian specific path for default JVM
   /usr/lib/jvm/default-java/include
+  # OpenBSD specific path for default JVM
+  /usr/local/jdk-1.7.0/include
+  /usr/local/jdk-1.6.0/include
   )
 
 foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}")
@@ -227,6 +235,7 @@ find_path(JAVA_INCLUDE_PATH2 jni_md.h
   ${JAVA_INCLUDE_PATH}/win32
   ${JAVA_INCLUDE_PATH}/linux
   ${JAVA_INCLUDE_PATH}/freebsd
+  ${JAVA_INCLUDE_PATH}/openbsd
   ${JAVA_INCLUDE_PATH}/solaris
   ${JAVA_INCLUDE_PATH}/hp-ux
   ${JAVA_INCLUDE_PATH}/alpha
index 1b4593d..2f02b7a 100644 (file)
@@ -80,6 +80,8 @@ set(_JAVA_PATHS
   /usr/java/j2sdk1.4.2_09/bin
   /usr/lib/j2sdk1.5-sun/bin
   /opt/sun-jdk-1.5.0.04/bin
+  /usr/local/jdk-1.7.0/bin
+  /usr/local/jdk-1.6.0/bin
   )
 find_program(Java_JAVA_EXECUTABLE
   NAMES java
@@ -107,6 +109,7 @@ if(Java_JAVA_EXECUTABLE)
       # 2. OpenJDK 1.6
       # 3. GCJ 1.5
       # 4. Kaffe 1.4.2
+      # 5. OpenJDK 1.7.x on OpenBSD
       if(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+.*\".*")
         # This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer
         string( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\".*"
@@ -115,6 +118,10 @@ if(Java_JAVA_EXECUTABLE)
         # Kaffe style
         string( REGEX REPLACE "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+).*"
                 "\\1" Java_VERSION_STRING "${var}" )
+      elseif(var MATCHES "openjdk version \"[0-9]+\\.[0-9]+\\.[0-9_]+\".*")
+        # OpenJDK ver 1.7.x on OpenBSD
+        string( REGEX REPLACE "openjdk version \"([0-9]+\\.[0-9]+\\.[0-9_]+).*"
+                "\\1" Java_VERSION_STRING "${var}" )
       else()
         if(NOT Java_FIND_QUIETLY)
           message(WARNING "regex not supported: ${var}. Please report")
index a092116..70eccef 100644 (file)
@@ -245,7 +245,7 @@ endif()
 
 
 # KDE3Macros.cmake contains all the KDE specific macros
-include(KDE3Macros)
+include(${CMAKE_CURRENT_LIST_DIR}/KDE3Macros.cmake)
 
 
 macro (KDE3_PRINT_RESULTS)
index 430e45f..3167850 100644 (file)
@@ -40,9 +40,9 @@ set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
 
 get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES)
 if (NOT _LANGUAGES_ MATCHES Fortran)
-include(CheckFunctionExists)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
 else ()
-include(CheckFortranFunctionExists)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
 endif ()
 
 set(LAPACK_FOUND FALSE)
index eac25f5..a2bf0c0 100644 (file)
@@ -28,7 +28,7 @@
 find_path(LUA_INCLUDE_DIR lua.h
   HINTS
     ENV LUA_DIR
-  PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
+  PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include
   PATHS
   ~/Library/Frameworks
   /Library/Frameworks
@@ -54,7 +54,7 @@ find_library(LUA_LIBRARY
 
 if(LUA_LIBRARY)
   # include the math library for Unix
-  if(UNIX AND NOT APPLE)
+  if(UNIX AND NOT APPLE AND NOT BEOS)
     find_library(LUA_MATH_LIBRARY m)
     set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
   # For Windows and Mac, don't need to explicitly include the math library
index 0290eca..fc01c4c 100644 (file)
@@ -45,7 +45,7 @@ if(MPEG2_FOUND)
 
   #some native mpeg2 installations will depend
   #on libSDL, if found, add it in.
-  include( FindSDL )
+  include(${CMAKE_CURRENT_LIST_DIR}/FindSDL.cmake)
   if(SDL_FOUND)
     set( MPEG2_LIBRARIES ${MPEG2_LIBRARIES} ${SDL_LIBRARY})
   endif()
index 4ce4de9..143d10a 100644 (file)
@@ -78,7 +78,7 @@
 
 # include this to handle the QUIETLY and REQUIRED arguments
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-include(GetPrerequisites)
+include(${CMAKE_CURRENT_LIST_DIR}/GetPrerequisites.cmake)
 
 #
 # This part detects MPI compilers, attempting to wade through the mess of compiler names in
index a6f4503..96c4d8d 100644 (file)
@@ -58,14 +58,22 @@ else ()
     find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OSX")
 
   else()
-    # Handle HP-UX cases where we only want to find OpenGL in either hpux64
-    # or hpux32 depending on if we're doing a 64 bit build.
-    if(CMAKE_SIZEOF_VOID_P EQUAL 4)
-      set(HPUX_IA_OPENGL_LIB_PATH /opt/graphics/OpenGL/lib/hpux32/)
-    else()
-      set(HPUX_IA_OPENGL_LIB_PATH
-        /opt/graphics/OpenGL/lib/hpux64/
-        /opt/graphics/OpenGL/lib/pa20_64)
+    if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
+      # Handle HP-UX cases where we only want to find OpenGL in either hpux64
+      # or hpux32 depending on if we're doing a 64 bit build.
+      if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+        set(_OPENGL_LIB_PATH
+          /opt/graphics/OpenGL/lib/hpux32/)
+      else()
+        set(_OPENGL_LIB_PATH
+          /opt/graphics/OpenGL/lib/hpux64/
+          /opt/graphics/OpenGL/lib/pa20_64)
+      endif()
+    elseif(CMAKE_SYSTEM_NAME STREQUAL Haiku)
+      set(_OPENGL_LIB_PATH
+        /boot/develop/lib/x86)
+      set(_OPENGL_INCLUDE_PATH
+        /boot/develop/headers/os/opengl)
     endif()
 
     # The first line below is to make sure that the proper headers
@@ -80,6 +88,7 @@ else ()
       /usr/share/doc/NVIDIA_GLX-1.0/include
       /usr/openwin/share/include
       /opt/graphics/OpenGL/include /usr/X11R6/include
+      ${_OPENGL_INCLUDE_PATH}
     )
 
     find_path(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h
@@ -93,9 +102,12 @@ else ()
       PATHS /opt/graphics/OpenGL/lib
             /usr/openwin/lib
             /usr/shlib /usr/X11R6/lib
-            ${HPUX_IA_OPENGL_LIB_PATH}
+            ${_OPENGL_LIB_PATH}
     )
 
+    unset(_OPENGL_INCLUDE_PATH)
+    unset(_OPENGL_LIB_PATH)
+
     # On Unix OpenGL most certainly always requires X11.
     # Feel free to tighten up these conditions if you don't
     # think this is always true.
@@ -103,7 +115,7 @@ else ()
 
     if (OPENGL_gl_LIBRARY)
       if(NOT X11_FOUND)
-        include(FindX11)
+        include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake)
       endif()
       if (X11_FOUND)
         if (NOT APPLE)
index ad15d8c..f4a9f44 100644 (file)
@@ -1,7 +1,9 @@
 # - Finds OpenMP support
 # This module can be used to detect OpenMP support in a compiler.
 # If the compiler supports OpenMP, the flags required to compile with
-# openmp support are set.
+# OpenMP support are returned in variables for the different languages.
+# The variables may be empty if the compiler does not need a special
+# flag to support OpenMP.
 #
 # The following variables are set:
 #   OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
@@ -95,7 +97,7 @@ if(CMAKE_C_COMPILER_LOADED)
     unset(OpenMP_C_FLAG_CANDIDATES)
   else()
     _OPENMP_FLAG_CANDIDATES("C")
-    include(CheckCSourceCompiles)
+    include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
   endif()
 
   foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES})
@@ -126,7 +128,7 @@ if(CMAKE_CXX_COMPILER_LOADED)
     unset(OpenMP_CXX_FLAG_CANDIDATES)
   else()
     _OPENMP_FLAG_CANDIDATES("CXX")
-    include(CheckCXXSourceCompiles)
+    include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
 
     # use the same source for CXX as C for now
     set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
index 4a5aaba..7affca8 100644 (file)
@@ -72,7 +72,7 @@
 #  Output variables of the form OPENSCENEGRAPH_FOO
 #
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 
 set(_osg_modules_to_process)
 foreach(_osg_component ${OpenSceneGraph_FIND_COMPONENTS})
index 25d8df3..70423a7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This function is intended to be used in FindXXX.cmake modules files.
 # It handles the REQUIRED, QUIET and version-related arguments to find_package().
-# It also sets the <UPPERCASED_NAME>_FOUND variable.
+# It also sets the <packagename>_FOUND variable.
 # The package is considered found if all variables <var1>... listed contain
 # valid results, e.g. valid filepaths.
 #
 # for the failure case. This is not recommended.
 #
 # The second mode is more powerful and also supports version checking:
-#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>]
+#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [FOUND_VAR <resultVar>]
+#                                           [REQUIRED_VARS <var1>...<varN>]
 #                                           [VERSION_VAR   <versionvar>]
 #                                           [HANDLE_COMPONENTS]
 #                                           [CONFIG_MODE]
 #                                           [FAIL_MESSAGE "Custom failure message"] )
 #
-# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND
-# will be set to TRUE.
+# In this mode, the name of the result-variable can be set either to either
+# <UPPERCASED_NAME>_FOUND or <OriginalCase_Name>_FOUND using the FOUND_VAR option.
+# Other names for the result-variable are not allowed.
+# So for a Find-module named FindFooBar.cmake, the two possible names are
+# FooBar_FOUND and FOOBAR_FOUND. It is recommended to use the original case version.
+# If the FOUND_VAR option is not used, the default is <UPPERCASED_NAME>_FOUND.
+#
+# As in the simple mode, if <var1> through <varN> are all valid,
+# <packagename>_FOUND will be set to TRUE.
 # After REQUIRED_VARS the variables which are required for this package are listed.
 # Following VERSION_VAR the name of the variable can be specified which holds
 # the version of the package which has been found. If this is done, this version
@@ -35,7 +43,7 @@
 # which has been actually found, both if the version is ok or not.
 # If the package supports components, use the HANDLE_COMPONENTS option to enable
 # handling them. In this case, find_package_handle_standard_args() will report
-# which components have been found and which are missing, and the <NAME>_FOUND
+# which components have been found and which are missing, and the <packagename>_FOUND
 # variable will be set to FALSE if any of the required components (i.e. not the
 # ones listed after OPTIONAL_COMPONENTS) are missing.
 # Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
@@ -47,7 +55,7 @@
 #
 # Example for mode 1:
 #
-#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2  DEFAULT_MSG  LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
+#    find_package_handle_standard_args(LibXml2  DEFAULT_MSG  LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
 #
 # LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
 # LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
 #
 # Example for mode 2:
 #
-#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON  REQUIRED_VARS BISON_EXECUTABLE
-#                                             VERSION_VAR BISON_VERSION)
-# In this case, BISON is considered to be found if the variable(s) listed
-# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case.
-# Also the version of BISON will be checked by using the version contained
-# in BISON_VERSION.
+#    find_package_handle_standard_args(LibXslt FOUND_VAR LibXslt_FOUND
+#                                             REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS
+#                                             VERSION_VAR LibXslt_VERSION_STRING)
+# In this case, LibXslt is considered to be found if the variable(s) listed
+# after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and LibXslt_INCLUDE_DIRS
+# in this case. The result will then be stored in LibXslt_FOUND .
+# Also the version of LibXslt will be checked by using the version contained
+# in LibXslt_VERSION_STRING.
 # Since no FAIL_MESSAGE is given, the default messages will be printed.
 #
 # Another example for mode 2:
 #
 #    find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
-#    FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4  CONFIG_MODE)
+#    find_package_handle_standard_args(Automoc4  CONFIG_MODE)
 # In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4 NO_MODULE)
 # and adds an additional search directory for automoc4.
+# Here the result will be stored in AUTOMOC4_FOUND.
 # The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
 # success/error message.
 
@@ -88,8 +99,8 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindPackageMessage)
-include(CMakeParseArguments)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
 
 # internal helper macro
 macro(_FPHSA_FAILURE_MESSAGE _msg)
@@ -137,8 +148,8 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
 
 # set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
 # new extended or in the "old" mode:
-  set(options CONFIG_MODE HANDLE_COMPONENTS)
-  set(oneValueArgs FAIL_MESSAGE VERSION_VAR)
+  set(options  CONFIG_MODE  HANDLE_COMPONENTS)
+  set(oneValueArgs  FAIL_MESSAGE  VERSION_VAR  FOUND_VAR)
   set(multiValueArgs REQUIRED_VARS)
   set(_KEYWORDS_FOR_EXTENDED_MODE  ${options} ${oneValueArgs} ${multiValueArgs} )
   list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
@@ -183,20 +194,33 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
   string(TOUPPER ${_NAME} _NAME_UPPER)
   string(TOLOWER ${_NAME} _NAME_LOWER)
 
+  if(FPHSA_FOUND_VAR)
+    if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$"  OR  FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
+      set(_FOUND_VAR ${FPHSA_FOUND_VAR})
+    else()
+      message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
+    endif()
+  else()
+    set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
+  endif()
+
   # collect all variables which were not found, so they can be printed, so the
   # user knows better what went wrong (#6375)
   set(MISSING_VARS "")
   set(DETAILS "")
-  set(${_NAME_UPPER}_FOUND TRUE)
   # check if all passed variables are valid
+  unset(${_FOUND_VAR})
   foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
     if(NOT ${_CURRENT_VAR})
-      set(${_NAME_UPPER}_FOUND FALSE)
+      set(${_FOUND_VAR} FALSE)
       set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
     else()
       set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
     endif()
   endforeach()
+  if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE")
+    set(${_FOUND_VAR} TRUE)
+  endif()
 
   # component handling
   unset(FOUND_COMPONENTS_MSG)
@@ -219,7 +243,7 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
         set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
 
         if(${_NAME}_FIND_REQUIRED_${comp})
-          set(${_NAME_UPPER}_FOUND FALSE)
+          set(${_FOUND_VAR} FALSE)
           set(MISSING_VARS "${MISSING_VARS} ${comp}")
         endif()
 
@@ -273,12 +297,12 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
   if(VERSION_OK)
     set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
   else()
-    set(${_NAME_UPPER}_FOUND FALSE)
+    set(${_FOUND_VAR} FALSE)
   endif()
 
 
   # print the result:
-  if (${_NAME_UPPER}_FOUND)
+  if (${_FOUND_VAR})
     FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
   else ()
 
@@ -294,6 +318,6 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
 
   endif ()
 
-  set(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
+  set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE)
 
 endfunction()
index e908a65..5eaf207 100644 (file)
@@ -18,7 +18,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindCygwin)
+include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
 
 set(PERL_POSSIBLE_BIN_PATHS
   ${CYGWIN_INSTALL_PATH}/bin
index e9313ad..492f047 100644 (file)
@@ -38,7 +38,7 @@
 #  License text for the above reference.)
 
 # find the perl executable
-include(FindPerl)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPerl.cmake)
 
 if (PERL_EXECUTABLE)
   ### PERL_PREFIX
index 0a9a990..bffa9fb 100644 (file)
@@ -32,7 +32,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CMakeFindFrameworks)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
 # Search for the python framework on Apple.
 CMAKE_FIND_FRAMEWORKS(Python)
 
index 13f18fe..54b7c6f 100644 (file)
@@ -31,7 +31,7 @@
 #  License text for the above reference.)
 
 # look for signs of qt3 installations
-file(GLOB GLOB_TEMP_VAR /usr/lib/qt-3*/bin/qmake)
+file(GLOB GLOB_TEMP_VAR /usr/lib*/qt-3*/bin/qmake /usr/lib*/qt3*/bin/qmake)
 if(GLOB_TEMP_VAR)
   set(QT3_INSTALLED TRUE)
 endif()
@@ -43,6 +43,12 @@ if(GLOB_TEMP_VAR)
 endif()
 set(GLOB_TEMP_VAR)
 
+file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt3/bin/qmake)
+if(GLOB_TEMP_VAR)
+  set(QT3_INSTALLED TRUE)
+endif()
+set(GLOB_TEMP_VAR)
+
 # look for qt4 installations
 file(GLOB GLOB_TEMP_VAR /usr/local/qt-x11-commercial-4*/bin/qmake)
 if(GLOB_TEMP_VAR)
@@ -56,6 +62,16 @@ if(GLOB_TEMP_VAR)
 endif()
 set(GLOB_TEMP_VAR)
 
+file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt4/bin/qmake)
+if(GLOB_TEMP_VAR)
+  set(QT4_INSTALLED TRUE)
+endif()
+set(GLOB_TEMP_VAR)
+
+if (Qt_FIND_VERSION)
+  set(DESIRED_QT_VERSION "${Qt_FIND_VERSION}")
+endif ()
+
 # now find qmake
 find_program(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake PATHS "${QT_SEARCH_PATH}/bin" "$ENV{QTDIR}/bin")
 if(QT_QMAKE_EXECUTABLE_FINDQT)
@@ -87,6 +103,7 @@ find_file( QT4_QGLOBAL_H_FILE qglobal.h
   /usr/lib/qt/include/Qt
   /usr/include/Qt
   /usr/share/qt4/include/Qt
+  /usr/local/include/X11/qt4/Qt
   C:/Progra~1/qt/include/Qt )
 
 if(QT4_QGLOBAL_H_FILE)
@@ -106,6 +123,7 @@ find_file( QT3_QGLOBAL_H_FILE qglobal.h
   /usr/lib/qt/include
   /usr/include
   /usr/share/qt3/include
+  /usr/local/include/X11/qt3
   C:/Progra~1/qt/include
   /usr/include/qt3 )
 
@@ -113,15 +131,15 @@ if(QT3_QGLOBAL_H_FILE)
   set(QT3_INSTALLED TRUE)
 endif()
 
-if(QT3_INSTALLED AND QT4_INSTALLED )
+if(QT3_INSTALLED AND QT4_INSTALLED AND NOT DESIRED_QT_VERSION)
   # force user to pick if we have both
   set(DESIRED_QT_VERSION 0 CACHE STRING "Pick a version of Qt to use: 3 or 4")
 else()
   # if only one found then pick that one
-  if(QT3_INSTALLED)
+  if(QT3_INSTALLED AND NOT DESIRED_QT_VERSION EQUAL 4)
     set(DESIRED_QT_VERSION 3 CACHE STRING "Pick a version of Qt to use: 3 or 4")
   endif()
-  if(QT4_INSTALLED)
+  if(QT4_INSTALLED AND NOT DESIRED_QT_VERSION EQUAL 3)
     set(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 3 or 4")
   endif()
 endif()
@@ -129,12 +147,12 @@ endif()
 if(DESIRED_QT_VERSION MATCHES 3)
   set(Qt3_FIND_REQUIRED ${Qt_FIND_REQUIRED})
   set(Qt3_FIND_QUIETLY  ${Qt_FIND_QUIETLY})
-  include(FindQt3)
+  include(${CMAKE_CURRENT_LIST_DIR}/FindQt3.cmake)
 endif()
 if(DESIRED_QT_VERSION MATCHES 4)
   set(Qt4_FIND_REQUIRED ${Qt_FIND_REQUIRED})
   set(Qt4_FIND_QUIETLY  ${Qt_FIND_QUIETLY})
-  include(FindQt4)
+  include(${CMAKE_CURRENT_LIST_DIR}/FindQt4.cmake)
 endif()
 
 if(NOT QT3_INSTALLED AND NOT QT4_INSTALLED)
index 07b6fef..4fc8e40 100644 (file)
@@ -64,6 +64,7 @@ find_path(QT_INCLUDE_DIR qt.h
   /usr/share/qt3/include
   C:/Progra~1/qt/include
   /usr/include/qt3
+  /usr/local/include/X11/qt3
   )
 
 # if qglobal.h is not in the qt_include_dir then set
@@ -146,7 +147,7 @@ find_library(QT_QASSISTANTCLIENT_LIBRARY
 
 # Qt 3 should prefer QTDIR over the PATH
 find_program(QT_MOC_EXECUTABLE
-  NAMES moc-qt3 moc
+  NAMES moc-qt3 moc moc3 moc3-mt
   HINTS
     ENV QTDIR
   PATHS
@@ -154,6 +155,7 @@ find_program(QT_MOC_EXECUTABLE
   "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
   "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
   ${GLOB_PATHS_BIN}
+    /usr/local/lib/qt3
     /usr/local/qt
     /usr/lib/qt
     /usr/lib/qt3
@@ -170,7 +172,7 @@ endif()
 
 # Qt 3 should prefer QTDIR over the PATH
 find_program(QT_UIC_EXECUTABLE
-  NAMES uic-qt3 uic
+  NAMES uic-qt3 uic uic3 uic3-mt
   HINTS
     ENV QTDIR
   PATHS
index a84074b..4c05cc0 100644 (file)
 #       is much more flexible, but requires that FindQt4.cmake is executed before
 #       such an exported dependency file is processed.
 #
+#       Note that if using IMPORTED targets, the qtmain.lib static library is
+#       automatically linked on Windows. To disable that globally, set the
+#       QT4_NO_LINK_QTMAIN variable before finding Qt4. To disable that for a
+#       particular executable, set the QT4_NO_LINK_QTMAIN target property to
+#       True on the executable.
+#
+#  QT_INCLUDE_DIRS_NO_SYSTEM
+#        If this variable is set to TRUE, the Qt include directories
+#        in the QT_USE_FILE will NOT have the SYSTEM keyword set.
+#
 # There are also some files that need processing by some Qt tools such as moc
 # and uic.  Listed below are macros that may be used to process those files.
 #
 #
 #  Below is a detailed list of variables that FindQt4.cmake sets.
 #  QT_FOUND         If false, don't try to use Qt.
-#  QT4_FOUND        If false, don't try to use Qt 4.
+#  Qt4_FOUND        If false, don't try to use Qt 4.
+#  QT4_FOUND        If false, don't try to use Qt 4. This variable is for compatibility only.
 #
 #  QT_VERSION_MAJOR The major version of Qt found.
 #  QT_VERSION_MINOR The minor version of Qt found.
@@ -376,8 +387,8 @@ if(QT_QT_LIBRARY)
 endif()
 
 
-include(CheckCXXSymbolExists)
-include(MacroAddFileDependencies)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSymbolExists.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/MacroAddFileDependencies.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
 set(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake)
@@ -414,6 +425,15 @@ macro (_QT4_ADJUST_LIB_VARS _camelCaseBasename)
           set_property(TARGET Qt4::${_camelCaseBasename}        PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" )
         endif()
       endif ()
+      set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES
+          "${QT_${basename}_INCLUDE_DIR}"
+      )
+      string(REGEX REPLACE "^QT" "" _stemname ${basename})
+      set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY
+        INTERFACE_COMPILE_DEFINITIONS
+          "QT_${_stemname}_LIB"
+      )
     endif()
 
     # If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these
@@ -490,50 +510,72 @@ function(_QT4_QUERY_QMAKE VAR RESULT)
   endif()
 endfunction()
 
+function(_QT4_GET_VERSION_COMPONENTS VERSION RESULT_MAJOR RESULT_MINOR RESULT_PATCH)
+  string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}")
+  string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}")
+  string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}")
 
-set(QT4_INSTALLED_VERSION_TOO_OLD FALSE)
+  set(${RESULT_MAJOR} ${QT_VERSION_MAJOR} PARENT_SCOPE)
+  set(${RESULT_MINOR} ${QT_VERSION_MINOR} PARENT_SCOPE)
+  set(${RESULT_PATCH} ${QT_VERSION_PATCH} PARENT_SCOPE)
+endfunction()
 
-get_filename_component(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME)
-# check for qmake
-# Debian uses qmake-qt4
-# macports' Qt uses qmake-mac
-find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 qmake-mac
-  PATHS
-    ENV QTDIR
-    "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]"
-  PATH_SUFFIXES bin
-  DOC "The qmake executable for the Qt installation to use"
-)
-
-# double check that it was a Qt4 qmake, if not, re-find with different names
-if (QT_QMAKE_EXECUTABLE)
-
-  if(QT_QMAKE_EXECUTABLE_LAST)
-    string(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED)
+function(_QT4_FIND_QMAKE QMAKE_NAMES QMAKE_RESULT VERSION_RESULT)
+  list(LENGTH QMAKE_NAMES QMAKE_NAMES_LEN)
+  if(${QMAKE_NAMES_LEN} EQUAL 0)
+    return()
   endif()
+  list(GET QMAKE_NAMES 0 QMAKE_NAME)
 
-  set(QT_QMAKE_EXECUTABLE_LAST "${QT_QMAKE_EXECUTABLE}" CACHE INTERNAL "" FORCE)
+  get_filename_component(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME)
 
-  _qt4_query_qmake(QT_VERSION QTVERSION)
+  find_program(QT_QMAKE_EXECUTABLE NAMES ${QMAKE_NAME}
+    PATHS
+      ENV QTDIR
+      "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]"
+    PATH_SUFFIXES bin
+    DOC "The qmake executable for the Qt installation to use"
+  )
+
+  set(major 0)
+  if (QT_QMAKE_EXECUTABLE)
+    _qt4_query_qmake(QT_VERSION QTVERSION)
+    _qt4_get_version_components("${QTVERSION}" major minor patch)
+  endif()
+
+  if (NOT QT_QMAKE_EXECUTABLE OR NOT "${major}" EQUAL 4)
+    set(curr_qmake "${QT_QMAKE_EXECUTABLE}")
+    set(curr_qt_version "${QTVERSION}")
 
-  # check for qt3 qmake and then try and find qmake4 or qmake-qt4 in the path
-  if(NOT QTVERSION)
     set(QT_QMAKE_EXECUTABLE NOTFOUND CACHE FILEPATH "" FORCE)
-    find_program(QT_QMAKE_EXECUTABLE NAMES qmake4 qmake-qt4 PATHS
-      "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin"
-      "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin"
-      $ENV{QTDIR}/bin
-      DOC "The qmake executable for the Qt installation to use"
-      )
-    if(QT_QMAKE_EXECUTABLE)
-      _qt4_query_qmake(QT_VERSION QTVERSION)
+    list(REMOVE_AT QMAKE_NAMES 0)
+    _qt4_find_qmake("${QMAKE_NAMES}" QMAKE QTVERSION)
+
+    _qt4_get_version_components("${QTVERSION}" major minor patch)
+    if (NOT ${major} EQUAL 4)
+      # Restore possibly found qmake and it's version; these are used later
+      # in error message if incorrect version is found
+      set(QT_QMAKE_EXECUTABLE "${curr_qmake}" CACHE FILEPATH "" FORCE)
+      set(QTVERSION "${curr_qt_version}")
     endif()
+
   endif()
 
-endif ()
+
+  set(${QMAKE_RESULT} "${QT_QMAKE_EXECUTABLE}" PARENT_SCOPE)
+  set(${VERSION_RESULT} "${QTVERSION}" PARENT_SCOPE)
+endfunction()
+
+
+set(QT4_INSTALLED_VERSION_TOO_OLD FALSE)
+
+set(_QT4_QMAKE_NAMES qmake qmake4 qmake-qt4 qmake-mac)
+_qt4_find_qmake("${_QT4_QMAKE_NAMES}" QT_QMAKE_EXECUTABLE QTVERSION)
 
 if (QT_QMAKE_EXECUTABLE AND QTVERSION)
 
+  _qt4_get_version_components("${QTVERSION}" QT_VERSION_MAJOR QT_VERSION_MINOR QT_VERSION_PATCH)
+
   # ask qmake for the mkspecs directory
   # we do this first because QT_LIBINFIX might be set
   if (NOT QT_MKSPECS_DIR  OR  QT_QMAKE_CHANGED)
@@ -644,7 +686,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
       find_path(QT_QTCORE_INCLUDE_DIR QtCore
                 HINTS ${qt_headers} ${QT_LIBRARY_DIR}
                 PATH_SUFFIXES QtCore qt4/QtCore
+                NO_DEFAULT_PATH
         )
+      if(NOT QT_QTCORE_INCLUDE_DIR)
+        find_path(QT_QTCORE_INCLUDE_DIR QtCore
+                  HINTS ${qt_headers} ${QT_LIBRARY_DIR}
+                  PATH_SUFFIXES QtCore qt4/QtCore
+          )
+      endif()
 
       # Set QT_HEADERS_DIR based on finding QtCore header
       if(QT_QTCORE_INCLUDE_DIR)
@@ -832,16 +881,20 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
   endforeach()
 
   if(Q_WS_WIN)
-    set(QT_MODULES ${QT_MODULES} QAxContainer QAxServer)
-    # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR
-    find_path(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt
-      PATHS ${QT_HEADERS_DIR}/ActiveQt
-      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-      )
-    find_path(QT_QAXSERVER_INCLUDE_DIR ActiveQt
-      PATHS ${QT_HEADERS_DIR}/ActiveQt
-      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
-      )
+    if (QT_QAXCONTAINER_FOUND)
+      set(QT_MODULES ${QT_MODULES} QAxContainer)
+      # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR
+      find_path(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt
+        PATHS ${QT_HEADERS_DIR}/ActiveQt
+        NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+        )
+    endif()
+    if (QT_QAXSERVER_FOUND)
+      find_path(QT_QAXSERVER_INCLUDE_DIR ActiveQt
+        PATHS ${QT_HEADERS_DIR}/ActiveQt
+        NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+        )
+    endif()
   endif()
 
   # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR
@@ -938,12 +991,59 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
   ############################################
 
 
+  macro(_qt4_add_target_depends_internal _QT_MODULE _PROPERTY)
+    if (TARGET Qt4::${_QT_MODULE})
+      foreach(_DEPEND ${ARGN})
+        set(_VALID_DEPENDS)
+        if (TARGET Qt4::Qt${_DEPEND})
+          list(APPEND _VALID_DEPENDS Qt4::Qt${_DEPEND})
+        endif()
+        if (_VALID_DEPENDS)
+          set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
+            ${_PROPERTY}
+            "${_VALID_DEPENDS}"
+          )
+        endif()
+        set(_VALID_DEPENDS)
+      endforeach()
+    endif()
+  endmacro()
+
+  macro(_qt4_add_target_depends _QT_MODULE)
+    get_target_property(_configs Qt4::${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+    foreach(_config ${_configs})
+      _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} ${ARGN})
+    endforeach()
+    set(_configs)
+  endmacro()
+
+  macro(_qt4_add_target_private_depends _QT_MODULE)
+    get_target_property(_configs ${_QT_MODULE} IMPORTED_CONFIGURATIONS)
+    foreach(_config ${_configs})
+      _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config} ${ARGN})
+    endforeach()
+    set(_configs)
+  endmacro()
+
+
   # Set QT_xyz_LIBRARY variable and add
   # library include path to QT_INCLUDES
   _QT4_ADJUST_LIB_VARS(QtCore)
+  set_property(TARGET Qt4::QtCore APPEND PROPERTY
+    INTERFACE_INCLUDE_DIRECTORIES
+      "${QT_MKSPECS_DIR}/default"
+      ${QT_INCLUDE_DIR}
+  )
+  set_property(TARGET Qt4::QtCore PROPERTY
+    INTERFACE_QT_MAJOR_VERSION 4
+  )
+  set_property(TARGET Qt4::QtCore APPEND PROPERTY
+    COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION
+  )
 
   foreach(QT_MODULE ${QT_MODULES})
     _QT4_ADJUST_LIB_VARS(${QT_MODULE})
+    _qt4_add_target_depends(${QT_MODULE} Core)
   endforeach()
 
   _QT4_ADJUST_LIB_VARS(QtAssistant)
@@ -954,10 +1054,81 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
   # platform dependent libraries
   if(Q_WS_WIN)
     _QT4_ADJUST_LIB_VARS(qtmain)
-    _QT4_ADJUST_LIB_VARS(QAxServer)
-    _QT4_ADJUST_LIB_VARS(QAxContainer)
+
+    if(QT_QAXSERVER_FOUND)
+      _QT4_ADJUST_LIB_VARS(QAxServer)
+      set_property(TARGET Qt4::QAxServer PROPERTY
+        INTERFACE_QT4_NO_LINK_QTMAIN ON
+      )
+      set_property(TARGET Qt4::QAxServer APPEND PROPERTY
+        COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN)
+    endif()
+
+    if(QT_QAXCONTAINER_FOUND)
+      _QT4_ADJUST_LIB_VARS(QAxContainer)
+    endif()
+  endif()
+
+  # Only public dependencies are listed here.
+  # Eg, QtDBus links to QtXml, but users of QtDBus do not need to
+  # link to QtXml because QtDBus only uses it internally, not in public
+  # headers.
+  # Everything depends on QtCore, but that is covered above already
+  _qt4_add_target_depends(Qt3Support Sql Gui Network)
+  if (TARGET Qt4::Qt3Support)
+    # An additional define is required for QT3_SUPPORT
+    set_property(TARGET Qt4::Qt3Support APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS QT3_SUPPORT)
+  endif()
+  _qt4_add_target_depends(QtDeclarative Script Gui)
+  _qt4_add_target_depends(QtDesigner Gui)
+  _qt4_add_target_depends(QtHelp Gui)
+  _qt4_add_target_depends(QtMultimedia Gui)
+  _qt4_add_target_depends(QtOpenGL Gui)
+  _qt4_add_target_depends(QtSvg Gui)
+  _qt4_add_target_depends(QtWebKit Gui Network)
+
+  _qt4_add_target_private_depends(Qt3Support Xml)
+  if(QT_VERSION VERSION_GREATER 4.6)
+    _qt4_add_target_private_depends(QtSvg Xml)
+  endif()
+  _qt4_add_target_private_depends(QtDBus Xml)
+  _qt4_add_target_private_depends(QtUiTools Xml Gui)
+  _qt4_add_target_private_depends(QtHelp Sql Xml Network)
+  _qt4_add_target_private_depends(QtXmlPatterns Network)
+  _qt4_add_target_private_depends(QtScriptTools Gui)
+  _qt4_add_target_private_depends(QtWebKit XmlPatterns)
+  _qt4_add_target_private_depends(QtDeclarative XmlPatterns Svg Sql Gui)
+  _qt4_add_target_private_depends(QtMultimedia Gui)
+  _qt4_add_target_private_depends(QtOpenGL Gui)
+  if(QT_QAXSERVER_FOUND)
+    _qt4_add_target_private_depends(QAxServer Gui)
+  endif()
+  if(QT_QAXCONTAINER_FOUND)
+    _qt4_add_target_private_depends(QAxContainer Gui)
+  endif()
+  _qt4_add_target_private_depends(phonon Gui)
+  if(QT_QTDBUS_FOUND)
+    _qt4_add_target_private_depends(phonon DBus)
   endif()
 
+  if (WIN32 AND NOT QT4_NO_LINK_QTMAIN)
+    set(_isExe $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
+    set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
+    set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:QT4_NO_LINK_QTMAIN>>>)
+    set(_isPolicyNEW $<TARGET_POLICY:CMP0020>)
+    get_target_property(_configs Qt4::QtCore IMPORTED_CONFIGURATIONS)
+    foreach(_config ${_configs})
+      set_property(TARGET Qt4::QtCore APPEND PROPERTY
+        IMPORTED_LINK_INTERFACE_LIBRARIES_${_config}
+          $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
+      )
+    endforeach()
+    unset(_configs)
+    unset(_isExe)
+    unset(_isWin32)
+    unset(_isNotExcluded)
+    unset(_isPolicyNEW)
+  endif()
 
   #######################################
   #
@@ -982,13 +1153,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
   endif()
 
   find_program(QT_MOC_EXECUTABLE
-    NAMES moc-qt4 moc
+    NAMES moc-qt4 moc moc4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
 
   find_program(QT_UIC_EXECUTABLE
-    NAMES uic-qt4 uic
+    NAMES uic-qt4 uic uic4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
@@ -1018,13 +1189,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
     )
 
   find_program(QT_LUPDATE_EXECUTABLE
-    NAMES lupdate-qt4 lupdate
+    NAMES lupdate-qt4 lupdate lupdate4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
 
   find_program(QT_LRELEASE_EXECUTABLE
-    NAMES lrelease-qt4 lrelease
+    NAMES lrelease-qt4 lrelease lrelease4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
@@ -1036,13 +1207,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
     )
 
   find_program(QT_DESIGNER_EXECUTABLE
-    NAMES designer-qt4 designer
+    NAMES designer-qt4 designer designer4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
 
   find_program(QT_LINGUIST_EXECUTABLE
-    NAMES linguist-qt4 linguist
+    NAMES linguist-qt4 linguist linguist4
     PATHS ${QT_BINARY_DIR}
     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
     )
@@ -1170,11 +1341,6 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
 
   include("${_qt4_current_dir}/Qt4Macros.cmake")
 
-  # set version variables
-  string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}")
-  string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}")
-  string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}")
-
 endif()
 
 #support old QT_MIN_VERSION if set, but not if version is supplied by find_package()
@@ -1209,7 +1375,7 @@ else()
 
 endif()
 
-if (QT_VERSION_MAJOR GREATER 4)
+if (NOT QT_VERSION_MAJOR EQUAL 4)
     set(VERSION_MSG "Found unsuitable Qt version \"${QTVERSION}\" from ${QT_QMAKE_EXECUTABLE}")
     set(QT4_FOUND FALSE)
     if(Qt4_FIND_REQUIRED)
@@ -1220,7 +1386,7 @@ if (QT_VERSION_MAJOR GREATER 4)
       endif()
     endif()
 else()
-  FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt4
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt4 FOUND_VAR Qt4_FOUND
     REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS}
     VERSION_VAR QTVERSION
     )
@@ -1235,5 +1401,6 @@ endif()
 set (QT_MOC_EXE ${QT_MOC_EXECUTABLE} )
 set (QT_UIC_EXE ${QT_UIC_EXECUTABLE} )
 set( QT_QT_LIBRARY "")
-set(QT_FOUND ${QT4_FOUND})
+set(QT4_FOUND ${Qt4_FOUND})
+set(QT_FOUND ${Qt4_FOUND})
 
index 119cb63..c02158f 100644 (file)
@@ -46,15 +46,24 @@ set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby)
 # if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8
 if(Ruby_FIND_VERSION_MAJOR  AND  Ruby_FIND_VERSION_MINOR)
    set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}")
+   # we can't construct that if only major version is given
+   set(_RUBY_POSSIBLE_EXECUTABLE_NAMES
+       ruby${Ruby_FIND_VERSION_MAJOR}.${Ruby_FIND_VERSION_MINOR}
+       ruby${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}
+       ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
 else()
    set(Ruby_FIND_VERSION_SHORT_NODOT "18")
 endif()
 
-set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES} ruby1.9 ruby19)
+if(NOT Ruby_FIND_VERSION_EXACT)
+  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19)
 
-# if we want a version below 1.9, also look for ruby 1.8
-if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
-   set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES} ruby1.8 ruby18)
+  # if we want a version below 1.9, also look for ruby 1.8
+  if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
+    list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18)
+  endif()
+
+  list(REMOVE_DUPLICATES _RUBY_POSSIBLE_EXECUTABLE_NAMES)
 endif()
 
 find_program(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
index f2e9f25..fec142e 100644 (file)
@@ -122,7 +122,7 @@ if(SDL_LIBRARY_TEMP)
   if(SDLMAIN_LIBRARY AND NOT SDL_BUILDING_LIBRARY)
     list(FIND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" _SDL_MAIN_INDEX)
     if(_SDL_MAIN_INDEX EQUAL -1)
-      list(APPEND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}")
+      set(SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" ${SDL_LIBRARY_TEMP})
     endif()
     unset(_SDL_MAIN_INDEX)
   endif()
index 4cae032..30d74ac 100644 (file)
@@ -40,7 +40,7 @@ find_path(SDL_IMAGE_INCLUDE_DIR SDL_image.h
   HINTS
     ENV SDLIMAGEDIR
     ENV SDLDIR
-  PATH_SUFFIXES SDL SDL12 SDL11
+  PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
 )
 
 if(NOT SDL_IMAGE_LIBRARY AND SDLIMAGE_LIBRARY)
@@ -52,6 +52,7 @@ find_library(SDL_IMAGE_LIBRARY
   HINTS
     ENV SDLIMAGEDIR
     ENV SDLDIR
+  PATH_SUFFIXES lib
 )
 
 if(SDL_IMAGE_INCLUDE_DIR AND EXISTS "${SDL_IMAGE_INCLUDE_DIR}/SDL_image.h")
index 666fc6e..8ca7cc3 100644 (file)
@@ -40,7 +40,7 @@ find_path(SDL_MIXER_INCLUDE_DIR SDL_mixer.h
   HINTS
     ENV SDLMIXERDIR
     ENV SDLDIR
-  PATH_SUFFIXES SDL SDL12 SDL11
+  PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
 )
 
 if(NOT SDL_MIXER_LIBRARY AND SDLMIXER_LIBRARY)
@@ -52,6 +52,7 @@ find_library(SDL_MIXER_LIBRARY
   HINTS
     ENV SDLMIXERDIR
     ENV SDLDIR
+  PATH_SUFFIXES lib
 )
 
 if(SDL_MIXER_INCLUDE_DIR AND EXISTS "${SDL_MIXER_INCLUDE_DIR}/SDL_mixer.h")
index d8f479f..ca707af 100644 (file)
@@ -40,7 +40,7 @@ find_path(SDL_NET_INCLUDE_DIR SDL_net.h
   HINTS
     ENV SDLNETDIR
     ENV SDLDIR
-  PATH_SUFFIXES SDL SDL12 SDL11
+  PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
 )
 
 if(NOT SDL_NET_LIBRARY AND SDLNET_LIBRARY)
@@ -52,6 +52,7 @@ find_library(SDL_NET_LIBRARY
   HINTS
     ENV SDLNETDIR
     ENV SDLDIR
+  PATH_SUFFIXES lib
 )
 
 if(SDL_NET_INCLUDE_DIR AND EXISTS "${SDL_NET_INCLUDE_DIR}/SDL_net.h")
index 5ff50be..efd2658 100644 (file)
@@ -77,7 +77,7 @@ find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h
   HINTS
     ENV SDLSOUNDDIR
     ENV SDLDIR
-  PATH_SUFFIXES SDL SDL12 SDL11
+  PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
   )
 
 find_library(SDL_SOUND_LIBRARY
@@ -85,6 +85,7 @@ find_library(SDL_SOUND_LIBRARY
   HINTS
     ENV SDLSOUNDDIR
     ENV SDLDIR
+  PATH_SUFFIXES lib
   )
 
 if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
index 2cc5ee2..bb0ca91 100644 (file)
@@ -40,7 +40,7 @@ find_path(SDL_TTF_INCLUDE_DIR SDL_ttf.h
   HINTS
     ENV SDLTTFDIR
     ENV SDLDIR
-  PATH_SUFFIXES SDL SDL12 SDL11
+  PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
 )
 
 if(NOT SDL_TTF_LIBRARY AND SDLTTF_LIBRARY)
@@ -52,6 +52,7 @@ find_library(SDL_TTF_LIBRARY
   HINTS
     ENV SDLTTFDIR
     ENV SDLDIR
+  PATH_SUFFIXES lib
 )
 
 if(SDL_TTF_INCLUDE_DIR AND EXISTS "${SDL_TTF_INCLUDE_DIR}/SDL_ttf.h")
index 7726dce..fd28642 100644 (file)
@@ -18,7 +18,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindCygwin)
+include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
 
 find_program(SELF_PACKER_FOR_EXECUTABLE
   upx
index a032496..b797805 100644 (file)
@@ -1,9 +1,13 @@
 #
 # ---- Find Squish
-# This module can be used to find Squish (currently support is aimed at version 3).
+# This module can be used to find Squish. Currently Squish versions 3 and 4 are supported.
 #
 # ---- Variables and Macros
 #  SQUISH_FOUND                    If false, don't try to use Squish
+#  SQUISH_VERSION                  The full version of Squish found
+#  SQUISH_VERSION_MAJOR            The major version of Squish found
+#  SQUISH_VERSION_MINOR            The minor version of Squish found
+#  SQUISH_VERSION_PATCH            The patch version of Squish found
 #
 #  SQUISH_INSTALL_DIR              The Squish installation directory (containing bin, lib, etc)
 #  SQUISH_SERVER_EXECUTABLE        The squishserver executable
 #  SQUISH_SERVER_EXECUTABLE_FOUND  Was the server executable found?
 #  SQUISH_CLIENT_EXECUTABLE_FOUND  Was the client executable found?
 #
-# macro SQUISH_ADD_TEST(testName applicationUnderTest testSuite testCase)
+# It provides the function squish_v4_add_test() for adding a squish test to cmake using Squish 4.x:
+#
+#   squish_v4_add_test(cmakeTestName AUT targetName SUITE suiteName TEST squishTestName
+#                   [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] )
+#
+# The arguments have the following meaning:
+#   cmakeTestName: this will be used as the first argument for add_test()
+#   AUT targetName: the name of the cmake target which will be used as AUT, i.e. the
+#                   executable which will be tested.
+#   SUITE suiteName: this is either the full path to the squish suite, or just the
+#                    last directory of the suite, i.e. the suite name. In this case
+#                    the CMakeLists.txt which calls squish_add_test() must be located
+#                    in the parent directory of the suite directory.
+#   TEST squishTestName: the name of the squish test, i.e. the name of the subdirectory
+#                        of the test inside the suite directory.
+#   SETTINGSGROUP group: if specified, the given settings group will be used for executing the test.
+#                        If not specified, the groupname will be "CTest_<username>"
+#   PRE_COMMAND command:  if specified, the given command will be executed before starting the squish test.
+#   POST_COMMAND command: same as PRE_COMMAND, but after the squish test has been executed.
+#
+# ---- Typical Use
+#   enable_testing()
+#   find_package(Squish 4.0)
+#   if (SQUISH_FOUND)
+#      squish_v4_add_test(myTestName AUT myApp SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite TEST someSquishTest SETTINGSGROUP myGroup )
+#   endif ()
+#
+#
+# For users of Squish version 3.x the macro squish_v3_add_test() is provided:
+#   squish_v3_add_test(testName applicationUnderTest testCase envVars testWrapper)
+#   Use this macro to add a test using Squish 3.x.
 #
 # ---- Typical Use
 #  enable_testing()
 #  find_package(Squish)
 #  if (SQUISH_FOUND)
-#    SQUISH_ADD_TEST(myTestName myApplication testSuiteName testCaseName)
+#    squish_v3_add_test(myTestName myApplication testCase envVars testWrapper)
 #  endif ()
 #
+# macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars testWrapper)
+#   This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead.
+
 
 #=============================================================================
 # Copyright 2008-2009 Kitware, Inc.
+# Copyright 2012 Alexander Neundorf
 #
 # Distributed under the OSI-approved BSD License (the "License");
 # see accompanying file Copyright.txt for details.
@@ -36,6 +74,9 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
+
+include(CMakeParseArguments)
+
 set(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.")
 set(SQUISH_SERVER_EXECUTABLE_STRING "The squishserver executable program.")
 set(SQUISH_CLIENT_EXECUTABLE_STRING "The squishclient executable program.")
@@ -74,21 +115,36 @@ if(SQUISH_INSTALL_DIR)
 
   # find the client program
   if(NOT SQUISH_CLIENT_EXECUTABLE)
-    find_program(SQUISH_CLIENT_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishrunner DOC "The ${SQUISH_CLIENT_EXECUTABLE_STRING}")
+    find_program(SQUISH_CLIENT_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishrunner${CMAKE_EXECUTABLE_SUFFIX} DOC "The ${SQUISH_CLIENT_EXECUTABLE_STRING}")
   endif()
 
   # find the server program
   if(NOT SQUISH_SERVER_EXECUTABLE)
-    find_program(SQUISH_SERVER_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishserver DOC "The ${SQUISH_SERVER_EXECUTABLE_STRING}")
+    find_program(SQUISH_SERVER_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishserver${CMAKE_EXECUTABLE_SUFFIX} DOC "The ${SQUISH_SERVER_EXECUTABLE_STRING}")
   endif()
 
 else()
   set(SQUISH_INSTALL_DIR_FOUND 0)
 endif()
 
+
+set(SQUISH_VERSION)
+set(SQUISH_VERSION_MAJOR )
+set(SQUISH_VERSION_MINOR )
+set(SQUISH_VERSION_PATCH )
+
 # record if executables are set
 if(SQUISH_CLIENT_EXECUTABLE)
   set(SQUISH_CLIENT_EXECUTABLE_FOUND 1)
+  execute_process(COMMAND "${SQUISH_CLIENT_EXECUTABLE}" --version
+                  OUTPUT_VARIABLE _squishVersionOutput
+                  ERROR_QUIET )
+  if("${_squishVersionOutput}" MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+).*$")
+    set(SQUISH_VERSION_MAJOR "${CMAKE_MATCH_1}")
+    set(SQUISH_VERSION_MINOR "${CMAKE_MATCH_2}")
+    set(SQUISH_VERSION_PATCH "${CMAKE_MATCH_3}")
+    set(SQUISH_VERSION "${SQUISH_VERSION_MAJOR}.${SQUISH_VERSION_MINOR}.${SQUISH_VERSION_PATCH}" )
+  endif()
 else()
   set(SQUISH_CLIENT_EXECUTABLE_FOUND 0)
 endif()
@@ -100,16 +156,21 @@ else()
 endif()
 
 # record if Squish was found
-set(SQUISH_FOUND 1)
-foreach(var SQUISH_INSTALL_DIR_FOUND SQUISH_CLIENT_EXECUTABLE_FOUND SQUISH_SERVER_EXECUTABLE_FOUND)
-  if(NOT ${var})
-    set(SQUISH_FOUND 0)
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Squish  REQUIRED_VARS  SQUISH_INSTALL_DIR SQUISH_CLIENT_EXECUTABLE SQUISH_SERVER_EXECUTABLE
+                                          VERSION_VAR  SQUISH_VERSION )
+
+
+set(_SQUISH_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}")
+
+macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper)
+  if("${SQUISH_VERSION_MAJOR}" STREQUAL "4")
+    message(STATUS "Using squish_v3_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
   endif()
-endforeach()
 
-macro(SQUISH_ADD_TEST testName testAUT testCase envVars testWraper)
   add_test(${testName}
     ${CMAKE_COMMAND} -V -VV
+    "-Dsquish_version:STRING=3"
     "-Dsquish_aut:STRING=${testAUT}"
     "-Dsquish_server_executable:STRING=${SQUISH_SERVER_EXECUTABLE}"
     "-Dsquish_client_executable:STRING=${SQUISH_CLIENT_EXECUTABLE}"
@@ -117,10 +178,84 @@ macro(SQUISH_ADD_TEST testName testAUT testCase envVars testWraper)
     "-Dsquish_test_case:STRING=${testCase}"
     "-Dsquish_env_vars:STRING=${envVars}"
     "-Dsquish_wrapper:STRING=${testWraper}"
-    -P "${CMAKE_ROOT}/Modules/SquishTestScript.cmake"
+    "-Dsquish_module_dir:STRING=${_SQUISH_MODULE_DIR}"
+    -P "${_SQUISH_MODULE_DIR}/SquishTestScript.cmake"
     )
   set_tests_properties(${testName}
     PROPERTIES FAIL_REGULAR_EXPRESSION "FAILED;ERROR;FATAL"
     )
 endmacro()
 
+
+macro(SQUISH_ADD_TEST)
+  message(STATUS "Using squish_add_test() is deprecated, use squish_v3_add_test() instead.")
+  squish_v3_add_test(${ARGV})
+endmacro()
+
+
+function(SQUISH_V4_ADD_TEST testName)
+
+  if(NOT "${SQUISH_VERSION_MAJOR}" STREQUAL "4")
+    message(STATUS "Using squish_v4_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
+  endif()
+
+  set(oneValueArgs AUT SUITE TEST SETTINGSGROUP PRE_COMMAND POST_COMMAND)
+
+  cmake_parse_arguments(_SQUISH "" "${oneValueArgs}" "" ${ARGN} )
+
+  if(_SQUISH_UNPARSED_ARGUMENTS)
+    message(FATAL_ERROR "Unknown keywords given to SQUISH_ADD_TEST(): \"${_SQUISH_UNPARSED_ARGUMENTS}\"")
+  endif()
+
+  if(NOT _SQUISH_AUT)
+    message(FATAL_ERROR "Required argument AUT not given for SQUISH_ADD_TEST()")
+  endif()
+
+  if(NOT _SQUISH_SUITE)
+    message(FATAL_ERROR "Required argument SUITE not given for SQUISH_ADD_TEST()")
+  endif()
+
+  if(NOT _SQUISH_TEST)
+    message(FATAL_ERROR "Required argument TEST not given for SQUISH_ADD_TEST()")
+  endif()
+
+  get_target_property(testAUTLocation ${_SQUISH_AUT} LOCATION)
+  get_filename_component(testAUTDir ${testAUTLocation} PATH)
+  get_filename_component(testAUTName ${testAUTLocation} NAME)
+
+  get_filename_component(absTestSuite "${_SQUISH_SUITE}" ABSOLUTE)
+  if(NOT EXISTS "${absTestSuite}")
+    message(FATAL_ERROR "Could not find squish test suite ${_SQUISH_SUITE} (checked ${absTestSuite})")
+  endif()
+
+  set(absTestCase "${absTestSuite}/${_SQUISH_TEST}")
+  if(NOT EXISTS "${absTestCase}")
+    message(FATAL_ERROR "Could not find squish testcase ${_SQUISH_TEST} (checked ${absTestCase})")
+  endif()
+
+  if(NOT _SQUISH_SETTINGSGROUP)
+    set(_SQUISH_SETTINGSGROUP "CTest_$ENV{LOGNAME}")
+  endif()
+
+  add_test(${testName}
+    ${CMAKE_COMMAND} -V -VV
+    "-Dsquish_version:STRING=4"
+    "-Dsquish_aut:STRING=${testAUTName}"
+    "-Dsquish_aut_dir:STRING=${testAUTDir}"
+    "-Dsquish_server_executable:STRING=${SQUISH_SERVER_EXECUTABLE}"
+    "-Dsquish_client_executable:STRING=${SQUISH_CLIENT_EXECUTABLE}"
+    "-Dsquish_libqtdir:STRING=${QT_LIBRARY_DIR}"
+    "-Dsquish_test_suite:STRING=${absTestSuite}"
+    "-Dsquish_test_case:STRING=${_SQUISH_TEST}"
+    "-Dsquish_env_vars:STRING=${envVars}"
+    "-Dsquish_wrapper:STRING=${testWraper}"
+    "-Dsquish_module_dir:STRING=${_SQUISH_MODULE_DIR}"
+    "-Dsquish_settingsgroup:STRING=${_SQUISH_SETTINGSGROUP}"
+    "-Dsquish_pre_command:STRING=${_SQUISH_PRE_COMMAND}"
+    "-Dsquish_post_command:STRING=${_SQUISH_POST_COMMAND}"
+    -P "${_SQUISH_MODULE_DIR}/SquishTestScript.cmake"
+    )
+  set_tests_properties(${testName}
+    PROPERTIES FAIL_REGULAR_EXPRESSION "FAIL;FAILED;ERROR;FATAL"
+    )
+endfunction()
index 0d20da5..f649ddc 100644 (file)
@@ -44,9 +44,9 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CMakeFindFrameworks)
-include(FindTclsh)
-include(FindWish)
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/FindTclsh.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/FindWish.cmake)
 
 if(TCLSH_VERSION_STRING)
   set(TCL_TCLSH_VERSION "${TCLSH_VERSION_STRING}")
@@ -82,6 +82,10 @@ set(TCLTK_POSSIBLE_LIB_PATHS
   "${TK_LIBRARY_PATH}"
   "${TCL_TCLSH_PATH_PARENT}/lib"
   "${TK_WISH_PATH_PARENT}/lib"
+  /usr/local/lib/tcl/tcl8.5
+  /usr/local/lib/tcl/tk8.5
+  /usr/local/lib/tcl/tcl8.4
+  /usr/local/lib/tcl/tk8.4
   )
 
 if(WIN32)
@@ -168,6 +172,10 @@ set(TCLTK_POSSIBLE_INCLUDE_PATHS
   /usr/include/tcl8.3
   /usr/include/tcl8.2
   /usr/include/tcl8.0
+  /usr/local/include/tcl8.5
+  /usr/local/include/tk8.5
+  /usr/local/include/tcl8.4
+  /usr/local/include/tk8.4
   )
 
 if(WIN32)
index e66f7bc..8dda94a 100644 (file)
@@ -34,7 +34,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindTCL)
+include(${CMAKE_CURRENT_LIST_DIR}/FindTCL.cmake)
 
 get_filename_component(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
 get_filename_component(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
index a69e3f1..87caadc 100644 (file)
@@ -15,7 +15,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindCygwin)
+include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
 
 find_program(BASH
   bash
index fa090ff..0dede2d 100644 (file)
@@ -62,7 +62,7 @@ set(VTK_DIR_MESSAGE "VTK not found.  Set the VTK_DIR cmake cache entry to the ${
 if(_VTK_40_ALLOW AND VTK_DIR)
   if(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake)
     set(VTK_FOUND 1)
-    include(UseVTKConfig40) # No VTKConfig; load VTK 4.0 settings.
+    include(${CMAKE_CURRENT_LIST_DIR}/UseVTKConfig40.cmake) # No VTKConfig; load VTK 4.0 settings.
   endif()
 endif()
 
@@ -117,7 +117,7 @@ if(_VTK_40_ALLOW AND NOT VTK_DIR)
   if(VTK_DIR)
     if(EXISTS ${VTK_DIR}/UseVTK.cmake AND NOT EXISTS ${VTK_DIR}/VTKConfig.cmake)
       set(VTK_FOUND 1)
-      include(UseVTKConfig40) # No VTKConfig; load VTK 4.0 settings.
+      include(${CMAKE_CURRENT_LIST_DIR}/UseVTKConfig40.cmake) # No VTKConfig; load VTK 4.0 settings.
     else()
       # We found the wrong version.  Pretend we did not find it.
       set(VTK_DIR "VTK_DIR-NOTFOUND" CACHE PATH "The ${VTK_DIR_DESCRIPTION}" FORCE)
index a1dd47f..4da98b1 100644 (file)
@@ -17,7 +17,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(FindCygwin)
+include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
 
 find_program(WGET_EXECUTABLE
   wget
index e12dc0a..3cd3cef 100644 (file)
@@ -336,8 +336,8 @@ if (UNIX)
   endif ()
 
   if(X11_FOUND)
-    include(CheckFunctionExists)
-    include(CheckLibraryExists)
+    include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+    include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
 
     # Translated from an autoconf-generated configure script.
     # See libs.m4 in autoconf's m4 directory.
@@ -417,7 +417,7 @@ if (UNIX)
     # Build the final list of libraries.
     set(X11_LIBRARIES ${X11_X_PRE_LIBS} ${X11_LIBRARIES} ${X11_X_EXTRA_LIBS})
 
-    include(FindPackageMessage)
+    include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
     FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
       "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
   else ()
index fb7421e..bc1e48a 100644 (file)
@@ -46,7 +46,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgUtil/SceneView>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSG osg/PositionAttitudeTransform)
 OSG_FIND_LIBRARY(OSG osg)
 
index 1c8eb50..121aefc 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgAnimation/Animation>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGANIMATION osgAnimation/Animation)
 OSG_FIND_LIBRARY(OSGANIMATION osgAnimation)
 
index 76272aa..1ed94a1 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgDB/DatabasePager>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGDB osgDB/DatabasePager)
 OSG_FIND_LIBRARY(OSGDB osgDB)
 
index 3314750..1f1d59f 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgFX/BumpMapping>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGFX osgFX/BumpMapping)
 OSG_FIND_LIBRARY(OSGFX osgFX)
 
index fd9317d..e60f7f5 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgGA/FlightManipulator>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGGA osgGA/FlightManipulator)
 OSG_FIND_LIBRARY(OSGGA osgGA)
 
index 2394c05..a430ad6 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgIntrospection/Reflection>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGINTROSPECTION osgIntrospection/Reflection)
 OSG_FIND_LIBRARY(OSGINTROSPECTION osgIntrospection)
 
index 9e58570..32d6def 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgManipulator/TrackballDragger>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGMANIPULATOR osgManipulator/TrackballDragger)
 OSG_FIND_LIBRARY(OSGMANIPULATOR osgManipulator)
 
index 2f93389..1a6ae0b 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgParticle/FireEffect>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGPARTICLE osgParticle/FireEffect)
 OSG_FIND_LIBRARY(OSGPARTICLE osgParticle)
 
index f89e25f..412502a 100644 (file)
@@ -43,7 +43,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgPresentation/SlideEventHandler>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGPRESENTATION osgPresentation/SlideEventHandler)
 OSG_FIND_LIBRARY(OSGPRESENTATION osgPresentation)
 
index 2c3800b..ea561a0 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgProducer/OsgSceneHandler>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGPRODUCER osgProducer/OsgSceneHandler)
 OSG_FIND_LIBRARY(OSGPRODUCER osgProducer)
 
index ddc9128..c7e8fee 100644 (file)
@@ -43,7 +43,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgQt/GraphicsWindowQt>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGQT osgQt/GraphicsWindowQt)
 OSG_FIND_LIBRARY(OSGQT osgQt)
 
index ca87b56..f3be0bf 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgShadow/ShadowTexture>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGSHADOW osgShadow/ShadowTexture)
 OSG_FIND_LIBRARY(OSGSHADOW osgShadow)
 
index 2fc5105..19cd175 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgSim/ImpostorSprite>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGSIM osgSim/ImpostorSprite)
 OSG_FIND_LIBRARY(OSGSIM osgSim)
 
index eafd8fb..4b7249e 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgTerrain/Terrain>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGTERRAIN osgTerrain/Terrain)
 OSG_FIND_LIBRARY(OSGTERRAIN osgTerrain)
 
index 57655b1..41683c7 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgText/Text>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGTEXT osgText/Text)
 OSG_FIND_LIBRARY(OSGTEXT osgText)
 
index eeabc34..85c1177 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgUtil/SceneView>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGUTIL osgUtil/SceneView)
 OSG_FIND_LIBRARY(OSGUTIL osgUtil)
 
index 2afd761..d2252f4 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgViewer/Viewer>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGVIEWER osgViewer/Viewer)
 OSG_FIND_LIBRARY(OSGVIEWER osgViewer)
 
index 1fa6764..ae2d95c 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgVolume/Volume>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGVOLUME osgVolume/Volume)
 OSG_FIND_LIBRARY(OSGVOLUME osgVolume)
 
index 1a51e60..cb2e12f 100644 (file)
@@ -42,7 +42,7 @@
 # #include <osg/PositionAttitudeTransform>
 # #include <osgWidget/Widget>
 
-include(Findosg_functions)
+include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)
 OSG_FIND_PATH   (OSGWIDGET osgWidget/Widget)
 OSG_FIND_LIBRARY(OSGWIDGET osgWidget)
 
index 5030bcc..4179f7b 100644 (file)
@@ -26,7 +26,7 @@
 #  HAVE_ISYSTEM      - true required to replace -I by -isystem on g++
 #
 # For convenience include Use_wxWindows.cmake in your project's
-# CMakeLists.txt using include(Use_wxWindows).
+# CMakeLists.txt using include(${CMAKE_CURRENT_LIST_DIR}/Use_wxWindows.cmake).
 #
 # USAGE
 #  set(WXWINDOWS_USE_GL 1)
index ce23d5d..892ebc6 100644 (file)
@@ -47,7 +47,7 @@
 #     ...
 #   };
 #
-# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BUILD_DIR}
+# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BINARY_DIR}
 # called somelib_export.h containing the macros SOMELIB_EXPORT, SOMELIB_NO_EXPORT,
 # SOMELIB_DEPRECATED, SOMELIB_DEPRECATED_EXPORT and SOMELIB_DEPRECATED_NO_EXPORT.
 # The resulting file should be installed with other headers in the library.
@@ -156,16 +156,12 @@ macro(_test_compiler_hidden_visibility)
 
   if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
     set(GCC_TOO_OLD TRUE)
-    message(WARNING "GCC version older than 4.2")
   elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
     set(GCC_TOO_OLD TRUE)
-    message(WARNING "GCC version older than 4.2")
   elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
     set(_INTEL_TOO_OLD TRUE)
-    message(WARNING "Intel compiler older than 12.0")
   endif()
 
-
   # Exclude XL here because it misinterprets -fvisibility=hidden even though
   # the check_cxx_compiler_flag passes
   # http://www.cdash.org/CDash/testDetails.php?test=109109951&build=1419259
index 8f2754e..18f449d 100644 (file)
@@ -5,6 +5,7 @@
 #
 # It uses various tools to obtain the list of required shared library files:
 #   dumpbin (Windows)
+#   objdump (MinGW on Windows)
 #   ldd (Linux/Unix)
 #   otool (Mac OSX)
 # The following functions are provided by this module:
@@ -567,6 +568,17 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
     message("warning: target '${target}' does not exist...")
   endif()
 
+  set(gp_cmd_paths ${gp_cmd_paths}
+    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "/usr/local/bin"
+    "/usr/bin"
+    )
+
   # <setup-gp_tool-vars>
   #
   # Try to choose the right tool by default. Caller can set gp_tool prior to
@@ -574,14 +586,28 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
   #
   if("${gp_tool}" STREQUAL "")
     set(gp_tool "ldd")
+
     if(APPLE)
       set(gp_tool "otool")
     endif()
+
     if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har!
-      set(gp_tool "dumpbin")
+      find_program(gp_dumpbin "dumpbin" PATHS ${gp_cmd_paths})
+      if(gp_dumpbin)
+        set(gp_tool "dumpbin")
+      else() # Try harder. Maybe we're on MinGW
+        set(gp_tool "objdump")
+      endif()
     endif()
   endif()
 
+  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
+
+  if(NOT gp_cmd)
+    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
+    return()
+  endif()
+
   set(gp_tool_known 0)
 
   if("${gp_tool}" STREQUAL "ldd")
@@ -612,30 +638,22 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
     set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
   endif()
 
+  if("${gp_tool}" STREQUAL "objdump")
+    set(gp_cmd_args "-p")
+    set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$")
+    set(gp_regex_error "")
+    set(gp_regex_fallback "")
+    set(gp_regex_cmp_count 1)
+    set(gp_tool_known 1)
+  endif()
+
   if(NOT gp_tool_known)
     message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
     message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
-    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
+    message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.")
     return()
   endif()
 
-  set(gp_cmd_paths ${gp_cmd_paths}
-    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
-    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
-    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
-    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
-    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
-    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
-    "/usr/local/bin"
-    "/usr/bin"
-    )
-
-  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
-
-  if(NOT gp_cmd)
-    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
-    return()
-  endif()
 
   if("${gp_tool}" STREQUAL "dumpbin")
     # When running dumpbin, it also needs the "Common7/IDE" directory in the
index bd97501..2479d68 100644 (file)
@@ -182,6 +182,10 @@ if(MSVC)
     MSVCRT_FILES_FOR_VERSION(11)
   endif()
 
+  if(MSVC12)
+    MSVCRT_FILES_FOR_VERSION(12)
+  endif()
+
   if(CMAKE_INSTALL_MFC_LIBRARIES)
     if(MSVC70)
       set(__install__libs ${__install__libs}
@@ -330,6 +334,10 @@ if(MSVC)
     if(MSVC11)
       MFC_FILES_FOR_VERSION(11)
     endif()
+
+    if(MSVC12)
+      MFC_FILES_FOR_VERSION(12)
+    endif()
   endif()
 
   foreach(lib
index ffc425e..59a444b 100644 (file)
@@ -37,6 +37,9 @@
   ;Set compression
   SetCompressor @CPACK_NSIS_COMPRESSOR@
 
+  ;Require administrator access
+  RequestExecutionLevel admin
+
 @CPACK_NSIS_DEFINES@
 
   !include Sections.nsh
@@ -119,7 +122,7 @@ Var AR_RegFlags
  "exit_${SecName}:"
 !macroend
 
-!macro RemoveSection SecName
+!macro RemoveSection_CPack SecName
   ;  This macro is used to call section's Remove_... macro
   ;from the uninstaller.
   ;Input: section index constant name specified in Section command.
@@ -841,7 +844,7 @@ Section "Uninstall"
   DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
 
   ; Removes all optional components
-  !insertmacro SectionList "RemoveSection"
+  !insertmacro SectionList "RemoveSection_CPack"
 
   !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
 
index 81ba365..e5d9434 100644 (file)
@@ -21,6 +21,7 @@ set(__AIX_COMPILER_GNU 1)
 macro(__aix_compiler_gnu lang)
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
-  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G,-brtl,-bnoipath")
+  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G,-bnoipath")
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall")  # +s, flag for exe link to use shared lib
+  set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
 endmacro()
index 1f94152..abf3855 100644 (file)
@@ -21,7 +21,7 @@ set(__AIX_COMPILER_XL 1)
 macro(__aix_compiler_xl lang)
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
-  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-G -Wl,-brtl,-bnoipath")  # -shared
+  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-G -Wl,-bnoipath")  # -shared
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall")  # +s, flag for exe link to use shared lib
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS " ")
   set(CMAKE_SHARED_MODULE_${lang}_FLAGS  " ")
index de7a856..528873c 100644 (file)
@@ -19,6 +19,7 @@ endif()
 set(__DARWIN_COMPILER_CLANG 1)
 
 macro(__darwin_compiler_clang lang)
+  set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
   set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
   set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot")
index d953503..5fee7e3 100644 (file)
@@ -19,6 +19,7 @@ endif()
 set(__DARWIN_COMPILER_GNU 1)
 
 macro(__darwin_compiler_gnu lang)
+  set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
   # GNU does not have -shared on OS X
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
   set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
index 4e7e99c..2e6b71e 100644 (file)
@@ -256,6 +256,24 @@ set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK
 if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
   set(CMAKE_FIND_FRAMEWORK FIRST)
 endif()
+
+# Older OS X linkers do not report their framework search path
+# with -v but "man ld" documents the following locations.
+set(CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+  ${_CMAKE_OSX_SYSROOT_PATH}/Library/Frameworks
+  ${_CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks
+  )
+if(_CMAKE_OSX_SYSROOT_PATH)
+  # Treat some paths as implicit so we do not override the SDK versions.
+  list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+    /System/Library/Frameworks)
+endif()
+if("${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5")
+  # Older OS X tools had more implicit paths.
+  list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
+    ${_CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks)
+endif()
+
 # set up the default search directories for frameworks
 set(CMAKE_SYSTEM_FRAMEWORK_PATH
   ~/Library/Frameworks
@@ -263,6 +281,23 @@ set(CMAKE_SYSTEM_FRAMEWORK_PATH
   /Network/Library/Frameworks
   /System/Library/Frameworks)
 
+# Warn about known system mis-configuration case.
+if(CMAKE_OSX_SYSROOT)
+  get_property(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE)
+  if(NOT _IN_TC AND
+     NOT IS_SYMLINK "${CMAKE_OSX_SYSROOT}/Library/Frameworks"
+     AND IS_SYMLINK "${CMAKE_OSX_SYSROOT}/Library/Frameworks/Frameworks")
+    message(WARNING "The SDK Library/Frameworks path\n"
+      " ${CMAKE_OSX_SYSROOT}/Library/Frameworks\n"
+      "is not set up correctly on this system.  "
+      "This is known to occur when installing Xcode 3.2.6:\n"
+      " http://bugs.python.org/issue14018\n"
+      "The problem may cause build errors that report missing system frameworks.  "
+      "Fix your SDK symlinks to resolve this issue and avoid this warning."
+      )
+  endif()
+endif()
+
 # default to searching for application bundles first
 if(NOT DEFINED CMAKE_FIND_APPBUNDLE)
   set(CMAKE_FIND_APPBUNDLE FIRST)
index cf18501..ce4d3ce 100644 (file)
@@ -1,16 +1,14 @@
-if(EXISTS /usr/include/dlfcn.h)
-  set(CMAKE_DL_LIBS "")
-  set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
-  set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
-  set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")            # -pic
-  set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")       # -shared
-  set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")         # +s, flag for exe link to use shared lib
-  set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")       # -rpath
-  set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")   # : or empty
-  set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
-  set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
-  set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
-endif()
+set(CMAKE_DL_LIBS "")
+set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")            # -pic
+set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")       # -shared
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")         # +s, flag for exe link to use shared lib
+set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")       # -rpath
+set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")   # : or empty
+set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
+set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
 
 # Shared libraries with no builtin soname may not be linked safely by
 # specifying the file path.
index 7318275..1004eb3 100644 (file)
@@ -1,15 +1,13 @@
-if(EXISTS /usr/include/dlfcn.h)
-  set(CMAKE_DL_LIBS "")
-  set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
-  set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
-  set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")            # -pic
-  set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")       # -shared
-  set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")         # +s, flag for exe link to use shared lib
-  set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")       # -rpath
-  set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")   # : or empty
-  set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
-  set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
-  set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
-endif()
+set(CMAKE_DL_LIBS "")
+set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")            # -pic
+set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")       # -shared
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")         # +s, flag for exe link to use shared lib
+set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")       # -rpath
+set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")   # : or empty
+set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
+set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
 
 include(Platform/UnixPaths)
index df240e0..53cabed 100644 (file)
@@ -16,3 +16,7 @@ if(NOT CMAKE_PLATFORM_RUNTIME_PATH)
 endif()
 
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_OPENBSD_VERSIONING 1)
+
+# OpenBSD policy requires that shared libraries be installed without
+# executable permission.
+set(CMAKE_INSTALL_SO_NO_EXE 1)
index 1662ac9..307230e 100644 (file)
@@ -64,7 +64,7 @@ set(CMAKE_CREATE_CONSOLE_EXE "${_tC}" )
 set (CMAKE_BUILD_TYPE Debug CACHE STRING
      "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.")
 
-set (CMAKE_EXE_LINKER_FLAGS_INIT "${_tM} -lS:10000000 -lSc:10000000 ")
+set (CMAKE_EXE_LINKER_FLAGS_INIT "${_tM} -lS:1048576 -lSc:4098 -lH:1048576 -lHc:8192 ")
 set (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "-v")
 set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "-v")
 set (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT})
index 58da8c5..8a9d630 100644 (file)
@@ -50,7 +50,7 @@ elseif(MSVC_CXX_ARCHITECTURE_ID)
 elseif(MSVC_Fortran_ARCHITECTURE_ID)
   set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}")
 endif()
-set (CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:YES ${_MACHINE_ARCH_FLAG}")
+set (CMAKE_EXE_LINKER_FLAGS_INIT "/INCREMENTAL:YES ${_MACHINE_ARCH_FLAG}")
 set (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug")
 set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug")
 
index 1f28c50..e03b601 100644 (file)
@@ -41,6 +41,7 @@ set(WIN32 1)
 if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
   set(CMAKE_CREATE_WIN32_EXE "/subsystem:windowsce /entry:WinMainCRTStartup")
   set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:windowsce /entry:mainACRTStartup")
+  set(WINCE 1)
 else()
   set(CMAKE_CREATE_WIN32_EXE "/subsystem:windows")
   set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:console")
@@ -80,6 +81,7 @@ if(NOT MSVC_VERSION)
 
   set(MSVC10)
   set(MSVC11)
+  set(MSVC12)
   set(MSVC60)
   set(MSVC70)
   set(MSVC71)
@@ -87,7 +89,9 @@ if(NOT MSVC_VERSION)
   set(MSVC90)
   set(CMAKE_COMPILER_2005)
   set(CMAKE_COMPILER_SUPPORTS_PDBTYPE)
-  if(NOT "${_compiler_version}" VERSION_LESS 17)
+  if(NOT "${_compiler_version}" VERSION_LESS 18)
+    set(MSVC12 1)
+  elseif(NOT "${_compiler_version}" VERSION_LESS 17)
     set(MSVC11 1)
   elseif(NOT  "${_compiler_version}" VERSION_LESS 16)
     set(MSVC10 1)
@@ -106,7 +110,7 @@ if(NOT MSVC_VERSION)
   endif()
 endif()
 
-if(MSVC_C_ARCHITECTURE_ID MATCHES 64)
+if(MSVC_C_ARCHITECTURE_ID MATCHES 64 OR MSVC_CXX_ARCHITECTURE_ID MATCHES 64)
   set(CMAKE_CL_64 1)
 else()
   set(CMAKE_CL_64 0)
@@ -122,7 +126,7 @@ endif()
 # default to Debug builds
 set(CMAKE_BUILD_TYPE_INIT Debug)
 
-if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
+if(WINCE)
   string(TOUPPER "${MSVC_C_ARCHITECTURE_ID}" _MSVC_C_ARCHITECTURE_ID_UPPER)
   string(TOUPPER "${MSVC_CXX_ARCHITECTURE_ID}" _MSVC_CXX_ARCHITECTURE_ID_UPPER)
 
@@ -154,18 +158,23 @@ else()
     set(_FLAGS_CXX " /GR /GX")
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
   endif()
+
+  if(MSVC_VERSION LESS 1310)
+    set(_FLAGS_C   " /Zm1000${_FLAGS_C}")
+    set(_FLAGS_CXX " /Zm1000${_FLAGS_CXX}")
+  endif()
 endif()
 
 set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
 
 # executable linker flags
 set (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
-# set the stack size and the machine type
+# set the machine type
 set(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID})
 if(NOT _MACHINE_ARCH_FLAG)
   set(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID})
 endif()
-if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
+if(WINCE)
   if(_MACHINE_ARCH_FLAG MATCHES "ARM")
     set(_MACHINE_ARCH_FLAG "THUMB")
   elseif(_MACHINE_ARCH_FLAG MATCHES "SH")
@@ -173,7 +182,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
   endif()
 endif()
 set (CMAKE_EXE_LINKER_FLAGS_INIT
-    "${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_MACHINE_ARCH_FLAG}")
+    "${CMAKE_EXE_LINKER_FLAGS_INIT} /machine:${_MACHINE_ARCH_FLAG}")
 
 # add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
 # on versions that support it
@@ -233,7 +242,7 @@ macro(__windows_compiler_msvc lang)
   set(CMAKE_${lang}_LINK_EXECUTABLE
     "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> <OBJECTS> /link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
 
-  set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3 /Zm1000${_FLAGS_${lang}}")
+  set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3${_FLAGS_${lang}}")
   set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}")
   set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
   set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
index 6db5da1..88dc8ec 100644 (file)
@@ -260,7 +260,7 @@ if(Q_WS_X11)
   # X11 libraries Qt always depends on
   set(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xext_LIB} ${X11_X11_LIB})
 
-  set(CMAKE_THREAD_PREFER_PTHREADS 1)
+  set(CMAKE_THREAD_PREFER_PTHREAD 1)
   find_package(Threads)
   if(CMAKE_USE_PTHREADS_INIT)
     set(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${CMAKE_THREAD_LIBS_INIT})
index 251d57c..f6c8476 100644 (file)
@@ -451,14 +451,22 @@ function(qt4_use_modules _target _link_type)
   endif()
   foreach(_module ${modules})
     string(TOUPPER ${_module} _ucmodule)
-    if (NOT QT_QT${_ucmodule}_FOUND)
-      message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
-    endif()
-    if ("${_ucmodule}" STREQUAL "MAIN")
-      message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.")
+    set(_targetPrefix QT_QT${_ucmodule})
+    if (_ucmodule STREQUAL QAXCONTAINER OR _ucmodule STREQUAL QAXSERVER)
+      if (NOT QT_Q${_ucmodule}_FOUND)
+        message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+      endif()
+      set(_targetPrefix QT_Q${_ucmodule})
+    else()
+      if (NOT QT_QT${_ucmodule}_FOUND)
+        message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.")
+      endif()
+      if ("${_ucmodule}" STREQUAL "MAIN")
+        message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.")
+      endif()
     endif()
-    target_link_libraries(${_target} ${link_type} ${QT_QT${_ucmodule}_LIBRARY})
-    set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${QT_QT${_ucmodule}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default)
-    set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${QT_QT${_ucmodule}_COMPILE_DEFINITIONS})
+    target_link_libraries(${_target} ${link_type} ${${_targetPrefix}_LIBRARIES})
+    set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${${_targetPrefix}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default)
+    set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${${_targetPrefix}_COMPILE_DEFINITIONS})
   endforeach()
 endfunction()
index 62137bb..5bca064 100644 (file)
@@ -62,7 +62,7 @@ macro( select_library_configurations basename )
         # if the generator supports configuration types or CMAKE_BUILD_TYPE
         # is set, then set optimized and debug options.
         if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
-            set( ${basename}_LIBRARY )
+            set( ${basename}_LIBRARY "" )
             foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE )
                 list( APPEND ${basename}_LIBRARY optimized "${_libname}" )
             endforeach()
diff --git a/Modules/Squish4RunTestCase.bat b/Modules/Squish4RunTestCase.bat
new file mode 100755 (executable)
index 0000000..ad1cc8c
--- /dev/null
@@ -0,0 +1,24 @@
+set SQUISHSERVER=%1
+set SQUISHRUNNER=%2
+set TESTSUITE=%3
+set TESTCASE=%4
+set AUT=%5
+set AUTDIR=%6
+set SETTINGSGROUP=%7
+
+%SQUISHSERVER% --stop
+
+echo "Adding AUT... %SQUISHSERVER% --config addAUT %AUT% %AUTDIR%"
+%SQUISHSERVER% --config addAUT "%AUT%" "%AUTDIR%"
+
+echo "Starting the squish server... %SQUISHSERVER%"
+start /B %SQUISHSERVER%
+
+echo "Running the test case...%SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%"
+%SQUISHRUNNER% --testsuite "%TESTSUITE%" --testcase "%TESTCASE%"
+set returnValue=%ERRORLEVEL%
+
+echo "Stopping the squish server... %SQUISHSERVER% --stop"
+%SQUISHSERVER% --stop
+
+exit /B %returnValue%
diff --git a/Modules/Squish4RunTestCase.sh b/Modules/Squish4RunTestCase.sh
new file mode 100755 (executable)
index 0000000..abd5deb
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+SQUISHSERVER=$1
+SQUISHRUNNER=$2
+TESTSUITE=$3
+TESTCASE=$4
+AUT=$5
+AUTDIR=$6
+SETTINGSGROUP=$7
+
+$SQUISHSERVER --stop > /dev/null 2>&1
+
+echo "Adding AUT... $SQUISHSERVER --settingsGroup $SETTINGSGROUP --config addAUT $AUT $AUTDIR"
+$SQUISHSERVER --settingsGroup "$SETTINGSGROUP" --config addAUT "$AUT" "$AUTDIR" || exit -1
+# sleep 1
+
+echo "Starting the squish server... $SQUISHSERVER --daemon"
+$SQUISHSERVER --daemon || exit -1
+# sleep 2
+
+echo "Running the test case...$SQUISHRUNNER --settingsGroup $SETTINGSGROUP --testsuite $TESTSUITE --testcase $TESTCASE"
+$SQUISHRUNNER --settingsGroup "$SETTINGSGROUP" --testsuite "$TESTSUITE" --testcase "$TESTCASE"
+returnValue=$?
+
+echo "Stopping the squish server... $SQUISHSERVER --stop"
+$SQUISHSERVER --stop
+
+exit $returnValue
index d565305..f794b3e 100644 (file)
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
-
 # print out the variable that we are using
 message(STATUS "squish_aut='${squish_aut}'")
+message(STATUS "squish_aut_dir='${squish_aut_dir}'")
 
+message(STATUS "squish_version='${squish_version}'")
 message(STATUS "squish_server_executable='${squish_server_executable}'")
 message(STATUS "squish_client_executable='${squish_client_executable}'")
 message(STATUS "squish_libqtdir ='${squish_libqtdir}'")
+message(STATUS "squish_test_suite='${squish_test_suite}'")
 message(STATUS "squish_test_case='${squish_test_case}'")
 message(STATUS "squish_wrapper='${squish_wrapper}'")
 message(STATUS "squish_env_vars='${squish_env_vars}'")
+message(STATUS "squish_module_dir='${squish_module_dir}'")
+message(STATUS "squish_settingsgroup='${squish_settingsgroup}'")
+message(STATUS "squish_pre_command='${squish_pre_command}'")
+message(STATUS "squish_post_command='${squish_post_command}'")
 
 # parse enviornment variables
 foreach(i ${squish_env_vars})
@@ -48,25 +53,38 @@ if (QT4_INSTALLED)
   set ( ENV{${SQUISH_LIBQTDIR}} ${squish_libqtdir} )
 endif ()
 
+if(squish_pre_command)
+  message(STATUS "Executing pre command: ${squish_pre_command}")
+  execute_process(COMMAND "${squish_pre_command}")
+endif()
+
 # run the test
-if (WIN32)
-  execute_process(
-    COMMAND ${CMAKE_ROOT}/Modules/SquishRunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
-    RESULT_VARIABLE test_rv
-    )
-endif ()
+if("${squish_version}" STREQUAL "4")
+  if (WIN32)
+    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup}
+                    RESULT_VARIABLE test_rv )
+  elseif(UNIX)
+    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup}
+                    RESULT_VARIABLE test_rv )
+  endif ()
 
-if (UNIX)
-  execute_process(
-    COMMAND ${CMAKE_ROOT}/Modules/SquishRunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
-    RESULT_VARIABLE test_rv
-    )
-endif ()
+else()
+
+  if (WIN32)
+    execute_process(COMMAND ${squish_module_dir}/SquishRunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
+                    RESULT_VARIABLE test_rv )
+  elseif(UNIX)
+    execute_process(COMMAND ${squish_module_dir}/SquishRunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
+                    RESULT_VARIABLE test_rv )
+  endif ()
+endif()
+
+if(squish_post_command)
+  message(STATUS "Executing post command: ${squish_post_command}")
+  execute_process(COMMAND "${squish_post_command}")
+endif()
 
 # check for an error with running the test
 if(NOT "${test_rv}" STREQUAL "0")
   message(FATAL_ERROR "Error running Squish test")
 endif()
-
-
-
index 4aa4023..060b3a4 100644 (file)
@@ -16,7 +16,7 @@
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
-include(CheckIncludeFileCXX)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckIncludeFileCXX.cmake)
 
 if(NOT CMAKE_NO_ANSI_STREAM_HEADERS)
   CHECK_INCLUDE_FILE_CXX(iostream CMAKE_ANSI_STREAM_HEADERS)
index 1b823a8..0438695 100644 (file)
@@ -3,11 +3,19 @@
 # has already been loaded.  See FindJava.cmake for information on how to
 # load Java into your CMake project.
 #
-# add_jar(TARGET_NAME SRC1 SRC2 .. SRCN RCS1 RCS2 .. RCSN)
-#
-# This command creates a <TARGET_NAME>.jar. It compiles the given source
-# files (SRC) and adds the given resource files (RCS) to the jar file.
-# If only resource files are given then just a jar file is created.
+# add_jar(target_name
+#         [SOURCES] source1 [source2 ...] [resource1 ...]
+#         [INCLUDE_JARS jar1 [jar2 ...]]
+#        )
+#
+# This command creates a <target_name>.jar. It compiles the given source files
+# (source) and adds the given resource files (resource) to the jar file. If
+# only resource files are given then just a jar file is created. The list of
+# include jars are added to the classpath when compiling the java sources and
+# also to the dependencies of the target. INCLUDE_JARS also accepts other
+# target names created by add_jar. For backwards compatibility, jar files
+# listed as sources are ignored (as they have been since the first version of
+# this module).
 #
 # Additional instructions:
 #   To add compile flags to the target you can set these flags with
 # (To distribute this file outside of CMake, substitute the full
 #  License text for the above reference.)
 
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
+
 function (__java_copy_file src dest comment)
     add_custom_command(
         OUTPUT  ${dest}
@@ -205,7 +215,10 @@ set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.c
 set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
 
 function(add_jar _TARGET_NAME)
-    set(_JAVA_SOURCE_FILES ${ARGN})
+
+    cmake_parse_arguments(_add_jar "" "" "SOURCES;INCLUDE_JARS" ${ARGN})
+
+    set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS})
 
     if (NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
       set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -257,6 +270,7 @@ function(add_jar _TARGET_NAME)
     set(_JAVA_CLASS_FILES)
     set(_JAVA_COMPILE_FILES)
     set(_JAVA_DEPENDS)
+    set(_JAVA_COMPILE_DEPENDS)
     set(_JAVA_RESOURCE_FILES)
     foreach(_JAVA_SOURCE_FILE ${_JAVA_SOURCE_FILES})
         get_filename_component(_JAVA_EXT ${_JAVA_SOURCE_FILE} EXT)
@@ -264,18 +278,18 @@ function(add_jar _TARGET_NAME)
         get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH)
         get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE)
 
-        file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR} ${_JAVA_FULL})
-        file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL})
-        string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN)
-        string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN)
-        if (${_BIN_LEN} LESS ${_SRC_LEN})
-            set(_JAVA_REL_PATH ${_JAVA_REL_BINARY_PATH})
-        else ()
-            set(_JAVA_REL_PATH ${_JAVA_REL_SOURCE_PATH})
-        endif ()
-        get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH)
-
         if (_JAVA_EXT MATCHES ".java")
+            file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR} ${_JAVA_FULL})
+            file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL})
+            string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN)
+            string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN)
+            if (${_BIN_LEN} LESS ${_SRC_LEN})
+                set(_JAVA_REL_PATH ${_JAVA_REL_BINARY_PATH})
+            else ()
+                set(_JAVA_REL_PATH ${_JAVA_REL_SOURCE_PATH})
+            endif ()
+            get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH)
+
             list(APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE})
             set(_JAVA_CLASS_FILE "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_REL_PATH}/${_JAVA_FILE}.class")
             set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES} ${_JAVA_CLASS_FILE})
@@ -284,7 +298,7 @@ function(add_jar _TARGET_NAME)
                 OR _JAVA_EXT MATCHES ".war"
                 OR _JAVA_EXT MATCHES ".ear"
                 OR _JAVA_EXT MATCHES ".sar")
-            list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_SOURCE_FILE})
+            # Ignored for backward compatibility
 
         elseif (_JAVA_EXT STREQUAL "")
             list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
@@ -298,6 +312,25 @@ function(add_jar _TARGET_NAME)
         endif ()
     endforeach()
 
+    foreach(_JAVA_INCLUDE_JAR ${_add_jar_INCLUDE_JARS})
+        if (TARGET ${_JAVA_INCLUDE_JAR})
+            get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE)
+            if (_JAVA_JAR_PATH)
+                set(CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_PATH_FINAL}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_JAR_PATH}")
+                list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH})
+                list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR})
+                list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_INCLUDE_JAR})
+            else ()
+                message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar")
+            endif ()
+        else ()
+            set(CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_PATH_FINAL}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_INCLUDE_JAR}")
+            list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}")
+            list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}")
+            list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}")
+        endif ()
+    endforeach()
+
     # create an empty java_class_filelist
     if (NOT EXISTS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist)
         file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "")
@@ -314,7 +347,7 @@ function(add_jar _TARGET_NAME)
                 -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
                 ${_JAVA_COMPILE_FILES}
             COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
-            DEPENDS ${_JAVA_COMPILE_FILES}
+            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_DEPENDS}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
         )
index e8166f4..f05a3d5 100644 (file)
@@ -25,7 +25,11 @@ if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
   set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG)
 endif()
 
-include_directories(${QT_INCLUDE_DIR})
+if(QT_INCLUDE_DIRS_NO_SYSTEM)
+  include_directories(${QT_INCLUDE_DIR})
+else(QT_INCLUDE_DIRS_NO_SYSTEM)
+  include_directories(SYSTEM ${QT_INCLUDE_DIR})
+endif(QT_INCLUDE_DIRS_NO_SYSTEM)
 
 set(QT_LIBRARIES "")
 set(QT_LIBRARIES_PLUGINS "")
@@ -89,7 +93,11 @@ foreach(module QT3SUPPORT QTOPENGL QTASSISTANT QTDESIGNER QTMOTIF QTNSPLUGIN
       if(QT_USE_${module})
         string(REPLACE "QT" "" qt_module_def "${module}")
         add_definitions(-DQT_${qt_module_def}_LIB)
-        include_directories(${QT_${module}_INCLUDE_DIR})
+        if(QT_INCLUDE_DIRS_NO_SYSTEM)
+          include_directories(${QT_${module}_INCLUDE_DIR})
+        else(QT_INCLUDE_DIRS_NO_SYSTEM)
+          include_directories(SYSTEM ${QT_${module}_INCLUDE_DIR})
+        endif(QT_INCLUDE_DIRS_NO_SYSTEM)
       endif()
       set(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY})
       set(QT_LIBRARIES_PLUGINS ${QT_LIBRARIES_PLUGINS} ${QT_${module}_PLUGINS})
diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in
new file mode 100644 (file)
index 0000000..0bc7e10
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?include "cpack_variables.wxi"?>
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+    RequiredVersion="3.6.3303.0">
+
+    <Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
+        Name="$(var.CPACK_PACKAGE_NAME)"
+        Language="1033"
+        Version="$(var.CPACK_PACKAGE_VERSION)"
+        Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
+        UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
+
+        <Package InstallerVersion="301" Compressed="yes"/>
+
+        <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+
+        <MajorUpgrade
+            Schedule="afterInstallInitialize"
+            AllowSameVersionUpgrades="yes"
+            DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."/>
+
+        <WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
+        <Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
+
+        <?ifdef CPACK_WIX_PRODUCT_ICON?>
+        <Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
+        <Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
+        <?endif?>
+
+        <?ifdef CPACK_WIX_UI_BANNER?>
+        <WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
+        <?endif?>
+
+        <?ifdef CPACK_WIX_UI_DIALOG?>
+        <WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
+        <?endif?>
+
+        <FeatureRef Id="ProductFeature"/>
+
+        <UIRef Id="WixUI_InstallDir" />
+    </Product>
+</Wix>
index 9dc1c6a..2f11994 100644 (file)
@@ -1,50 +1,65 @@
 For more information about how to contribute modules to CMake, see this page:
 http://www.itk.org/Wiki/CMake:Module_Maintainers
 
-Note to authors of FindXXX.cmake files
+Note to authors of FindXxx.cmake files
 
-We would like all FindXXX.cmake files to produce consistent variable names.
+We would like all FindXxx.cmake files to produce consistent variable names.
 
 Please use the following consistent variable names for general use.
 
-XXX_INCLUDE_DIRS        The final set of include directories listed in one variable for use by client code.  This should not be a cache entry.
-XXX_LIBRARIES           The libraries to link against to use XXX. These should include full paths.  This should not be a cache entry.
-XXX_DEFINITIONS         Definitions to use when compiling code that uses XXX. This really shouldn't include options such as (-DHAS_JPEG)that a client source-code file uses to decide whether to #include <jpeg.h>
-XXX_EXECUTABLE          Where to find the XXX tool.
-XXX_YYY_EXECUTABLE      Where to find the YYY tool that comes with XXX.
-XXX_LIBRARY_DIRS        Optionally, the final set of library directories listed in one variable for use by client code.  This should not be a cache entry.
-XXX_ROOT_DIR            Where to find the base directory of XXX.
-XXX_VERSION_YY          Expect Version YY if true. Make sure at most one of these is ever true.
-XXX_WRAP_YY             If False, do not try to use the relevent CMake wrapping command.
-XXX_YY_FOUND            If False, optional YY part of XXX sytem is not available.
-XXX_FOUND               Set to false, or undefined, if we haven't found, or don't want to use XXX.
-XXX_NOT_FOUND_MESSAGE   Should be set by config-files in the case that it has set XXX_FOUND to FALSE.
+Xxx_INCLUDE_DIRS        The final set of include directories listed in one variable for use by client code.
+                        This should not be a cache entry.
+Xxx_LIBRARIES           The libraries to link against to use Xxx. These should include full paths.
+                        This should not be a cache entry.
+Xxx_DEFINITIONS         Definitions to use when compiling code that uses Xxx. This really shouldn't include options such
+                        as (-DHAS_JPEG)that a client source-code file uses to decide whether to #include <jpeg.h>
+Xxx_EXECUTABLE          Where to find the Xxx tool.
+Xxx_Yyy_EXECUTABLE      Where to find the Yyy tool that comes with Xxx.
+Xxx_LIBRARY_DIRS        Optionally, the final set of library directories listed in one variable for use by client code.
+                        This should not be a cache entry.
+Xxx_ROOT_DIR            Where to find the base directory of Xxx.
+Xxx_VERSION_Yy          Expect Version Yy if true. Make sure at most one of these is ever true.
+Xxx_WRAP_Yy             If False, do not try to use the relevant CMake wrapping command.
+Xxx_Yy_FOUND            If False, optional Yy part of Xxx sytem is not available.
+Xxx_FOUND               Set to false, or undefined, if we haven't found, or don't want to use Xxx.
+Xxx_NOT_FOUND_MESSAGE   Should be set by config-files in the case that it has set Xxx_FOUND to FALSE.
                         The contained message will be printed by the find_package() command and by
                         find_package_handle_standard_args() to inform the user about the problem.
-XXX_RUNTIME_LIBRARY_DIRS Optionally, the runtime library search path for use when running an executable linked to shared libraries.
+Xxx_RUNTIME_LIBRARY_DIRS Optionally, the runtime library search path for use when running an executable linked to
+                         shared libraries.
                          The list should be used by user code to create the PATH on windows or LD_LIBRARY_PATH on unix.
                          This should not be a cache entry.
-XXX_VERSION_STRING      A human-readable string containing the version of the package found, if any.
-XXX_VERSION_MAJOR       The major version of the package found, if any.
-XXX_VERSION_MINOR       The minor version of the package found, if any.
-XXX_VERSION_PATCH       The patch version of the package found, if any.
+Xxx_VERSION_STRING      A human-readable string containing the version of the package found, if any.
+Xxx_VERSION_MAJOR       The major version of the package found, if any.
+Xxx_VERSION_MINOR       The minor version of the package found, if any.
+Xxx_VERSION_PATCH       The patch version of the package found, if any.
 
-You do not have to provide all of the above variables. You should provide XXX_FOUND under most circumstances. If XXX is a library, then  XXX_LIBRARIES, should also be defined, and XXX_INCLUDE_DIRS should usually be defined (I guess libm.a might be an exception)
+You do not have to provide all of the above variables. You should provide Xxx_FOUND under most circumstances.
+If Xxx is a library, then  Xxx_LIBRARIES, should also be defined, and Xxx_INCLUDE_DIRS should usually be
+defined (I guess libm.a might be an exception)
 
-The following names should not usually be used in CMakeLists.txt files, but they may be usefully modified in users' CMake Caches to control stuff.
+The following names should not usually be used in CMakeLists.txt files, but they may be usefully modified in
+users' CMake Caches to control stuff.
 
-XXX_LIBRARY             Name of XXX Library. A User may set this and XXX_INCLUDE_DIR to ignore to force non-use of XXX.
-XXX_YY_LIBRARY          Name of YY library that is part of the XXX system. It may or may not be required to use XXX.
-XXX_INCLUDE_DIR         Where to find xxx.h, etc.  (XXX_INCLUDE_PATH was considered bad because a path includes an actual filename.)
-XXX_YY_INCLUDE_DIR      Where to find xxx_yy.h, etc.
+Xxx_LIBRARY             Name of Xxx Library. A User may set this and Xxx_INCLUDE_DIR to ignore to force non-use of Xxx.
+Xxx_Yy_LIBRARY          Name of Yy library that is part of the Xxx system. It may or may not be required to use Xxx.
+Xxx_INCLUDE_DIR         Where to find xxx.h, etc.  (Xxx_INCLUDE_PATH was considered bad because a path includes an
+                        actual filename.)
+Xxx_Yy_INCLUDE_DIR      Where to find xxx_yy.h, etc.
 
-For tidiness's sake, try to keep as many options as possible out of the cache, leaving at least one option which can be used to disable use of the module, or locate a not-found library (e.g. XXX_ROOT_DIR). For the same reason, mark most cache options as advanced.
+For tidiness's sake, try to keep as many options as possible out of the cache, leaving at least one option which can be
+used to disable use of the module, or locate a not-found library (e.g. Xxx_ROOT_DIR).
+For the same reason, mark most cache options as advanced.
 
-If you need other commands to do special things then it should still begin with XXX_. This gives a sort of namespace effect and keeps things tidy for the user. You should put comments describing all the exported settings, plus descriptions of any the users can use to control stuff.
+If you need other commands to do special things then it should still begin with Xxx_. This gives a sort of namespace
+effect and keeps things tidy for the user. You should put comments describing all the exported settings, plus
+descriptions of any the users can use to control stuff.
 
-You really should also provide backwards compatibility any old settings that were actually in use. Make sure you comment them as deprecated, so that no-one starts using them.
+You really should also provide backwards compatibility any old settings that were actually in use.
+Make sure you comment them as deprecated, so that no-one starts using them.
 
-To correctly document a module, create a comment block at the top with # comments.  There are three types of comments that can be in the block:
+To correctly document a module, create a comment block at the top with # comments.
+There are three types of comments that can be in the block:
 
 1. The brief description of the module, this is done by:
 # - a small description
@@ -67,7 +82,7 @@ For example:
 #  VAR_REALLY_COOL - cool right?
 #
 
-Test the documentation formatting by running "cmake --help-module FindXXX".
+Test the documentation formatting by running "cmake --help-module FindXxx".
 Edit the comments until the output of this command looks satisfactory.
 
 To have a .cmake file in this directory NOT show up in the
@@ -93,38 +108,38 @@ copyright and licence notice block like this one:
 The layout of the notice block is strictly enforced by the ModuleNotices test.
 Only the year range and name may be changed freely.
 
-A FindXXX.cmake module will typically be loaded by the command
+A FindXxx.cmake module will typically be loaded by the command
 
-  FIND_PACKAGE(XXX [major[.minor[.patch[.tweak]]]] [EXACT]
+  FIND_PACKAGE(Xxx [major[.minor[.patch[.tweak]]]] [EXACT]
                [QUIET] [[REQUIRED|COMPONENTS] [components...]])
 
 If any version numbers are given to the command it will set the
 following variables before loading the module:
 
-  XXX_FIND_VERSION       = full requested version string
-  XXX_FIND_VERSION_MAJOR = major version if requested, else 0
-  XXX_FIND_VERSION_MINOR = minor version if requested, else 0
-  XXX_FIND_VERSION_PATCH = patch version if requested, else 0
-  XXX_FIND_VERSION_TWEAK = tweak version if requested, else 0
-  XXX_FIND_VERSION_COUNT = number of version components, 0 to 4
-  XXX_FIND_VERSION_EXACT = true if EXACT option was given
+  Xxx_FIND_VERSION       = full requested version string
+  Xxx_FIND_VERSION_MAJOR = major version if requested, else 0
+  Xxx_FIND_VERSION_MINOR = minor version if requested, else 0
+  Xxx_FIND_VERSION_PATCH = patch version if requested, else 0
+  Xxx_FIND_VERSION_TWEAK = tweak version if requested, else 0
+  Xxx_FIND_VERSION_COUNT = number of version components, 0 to 4
+  Xxx_FIND_VERSION_EXACT = true if EXACT option was given
 
 If the find module supports versioning it should locate a version of
 the package that is compatible with the version requested.  If a
 compatible version of the package cannot be found the module should
 not report success.  The version of the package found should be stored
-in "XXX_VERSION..." version variables documented by the module.
+in "Xxx_VERSION..." version variables documented by the module.
 
 If the QUIET option is given to the command it will set the variable
-XXX_FIND_QUIETLY to true before loading the FindXXX.cmake module.  If
+Xxx_FIND_QUIETLY to true before loading the FindXxx.cmake module.  If
 this variable is set the module should not complain about not being
 able to find the package.  If the
 REQUIRED option is given to the command it will set the variable
-XXX_FIND_REQUIRED to true before loading the FindXXX.cmake module.  If
+Xxx_FIND_REQUIRED to true before loading the FindXxx.cmake module.  If
 this variable is set the module should issue a FATAL_ERROR if the
 package cannot be found.
 If neither the QUIET nor REQUIRED options are given then the
-FindXXX.cmake module should look for the package and complain without
+FindXxx.cmake module should look for the package and complain without
 error if the module is not found.
 
 FIND_PACKAGE() will set the variable CMAKE_FIND_PACKAGE_NAME to
@@ -133,19 +148,19 @@ contain the actual name of the package.
 A package can provide sub-components.
 Those components can be listed after the COMPONENTS (or REQUIRED)
 or OPTIONAL_COMPONENTS keywords.  The set of all listed components will be
-specified in a XXX_FIND_COMPONENTS variable.
-For each package-specific component, say Yyy, a variable XXX_FIND_REQUIRED_Yyy
+specified in a Xxx_FIND_COMPONENTS variable.
+For each package-specific component, say Yyy, a variable Xxx_FIND_REQUIRED_Yyy
 will be set to true if it listed after COMPONENTS and it will be set to false
 if it was listed after OPTIONAL_COMPONENTS.
-Using those variables a FindXXX.cmake module and also a XXXConfig.cmake package
+Using those variables a FindXxx.cmake module and also a XxxConfig.cmake package
 configuration file can determine whether and which components have been requested,
 and whether they were requested as required or as optional.
-For each of the requested components a XXX_Yyy_FOUND variable should be set
+For each of the requested components a Xxx_Yyy_FOUND variable should be set
 accordingly.
-The per-package XXX_FOUND variable should be only set to true if all requested
+The per-package Xxx_FOUND variable should be only set to true if all requested
 required components have been found. A missing optional component should not
-keep the XXX_FOUND variable from being set to true.
-If the package provides XXX_INCLUDE_DIRS and XXX_LIBRARIES variables, the include
+keep the Xxx_FOUND variable from being set to true.
+If the package provides Xxx_INCLUDE_DIRS and Xxx_LIBRARIES variables, the include
 dirs and libraries for all components which were requested and which have been
 found should be added to those two variables.
 
index 8bf6c40..f0519fe 100644 (file)
@@ -176,6 +176,8 @@ set(SRCS
   cmExportFileGenerator.cxx
   cmExportInstallFileGenerator.h
   cmExportInstallFileGenerator.cxx
+  cmExportTryCompileFileGenerator.h
+  cmExportTryCompileFileGenerator.cxx
   cmExportSet.h
   cmExportSet.cxx
   cmExportSetMap.h
@@ -184,6 +186,8 @@ set(SRCS
   cmExtraCodeBlocksGenerator.h
   cmExtraEclipseCDT4Generator.cxx
   cmExtraEclipseCDT4Generator.h
+  cmExtraSublimeTextGenerator.cxx
+  cmExtraSublimeTextGenerator.h
   cmFileTimeComparison.cxx
   cmFileTimeComparison.h
   cmGeneratedFileStream.cxx
@@ -201,6 +205,7 @@ set(SRCS
   cmGeneratorTarget.h
   cmGlobalGenerator.cxx
   cmGlobalGenerator.h
+  cmGlobalGeneratorFactory.h
   cmGlobalUnixMakefileGenerator3.cxx
   cmGlobalUnixMakefileGenerator3.h
   cmGraphAdjacencyList.h
@@ -330,12 +335,6 @@ if (WIN32)
       cmGlobalVisualStudio8Generator.h
       cmGlobalVisualStudio9Generator.cxx
       cmGlobalVisualStudio9Generator.h
-      cmGlobalVisualStudio8Win64Generator.cxx
-      cmGlobalVisualStudio8Win64Generator.h
-      cmGlobalVisualStudio9Win64Generator.cxx
-      cmGlobalVisualStudio9Win64Generator.h
-      cmGlobalVisualStudio9IA64Generator.cxx
-      cmGlobalVisualStudio9IA64Generator.h
       cmVisualStudioGeneratorOptions.h
       cmVisualStudioGeneratorOptions.cxx
       cmVisualStudio10TargetGenerator.h
@@ -344,16 +343,10 @@ if (WIN32)
       cmLocalVisualStudio10Generator.h
       cmGlobalVisualStudio10Generator.h
       cmGlobalVisualStudio10Generator.cxx
-      cmGlobalVisualStudio10Win64Generator.h
-      cmGlobalVisualStudio10Win64Generator.cxx
-      cmGlobalVisualStudio10IA64Generator.h
-      cmGlobalVisualStudio10IA64Generator.cxx
       cmGlobalVisualStudio11Generator.h
       cmGlobalVisualStudio11Generator.cxx
-      cmGlobalVisualStudio11Win64Generator.h
-      cmGlobalVisualStudio11Win64Generator.cxx
-      cmGlobalVisualStudio11ARMGenerator.h
-      cmGlobalVisualStudio11ARMGenerator.cxx
+      cmGlobalVisualStudio12Generator.h
+      cmGlobalVisualStudio12Generator.cxx
       cmGlobalVisualStudioGenerator.cxx
       cmGlobalVisualStudioGenerator.h
       cmGlobalWatcomWMakeGenerator.cxx
@@ -366,6 +359,8 @@ if (WIN32)
       cmLocalVisualStudio7Generator.h
       cmLocalVisualStudioGenerator.cxx
       cmLocalVisualStudioGenerator.h
+      cmVisualStudioWCEPlatformParser.h
+      cmVisualStudioWCEPlatformParser.cxx
       cmWin32ProcessExecution.cxx
       cmWin32ProcessExecution.h
       )
@@ -510,6 +505,14 @@ if(UNIX)
     )
 endif()
 
+if(WIN32)
+  set(CPACK_SRCS ${CPACK_SRCS}
+    CPack/WiX/cmCPackWIXGenerator.cxx
+    CPack/WiX/cmWIXSourceWriter.cxx
+    CPack/WiX/cmWIXRichTextFormatWriter.cxx
+  )
+endif()
+
 if(APPLE)
   set(CPACK_SRCS ${CPACK_SRCS}
     CPack/cmCPackBundleGenerator.cxx
index c59c618..a8b8907 100644 (file)
@@ -1,6 +1,6 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 2)
 set(CMake_VERSION_MINOR 8)
-set(CMake_VERSION_PATCH 10)
+set(CMake_VERSION_PATCH 11)
 set(CMake_VERSION_TWEAK 2)
-#set(CMake_VERSION_RC 3)
+#set(CMake_VERSION_RC 0)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
new file mode 100644 (file)
index 0000000..e8b0ea9
--- /dev/null
@@ -0,0 +1,571 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 "cmCPackWIXGenerator.h"
+
+#include <cmSystemTools.h>
+#include <cmGeneratedFileStream.h>
+#include <CPack/cmCPackLog.h>
+#include <CPack/cmCPackComponentGroup.h>
+
+#include "cmWIXSourceWriter.h"
+#include "cmWIXRichTextFormatWriter.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Directory.hxx>
+
+#include <rpc.h> // for GUID generation
+
+int cmCPackWIXGenerator::InitializeInternal()
+{
+  componentPackageMethod = ONE_PACKAGE;
+
+  return this->Superclass::InitializeInternal();
+}
+
+bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
+{
+  std::string cpackTopLevel;
+  if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+    {
+    return false;
+    }
+
+  std::string logFileName = cpackTopLevel + "/wix.log";
+
+  cmCPackLogger(cmCPackLog::LOG_DEBUG,
+    "Running WiX command: " << command << std::endl);
+
+  std::string output;
+
+  int returnValue = 0;
+  bool status = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+    &returnValue, 0, cmSystemTools::OUTPUT_NONE);
+
+  std::ofstream logFile(logFileName.c_str(), std::ios::app);
+  logFile << command << std::endl;
+  logFile << output;
+  logFile.close();
+
+  if(!status || returnValue)
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Problem running WiX candle. "
+      "Please check '" << logFileName << "' for errors." << std::endl);
+
+    return false;
+    }
+
+  return true;
+}
+
+bool cmCPackWIXGenerator::RunCandleCommand(
+  const std::string& sourceFile, const std::string& objectFile)
+{
+  std::string executable;
+  if(!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable))
+    {
+    return false;
+    }
+
+  std::stringstream command;
+  command << QuotePath(executable);
+  command << " -nologo";
+  command << " -arch " << GetArchitecture();
+  command << " -out " << QuotePath(objectFile);
+  command << " " << QuotePath(sourceFile);
+
+  return RunWiXCommand(command.str());
+}
+
+bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
+{
+  std::string executable;
+  if(!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable))
+    {
+    return false;
+    }
+
+  std::stringstream command;
+  command << QuotePath(executable);
+  command << " -nologo";
+  command << " -out " << QuotePath(packageFileNames.at(0));
+  command << " -ext WixUIExtension";
+  command << " " << objectFiles;
+
+  return RunWiXCommand(command.str());
+}
+
+int cmCPackWIXGenerator::PackageFiles()
+{
+  if(!PackageFilesImpl() || cmSystemTools::GetErrorOccuredFlag())
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Fatal WiX Generator Error" << std::endl);
+    return false;
+    }
+
+  return true;
+}
+
+bool cmCPackWIXGenerator::InitializeWiXConfiguration()
+{
+  if(!ReadListFile("CPackWIX.cmake"))
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Error while executing CPackWIX.cmake" << std::endl);
+    return false;
+    }
+
+  if(GetOption("CPACK_WIX_PRODUCT_GUID") == 0)
+    {
+    std::string guid = GenerateGUID();
+    SetOption("CPACK_WIX_PRODUCT_GUID", guid.c_str());
+
+    cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+      "CPACK_WIX_PRODUCT_GUID implicitly set to " << guid << " . "
+      << std::endl);
+    }
+
+  if(GetOption("CPACK_WIX_UPGRADE_GUID") == 0)
+    {
+    std::string guid = GenerateGUID();
+    SetOption("CPACK_WIX_UPGRADE_GUID", guid.c_str());
+
+    cmCPackLogger(cmCPackLog::LOG_WARNING,
+      "CPACK_WIX_UPGRADE_GUID implicitly set to " << guid << " . "
+      "Please refer to the documentation on how and why "
+      "you might want to set this explicitly." << std::endl);
+    }
+
+  std::string cpackTopLevel;
+  if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+    {
+    return false;
+    }
+
+  if(GetOption("CPACK_WIX_LICENSE_RTF") == 0)
+    {
+    std::string licenseFilename = cpackTopLevel + "/License.rtf";
+    SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str());
+
+    if(!CreateLicenseFile())
+      {
+      return false;
+      }
+    }
+
+  return true;
+}
+
+bool cmCPackWIXGenerator::PackageFilesImpl()
+{
+  if(!InitializeWiXConfiguration())
+    {
+    return false;
+    }
+
+  if(!CreateWiXVariablesIncludeFile())
+    {
+    return false;
+    }
+
+  if(!CreateWiXSourceFiles())
+    {
+    return false;
+    }
+
+  std::stringstream objectFiles;
+  for(size_t i = 0; i < wixSources.size(); ++i)
+    {
+    const std::string& sourceFilename = wixSources[i];
+
+    std::string objectFilename =
+      cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj";
+
+    if(!RunCandleCommand(sourceFilename, objectFilename))
+      {
+      return false;
+      }
+
+    objectFiles << " " << QuotePath(objectFilename);
+    }
+
+  return RunLightCommand(objectFiles.str());
+}
+
+bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
+{
+  std::string cpackTopLevel;
+  if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+    {
+    return false;
+    }
+
+  std::string includeFilename =
+    cpackTopLevel + "/cpack_variables.wxi";
+
+  cmWIXSourceWriter includeFile(Logger, includeFilename, true);
+  CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID");
+  CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID");
+  CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
+  CopyDefinition(includeFile, "CPACK_PACKAGE_NAME");
+  CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION");
+  CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF");
+  CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON");
+  CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER");
+  CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG");
+
+  return true;
+}
+
+void cmCPackWIXGenerator::CopyDefinition(
+  cmWIXSourceWriter &source, const std::string &name)
+{
+  const char* value = GetOption(name.c_str());
+  if(value)
+    {
+    AddDefinition(source, name, value);
+    }
+}
+
+void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
+  const std::string& name, const std::string& value)
+{
+  std::stringstream tmp;
+  tmp << name << "=\"" << value << '"';
+
+  source.AddProcessingInstruction("define",
+    cmWIXSourceWriter::WindowsCodepageToUtf8(tmp.str()));
+}
+
+bool cmCPackWIXGenerator::CreateWiXSourceFiles()
+{
+  std::string cpackTopLevel;
+  if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
+    {
+    return false;
+    }
+
+  std::string directoryDefinitionsFilename =
+    cpackTopLevel + "/directories.wxs";
+
+  wixSources.push_back(directoryDefinitionsFilename);
+
+  cmWIXSourceWriter directoryDefinitions(Logger, directoryDefinitionsFilename);
+  directoryDefinitions.BeginElement("Fragment");
+
+  directoryDefinitions.BeginElement("Directory");
+  directoryDefinitions.AddAttribute("Id", "TARGETDIR");
+  directoryDefinitions.AddAttribute("Name", "SourceDir");
+
+  directoryDefinitions.BeginElement("Directory");
+  if(GetArchitecture() == "x86")
+    {
+    directoryDefinitions.AddAttribute("Id", "ProgramFilesFolder");
+    }
+  else
+    {
+    directoryDefinitions.AddAttribute("Id", "ProgramFiles64Folder");
+    }
+
+  std::vector<std::string> install_root;
+
+  std::string tmp;
+  if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", tmp))
+    {
+    return false;
+    }
+
+  cmSystemTools::SplitPath(tmp.c_str(), install_root);
+
+  if(!install_root.empty() && install_root.back().empty())
+    {
+    install_root.pop_back();
+    }
+
+  for(size_t i = 1; i < install_root.size(); ++i)
+    {
+    directoryDefinitions.BeginElement("Directory");
+
+    if(i == install_root.size() - 1)
+      {
+      directoryDefinitions.AddAttribute("Id", "INSTALL_ROOT");
+      }
+    else
+      {
+      std::stringstream ss;
+      ss << "INSTALL_PREFIX_" << i;
+      directoryDefinitions.AddAttribute("Id", ss.str());
+      }
+
+    directoryDefinitions.AddAttribute("Name", install_root[i]);
+  }
+
+  size_t directoryCounter = 0;
+  size_t fileCounter = 0;
+
+  std::string fileDefinitionsFilename =
+    cpackTopLevel + "/files.wxs";
+
+  wixSources.push_back(fileDefinitionsFilename);
+
+  cmWIXSourceWriter fileDefinitions(Logger, fileDefinitionsFilename);
+  fileDefinitions.BeginElement("Fragment");
+
+  std::string featureDefinitionsFilename =
+      cpackTopLevel +"/features.wxs";
+
+  wixSources.push_back(featureDefinitionsFilename);
+
+  cmWIXSourceWriter featureDefinitions(Logger, featureDefinitionsFilename);
+  featureDefinitions.BeginElement("Fragment");
+
+  featureDefinitions.BeginElement("Feature");
+  featureDefinitions.AddAttribute("Id", "ProductFeature");
+  featureDefinitions.AddAttribute("Title", Name);
+  featureDefinitions.AddAttribute("Level", "1");
+  featureDefinitions.EndElement();
+
+  featureDefinitions.BeginElement("FeatureRef");
+  featureDefinitions.AddAttribute("Id", "ProductFeature");
+
+  AddDirectoryAndFileDefinitons(
+    toplevel, "INSTALL_ROOT",
+    directoryDefinitions, fileDefinitions, featureDefinitions,
+    directoryCounter, fileCounter);
+
+  featureDefinitions.EndElement();
+  featureDefinitions.EndElement();
+  fileDefinitions.EndElement();
+
+  for(size_t i = 1; i < install_root.size(); ++i)
+    {
+    directoryDefinitions.EndElement();
+    }
+
+  directoryDefinitions.EndElement();
+  directoryDefinitions.EndElement();
+  directoryDefinitions.EndElement();
+
+  std::string wixTemplate = FindTemplate("WIX.template.in");
+  if(wixTemplate.empty())
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Could not find CPack WiX template file WIX.template.in" << std::endl);
+    return false;
+    }
+
+  std::string mainSourceFilePath = cpackTopLevel + "/main.wxs";
+
+  if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str()))
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Failed creating '" << mainSourceFilePath  <<
+      "'' from template." << std::endl);
+
+    return false;
+    }
+
+  wixSources.push_back(mainSourceFilePath);
+
+  return true;
+}
+
+bool cmCPackWIXGenerator::CreateLicenseFile()
+{
+  std::string licenseSourceFilename;
+  if(!RequireOption("CPACK_RESOURCE_FILE_LICENSE", licenseSourceFilename))
+    {
+    return false;
+    }
+
+  std::string licenseDestinationFilename;
+  if(!RequireOption("CPACK_WIX_LICENSE_RTF", licenseDestinationFilename))
+    {
+    return false;
+    }
+
+  std::string extension = GetRightmostExtension(licenseSourceFilename);
+
+  if(extension == ".rtf")
+    {
+    cmSystemTools::CopyAFile(
+      licenseSourceFilename.c_str(),
+      licenseDestinationFilename.c_str());
+    }
+  else if(extension == ".txt")
+    {
+    cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename);
+
+    std::ifstream licenseSource(licenseSourceFilename.c_str());
+
+    std::string line;
+    while(std::getline(licenseSource, line))
+      {
+      rtfWriter.AddText(line);
+      rtfWriter.AddText("\n");
+      }
+    }
+  else
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "unsupported WiX License file extension '" <<
+      extension << "'" << std::endl);
+
+    return false;
+    }
+
+  return true;
+}
+
+void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
+  const std::string& topdir,
+  const std::string& directoryId,
+  cmWIXSourceWriter& directoryDefinitions,
+  cmWIXSourceWriter& fileDefinitions,
+  cmWIXSourceWriter& featureDefinitions,
+  size_t& directoryCounter,
+  size_t& fileCounter)
+{
+  cmsys::Directory dir;
+  dir.Load(topdir.c_str());
+
+  for(size_t i = 0; i < dir.GetNumberOfFiles(); ++i)
+    {
+    std::string fileName = dir.GetFile(static_cast<unsigned long>(i));
+
+    if(fileName == "." || fileName == "..")
+      {
+      continue;
+      }
+
+    std::string fullPath = topdir + "/" + fileName;
+
+    if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
+      {
+      std::stringstream tmp;
+      tmp << "DIR_ID_" << ++directoryCounter;
+      std::string subDirectoryId = tmp.str();
+
+      directoryDefinitions.BeginElement("Directory");
+      directoryDefinitions.AddAttribute("Id", subDirectoryId);
+      directoryDefinitions.AddAttribute("Name", fileName);
+
+      AddDirectoryAndFileDefinitons(
+        fullPath, subDirectoryId,
+        directoryDefinitions,
+        fileDefinitions,
+        featureDefinitions,
+        directoryCounter,
+        fileCounter);
+
+      directoryDefinitions.EndElement();
+      }
+    else
+      {
+      std::stringstream tmp;
+      tmp << "_ID_" << ++fileCounter;
+      std::string idSuffix = tmp.str();
+
+      std::string componentId = std::string("CMP") + idSuffix;
+      std::string fileId = std::string("FILE") + idSuffix;
+
+      fileDefinitions.BeginElement("DirectoryRef");
+      fileDefinitions.AddAttribute("Id", directoryId);
+
+      fileDefinitions.BeginElement("Component");
+      fileDefinitions.AddAttribute("Id", componentId);
+      fileDefinitions.AddAttribute("Guid", "*");
+
+      fileDefinitions.BeginElement("File");
+      fileDefinitions.AddAttribute("Id", fileId);
+      fileDefinitions.AddAttribute("Source", fullPath);
+      fileDefinitions.AddAttribute("KeyPath", "yes");
+
+      fileDefinitions.EndElement();
+      fileDefinitions.EndElement();
+      fileDefinitions.EndElement();
+
+      featureDefinitions.BeginElement("ComponentRef");
+      featureDefinitions.AddAttribute("Id", componentId);
+      featureDefinitions.EndElement();
+      }
+    }
+}
+
+bool cmCPackWIXGenerator::RequireOption(
+  const std::string& name, std::string &value) const
+{
+  const char* tmp = GetOption(name.c_str());
+  if(tmp)
+    {
+    value = tmp;
+
+    return true;
+    }
+  else
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "Required variable " << name << " not set" << std::endl);
+
+    return false;
+    }
+}
+
+std::string cmCPackWIXGenerator::GetArchitecture() const
+{
+  std::string void_p_size;
+  RequireOption("CPACK_WIX_SIZEOF_VOID_P", void_p_size);
+
+  if(void_p_size == "8")
+    {
+    return "x64";
+    }
+  else
+    {
+    return "x86";
+    }
+}
+
+std::string cmCPackWIXGenerator::GenerateGUID()
+{
+  UUID guid;
+  UuidCreate(&guid);
+
+  unsigned char *tmp = 0;
+  UuidToString(&guid, &tmp);
+
+  std::string result(reinterpret_cast<char*>(tmp));
+  RpcStringFree(&tmp);
+
+  return cmSystemTools::UpperCase(result);
+}
+
+std::string cmCPackWIXGenerator::QuotePath(const std::string& path)
+{
+  return std::string("\"") + path + '"';
+}
+
+std::string cmCPackWIXGenerator::GetRightmostExtension(
+  const std::string& filename)
+{
+  std::string extension;
+
+  std::string::size_type i = filename.rfind(".");
+  if(i != std::string::npos)
+    {
+    extension = filename.substr(i);
+    }
+
+  return cmSystemTools::LowerCase(extension);
+}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
new file mode 100644 (file)
index 0000000..0e95d70
--- /dev/null
@@ -0,0 +1,101 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmCPackWIXGenerator_h
+#define cmCPackWIXGenerator_h
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <string>
+#include <map>
+
+class cmWIXSourceWriter;
+
+/** \class cmCPackWIXGenerator
+ * \brief A generator for WIX files
+ */
+class cmCPackWIXGenerator : public cmCPackGenerator
+{
+public:
+  cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
+
+protected:
+  virtual int InitializeInternal();
+
+  virtual int PackageFiles();
+
+  virtual const char* GetOutputExtension()
+    {
+    return ".msi";
+    }
+
+  virtual enum CPackSetDestdirSupport SupportsSetDestdir() const
+    {
+    return SETDESTDIR_UNSUPPORTED;
+    }
+
+  virtual bool SupportsAbsoluteDestination() const
+    {
+    return false;
+    }
+
+  virtual bool SupportsComponentInstallation() const
+    {
+    return false;
+    }
+
+private:
+  bool InitializeWiXConfiguration();
+
+  bool PackageFilesImpl();
+
+  bool CreateWiXVariablesIncludeFile();
+
+  void CopyDefinition(
+    cmWIXSourceWriter &source, const std::string &name);
+
+  void AddDefinition(cmWIXSourceWriter& source,
+    const std::string& name, const std::string& value);
+
+  bool CreateWiXSourceFiles();
+
+  bool CreateLicenseFile();
+
+  bool RunWiXCommand(const std::string& command);
+
+  bool RunCandleCommand(
+    const std::string& sourceFile, const std::string& objectFile);
+
+  bool RunLightCommand(const std::string& objectFiles);
+
+  void AddDirectoryAndFileDefinitons(const std::string& topdir,
+    const std::string& directoryId,
+    cmWIXSourceWriter& directoryDefinitions,
+    cmWIXSourceWriter& fileDefinitions,
+    cmWIXSourceWriter& featureDefinitions,
+    size_t& directoryCounter,
+    size_t& fileCounter);
+
+  bool RequireOption(const std::string& name, std::string& value) const;
+
+  std::string GetArchitecture() const;
+
+  static std::string GenerateGUID();
+
+  static std::string QuotePath(const std::string& path);
+
+  static std::string GetRightmostExtension(const std::string& filename);
+
+  std::vector<std::string> wixSources;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
new file mode 100644 (file)
index 0000000..774c22c
--- /dev/null
@@ -0,0 +1,137 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 "cmWIXRichTextFormatWriter.h"
+
+#include <cmVersion.h>
+
+cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter(
+  const std::string& filename):
+    file(filename.c_str(), std::ios::binary)
+{
+  StartGroup();
+  WriteHeader();
+  WriteDocumentPrefix();
+}
+
+cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
+{
+  EndGroup();
+
+  /* I haven't seen this in the RTF spec but
+   *  wordpad terminates its RTF like this */
+  file << "\r\n";
+  file.put(0);
+}
+
+void cmWIXRichTextFormatWriter::AddText(const std::string& text)
+{
+  typedef unsigned char rtf_byte_t;
+
+  for(size_t i = 0; i < text.size(); ++i)
+    {
+    rtf_byte_t c = rtf_byte_t(text[i]);
+
+    switch(c)
+      {
+    case '\\':
+      file << "\\\\";
+      break;
+    case '{':
+      file << "\\{";
+      break;
+    case '}':
+      file << "\\}";
+      break;
+    case '\n':
+      file << "\\par\r\n";
+      break;
+    case '\r':
+      continue;
+    default:
+        {
+        if(c <= 0x7F)
+          {
+          file << c;
+          }
+        else
+          {
+          file << "[NON-ASCII-" << int(c) << "]";
+          }
+        }
+      break;
+      }
+    }
+}
+
+void cmWIXRichTextFormatWriter::WriteHeader()
+{
+  ControlWord("rtf1");
+  ControlWord("ansi");
+  ControlWord("ansicpg1252");
+  ControlWord("deff0");
+  ControlWord("deflang1031");
+
+  WriteFontTable();
+  WriteGenerator();
+}
+
+void cmWIXRichTextFormatWriter::WriteFontTable()
+{
+  StartGroup();
+  ControlWord("fonttbl");
+
+  StartGroup();
+  ControlWord("f0");
+  ControlWord("fswiss");
+  ControlWord("fcharset0 Arial;");
+  EndGroup();
+
+  EndGroup();
+}
+
+void cmWIXRichTextFormatWriter::WriteGenerator()
+{
+  StartGroup();
+  NewControlWord("generator");
+  file << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");";
+  EndGroup();
+}
+
+void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
+{
+  ControlWord("viewkind4");
+  ControlWord("uc1");
+  ControlWord("pard");
+  ControlWord("f0");
+  ControlWord("fs20");
+}
+
+void cmWIXRichTextFormatWriter::ControlWord(const std::string& keyword)
+{
+  file << "\\" << keyword;
+}
+
+void cmWIXRichTextFormatWriter::NewControlWord(const std::string& keyword)
+{
+  file << "\\*\\" << keyword;
+}
+
+void cmWIXRichTextFormatWriter::StartGroup()
+{
+  file.put('{');
+}
+
+void cmWIXRichTextFormatWriter::EndGroup()
+{
+  file.put('}');
+}
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
new file mode 100644 (file)
index 0000000..10b67c3
--- /dev/null
@@ -0,0 +1,46 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmWIXRichTextFormatWriter_h
+#define cmWIXRichTextFormatWriter_h
+
+#include <fstream>
+
+/** \class cmWIXRichtTextFormatWriter
+ * \brief Helper class to generate Rich Text Format (RTF) documents
+ * from plain text (e.g. for license and welcome text)
+ */
+class cmWIXRichTextFormatWriter
+{
+public:
+  cmWIXRichTextFormatWriter(const std::string& filename);
+  ~cmWIXRichTextFormatWriter();
+
+  void AddText(const std::string& text);
+
+private:
+  void WriteHeader();
+  void WriteFontTable();
+  void WriteGenerator();
+
+  void WriteDocumentPrefix();
+
+  void ControlWord(const std::string& keyword);
+  void NewControlWord(const std::string& keyword);
+
+  void StartGroup();
+  void EndGroup();
+
+  std::ofstream file;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
new file mode 100644 (file)
index 0000000..af7ba80
--- /dev/null
@@ -0,0 +1,189 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 "cmWIXSourceWriter.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <windows.h>
+
+cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
+  const std::string& filename,
+  bool isIncludeFile):
+    Logger(logger),
+    file(filename.c_str()),
+    state(DEFAULT)
+{
+  WriteXMLDeclaration();
+
+  if(isIncludeFile)
+    {
+    BeginElement("Include");
+    }
+  else
+    {
+    BeginElement("Wix");
+    }
+
+  AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
+}
+
+cmWIXSourceWriter::~cmWIXSourceWriter()
+{
+  while(elements.size())
+    {
+    EndElement();
+    }
+}
+
+void cmWIXSourceWriter::BeginElement(const std::string& name)
+{
+  if(state == BEGIN)
+    {
+    file << ">";
+    }
+
+  file << "\n";
+  Indent(elements.size());
+  file << "<" << name;
+
+  elements.push_back(name);
+  state = BEGIN;
+}
+
+void cmWIXSourceWriter::EndElement()
+{
+  if(elements.empty())
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "can not end WiX element with no open elements" << std::endl);
+    return;
+    }
+
+  if(state == DEFAULT)
+    {
+    file << "\n";
+    Indent(elements.size()-1);
+    file << "</" << elements.back() << ">";
+    }
+  else
+    {
+    file << "/>";
+    }
+
+  elements.pop_back();
+  state = DEFAULT;
+}
+
+void cmWIXSourceWriter::AddProcessingInstruction(
+  const std::string& target, const std::string& content)
+{
+  if(state == BEGIN)
+    {
+    file << ">";
+    }
+
+  file << "\n";
+  Indent(elements.size());
+  file << "<?" << target << " " << content << "?>";
+
+  state = DEFAULT;
+}
+
+void cmWIXSourceWriter::AddAttribute(
+  const std::string& key, const std::string& value)
+{
+  std::string utf8 = WindowsCodepageToUtf8(value);
+
+  file << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"';
+}
+
+std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value)
+{
+  if(value.empty())
+    {
+    return std::string();
+    }
+
+  int characterCount = MultiByteToWideChar(
+    CP_ACP, 0, value.c_str(), static_cast<int>(value.size()), 0, 0);
+
+  if(characterCount == 0)
+    {
+    return std::string();
+    }
+
+  std::vector<wchar_t> utf16(characterCount);
+
+  MultiByteToWideChar(
+    CP_ACP, 0, value.c_str(), static_cast<int>(value.size()),
+    &utf16[0], static_cast<int>(utf16.size()));
+
+  int utf8ByteCount = WideCharToMultiByte(
+    CP_UTF8, 0, &utf16[0], static_cast<int>(utf16.size()), 0, 0, 0, 0);
+
+  if(utf8ByteCount == 0)
+    {
+    return std::string();
+    }
+
+  std::vector<char> utf8(utf8ByteCount);
+
+  WideCharToMultiByte(CP_UTF8, 0, &utf16[0], static_cast<int>(utf16.size()),
+    &utf8[0], static_cast<int>(utf8.size()), 0, 0);
+
+  return std::string(&utf8[0], utf8.size());
+}
+
+
+void cmWIXSourceWriter::WriteXMLDeclaration()
+{
+  file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+}
+
+void cmWIXSourceWriter::Indent(size_t count)
+{
+  for(size_t i = 0; i < count; ++i)
+    {
+    file << "    ";
+    }
+}
+
+std::string cmWIXSourceWriter::EscapeAttributeValue(
+  const std::string& value)
+{
+  std::string result;
+  result.reserve(value.size());
+
+  char c = 0;
+  for(size_t i = 0 ; i < value.size(); ++i)
+    {
+    c = value[i];
+    switch(c)
+      {
+    case '<':
+      result += "&lt;";
+      break;
+    case '&':
+      result +="&amp;";
+      break;
+    case '"':
+      result += "&quot;";
+      break;
+    default:
+      result += c;
+      break;
+      }
+    }
+
+  return result;
+}
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
new file mode 100644 (file)
index 0000000..1dafc1f
--- /dev/null
@@ -0,0 +1,67 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 cmWIXSourceWriter_h
+#define cmWIXSourceWriter_h
+
+#include <vector>
+#include <string>
+#include <fstream>
+
+#include <CPack/cmCPackLog.h>
+
+/** \class cmWIXSourceWriter
+ * \brief Helper class to generate XML WiX source files
+ */
+class cmWIXSourceWriter
+{
+public:
+  cmWIXSourceWriter(cmCPackLog* logger,
+    const std::string& filename, bool isIncludeFile = false);
+
+  ~cmWIXSourceWriter();
+
+  void BeginElement(const std::string& name);
+
+  void EndElement();
+
+  void AddProcessingInstruction(
+    const std::string& target, const std::string& content);
+
+  void AddAttribute(
+    const std::string& key, const std::string& value);
+
+  static std::string WindowsCodepageToUtf8(const std::string& value);
+
+private:
+  enum State
+  {
+    DEFAULT,
+    BEGIN
+  };
+
+  void WriteXMLDeclaration();
+
+  void Indent(size_t count);
+
+  static std::string EscapeAttributeValue(const std::string& value);
+
+  cmCPackLog* Logger;
+
+  std::ofstream file;
+
+  State state;
+
+  std::vector<std::string> elements;
+};
+
+#endif
index 48d935c..abae372 100644 (file)
@@ -42,7 +42,9 @@ public:
 class cmCPackComponent
 {
 public:
- cmCPackComponent() : Group(0), TotalSize(0) { }
+ cmCPackComponent() : Group(0), IsRequired(true), IsHidden(false),
+                      IsDisabledByDefault(false), IsDownloaded(false),
+                      TotalSize(0) { }
 
   /// The name of the component (used to reference the component).
   std::string Name;
index 4bd5d5c..4494e8a 100644 (file)
@@ -76,6 +76,11 @@ int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
       packageFileName.c_str());
   // Tell CPackDeb.cmake the name of the component GROUP.
   this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",packageName.c_str());
+  // Tell CPackDeb.cmake the path where the component is.
+  std::string component_path = "/";
+  component_path += packageName;
+  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
+                  component_path.c_str());
   if (!this->ReadListFile("CPackDeb.cmake"))
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -198,8 +203,11 @@ int cmCPackDebGenerator::PackageComponentsAllInOne()
   /* replace the TEMPORARY package file name */
   this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
       packageFileName.c_str());
-  // Tell CPackDeb.cmake the name of the component GROUP.
-  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",compInstDirName.c_str());
+  // Tell CPackDeb.cmake the path where the component is.
+  std::string component_path = "/";
+  component_path += compInstDirName;
+  this->SetOption("CPACK_DEB_PACKAGE_COMPONENT_PART_PATH",
+                  component_path.c_str());
   if (!this->ReadListFile("CPackDeb.cmake"))
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -763,13 +771,13 @@ static int put_arobj(CF *cfp, struct stat *sb)
     }
   if (lname > sizeof(hdr->ar_name) || strchr(name, ' '))
     (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname,
-                  (long int)sb->st_mtime, uid, gid, sb->st_mode,
-                  (long long)sb->st_size + lname, ARFMAG);
+                  (long int)sb->st_mtime, (unsigned)uid, (unsigned)gid,
+                  sb->st_mode, (long long)sb->st_size + lname, ARFMAG);
     else {
       lname = 0;
       (void)sprintf(ar_hb, HDR2, name,
-                    (long int)sb->st_mtime, uid, gid, sb->st_mode,
-                    (long long)sb->st_size, ARFMAG);
+                    (long int)sb->st_mtime, (unsigned)uid, (unsigned)gid,
+                    sb->st_mode, (long long)sb->st_size, ARFMAG);
       }
     off_t size = sb->st_size;
 
index 78cb1b6..d973c01 100644 (file)
@@ -442,7 +442,22 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
           line.replace(pos, 1, "\\\"");
           pos = line.find('\"', pos+2);
         }
-        osf << "        \"" << line << "\\n\"\n";
+        // break up long lines to avoid Rez errors
+        std::vector<std::string> lines;
+        const size_t max_line_length = 512;
+        for(size_t i=0; i<line.size(); i+= max_line_length)
+          {
+          int line_length = max_line_length;
+          if(i+max_line_length > line.size())
+            line_length = line.size()-i;
+          lines.push_back(line.substr(i, line_length));
+          }
+
+        for(size_t i=0; i<lines.size(); i++)
+          {
+          osf << "        \"" << lines[i] << "\"\n";
+          }
+        osf << "        \"\\n\"\n";
       }
       osf << "};\n";
       osf << "\n";
index e964696..7cc1522 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <cmsys/SystemTools.hxx>
 #include <cmsys/Glob.hxx>
-#include <memory> // auto_ptr
 #include <algorithm>
 
 #if defined(__HAIKU__)
@@ -97,7 +96,6 @@ int cmCPackGenerator::PrepareNames()
     }
   tempDirectory += this->GetOption("CPACK_GENERATOR");
   std::string topDirectory = tempDirectory;
-  this->GetOption("CPACK_PACKAGE_FILE_NAME");
   const char* pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME");
   if(!pfname)
     {
@@ -208,7 +206,7 @@ int cmCPackGenerator::InstallProject()
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
       "Problem creating temporary directory: "
-                  << (tempInstallDirectory ? tempInstallDirectory : "(NULL}")
+                  << (tempInstallDirectory ? tempInstallDirectory : "(NULL)")
                   << std::endl);
     return 0;
     }
@@ -697,7 +695,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
         cm.SetProgressCallback(cmCPackGeneratorProgress, this);
         cmGlobalGenerator gg;
         gg.SetCMakeInstance(&cm);
-        std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+        cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
         cmMakefile *mf = lg->GetMakefile();
         std::string realInstallDirectory = tempInstallDirectory;
         if ( !installSubDirectory.empty() && installSubDirectory != "/" )
index 37ff460..b36c2a2 100644 (file)
@@ -19,6 +19,7 @@
 #include "cmCPackZIPGenerator.h"
 #include "cmCPackSTGZGenerator.h"
 #include "cmCPackNSISGenerator.h"
+
 #ifdef __APPLE__
 #  include "cmCPackDragNDropGenerator.h"
 #  include "cmCPackBundleGenerator.h"
 #endif
 
 #if !defined(_WIN32) \
- && !defined(__QNXNTO__) && !defined(__BEOS__)
+ && !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__)
 #  include "cmCPackDebGenerator.h"
 #  include "cmCPackRPMGenerator.h"
 #endif
 
+#ifdef _WIN32
+#  include "WiX/cmCPackWIXGenerator.h"
+#endif
 
 #include "cmCPackLog.h"
 
@@ -61,6 +65,8 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     {
     this->RegisterGenerator("NSIS", "Null Soft Installer",
       cmCPackNSISGenerator::CreateGenerator);
+    this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)",
+      cmCPackNSISGenerator::CreateGenerator64);
     }
 #ifdef __CYGWIN__
   if (cmCPackCygwinBinaryGenerator::CanGenerate())
@@ -80,6 +86,13 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     this->RegisterGenerator("ZIP", "ZIP file format",
       cmCPackZIPGenerator::CreateGenerator);
     }
+#ifdef _WIN32
+  if (cmCPackWIXGenerator::CanGenerate())
+    {
+    this->RegisterGenerator("WIX", "MSI file format via WiX tools",
+      cmCPackWIXGenerator::CreateGenerator);
+    }
+#endif
   if (cmCPackTarBZip2Generator::CanGenerate())
     {
     this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
@@ -113,7 +126,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     }
 #endif
 #if !defined(_WIN32) \
-  && !defined(__QNXNTO__) && !defined(__BEOS__)
+  && !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__)
   if (cmCPackDebGenerator::CanGenerate())
     {
     this->RegisterGenerator("DEB", "Debian packages",
index b2e57a2..62bfa91 100644 (file)
@@ -33,8 +33,9 @@
 #endif
 
 //----------------------------------------------------------------------
-cmCPackNSISGenerator::cmCPackNSISGenerator()
+cmCPackNSISGenerator::cmCPackNSISGenerator(bool nsis64)
 {
+  Nsis64 = nsis64;
 }
 
 //----------------------------------------------------------------------
@@ -356,19 +357,46 @@ int cmCPackNSISGenerator::InitializeInternal()
     << std::endl);
   std::vector<std::string> path;
   std::string nsisPath;
-  bool gotRegValue = true;
+  bool gotRegValue = false;
 
 #ifdef _WIN32
-  if ( !cmsys::SystemTools::ReadRegistryValue(
-      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath,
-      cmsys::SystemTools::KeyWOW64_32) )
+  if (Nsis64)
     {
-    if ( !cmsys::SystemTools::ReadRegistryValue(
-        "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) )
+    if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath,
+      cmsys::SystemTools::KeyWOW64_64) )
       {
-      gotRegValue = false;
+      gotRegValue = true;
+      }
+    if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath,
+      cmsys::SystemTools::KeyWOW64_64) )
+      {
+      gotRegValue = true;
       }
     }
+  if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath,
+      cmsys::SystemTools::KeyWOW64_32) )
+    {
+    gotRegValue = true;
+    }
+  if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath) )
+    {
+    gotRegValue = true;
+    }
+  if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath,
+      cmsys::SystemTools::KeyWOW64_32) )
+    {
+    gotRegValue = true;
+    }
+  if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) )
+    {
+    gotRegValue = true;
+    }
 
   if (gotRegValue)
     {
@@ -404,11 +432,14 @@ int cmCPackNSISGenerator::InitializeInternal()
   int retVal = 1;
   bool resS = cmSystemTools::RunSingleCommand(nsisCmd.c_str(),
     &output, &retVal, 0, this->GeneratorVerbose, 0);
-
   cmsys::RegularExpression versionRex("v([0-9]+.[0-9]+)");
-  if ( !resS || retVal || !versionRex.find(output))
+  cmsys::RegularExpression versionRexCVS("v(.*)\\.cvs");
+  if ( !resS || retVal ||
+      (!versionRex.find(output) && !versionRexCVS.find(output))
+     )
     {
-    std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+    const char* topDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+    std::string tmpFile = topDir ? topDir : ".";
     tmpFile += "/NSISOutput.log";
     cmGeneratedFileStream ofs(tmpFile.c_str());
     ofs << "# Run command: " << nsisCmd.c_str() << std::endl
@@ -420,17 +451,26 @@ int cmCPackNSISGenerator::InitializeInternal()
       << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
     return 0;
     }
-  double nsisVersion = atof(versionRex.match(1).c_str());
-  double minNSISVersion = 2.09;
-  cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: "
-    << nsisVersion << std::endl);
-  if ( nsisVersion < minNSISVersion )
+  if ( versionRex.find(output))
     {
-    cmCPackLogger(cmCPackLog::LOG_ERROR,
-      "CPack requires NSIS Version 2.09 or greater. NSIS found on the system "
-      "was: "
+    double nsisVersion = atof(versionRex.match(1).c_str());
+    double minNSISVersion = 2.09;
+    cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: "
       << nsisVersion << std::endl);
-    return 0;
+    if ( nsisVersion < minNSISVersion )
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+        "CPack requires NSIS Version 2.09 or greater.  "
+        "NSIS found on the system was: "
+        << nsisVersion << std::endl);
+      return 0;
+      }
+    }
+  if ( versionRexCVS.find(output))
+    {
+    // No version check for NSIS cvs build
+    cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: CVS "
+      << versionRexCVS.match(1).c_str() << std::endl);
     }
   this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str());
   this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLES_DIRECTORY", "bin");
index 8224854..e46fbda 100644 (file)
@@ -27,10 +27,13 @@ class cmCPackNSISGenerator : public cmCPackGenerator
 public:
   cmCPackTypeMacro(cmCPackNSISGenerator, cmCPackGenerator);
 
+  static cmCPackGenerator* CreateGenerator64()
+    { return new cmCPackNSISGenerator(true); }
+
   /**
    * Construct generator
    */
-  cmCPackNSISGenerator();
+  cmCPackNSISGenerator(bool nsis64 = false);
   virtual ~cmCPackNSISGenerator();
 
 protected:
@@ -77,6 +80,8 @@ protected:
   /// Translations any newlines found in the string into \\r\\n, so that the
   /// resulting string can be used within NSIS.
   static std::string TranslateNewlines(std::string str);
+
+  bool Nsis64;
 };
 
 #endif
index edbe838..c617a3e 100644 (file)
@@ -106,56 +106,101 @@ int cmCPackPackageMakerGenerator::PackageFiles()
     resDir += "/en.lproj";
     }
 
-
-  // Create directory structure
-  std::string preflightDirName = resDir + "/PreFlight";
-  std::string postflightDirName = resDir + "/PostFlight";
   const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT");
   const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT");
   const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT");
-  // if preflight or postflight scripts not there create directories
-  // of the same name, I think this makes it work
-  if(!preflight)
+
+  if(this->Components.empty())
     {
-    if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str()))
+    // Create directory structure
+    std::string preflightDirName = resDir + "/PreFlight";
+    std::string postflightDirName = resDir + "/PostFlight";
+    // if preflight or postflight scripts not there create directories
+    // of the same name, I think this makes it work
+    if(!preflight)
       {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Problem creating installer directory: "
-                    << preflightDirName.c_str() << std::endl);
-      return 0;
+      if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str()))
+        {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "Problem creating installer directory: "
+                      << preflightDirName.c_str() << std::endl);
+        return 0;
+        }
+      }
+    if(!postflight)
+      {
+      if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str()))
+        {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "Problem creating installer directory: "
+                      << postflightDirName.c_str() << std::endl);
+        return 0;
+        }
+      }
+    // if preflight, postflight, or postupgrade are set
+    // then copy them into the resource directory and make
+    // them executable
+    if(preflight)
+      {
+      this->CopyInstallScript(resDir.c_str(),
+                              preflight,
+                              "preflight");
+      }
+    if(postflight)
+      {
+      this->CopyInstallScript(resDir.c_str(),
+                              postflight,
+                              "postflight");
+      }
+    if(postupgrade)
+      {
+      this->CopyInstallScript(resDir.c_str(),
+                              postupgrade,
+                              "postupgrade");
       }
     }
-  if(!postflight)
+  else if(postflight)
     {
-    if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str()))
+    // create a postflight component to house the script
+    this->PostFlightComponent.Name = "PostFlight";
+    this->PostFlightComponent.DisplayName = "PostFlight";
+    this->PostFlightComponent.Description = "PostFlight";
+    this->PostFlightComponent.IsHidden = true;
+
+    // empty directory for pkg contents
+    std::string packageDir = toplevel + "/" + PostFlightComponent.Name;
+    if (!cmsys::SystemTools::MakeDirectory(packageDir.c_str()))
       {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Problem creating installer directory: "
-                    << postflightDirName.c_str() << std::endl);
+                    "Problem creating component packages directory: "
+                    << packageDir.c_str() << std::endl);
       return 0;
       }
-    }
-  // if preflight, postflight, or postupgrade are set
-  // then copy them into the resource directory and make
-  // them executable
-  if(preflight)
-    {
-    this->CopyInstallScript(resDir.c_str(),
-                            preflight,
-                            "preflight");
-    }
-  if(postflight)
-    {
-    this->CopyInstallScript(resDir.c_str(),
+
+    // create package
+    std::string packageFileDir = packageDirFileName + "/Contents/Packages/";
+    if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str()))
+      {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                   "Problem creating component PostFlight Packages directory: "
+                    << packageFileDir.c_str() << std::endl);
+      return 0;
+      }
+    std::string packageFile = packageFileDir +
+      this->GetPackageName(PostFlightComponent);
+    if (!this->GenerateComponentPackage(packageFile.c_str(),
+                                        packageDir.c_str(),
+                                        PostFlightComponent))
+      {
+      return 0;
+      }
+
+    // copy postflight script into resource directory of .pkg
+    std::string resourceDir = packageFile + "/Contents/Resources";
+    this->CopyInstallScript(resourceDir.c_str(),
                             postflight,
                             "postflight");
     }
-  if(postupgrade)
-    {
-    this->CopyInstallScript(resDir.c_str(),
-                            postupgrade,
-                            "postupgrade");
-    }
 
   if (!this->Components.empty())
     {
@@ -778,6 +823,11 @@ WriteDistributionFile(const char* metapackageFile)
                 << std::endl;
       }
     }
+  if(!this->PostFlightComponent.Name.empty())
+    {
+      choiceOut << "<line choice=\"" << PostFlightComponent.Name
+                << "Choice\"></line>" << std::endl;
+    }
   choiceOut << "</choices-outline>" << std::endl;
 
   // Create the actual choices
@@ -792,6 +842,12 @@ WriteDistributionFile(const char* metapackageFile)
     {
     CreateChoice(compIt->second, choiceOut);
     }
+
+  if(!this->PostFlightComponent.Name.empty())
+    {
+    CreateChoice(PostFlightComponent, choiceOut);
+    }
+
   this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
 
   // Create the distribution.dist file in the metapackage to turn it
index 101813f..ba3d968 100644 (file)
@@ -112,6 +112,9 @@ protected:
   // value.
   std::string EscapeForXML(std::string str);
 
+  // The PostFlight component when creating a metapackage
+  cmCPackComponent PostFlightComponent;
+
   double PackageMakerVersion;
   double PackageCompatibilityVersion;
 };
index 13aa6d8..66a4194 100644 (file)
@@ -77,6 +77,11 @@ int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel,
                   packageFileName.c_str());
   // Tell CPackRPM.cmake the name of the component NAME.
   this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",packageName.c_str());
+  // Tell CPackRPM.cmake the path where the component is.
+  std::string component_path = "/";
+  component_path += packageName;
+  this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
+                  component_path.c_str());
   if (!this->ReadListFile("CPackRPM.cmake"))
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -178,8 +183,11 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne()
   /* replace the TEMPORARY package file name */
   this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
       packageFileName.c_str());
-  // Tell CPackRPM.cmake the name of the component GROUP.
-  this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compInstDirName.c_str());
+  // Tell CPackRPM.cmake the path where the component is.
+  std::string component_path = "/";
+  component_path += compInstDirName;
+  this->SetOption("CPACK_RPM_PACKAGE_COMPONENT_PART_PATH",
+                  component_path.c_str());
   if (!this->ReadListFile("CPackRPM.cmake"))
     {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
index b603585..b188918 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <cmsys/CommandLineArguments.hxx>
 #include <cmsys/SystemTools.hxx>
-#include <memory> // auto_ptr
 
 //----------------------------------------------------------------------------
 static const char * cmDocumentationName[][3] =
@@ -181,7 +180,6 @@ int main (int argc, char *argv[])
 {
   cmSystemTools::FindExecutableDirectory(argv[0]);
   cmCPackLog log;
-  int nocwd = 0;
 
   log.SetErrorPrefix("CPack Error: ");
   log.SetWarningPrefix("CPack Warning: ");
@@ -194,7 +192,7 @@ int main (int argc, char *argv[])
     {
     cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
       "Current working directory cannot be established." << std::endl);
-    nocwd = 1;
+    return 1;
     }
 
   std::string generator;
@@ -276,7 +274,7 @@ int main (int argc, char *argv[])
   cminst.RemoveUnscriptableCommands();
   cmGlobalGenerator cmgg;
   cmgg.SetCMakeInstance(&cminst);
-  std::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
+  cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
   cmMakefile* globalMF = cmlg->GetMakefile();
 
   bool cpackConfigFileSpecified = true;
@@ -298,7 +296,7 @@ int main (int argc, char *argv[])
    * should launch cpack using "cpackConfigFile" if it exists
    * in the current directory.
    */
-  if((doc.CheckOptions(argc, argv,"-G") || nocwd) && !(argc==1))
+  if((doc.CheckOptions(argc, argv,"-G")) && !(argc==1))
     {
       help = true;
     }
index 554efb5..4fa3c53 100644 (file)
@@ -67,6 +67,12 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
     generator += this->BuildGenerator;
     args.push_back(generator);
     }
+  if(this->BuildGeneratorToolset.size())
+    {
+    std::string toolset = "-T";
+    toolset += this->BuildGeneratorToolset;
+    args.push_back(toolset);
+    }
 
   const char* config = 0;
   if ( this->CTest->GetConfigType().size() > 0 )
@@ -229,10 +235,14 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
   // should we cmake?
   cmake cm;
   cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString);
-  cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
-      this->BuildGenerator.c_str()));
 
-  if(!this->BuildNoCMake)
+  if(this->BuildNoCMake)
+    {
+    cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
+                            this->BuildGenerator.c_str()));
+    cm.SetGeneratorToolset(this->BuildGeneratorToolset);
+    }
+  else
     {
     // do the cmake step, no timeout here since it is not a sub process
     if (this->RunCMake(outstring,out,cmakeOutString,cwd,&cm))
@@ -466,11 +476,17 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
     idx++;
     this->Timeout = atof(allArgs[idx].c_str());
     }
-  if(currentArg.find("--build-generator",0) == 0 && idx < allArgs.size() - 1)
+  if(currentArg == "--build-generator" && idx < allArgs.size() - 1)
     {
     idx++;
     this->BuildGenerator = allArgs[idx];
     }
+  if(currentArg == "--build-generator-toolset" &&
+     idx < allArgs.size() - 1)
+    {
+    idx++;
+    this->BuildGeneratorToolset = allArgs[idx];
+    }
   if(currentArg.find("--build-project",0) == 0 && idx < allArgs.size() - 1)
     {
     idx++;
index 9029600..ca50c64 100644 (file)
@@ -57,6 +57,7 @@ protected:
   cmStdString  Output;
 
   std::string              BuildGenerator;
+  std::string              BuildGeneratorToolset;
   std::vector<std::string> BuildOptions;
   bool                     BuildTwoConfig;
   std::string              BuildMakeProgram;
index 7a99ddf..d6d39a9 100644 (file)
@@ -144,6 +144,15 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
       cmakeConfigureCommand += cmakeGeneratorName;
       cmakeConfigureCommand += "\"";
 
+      const char* cmakeGeneratorToolset =
+        this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
+      if(cmakeGeneratorToolset && *cmakeGeneratorToolset)
+        {
+        cmakeConfigureCommand += " \"-T";
+        cmakeConfigureCommand += cmakeGeneratorToolset;
+        cmakeConfigureCommand += "\"";
+        }
+
       cmakeConfigureCommand += " \"";
       cmakeConfigureCommand += source_dir;
       cmakeConfigureCommand += "\"";
index 4d1e249..20aded2 100644 (file)
@@ -1097,10 +1097,17 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
         }
       else
         {
-        cmCTestLog(this->CTest, ERROR_MESSAGE,
-          "Unknown gcov output line: [" << line->c_str() << "]" << std::endl);
-        cont->Error ++;
-        //abort();
+        // gcov 4.7 can have output lines saying "No executable lines" and
+        // "Removing 'filename.gcov'"... Don't log those as "errors."
+        if(*line != "No executable lines" &&
+           !cmSystemTools::StringStartsWith(line->c_str(), "Removing "))
+          {
+          cmCTestLog(this->CTest, ERROR_MESSAGE,
+            "Unknown gcov output line: [" << line->c_str() << "]"
+            << std::endl);
+          cont->Error ++;
+          //abort();
+          }
         }
 
 
index 2c1a0af..5b34491 100644 (file)
@@ -68,7 +68,7 @@ std::string cmCTestGIT::GetWorkingRevision()
 {
   // Run plumbing "git rev-list" to get work tree revision.
   const char* git = this->CommandLineTool.c_str();
-  const char* git_rev_list[] = {git, "rev-list", "-n", "1", "HEAD", 0};
+  const char* git_rev_list[] = {git, "rev-list", "-n", "1", "HEAD", "--", 0};
   std::string rev;
   OneLineParser out(this, "rl-out> ", rev);
   OutputLogger err(this->Log, "rl-err> ");
@@ -639,7 +639,7 @@ void cmCTestGIT::LoadModifications()
   this->RunChild(git_update_index, &ui_out, &ui_err);
 
   // Use 'git diff-index' to get modified files.
-  const char* git_diff_index[] = {git, "diff-index", "-z", "HEAD", 0};
+  const char* git_diff_index[] = {git, "diff-index", "-z", "HEAD", "--", 0};
   DiffParser out(this, "di-out> ");
   OutputLogger err(this->Log, "di-err> ");
   this->RunChild(git_diff_index, &out, &err);
index 0da8aae..453e32c 100644 (file)
@@ -121,7 +121,7 @@ bool cmCTestHandlerCommand
     }
   if ( this->Values[ct_SUBMIT_INDEX] )
     {
-    if ( this->CTest->GetDartVersion() <= 1 )
+    if(!this->CTest->GetDropSiteCDash() && this->CTest->GetDartVersion() <= 1)
       {
       cmCTestLog(this->CTest, ERROR_MESSAGE,
         "Dart before version 2.0 does not support collecting submissions."
index ebef1ed..76ddeea 100644 (file)
@@ -248,7 +248,12 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
 //---------------------------------------------------------
 void cmCTestMultiProcessHandler::StartNextTests()
 {
-  size_t numToStart = this->ParallelLevel - this->RunningCount;
+  size_t numToStart = 0;
+  if(this->RunningCount < this->ParallelLevel)
+    {
+    numToStart = this->ParallelLevel - this->RunningCount;
+    }
+
   if(numToStart == 0)
     {
     return;
index b796b83..e7491bb 100644 (file)
@@ -32,7 +32,6 @@
 #include <math.h>
 #include <float.h>
 
-#include <memory> // auto_ptr
 #include <set>
 
 //----------------------------------------------------------------------
@@ -1547,7 +1546,7 @@ void cmCTestTestHandler::GetListOfTests()
   cmake cm;
   cmGlobalGenerator gg;
   gg.SetCMakeInstance(&cm);
-  std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
   cmMakefile *mf = lg->GetMakefile();
   mf->AddDefinition("CTEST_CONFIGURATION_TYPE",
     this->CTest->GetConfigType().c_str());
index 5c7414f..bd1ff71 100644 (file)
@@ -175,7 +175,7 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
       }
     else if ( key == ctrl('d') ||key == KEY_DC )
       {
-      if ( form->curcol > 0 )
+      if ( form->curcol >= 0 )
         {
         form_driver(form, REQ_DEL_CHAR);
         }
index 29daffd..1684fb2 100644 (file)
@@ -27,6 +27,8 @@ if (Qt5Widgets_FOUND)
   set(QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
   # Remove this when the minimum version of Qt is 4.6.
   add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
+
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 else()
   set(QT_MIN_VERSION "4.4.0")
   find_package(Qt4 REQUIRED)
index 1d21d42..6006758 100644 (file)
@@ -490,7 +490,11 @@ QCMakePropertyList QCMakeCacheModel::properties() const
       }
 
       // go to the next in the tree
-      while(!idxs.isEmpty() && !idxs.last().sibling(idxs.last().row()+1, 0).isValid())
+      while(!idxs.isEmpty() && (
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
+        (idxs.last().row()+1) >= rowCount(idxs.last().parent()) ||
+#endif
+        !idxs.last().sibling(idxs.last().row()+1, 0).isValid()))
       {
         idxs.removeLast();
       }
index c5252b7..1cc1e3a 100644 (file)
@@ -68,7 +68,8 @@ public:
       "                     [COMMAND command2 [ARGS] [args2...] ...]\n"
       "                     [MAIN_DEPENDENCY depend]\n"
       "                     [DEPENDS [depends...]]\n"
-      "                     [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
+      "                     [IMPLICIT_DEPENDS <lang1> depend1\n"
+      "                                      [<lang2> depend2] ...]\n"
       "                     [WORKING_DIRECTORY dir]\n"
       "                     [COMMENT comment] [VERBATIM] [APPEND])\n"
       "This defines a command to generate specified OUTPUT file(s).  "
@@ -142,6 +143,8 @@ public:
       "dependencies of an input file.  The language given specifies the "
       "programming language whose corresponding dependency scanner should "
       "be used.  Currently only C and CXX language scanners are supported. "
+      "The language has to be specified for every file in the "
+      "IMPLICIT_DEPENDS list. "
       "Dependencies discovered from the scanning are added to those of "
       "the custom command at build time.  Note that the IMPLICIT_DEPENDS "
       "option is currently supported only for Makefile generators and "
index a77140d..04a304e 100644 (file)
@@ -35,10 +35,14 @@ bool cmAddDependenciesCommand
     }
   else
     {
-    std::string error = "Adding dependency to non-existent target: ";
-    error += target_name;
-    this->SetError(error.c_str());
-    return false;
+    cmOStringStream e;
+    e << "Cannot add target-level dependencies to non-existent target \""
+      << target_name << "\".\n"
+      << "The add_dependencies works for top-level logical targets created "
+      << "by the add_executable, add_library, or add_custom_target commands.  "
+      << "If you want to add file-level dependencies see the DEPENDS option "
+      << "of the add_custom_target and add_custom_command commands.";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
     }
 
   return true;
index c144565..e5f27cb 100644 (file)
@@ -134,6 +134,10 @@ public:
       "They may contain custom commands generating such sources, but not "
       "PRE_BUILD, PRE_LINK, or POST_BUILD commands.  "
       "Object libraries cannot be imported, exported, installed, or linked."
+      "  "
+      "Some native build systems may not like targets that have only "
+      "object files, so consider adding at least one real source file "
+      "to any target that references $<TARGET_OBJECTS:objlib>."
       ;
     }
 
index 9efeda4..5b1c9c6 100644 (file)
@@ -78,7 +78,7 @@ bool cmAddSubDirectoryCommand::InitialPass
     // No binary directory was specified.  If the source directory is
     // not a subdirectory of the current directory then it is an
     // error.
-    if(!cmSystemTools::FindLastString(srcPath.c_str(),
+    if(!cmSystemTools::IsSubDirectory(srcPath.c_str(),
                                       this->Makefile->GetCurrentDirectory()))
       {
       cmOStringStream e;
@@ -93,10 +93,15 @@ bool cmAddSubDirectoryCommand::InitialPass
 
     // Remove the CurrentDirectory from the srcPath and replace it
     // with the CurrentOutputDirectory.
-    binPath = srcPath;
-    cmSystemTools::ReplaceString(binPath,
-                                 this->Makefile->GetCurrentDirectory(),
-                                 this->Makefile->GetCurrentOutputDirectory());
+    const char* src = this->Makefile->GetCurrentDirectory();
+    const char* bin = this->Makefile->GetCurrentOutputDirectory();
+    size_t srcLen = strlen(src);
+    size_t binLen = strlen(bin);
+    if(srcLen > 0 && src[srcLen-1] == '/')
+      { --srcLen; }
+    if(binLen > 0 && bin[binLen-1] == '/')
+      { --binLen; }
+    binPath = std::string(bin, binLen) + srcPath.substr(srcLen);
     }
   else
     {
index 9097a74..e3a2ad4 100644 (file)
@@ -89,6 +89,7 @@
 #include "cmStringCommand.cxx"
 #include "cmSubdirCommand.cxx"
 #include "cmTargetLinkLibrariesCommand.cxx"
+#include "cmTimestamp.cxx"
 #include "cmTryCompileCommand.cxx"
 #include "cmTryRunCommand.cxx"
 #include "cmUnsetCommand.cxx"
index 3722ab6..91d55a5 100644 (file)
@@ -87,6 +87,14 @@ bool cmBuildCommand
 
   const char* makeprogram
     = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
+  if(!makeprogram)
+    {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "build_command() requires CMAKE_MAKE_PROGRAM to be defined.  "
+      "Call project() or enable_language() first.");
+    return true;
+    }
 
   // If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug'
   // in the currently implemented multi-configuration global generators...
index a6d04b7..322a6a2 100644 (file)
@@ -53,7 +53,7 @@
 #include <cm_zlib.h>
 #include <cmsys/Base64.h>
 
-#if defined(__BEOS__) && !defined(__HAIKU__)
+#if defined(__BEOS__)
 #include <be/kernel/OS.h>   /* disable_debugger() API. */
 #endif
 
@@ -327,6 +327,7 @@ cmCTest::cmCTest()
   this->OutputLogFileLastTag   = -1;
   this->SuppressUpdatingCTestConfiguration = false;
   this->DartVersion            = 1;
+  this->DropSiteCDash          = false;
   this->OutputTestOutputOnTestFailure = false;
   this->ComputedCompressTestOutput = false;
   this->ComputedCompressMemCheckOutput = false;
@@ -653,6 +654,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
     = this->GetCTestConfiguration("SourceDirectory").c_str();
   std::string bld_dir = this->GetCTestConfiguration("BuildDirectory").c_str();
   this->DartVersion = 1;
+  this->DropSiteCDash = false;
   for(Part p = PartStart; p != PartCount; p = Part(p+1))
     {
     this->Parts[p].SubmitFiles.clear();
@@ -719,6 +721,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
       return false;
       }
     }
+  this->DropSiteCDash = mf->IsOn("CTEST_DROP_SITE_CDASH");
 
   if ( !this->Initialize(bld_dir.c_str(), command) )
     {
index f2638fe..587a6db 100644 (file)
@@ -384,6 +384,7 @@ public:
 
   //! Get the version of dart server
   int GetDartVersion() { return this->DartVersion; }
+  int GetDropSiteCDash() { return this->DropSiteCDash; }
 
   //! Add file to be submitted
   void AddSubmitFile(Part part, const char* name);
@@ -561,6 +562,7 @@ private:
   bool Quiet;
 
   int  DartVersion;
+  bool DropSiteCDash;
 
   std::vector<cmStdString> InitialCommandLineArguments;
 
index 4231243..3d5b24b 100644 (file)
@@ -584,23 +584,15 @@ bool cmCacheManager::DeleteCache(const char* path)
   cmSystemTools::ConvertToUnixSlashes(cacheFile);
   std::string cmakeFiles = cacheFile;
   cacheFile += "/CMakeCache.txt";
-  cmSystemTools::RemoveFile(cacheFile.c_str());
-  // now remove the files in the CMakeFiles directory
-  // this cleans up language cache files
-  cmsys::Directory dir;
-  cmakeFiles += cmake::GetCMakeFilesDirectory();
-  dir.Load(cmakeFiles.c_str());
-  for (unsigned long fileNum = 0;
-    fileNum <  dir.GetNumberOfFiles();
-    ++fileNum)
-    {
-    if(!cmSystemTools::
-       FileIsDirectory(dir.GetFile(fileNum)))
+  if(cmSystemTools::FileExists(cacheFile.c_str()))
+    {
+    cmSystemTools::RemoveFile(cacheFile.c_str());
+    // now remove the files in the CMakeFiles directory
+    // this cleans up language cache files
+    cmakeFiles += cmake::GetCMakeFilesDirectory();
+    if(cmSystemTools::FileIsDirectory(cmakeFiles.c_str()))
       {
-      std::string fullPath = cmakeFiles;
-      fullPath += "/";
-      fullPath += dir.GetFile(fileNum);
-      cmSystemTools::RemoveFile(fullPath.c_str());
+      cmSystemTools::RemoveADirectory(cmakeFiles.c_str());
       }
     }
   return true;
index 696a6a8..c5146c5 100644 (file)
@@ -279,7 +279,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -701,7 +701,7 @@ while (YYID (0))
    we won't break user code: when these are the locations we know.  */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
 #  define YY_LOCATION_PRINT(File, Loc)                  \
      fprintf (File, "%d.%d-%d.%d",                      \
               (Loc).first_line, (Loc).first_column,     \
index 49ed967..227b226 100644 (file)
@@ -28,6 +28,9 @@
 #include "cmRemoveDefinitionsCommand.cxx"
 #include "cmSourceGroupCommand.cxx"
 #include "cmSubdirDependsCommand.cxx"
+#include "cmTargetCompileDefinitionsCommand.cxx"
+#include "cmTargetIncludeDirectoriesCommand.cxx"
+#include "cmTargetPropCommandBase.cxx"
 #include "cmUseMangledMesaCommand.cxx"
 #include "cmUtilitySourceCommand.cxx"
 #include "cmVariableRequiresCommand.cxx"
@@ -66,6 +69,8 @@ void GetPredefinedCommands(std::list<cmCommand*>&
   commands.push_back(new cmRemoveDefinitionsCommand);
   commands.push_back(new cmSourceGroupCommand);
   commands.push_back(new cmSubdirDependsCommand);
+  commands.push_back(new cmTargetIncludeDirectoriesCommand);
+  commands.push_back(new cmTargetCompileDefinitionsCommand);
   commands.push_back(new cmUseMangledMesaCommand);
   commands.push_back(new cmUtilitySourceCommand);
   commands.push_back(new cmVariableRequiresCommand);
index 055aab0..dec2b54 100644 (file)
@@ -172,10 +172,11 @@ satisfy dependencies.
 
 //----------------------------------------------------------------------------
 cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget* target, const char* config)
+::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
 {
   // Store context information.
   this->Target = target;
+  this->HeadTarget = head;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
     {
     // Follow the target dependencies.
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config))
+       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
       {
       // This target provides its own link interface information.
       this->AddLinkEntries(depender_index, iface->Libraries);
@@ -444,7 +445,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   if(entry.Target)
     {
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config))
+       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
   cmTarget::LinkImplementation const* impl =
-    this->Target->GetLinkImplementation(this->Config);
+    this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<std::string>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
@@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
     if(cmTarget* target = this->EntryList[*ni].Target)
       {
       if(cmTarget::LinkInterface const* iface =
-         target->GetLinkInterface(this->Config))
+         target->GetLinkInterface(this->Config, this->HeadTarget))
         {
         if(iface->Multiplicity > count)
           {
index 80a0454..1d5d1b9 100644 (file)
@@ -32,7 +32,7 @@ class cmake;
 class cmComputeLinkDepends
 {
 public:
-  cmComputeLinkDepends(cmTarget* target, const char* config);
+  cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
   ~cmComputeLinkDepends();
 
   // Basic information about each link item.
@@ -59,6 +59,7 @@ private:
 
   // Context information.
   cmTarget* Target;
+  cmTarget* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
index cd3ef59..896b50a 100644 (file)
@@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s.
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget* target, const char* config)
+::cmComputeLinkInformation(cmTarget* target, const char* config,
+                           cmTarget *headTarget)
 {
   // Store context information.
   this->Target = target;
+  this->HeadTarget = headTarget;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -265,7 +267,7 @@ cmComputeLinkInformation
   this->OrderDependentRPath = 0;
 
   // Get the language used for linking this target.
-  this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+  this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
   if(!this->LinkLanguage)
     {
     // The Compute method will do nothing, so skip the rest of the
@@ -277,6 +279,10 @@ cmComputeLinkInformation
   this->UseImportLibrary =
     this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
 
+  // Check whether we should skip dependencies on shared library files.
+  this->LinkDependsNoShared =
+    this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
+
   // On platforms without import libraries there may be a special flag
   // to use when creating a plugin (module) that obtains symbols from
   // the program that will load it.
@@ -499,7 +505,7 @@ bool cmComputeLinkInformation::Compute()
     }
 
   // Compute the ordered link line items.
-  cmComputeLinkDepends cld(this->Target, this->Config);
+  cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
   cld.SetOldLinkDirMode(this->OldLinkDirMode);
   cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
 
@@ -565,7 +571,8 @@ 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);
+  cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
+                                                          this->HeadTarget);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
@@ -650,7 +657,11 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
 
       // Pass the full path to the target file.
       std::string lib = tgt->GetFullPath(config, implib, true);
-      this->Depends.push_back(lib);
+      if(!this->LinkDependsNoShared ||
+         tgt->GetType() != cmTarget::SHARED_LIBRARY)
+        {
+        this->Depends.push_back(lib);
+        }
 
       this->AddTargetItem(lib, tgt);
       this->AddLibraryRuntimeInfo(lib, tgt);
@@ -1368,10 +1379,31 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
 //----------------------------------------------------------------------------
 void cmComputeLinkInformation::ComputeFrameworkInfo()
 {
-  // Avoid adding system framework paths.  See "man ld" on OS X.
-  this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
-  this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
-  this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
+  // Avoid adding implicit framework paths.
+  std::vector<std::string> implicitDirVec;
+
+  // Get platform-wide implicit directories.
+  if(const char* implicitLinks = this->Makefile->GetDefinition
+     ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
+    {
+    cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
+    }
+
+  // Get language-specific implicit directories.
+  std::string implicitDirVar = "CMAKE_";
+  implicitDirVar += this->LinkLanguage;
+  implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
+  if(const char* implicitDirs =
+     this->Makefile->GetDefinition(implicitDirVar.c_str()))
+    {
+    cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
+    }
+
+  for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
+      i != implicitDirVec.end(); ++i)
+    {
+    this->FrameworkPathsEmmitted.insert(*i);
+    }
 
   // Regular expression to extract a framework path and name.
   this->SplitFramework.compile("(.*)/(.*)\\.framework$");
@@ -1752,6 +1784,22 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
 }
 
 //----------------------------------------------------------------------------
+static void cmCLI_ExpandListUnique(const char* str,
+                                   std::vector<std::string>& out,
+                                   std::set<cmStdString>& emitted)
+{
+  std::vector<std::string> tmp;
+  cmSystemTools::ExpandListArgument(str, tmp);
+  for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
+    {
+    if(emitted.insert(*i).second)
+      {
+      out.push_back(*i);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
                                         bool for_install)
 {
@@ -1768,7 +1816,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
      linking_for_install);
   bool use_build_rpath =
-    (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
+    (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
      !linking_for_install);
   bool use_link_rpath =
     outputRuntime && linking_for_install &&
@@ -1776,10 +1824,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
 
   // Construct the RPATH.
+  std::set<cmStdString> emitted;
   if(use_install_rpath)
     {
     const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
-    cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
+    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
     }
   if(use_build_rpath || use_link_rpath)
     {
@@ -1791,7 +1840,10 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
       // support or if using the link path as an rpath.
       if(use_build_rpath)
         {
-        runtimeDirs.push_back(*ri);
+        if(emitted.insert(*ri).second)
+          {
+          runtimeDirs.push_back(*ri);
+          }
         }
       else if(use_link_rpath)
         {
@@ -1803,15 +1855,40 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
            !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
           {
-          runtimeDirs.push_back(*ri);
+          if(emitted.insert(*ri).second)
+            {
+            runtimeDirs.push_back(*ri);
+            }
           }
         }
       }
     }
 
+  // Add runtime paths required by the languages to always be
+  // present.  This is done even when skipping rpath support.
+  {
+  cmTarget::LinkClosure const* lc =
+    this->Target->GetLinkClosure(this->Config, this->HeadTarget);
+  for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
+      li != lc->Languages.end(); ++li)
+    {
+    std::string useVar = "CMAKE_" + *li +
+      "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
+    if(this->Makefile->IsOn(useVar.c_str()))
+      {
+      std::string dirVar = "CMAKE_" + *li +
+        "_IMPLICIT_LINK_DIRECTORIES";
+      if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
+        {
+        cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
+        }
+      }
+    }
+  }
+
   // Add runtime paths required by the platform to always be
   // present.  This is done even when skipping rpath support.
-  cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
+  cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
 }
 
 //----------------------------------------------------------------------------
index f60f8d3..1a76922 100644 (file)
@@ -29,7 +29,8 @@ class cmOrderDirectories;
 class cmComputeLinkInformation
 {
 public:
-  cmComputeLinkInformation(cmTarget* target, const char* config);
+  cmComputeLinkInformation(cmTarget* target, const char* config,
+                           cmTarget* headTarget);
   ~cmComputeLinkInformation();
   bool Compute();
 
@@ -74,6 +75,7 @@ private:
 
   // Context information.
   cmTarget* Target;
+  cmTarget* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
@@ -82,6 +84,7 @@ private:
   // Configuration information.
   const char* Config;
   const char* LinkLanguage;
+  bool LinkDependsNoShared;
 
   // Modes for dealing with dependent shared libraries.
   enum SharedDepMode
index ab77c6b..8fd95b9 100644 (file)
@@ -200,20 +200,48 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // Get the depender.
   cmTarget* depender = this->Targets[depender_index];
 
-  // Loop over all targets linked directly.
+  // Loop over all targets linked directly in all configs.
+  // We need to make targets depend on the union of all config-specific
+  // dependencies in all targets, because the generated build-systems can't
+  // deal with config-specific dependencies.
   {
-  cmTarget::LinkLibraryVectorType const& tlibs =
-    depender->GetOriginalLinkLibraries();
   std::set<cmStdString> emitted;
+  {
+  std::vector<std::string> tlibs;
+  depender->GetDirectLinkLibraries(0, tlibs, depender);
   // A target should not depend on itself.
   emitted.insert(depender->GetName());
-  for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+  for(std::vector<std::string>::const_iterator lib = tlibs.begin();
       lib != tlibs.end(); ++lib)
     {
     // Don't emit the same library twice for this target.
-    if(emitted.insert(lib->first).second)
+    if(emitted.insert(*lib).second)
       {
-      this->AddTargetDepend(depender_index, lib->first.c_str(), true);
+      this->AddTargetDepend(depender_index, lib->c_str(), true);
+      this->AddInterfaceDepends(depender_index, lib->c_str(),
+                                true, emitted);
+      }
+    }
+  }
+  std::vector<std::string> configs;
+  depender->GetMakefile()->GetConfigurations(configs);
+  for (std::vector<std::string>::const_iterator it = configs.begin();
+    it != configs.end(); ++it)
+    {
+    std::vector<std::string> tlibs;
+    depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
+    // 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)
+      {
+      // Don't emit the same library twice for this target.
+      if(emitted.insert(*lib).second)
+        {
+        this->AddTargetDepend(depender_index, lib->c_str(), true);
+        this->AddInterfaceDepends(depender_index, lib->c_str(),
+                                  true, emitted);
+        }
       }
     }
   }
@@ -237,6 +265,64 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 }
 
 //----------------------------------------------------------------------------
+void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
+                                                 cmTarget* dependee,
+                                                 const char *config,
+                                               std::set<cmStdString> &emitted)
+{
+  cmTarget* depender = this->Targets[depender_index];
+  if(cmTarget::LinkInterface const* iface =
+                                dependee->GetLinkInterface(config, depender))
+    {
+    for(std::vector<std::string>::const_iterator
+        lib = iface->Libraries.begin();
+        lib != iface->Libraries.end(); ++lib)
+      {
+      // Don't emit the same library twice for this target.
+      if(emitted.insert(*lib).second)
+        {
+        this->AddTargetDepend(depender_index, lib->c_str(), true);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
+                                             const char* dependee_name,
+                                             bool linking,
+                                             std::set<cmStdString> &emitted)
+{
+  cmTarget* depender = this->Targets[depender_index];
+  cmTarget* dependee =
+    depender->GetMakefile()->FindTargetToUse(dependee_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(linking && dependee &&
+     dependee->GetType() == cmTarget::EXECUTABLE &&
+     !dependee->IsExecutableWithExports())
+    {
+    dependee = 0;
+    }
+
+  if(dependee)
+    {
+    this->AddInterfaceDepends(depender_index, dependee, 0, emitted);
+    std::vector<std::string> configs;
+    depender->GetMakefile()->GetConfigurations(configs);
+    for (std::vector<std::string>::const_iterator it = configs.begin();
+      it != configs.end(); ++it)
+      {
+      // A target should not depend on itself.
+      emitted.insert(depender->GetName());
+      this->AddInterfaceDepends(depender_index, dependee,
+                                it->c_str(), emitted);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmComputeTargetDepends::AddTargetDepend(int depender_index,
                                              const char* dependee_name,
                                              bool linking)
index 67bce72..d6131cf 100644 (file)
@@ -48,7 +48,11 @@ private:
                        bool linking);
   void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking);
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
-
+  void AddInterfaceDepends(int depender_index, const char* dependee_name,
+                           bool linking, std::set<cmStdString> &emitted);
+  void AddInterfaceDepends(int depender_index, cmTarget* dependee,
+                           const char *config,
+                           std::set<cmStdString> &emitted);
   cmGlobalGenerator* GlobalGenerator;
   bool DebugMode;
   bool NoCycles;
index 347174a..0393ecf 100644 (file)
@@ -68,6 +68,9 @@ public:
         "If <output> names an existing directory the input file is placed "
         "in that directory with its original name.  "
         "\n"
+        "If the <input> file is modified the build system will re-run CMake "
+        "to re-configure the file and generate the build system again."
+        "\n"
         "This command replaces any variables in the input file referenced as "
         "${VAR} or @VAR@ with their values as determined by CMake.  If a "
         "variable is not defined, it will be replaced with nothing.  "
@@ -76,13 +79,18 @@ public:
         "will be C-style escaped.  "
         "The file will be configured with the current values of CMake "
         "variables. If @ONLY is specified, only variables "
-        "of the form @VAR@ will be replaces and ${VAR} will be ignored.  "
-        "This is useful for configuring scripts that use ${VAR}. "
-        "Any occurrences of #cmakedefine VAR will be replaced with "
-        "either #define VAR or /* #undef VAR */ depending on "
-        "the setting of VAR in CMake. Any occurrences of #cmakedefine01 VAR "
-        "will be replaced with either #define VAR 1 or #define VAR 0 "
-        "depending on whether VAR evaluates to TRUE or FALSE in CMake.\n"
+        "of the form @VAR@ will be replaced and ${VAR} will be ignored.  "
+        "This is useful for configuring scripts that use ${VAR}."
+        "\n"
+        "Input file lines of the form \"#cmakedefine VAR ...\" "
+        "will be replaced with either \"#define VAR ...\" or "
+        "\"/* #undef VAR */\" depending on whether VAR is set in CMake to "
+        "any value not considered a false constant by the if() command. "
+        "(Content of \"...\", if any, is processed as above.) "
+        "Input file lines of the form \"#cmakedefine01 VAR\" "
+        "will be replaced with either \"#define VAR 1\" or "
+        "\"#define VAR 0\" similarly."
+        "\n"
         "With NEWLINE_STYLE the line ending could be adjusted: \n"
         "    'UNIX' or 'LF' for \\n, 'DOS', 'WIN32' or 'CRLF' for \\r\\n.\n"
         "COPYONLY must not be used with NEWLINE_STYLE.\n";
index 1ae7035..85e49a9 100644 (file)
 #include "cmake.h"
 #include "cmCacheManager.h"
 #include "cmGlobalGenerator.h"
+#include "cmExportTryCompileFileGenerator.h"
 #include <cmsys/Directory.hxx>
 
+#include <assert.h>
+
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
 {
   this->BinaryDirectory = argv[1].c_str();
@@ -39,7 +42,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
      // is not used, so it matches regular command line parsing which has
      // the program name as arg 0
       for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
-             argv[i] != "OUTPUT_VARIABLE";
+             argv[i] != "OUTPUT_VARIABLE" &&
+             argv[i] != "LINK_LIBRARIES";
            ++i)
         {
         extraArgs++;
@@ -75,7 +79,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       {
       extraArgs++;
       for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" &&
-             argv[i] != "OUTPUT_VARIABLE";
+             argv[i] != "OUTPUT_VARIABLE" &&
+             argv[i] != "LINK_LIBRARIES";
            ++i)
         {
         extraArgs++;
@@ -85,6 +90,61 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       }
     }
 
+  std::vector<cmTarget*> targets;
+  std::string libsToLink = " ";
+  bool useOldLinkLibs = true;
+  for (i = 3; i < argv.size(); ++i)
+    {
+    if (argv[i] == "LINK_LIBRARIES")
+      {
+      if ( argv.size() <= (i+1) )
+        {
+        this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+          "LINK_LIBRARIES specified but there is no content");
+        return -1;
+        }
+      extraArgs++;
+      ++i;
+      useOldLinkLibs = false;
+      for ( ; i < argv.size() && argv[i] != "CMAKE_FLAGS"
+          && argv[i] != "COMPILE_DEFINITIONS" && argv[i] != "OUTPUT_VARIABLE";
+          ++i)
+        {
+        extraArgs++;
+        libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
+        cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str());
+        if (!tgt)
+          {
+          continue;
+          }
+        switch(tgt->GetType())
+        {
+        case cmTarget::SHARED_LIBRARY:
+        case cmTarget::STATIC_LIBRARY:
+        case cmTarget::UNKNOWN_LIBRARY:
+          break;
+        case cmTarget::EXECUTABLE:
+          if (tgt->IsExecutableWithExports())
+            {
+            break;
+            }
+        default:
+          this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+            "Only libraries may be used as try_compile IMPORTED "
+            "LINK_LIBRARIES.  Got " + std::string(tgt->GetName()) + " of "
+            "type " + tgt->GetTargetTypeName(tgt->GetType()) + ".");
+          return -1;
+        }
+        if (!tgt->IsImported())
+          {
+          continue;
+          }
+        targets.push_back(tgt);
+        }
+      break;
+      }
+    }
+
   // look for COPY_FILE
   std::string copyFile;
   for (i = 3; i < argv.size(); ++i)
@@ -247,6 +307,33 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       fprintf(fout, ")\n");
       }
 
+    /* Use a random file name to avoid rapid creation and deletion
+       of the same executable name (some filesystems fail on that).  */
+    sprintf(targetNameBuf, "cmTryCompileExec%u",
+            cmSystemTools::RandomSeed());
+    targetName = targetNameBuf;
+
+    if (!targets.empty())
+      {
+      std::string fname = "/" + std::string(targetName) + "Targets.cmake";
+      cmExportTryCompileFileGenerator tcfg;
+      tcfg.SetExportFile((this->BinaryDirectory + fname).c_str());
+      tcfg.SetExports(targets);
+      tcfg.SetConfig(this->Makefile->GetDefinition(
+                                          "CMAKE_TRY_COMPILE_CONFIGURATION"));
+
+      if(!tcfg.GenerateImportFile())
+        {
+        this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+                                     "could not write export file.");
+        fclose(fout);
+        return -1;
+        }
+      fprintf(fout,
+              "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
+              fname.c_str());
+      }
+
     /* for the TRY_COMPILEs we want to be able to specify the architecture.
       So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set
       CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to
@@ -286,18 +373,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       fprintf(fout, "SET(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
       }
 
-    /* Use a random file name to avoid rapid creation and deletion
-       of the same executable name (some filesystems fail on that).  */
-    sprintf(targetNameBuf, "cmTryCompileExec%u",
-            cmSystemTools::RandomSeed());
-    targetName = targetNameBuf;
-
     /* Put the executable at a known location (for COPY_FILE).  */
     fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
             this->BinaryDirectory.c_str());
     /* Create the actual executable.  */
     fprintf(fout, "ADD_EXECUTABLE(%s \"%s\")\n", targetName, source.c_str());
-    fprintf(fout, "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName);
+    if (useOldLinkLibs)
+      {
+      fprintf(fout,
+              "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName);
+      }
+    else
+      {
+      fprintf(fout, "TARGET_LINK_LIBRARIES(%s %s)\n",
+              targetName,
+              libsToLink.c_str());
+      }
     fclose(fout);
     projectName = "CMAKE_TRY_COMPILE";
     // if the source is not in CMakeTmp
index a1505bd..a4f6ac4 100644 (file)
@@ -54,8 +54,8 @@ std::string cmCryptoHash::HashFile(const char* file)
   this->Initialize();
 
   // Should be efficient enough on most system:
-  const int bufferSize = 4096;
-  char buffer[bufferSize];
+  cm_sha2_uint64_t buffer[512];
+  char* buffer_c = reinterpret_cast<char*>(buffer);
   unsigned char const* buffer_uc =
     reinterpret_cast<unsigned char const*>(buffer);
   // This copy loop is very sensitive on certain platforms with
@@ -65,7 +65,7 @@ std::string cmCryptoHash::HashFile(const char* file)
   // error occurred.  Therefore, the loop should be safe everywhere.
   while(fin)
     {
-    fin.read(buffer, bufferSize);
+    fin.read(buffer_c, sizeof(buffer));
     if(int gcount = static_cast<int>(fin.gcount()))
       {
       this->Append(buffer_uc, gcount);
index 07df7d5..f2f77ee 100644 (file)
@@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
     {
     return target->GetLocation(this->Config);
     }
-  return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config);
+  return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
 }
 
 //----------------------------------------------------------------------------
@@ -58,7 +58,7 @@ cmCustomCommandGenerator
   cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
   for(unsigned int j=1;j < commandLine.size(); ++j)
     {
-    std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile,
+    std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
                                                                this->Config);
     cmd += " ";
     if(this->OldStyle)
index 166a584..74a0ccb 100644 (file)
@@ -50,6 +50,7 @@ bool cmDepends::Write(std::ostream &makeDepends,
   std::vector<std::string> pairs;
   cmSystemTools::ExpandListArgument(srcStr, pairs);
 
+  std::map<std::string, std::set<std::string> > dependencies;
   for(std::vector<std::string>::iterator si = pairs.begin();
       si != pairs.end();)
     {
@@ -62,9 +63,14 @@ bool cmDepends::Write(std::ostream &makeDepends,
     obj = this->LocalGenerator->Convert(obj.c_str(),
                                         cmLocalGenerator::HOME_OUTPUT,
                                         cmLocalGenerator::MAKEFILE);
+    dependencies[obj].insert(src);
+    }
+  for(std::map<std::string, std::set<std::string> >::const_iterator
+      it = dependencies.begin(); it != dependencies.end(); ++it)
+    {
 
     // Write the dependencies for this pair.
-    if(!this->WriteDependencies(src.c_str(), obj.c_str(),
+    if(!this->WriteDependencies(it->second, it->first,
                                 makeDepends, internalDepends))
       {
       return false;
@@ -134,8 +140,9 @@ void cmDepends::Clear(const char *file)
 }
 
 //----------------------------------------------------------------------------
-bool cmDepends::WriteDependencies(const char*, const char*,
-                                  std::ostream&, std::ostream&)
+bool cmDepends::WriteDependencies(
+    const std::set<std::string>&, const std::string&,
+    std::ostream&, std::ostream&)
 {
   // This should be implemented by the subclass.
   return false;
@@ -174,8 +181,10 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
       // kdelibs/khtml this reduces the number of calls from 184k down to 92k,
       // or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s.
       dependerExists = cmSystemTools::FileExists(this->Depender);
-      DependencyVector tmp;
-      validDeps[this->Depender] = tmp;
+      // If we erase validDeps[this->Depender] by overwriting it with an empty
+      // vector, we lose dependencies for dependers that have multiple
+      // entries. No need to initialize the entry, std::map will do so on first
+      // access.
       currentDependencies = &validDeps[this->Depender];
       continue;
       }
index f7dc881..d787edd 100644 (file)
@@ -76,8 +76,10 @@ protected:
 
   // Write dependencies for the target file to the given stream.
   // Return true for success and false for failure.
-  virtual bool WriteDependencies(const char *src, const char* obj,
-    std::ostream& makeDepends, std::ostream& internalDepends);
+  virtual bool WriteDependencies(const std::set<std::string>& sources,
+                                 const std::string& obj,
+                                 std::ostream& makeDepends,
+                                 std::ostream& internalDepends);
 
   // Check dependencies for the target file in the given stream.
   // Return false if dependencies must be regenerated and true
index 44841a9..43b7b8a 100644 (file)
@@ -98,176 +98,179 @@ cmDependsC::~cmDependsC()
 }
 
 //----------------------------------------------------------------------------
-bool cmDependsC::WriteDependencies(const char *src, const char *obj,
-  std::ostream& makeDepends, std::ostream& internalDepends)
+bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
+                                   const std::string& obj,
+                                   std::ostream& makeDepends,
+                                   std::ostream& internalDepends)
 {
   // Make sure this is a scanning instance.
-  if(!src || src[0] == '\0')
+  if(sources.empty() || sources.begin()->empty())
     {
     cmSystemTools::Error("Cannot scan dependencies without a source file.");
     return false;
     }
-  if(!obj || obj[0] == '\0')
+  if(obj.empty())
     {
     cmSystemTools::Error("Cannot scan dependencies without an object file.");
     return false;
     }
 
+  std::set<cmStdString> dependencies;
+  bool haveDeps = false;
+
   if (this->ValidDeps != 0)
     {
     std::map<std::string, DependencyVector>::const_iterator tmpIt =
                                                     this->ValidDeps->find(obj);
     if (tmpIt!= this->ValidDeps->end())
       {
-      // Write the dependencies to the output stream.  Makefile rules
-      // 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;
       for(DependencyVector::const_iterator i=tmpIt->second.begin();
          i != tmpIt->second.end(); ++i)
         {
-        makeDepends << obj << ": " <<
-           this->LocalGenerator->Convert(i->c_str(),
-                                         cmLocalGenerator::HOME_OUTPUT,
-                                         cmLocalGenerator::MAKEFILE)
-           << std::endl;
-        internalDepends << " " << i->c_str() << std::endl;
+        dependencies.insert(*i);
         }
-      makeDepends << std::endl;
-      return true;
+      haveDeps = true;
       }
     }
 
-  // Walk the dependency graph starting with the source file.
-  bool first = true;
-  UnscannedEntry root;
-  root.FileName = src;
-  this->Unscanned.push(root);
-  this->Encountered.clear();
-  this->Encountered.insert(src);
-  std::set<cmStdString> dependencies;
-  std::set<cmStdString> scanned;
+  if (!haveDeps)
+    {
+    // Walk the dependency graph starting with the source file.
+    int srcFiles = (int)sources.size();
+    this->Encountered.clear();
+
+    for(std::set<std::string>::const_iterator srcIt = sources.begin();
+        srcIt != sources.end(); ++srcIt)
+      {
+      UnscannedEntry root;
+      root.FileName = *srcIt;
+      this->Unscanned.push(root);
+      this->Encountered.insert(*srcIt);
+      }
 
-  // Use reserve to allocate enough memory for tempPathStr
-  // so that during the loops no memory is allocated or freed
-  std::string tempPathStr;
-  tempPathStr.reserve(4*1024);
+    std::set<cmStdString> scanned;
 
-  while(!this->Unscanned.empty())
-    {
-    // Get the next file to scan.
-    UnscannedEntry current = this->Unscanned.front();
-    this->Unscanned.pop();
+    // Use reserve to allocate enough memory for tempPathStr
+    // so that during the loops no memory is allocated or freed
+    std::string tempPathStr;
+    tempPathStr.reserve(4*1024);
 
-    // If not a full path, find the file in the include path.
-    std::string fullName;
-    if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
+    while(!this->Unscanned.empty())
       {
-      if(cmSystemTools::FileExists(current.FileName.c_str(), true))
+      // Get the next file to scan.
+      UnscannedEntry current = this->Unscanned.front();
+      this->Unscanned.pop();
+
+      // If not a full path, find the file in the include path.
+      std::string fullName;
+      if((srcFiles>0)
+         || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
         {
-        fullName = current.FileName;
+        if(cmSystemTools::FileExists(current.FileName.c_str(), true))
+          {
+          fullName = current.FileName;
+          }
         }
-      }
-    else if(!current.QuotedLocation.empty() &&
-            cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
-      {
-      // The include statement producing this entry was a double-quote
-      // include and the included file is present in the directory of
-      // the source containing the include statement.
-      fullName = current.QuotedLocation;
-      }
-    else
-      {
-      std::map<cmStdString, cmStdString>::iterator
-        headerLocationIt=this->HeaderLocationCache.find(current.FileName);
-      if (headerLocationIt!=this->HeaderLocationCache.end())
+      else if(!current.QuotedLocation.empty() &&
+              cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
         {
-        fullName=headerLocationIt->second;
+        // The include statement producing this entry was a double-quote
+        // include and the included file is present in the directory of
+        // the source containing the include statement.
+        fullName = current.QuotedLocation;
         }
-      else for(std::vector<std::string>::const_iterator i =
-            this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+      else
         {
-        // Construct the name of the file as if it were in the current
-        // include directory.  Avoid using a leading "./".
-
-        tempPathStr = "";
-        if((*i) == ".")
+        std::map<cmStdString, cmStdString>::iterator
+          headerLocationIt=this->HeaderLocationCache.find(current.FileName);
+        if (headerLocationIt!=this->HeaderLocationCache.end())
           {
-          tempPathStr += current.FileName;
+          fullName=headerLocationIt->second;
           }
-        else
+        else for(std::vector<std::string>::const_iterator i =
+              this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
           {
-          tempPathStr += *i;
-          tempPathStr+="/";
-          tempPathStr+=current.FileName;
-          }
+          // Construct the name of the file as if it were in the current
+          // include directory.  Avoid using a leading "./".
 
-        // Look for the file in this location.
-        if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
-          {
-          fullName = tempPathStr;
-          HeaderLocationCache[current.FileName]=fullName;
-          break;
+          tempPathStr = "";
+          if((*i) == ".")
+            {
+            tempPathStr += current.FileName;
+            }
+          else
+            {
+            tempPathStr += *i;
+            tempPathStr+="/";
+            tempPathStr+=current.FileName;
+            }
+
+          // Look for the file in this location.
+          if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
+            {
+            fullName = tempPathStr;
+            HeaderLocationCache[current.FileName]=fullName;
+            break;
+            }
           }
         }
-      }
-
-    // Complain if the file cannot be found and matches the complain
-    // regex.
-    if(fullName.empty() &&
-       this->IncludeRegexComplain.find(current.FileName.c_str()))
-      {
-      cmSystemTools::Error("Cannot find file \"",
-                           current.FileName.c_str(), "\".");
-      return false;
-      }
 
-    // Scan the file if it was found and has not been scanned already.
-    if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
-      {
-      // Record scanned files.
-      scanned.insert(fullName);
+      // Complain if the file cannot be found and matches the complain
+      // regex.
+      if(fullName.empty() &&
+        this->IncludeRegexComplain.find(current.FileName.c_str()))
+        {
+        cmSystemTools::Error("Cannot find file \"",
+                            current.FileName.c_str(), "\".");
+        return false;
+        }
 
-      // Check whether this file is already in the cache
-      std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
-        this->FileCache.find(fullName);
-      if (fileIt!=this->FileCache.end())
+      // Scan the file if it was found and has not been scanned already.
+      if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
         {
-        fileIt->second->Used=true;
-        dependencies.insert(fullName);
-        for (std::vector<UnscannedEntry>::const_iterator incIt=
-               fileIt->second->UnscannedEntries.begin();
-             incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
+        // Record scanned files.
+        scanned.insert(fullName);
+
+        // Check whether this file is already in the cache
+        std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
+          this->FileCache.find(fullName);
+        if (fileIt!=this->FileCache.end())
           {
-          if (this->Encountered.find(incIt->FileName) ==
-              this->Encountered.end())
+          fileIt->second->Used=true;
+          dependencies.insert(fullName);
+          for (std::vector<UnscannedEntry>::const_iterator incIt=
+                fileIt->second->UnscannedEntries.begin();
+              incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
             {
-            this->Encountered.insert(incIt->FileName);
-            this->Unscanned.push(*incIt);
+            if (this->Encountered.find(incIt->FileName) ==
+                this->Encountered.end())
+              {
+              this->Encountered.insert(incIt->FileName);
+              this->Unscanned.push(*incIt);
+              }
             }
           }
-        }
-      else
-        {
-
-        // Try to scan the file.  Just leave it out if we cannot find
-        // it.
-        std::ifstream fin(fullName.c_str());
-        if(fin)
+        else
           {
-          // Add this file as a dependency.
-          dependencies.insert(fullName);
 
-          // Scan this file for new dependencies.  Pass the directory
-          // containing the file to handle double-quote includes.
-          std::string dir = cmSystemTools::GetFilenamePath(fullName);
-          this->Scan(fin, dir.c_str(), fullName);
+          // Try to scan the file.  Just leave it out if we cannot find
+          // it.
+          std::ifstream fin(fullName.c_str());
+          if(fin)
+            {
+            // Add this file as a dependency.
+            dependencies.insert(fullName);
+
+            // Scan this file for new dependencies.  Pass the directory
+            // containing the file to handle double-quote includes.
+            std::string dir = cmSystemTools::GetFilenamePath(fullName);
+            this->Scan(fin, dir.c_str(), fullName);
+            }
           }
         }
-      }
 
-    first = false;
+      srcFiles--;
+      }
     }
 
   // Write the dependencies to the output stream.  Makefile rules
@@ -275,7 +278,7 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj,
   // convert the dependencies to paths relative to the home output
   // directory.  We must do the same here.
   internalDepends << obj << std::endl;
-  for(std::set<cmStdString>::iterator i=dependencies.begin();
+  for(std::set<cmStdString>::const_iterator i=dependencies.begin();
       i != dependencies.end(); ++i)
     {
     makeDepends << obj << ": " <<
index bd9a4b7..16dfad7 100644 (file)
@@ -32,11 +32,9 @@ public:
   virtual ~cmDependsC();
 
 protected:
-  typedef std::vector<char> t_CharBuffer;
-
   // Implement writing/checking methods required by superclass.
-  virtual bool WriteDependencies(const char *src,
-                                 const char *file,
+  virtual bool WriteDependencies(const std::set<std::string>& sources,
+                                 const std::string&           obj,
                                  std::ostream& makeDepends,
                                  std::ostream& internalDepends);
 
@@ -82,7 +80,6 @@ protected:
   const std::map<std::string, DependencyVector>* ValidDeps;
   std::set<cmStdString> Encountered;
   std::queue<UnscannedEntry> Unscanned;
-  t_CharBuffer Buffer;
 
   std::map<cmStdString, cmIncludeLines *> FileCache;
   std::map<cmStdString, cmStdString> HeaderLocationCache;
index 3e66058..e41e5ea 100644 (file)
@@ -170,44 +170,50 @@ cmDependsFortran::~cmDependsFortran()
 }
 
 //----------------------------------------------------------------------------
-bool cmDependsFortran::WriteDependencies(const char *src, const char *obj,
-                                         std::ostream&, std::ostream&)
+bool cmDependsFortran::WriteDependencies(
+    const std::set<std::string>& sources, const std::string& obj,
+    std::ostream&, std::ostream&)
 {
   // Make sure this is a scanning instance.
-  if(!src || src[0] == '\0')
+  if(sources.empty() || sources.begin()->empty())
     {
-    cmSystemTools::Error("Cannot scan dependencies without an source file.");
+    cmSystemTools::Error("Cannot scan dependencies without a source file.");
     return false;
     }
-  if(!obj || obj[0] == '\0')
+  if(obj.empty())
     {
     cmSystemTools::Error("Cannot scan dependencies without an object file.");
     return false;
     }
 
-  // Get the information object for this source.
-  cmDependsFortranSourceInfo& info =
-    this->Internal->CreateObjectInfo(obj, src);
+  bool okay = true;
+  for(std::set<std::string>::const_iterator it = sources.begin();
+      it != sources.end(); ++it)
+    {
+    const std::string& src = *it;
+    // Get the information object for this source.
+    cmDependsFortranSourceInfo& info =
+      this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
 
-  // Make a copy of the macros defined via ADD_DEFINITIONS
-  std::set<std::string> ppDefines(this->PPDefinitions.begin(),
-                                  this->PPDefinitions.end());
+    // Make a copy of the macros defined via ADD_DEFINITIONS
+    std::set<std::string> ppDefines(this->PPDefinitions.begin(),
+                                    this->PPDefinitions.end());
 
-  // Create the parser object. The constructor takes ppMacro and info per
-  // reference, so we may look into the resulting objects later.
-  cmDependsFortranParser parser(this, ppDefines, info);
+    // Create the parser object. The constructor takes ppMacro and info per
+    // reference, so we may look into the resulting objects later.
+    cmDependsFortranParser parser(this, ppDefines, info);
 
-  // Push on the starting file.
-  cmDependsFortranParser_FilePush(&parser, src);
+    // Push on the starting file.
+    cmDependsFortranParser_FilePush(&parser, src.c_str());
 
-  // Parse the translation unit.
-  if(cmDependsFortran_yyparse(parser.Scanner) != 0)
-    {
-    // Failed to parse the file.  Report failure to write dependencies.
-    return false;
+    // Parse the translation unit.
+    if(cmDependsFortran_yyparse(parser.Scanner) != 0)
+      {
+      // Failed to parse the file.  Report failure to write dependencies.
+      okay = false;
+      }
     }
-
-  return true;
+  return okay;
 }
 
 //----------------------------------------------------------------------------
index cdfde6e..cb40796 100644 (file)
@@ -66,7 +66,7 @@ protected:
 
   // Implement writing/checking methods required by superclass.
   virtual bool WriteDependencies(
-    const char *src, const char *file,
+    const std::set<std::string>& sources, const std::string& file,
     std::ostream& makeDepends, std::ostream& internalDepends);
 
   // Actually write the depenencies to the streams.
index ba0e8fb..949d465 100644 (file)
@@ -25,11 +25,11 @@ cmDependsJava::~cmDependsJava()
 }
 
 //----------------------------------------------------------------------------
-bool cmDependsJava::WriteDependencies(const char *src, const char *,
-  std::ostream&, std::ostream&)
+bool cmDependsJava::WriteDependencies(const std::set<std::string>& sources,
+    const std::string&, std::ostream&, std::ostream&)
 {
   // Make sure this is a scanning instance.
-  if(!src || src[0] == '\0')
+  if(sources.empty() || sources.begin()->empty())
     {
     cmSystemTools::Error("Cannot scan dependencies without an source file.");
     return false;
index bf7e234..22af53f 100644 (file)
@@ -29,7 +29,8 @@ public:
 
 protected:
   // Implement writing/checking methods required by superclass.
-  virtual bool WriteDependencies(const char *src, const char *file,
+  virtual bool WriteDependencies(
+    const std::set<std::string>& sources, const std::string& file,
     std::ostream& makeDepends, std::ostream& internalDepends);
   virtual bool CheckDependencies(std::istream& internalDepends,
                                  const char* internalDependsFileName,
index 445fd0e..6cc3f25 100644 (file)
   "strings which contain a '>' for example.\n"                          \
   "  $<COMMA>                  = A literal ','. Used to compare "       \
   "strings which contain a ',' for example.\n"                          \
+  "  $<SEMICOLON>              = A literal ';'. Used to prevent "       \
+  "list expansion on an argument with ';'.\n"                           \
+  "  $<TARGET_NAME:...>        = Marks ... as being the name of a "     \
+  "target.  This is required if exporting targets to multiple "         \
+  "dependent export sets.  The '...' must be a literal name of a "      \
+  "target- it may not contain generator expressions.\n"                 \
+  "  $<INSTALL_INTERFACE:...>  = content of \"...\" when the property " \
+  "is exported using install(EXPORT), and empty otherwise.\n"           \
+  "  $<BUILD_INTERFACE:...>    = content of \"...\" when the property " \
+  "is exported using export(), or when the target is used by another "  \
+  "target in the same buildsystem. Expands to the empty string "        \
+  "otherwise.\n"                                                        \
   "  $<TARGET_FILE:tgt>        = main file (.exe, .so.1.2, .a)\n"       \
   "  $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n"   \
   "  $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n"            \
   "  $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n"    \
   "  $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n"    \
   "\n"                                                                  \
-  "  $<TARGET_PROPERTY:tgt,prop>   = The value of the property prop\n"  \
-  "on the target tgt. Note that tgt is not added as a dependency of\n"  \
-  "the target this expression is evaluated on.\n"                       \
+  "  $<TARGET_PROPERTY:tgt,prop>   = The value of the property prop "   \
+  "on the target tgt.\n"                                                \
+  "Note that tgt is not added as a dependency of the target this "      \
+  "expression is evaluated on.\n"                                       \
+  "  $<TARGET_POLICY:pol>          = '1' if the policy was NEW when "   \
+  "the 'head' target was created, else '0'.  If the policy was not "    \
+  "set, the warning message for the policy will be emitted.  This "     \
+  "generator expression only works for a subset of policies.\n"         \
+  "  $<INSTALL_PREFIX>         = Content of the install prefix when "   \
+  "the target is exported via INSTALL(EXPORT) and empty otherwise.\n"   \
   "Boolean expressions:\n"                                              \
   "  $<AND:?[,?]...>           = '1' if all '?' are '1', else '0'\n"    \
   "  $<OR:?[,?]...>            = '0' if all '?' are '0', else '1'\n"    \
@@ -49,7 +68,7 @@
 #define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS                       \
   CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
   "Expressions with an implicit 'this' target:\n"                       \
-  "  $<TARGET_PROPERTY:prop>   = The value of the property prop on\n"   \
+  "  $<TARGET_PROPERTY:prop>   = The value of the property prop on "    \
   "the target on which the generator expression is evaluated.\n"        \
   ""
 
index 8db0e8f..61f9f5a 100644 (file)
@@ -255,6 +255,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "CMAKE_EXTRA_GENERATOR (e.g. \"Eclipse CDT4\").",false,
      "Variables that Provide Information");
   cm->DefineProperty
+    ("CMAKE_GENERATOR_TOOLSET", cmProperty::VARIABLE,
+     "Native build system toolset name specified by user.",
+     "Some CMake generators support a toolset name to be given to the "
+     "native build system to choose a compiler.  "
+     "If the user specifies a toolset name (e.g. via the cmake -T option) "
+     "the value will be available in this variable.",false,
+     "Variables that Provide Information");
+  cm->DefineProperty
     ("CMAKE_HOME_DIRECTORY", cmProperty::VARIABLE,
      "Path to top of source tree.",
      "This is the path to the top level of the source tree.",false,
@@ -295,6 +303,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      ,false,
      "Variables that Provide Information");
   cm->DefineProperty
+    ("CMAKE_XCODE_PLATFORM_TOOLSET", cmProperty::VARIABLE,
+     "Xcode compiler selection.",
+     "Xcode supports selection of a compiler from one of the installed "
+     "toolsets.  "
+     "CMake provides the name of the chosen toolset in this variable, "
+     "if any is explicitly selected (e.g. via the cmake -T option)."
+     ,false,
+     "Variables that Provide Information");
+  cm->DefineProperty
     ("CMAKE_MINOR_VERSION", cmProperty::VARIABLE,
      "The Minor version of cmake (i.e. the 4 in X.4.X).",
      "This specifies the minor version of the CMake"
@@ -896,6 +913,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
       " script, it may get fatal error messages from the script.",false,
       "Variables That Change Behavior");
 
+  cm->DefineProperty
+    ("CMAKE_DEBUG_TARGET_PROPERTIES", cmProperty::VARIABLE,
+     "Enables tracing output for target properties.",
+     "This variable can be populated with a list of properties to generate "
+     "debug output for when evaluating target properties.  Currently it can "
+     "only be used when evaluating the INCLUDE_DIRECTORIES target property.  "
+     "In that case, it outputs a backtrace for each include directory in "
+     "the build.  Default is unset.",false,"Variables That Change Behavior");
+
   // Variables defined by CMake that describe the system
 
   cm->DefineProperty
@@ -996,7 +1022,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      false,
      "Variables That Describe the System");
 
-  int msvc_versions[] = { 60, 70, 71, 80, 90, 100, 110, 0 };
+  int msvc_versions[] = { 60, 70, 71, 80, 90, 100, 110, 120, 0 };
   for (int i = 0; msvc_versions[i] != 0; i ++)
     {
     const char minor = (char)('0' + (msvc_versions[i] % 10));
@@ -1043,6 +1069,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "  1500 = VS  9.0\n"
      "  1600 = VS 10.0\n"
      "  1700 = VS 11.0\n"
+     "  1800 = VS 12.0\n"
      "",
      false,
      "Variables That Describe the System");
@@ -1138,6 +1165,18 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "Variables that Control the Build");
 
   cm->DefineProperty
+    ("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE", cmProperty::VARIABLE,
+     "Automatically add the current source- and build directories "
+     "to the INTERFACE_INCLUDE_DIRECTORIES.",
+     "If this variable is enabled, CMake automatically adds for each shared "
+     "library target, static library target, module target and executable "
+     "target, ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} to "
+     "the INTERFACE_INCLUDE_DIRECTORIES."
+     "By default CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE is OFF.",
+     false,
+     "Variables that Control the Build");
+
+  cm->DefineProperty
     ("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE,
      "The rpath to use for installed targets.",
      "A semicolon-separated list specifying the rpath "
@@ -1222,6 +1261,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "Variables that Control the Build");
 
   cm->DefineProperty
+    ("CMAKE_LINK_DEPENDS_NO_SHARED", cmProperty::VARIABLE,
+     "Whether to skip link dependencies on shared library files.",
+     "This variable initializes the LINK_DEPENDS_NO_SHARED "
+     "property on targets when they are created.  "
+     "See that target property for additional information.",
+     false,
+     "Variables that Control the Build");
+
+  cm->DefineProperty
     ("CMAKE_AUTOMOC", cmProperty::VARIABLE,
      "Whether to handle moc automatically for Qt targets.",
      "This variable is used to initialize the "
@@ -1452,7 +1500,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "  PathScale = PathScale (pathscale.com)\n"
      "  SDCC = Small Device C Compiler (sdcc.sourceforge.net)\n"
      "  SunPro = Oracle Solaris Studio (oracle.com)\n"
-     "  TI_DSP = Texas Instruments (ti.com)\n"
+     "  TI = Texas Instruments (ti.com)\n"
      "  TinyCC = Tiny C Compiler (tinycc.org)\n"
      "  Watcom = Open Watcom (openwatcom.org)\n"
      "  XL, VisualAge, zOS = IBM XL (ibm.com)\n"
@@ -1504,7 +1552,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
     ("CMAKE_COMPILER_IS_GNU<LANG>", cmProperty::VARIABLE,
      "True if the compiler is GNU.",
      "If the selected <LANG> compiler is the GNU "
-     "compiler then this is TRUE, if not it is FALSE.",false,
+     "compiler then this is TRUE, if not it is FALSE. "
+     "Unlike the other per-language variables, this uses the GNU syntax for "
+     "identifying languages instead of the CMake syntax. Recognized values of "
+     "the <LANG> suffix are:\n"
+     "  CC = C compiler\n"
+     "  CXX = C++ compiler\n"
+     "  G77 = Fortran compiler",
+     false,
      "Variables for Languages");
 
   cm->DefineProperty
@@ -1612,6 +1667,23 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "These paths are implicit linker search directories for the compiler's "
      "language.  "
      "CMake automatically detects these directories for each language and "
+     "reports the results in this variable."
+     "\n"
+     "When a library in one of these directories is given by full path to "
+     "target_link_libraries() CMake will generate the -l<name> form on "
+     "link lines to ensure the linker searches its implicit directories "
+     "for the library.  "
+     "Note that some toolchains read implicit directories from an "
+     "environment variable such as LIBRARY_PATH so keep its value "
+     "consistent when operating in a given build tree.",false,
+     "Variables for Languages");
+
+  cm->DefineProperty
+    ("CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", cmProperty::VARIABLE,
+     "Implicit linker framework search path detected for language <LANG>.",
+     "These paths are implicit linker framework search directories for "
+     "the compiler's language.  "
+     "CMake automatically detects these directories for each language and "
      "reports the results in this variable.", false,
      "Variables for Languages");
 
@@ -1803,6 +1875,9 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
                      cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH",
                      cmProperty::VARIABLE,0,0);
+  cm->DefineProperty(
+    "CMAKE_<LANG>_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH",
+    cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS",
                      cmProperty::VARIABLE,0,0);
   cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS",
index e4bb251..ee963f9 100644 (file)
@@ -65,7 +65,12 @@ public:
       "any of the extra variables that are created by the project command. "
       "Example languages are CXX, C, Fortran. "
       "If OPTIONAL is used, use the CMAKE_<languageName>_COMPILER_WORKS "
-      "variable to check whether the language has been enabled successfully.";
+      "variable to check whether the language has been enabled successfully."
+      "\n"
+      "This command must be called on file scope (not inside a function) and "
+      "the language enabled can only be used in the calling project or its "
+      "subdirectories added by add_subdirectory(). Also note that at present, "
+      "the OPTIONAL argument does not work.";
     }
 
   cmTypeMacro(cmEnableLanguageCommand, cmCommand);
index fb3f39f..7147f86 100644 (file)
@@ -22,15 +22,20 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator()
 //----------------------------------------------------------------------------
 bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
 {
-  // Create all the imported targets.
+  std::vector<cmTarget*> allTargets;
+  {
+  std::string expectedTargets;
+  std::string sep;
   for(std::vector<cmTarget*>::const_iterator
         tei = this->Exports->begin();
       tei != this->Exports->end(); ++tei)
     {
+    expectedTargets += sep + this->Namespace + (*tei)->GetName();
+    sep = " ";
     cmTarget* te = *tei;
     if(this->ExportedTargets.insert(te).second)
       {
-      this->GenerateImportTargetCode(os, te);
+      allTargets.push_back(te);
       }
     else
       {
@@ -44,14 +49,46 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
       }
     }
 
+  this->GenerateExpectedTargetsCode(os, expectedTargets);
+  }
+
+  std::vector<std::string> missingTargets;
+
+  // Create all the imported targets.
+  for(std::vector<cmTarget*>::const_iterator
+        tei = allTargets.begin();
+      tei != allTargets.end(); ++tei)
+    {
+    cmTarget* te = *tei;
+    this->GenerateImportTargetCode(os, te);
+
+    te->AppendBuildInterfaceIncludes();
+
+    ImportPropertyMap properties;
+
+    this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
+                                    cmGeneratorExpression::BuildInterface,
+                                    properties, missingTargets);
+    this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
+                                    cmGeneratorExpression::BuildInterface,
+                                    properties, missingTargets);
+    this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
+                                  te, properties);
+    this->PopulateCompatibleInterfaceProperties(te, properties);
+
+    this->GenerateInterfaceProperties(te, os, properties);
+    }
+
   // Generate import file content for each configuration.
   for(std::vector<std::string>::const_iterator
         ci = this->Configurations.begin();
       ci != this->Configurations.end(); ++ci)
     {
-    this->GenerateImportConfig(os, ci->c_str());
+    this->GenerateImportConfig(os, ci->c_str(), missingTargets);
     }
 
+  this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
   return true;
 }
 
@@ -59,7 +96,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
 void
 cmExportBuildFileGenerator
 ::GenerateImportTargetsConfig(std::ostream& os,
-                              const char* config, std::string const& suffix)
+                              const char* config, std::string const& suffix,
+                            std::vector<std::string> &missingTargets)
 {
   for(std::vector<cmTarget*>::const_iterator
         tei = this->Exports->begin();
@@ -72,9 +110,12 @@ cmExportBuildFileGenerator
     if(!properties.empty())
       {
       // Get the rest of the target details.
-      std::vector<std::string> missingTargets;
       this->SetImportDetailProperties(config, suffix,
                                       target, properties, missingTargets);
+      this->SetImportLinkInterface(config, suffix,
+                                   cmGeneratorExpression::BuildInterface,
+                                   target, properties, missingTargets);
+
 
       // TOOD: PUBLIC_HEADER_LOCATION
       // This should wait until the build feature propagation stuff
@@ -83,7 +124,6 @@ cmExportBuildFileGenerator
       //                              properties);
 
       // Generate code in the export file.
-      this->GenerateMissingTargetsCheckCode(os, missingTargets);
       this->GenerateImportPropertyCode(os, config, target, properties);
       }
     }
index 726537b..5e1be16 100644 (file)
@@ -44,7 +44,8 @@ protected:
   virtual bool GenerateMainFile(std::ostream& os);
   virtual void GenerateImportTargetsConfig(std::ostream& os,
                                            const char* config,
-                                           std::string const& suffix);
+                                           std::string const& suffix,
+                            std::vector<std::string> &missingTargets);
   virtual void HandleMissingTarget(std::string& link_libs,
                                    std::vector<std::string>& missingTargets,
                                    cmMakefile* mf,
index 8dffae4..27ec56b 100644 (file)
 #include "cmTarget.h"
 #include "cmTargetExport.h"
 #include "cmVersion.h"
+#include "cmComputeLinkInformation.h"
 
 #include <cmsys/auto_ptr.hxx>
+#include <assert.h>
 
 //----------------------------------------------------------------------------
 cmExportFileGenerator::cmExportFileGenerator()
@@ -81,16 +83,16 @@ bool cmExportFileGenerator::GenerateImportFile()
 
   // Protect that file against use with older CMake versions.
   os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
-  os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
-     << "   MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
-     << "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";
+  os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
+     << "   message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
+     << "endif()\n";
 
   // Isolate the file policy level.
   // We use 2.6 here instead of the current version because newer
   // versions of CMake should be able to export files imported by 2.6
   // until the import format changes.
-  os << "CMAKE_POLICY(PUSH)\n"
-     << "CMAKE_POLICY(VERSION 2.6)\n";
+  os << "cmake_policy(PUSH)\n"
+     << "cmake_policy(VERSION 2.6)\n";
 
   // Start with the import file header.
   this->GenerateImportHeaderCode(os);
@@ -100,14 +102,15 @@ bool cmExportFileGenerator::GenerateImportFile()
 
   // End with the import file footer.
   this->GenerateImportFooterCode(os);
-  os << "CMAKE_POLICY(POP)\n";
+  os << "cmake_policy(POP)\n";
 
   return result;
 }
 
 //----------------------------------------------------------------------------
 void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
-                                                 const char* config)
+                                    const char* config,
+                                    std::vector<std::string> &missingTargets)
 {
   // Construct the property configuration suffix.
   std::string suffix = "_";
@@ -121,7 +124,480 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
     }
 
   // Generate the per-config target information.
-  this->GenerateImportTargetsConfig(os, config, suffix);
+  this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
+                                              cmTarget *target,
+                                              ImportPropertyMap &properties)
+{
+  const char *input = target->GetProperty(propName);
+  if (input)
+    {
+    properties[propName] = input;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
+                      const char *outputName,
+                      cmTarget *target,
+                      cmGeneratorExpression::PreprocessContext preprocessRule,
+                      ImportPropertyMap &properties,
+                      std::vector<std::string> &missingTargets)
+{
+  const char *input = target->GetProperty(propName);
+  if (input)
+    {
+    if (!*input)
+      {
+      // Set to empty
+      properties[outputName] = "";
+      return;
+      }
+
+    std::string prepro = cmGeneratorExpression::Preprocess(input,
+                                                           preprocessRule);
+    if (!prepro.empty())
+      {
+      this->ResolveTargetsInGeneratorExpressions(prepro, target,
+                                                 missingTargets);
+      properties[outputName] = prepro;
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+static bool isSubDirectory(const char* a, const char* b)
+{
+  return (cmSystemTools::ComparePath(a, b) ||
+          cmSystemTools::IsSubDirectory(a, b));
+}
+
+//----------------------------------------------------------------------------
+static bool checkInterfaceDirs(const std::string &prepro,
+                      cmTarget *target)
+{
+  const char* installDir =
+            target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+  const char* topSourceDir = target->GetMakefile()->GetHomeDirectory();
+  const char* topBinaryDir = target->GetMakefile()->GetHomeOutputDirectory();
+
+  std::vector<std::string> parts;
+  cmGeneratorExpression::Split(prepro, parts);
+
+  const bool inSourceBuild = strcmp(topSourceDir, topBinaryDir) == 0;
+
+  for(std::vector<std::string>::iterator li = parts.begin();
+      li != parts.end(); ++li)
+    {
+    if (cmGeneratorExpression::Find(*li) != std::string::npos)
+      {
+      continue;
+      }
+    if (strncmp(li->c_str(), "${_IMPORT_PREFIX}", 17) == 0)
+      {
+      continue;
+      }
+    if (!cmSystemTools::FileIsFullPath(li->c_str()))
+      {
+      cmOStringStream e;
+      e << "Target \"" << target->GetName() << "\" "
+           "INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n"
+           "  \"" << *li << "\"";
+      target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
+                                          e.str().c_str());
+      return false;
+      }
+    if (isSubDirectory(li->c_str(), installDir))
+      {
+      continue;
+      }
+    if (isSubDirectory(li->c_str(), topBinaryDir))
+      {
+      cmOStringStream e;
+      e << "Target \"" << target->GetName() << "\" "
+           "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
+           "  \"" << *li << "\"\nwhich is prefixed in the build directory.";
+      target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
+                                          e.str().c_str());
+      return false;
+      }
+    if (!inSourceBuild)
+      {
+      if (isSubDirectory(li->c_str(), topSourceDir))
+        {
+        cmOStringStream e;
+        e << "Target \"" << target->GetName() << "\" "
+            "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n"
+            "  \"" << *li << "\"\nwhich is prefixed in the source directory.";
+        target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
+                                            e.str().c_str());
+        return false;
+        }
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
+                      cmTarget *target,
+                      cmGeneratorExpression::PreprocessContext preprocessRule,
+                      ImportPropertyMap &properties,
+                      std::vector<std::string> &missingTargets)
+{
+  assert(preprocessRule == cmGeneratorExpression::InstallInterface);
+
+  const char *propName = "INTERFACE_INCLUDE_DIRECTORIES";
+  const char *input = target->GetProperty(propName);
+  if (!input)
+    {
+    return;
+    }
+  if (!*input)
+    {
+    // Set to empty
+    properties[propName] = "";
+    return;
+    }
+
+  std::string prepro = cmGeneratorExpression::Preprocess(input,
+                                                          preprocessRule);
+  if (!prepro.empty())
+    {
+    this->ResolveTargetsInGeneratorExpressions(prepro, target,
+                                                missingTargets);
+
+    if (!checkInterfaceDirs(prepro, target))
+      {
+      return;
+      }
+    properties[propName] = prepro;
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
+                      cmTarget *target,
+                      cmGeneratorExpression::PreprocessContext preprocessRule,
+                      ImportPropertyMap &properties,
+                      std::vector<std::string> &missingTargets)
+{
+  this->PopulateInterfaceProperty(propName, propName, target, preprocessRule,
+                            properties, missingTargets);
+}
+
+
+//----------------------------------------------------------------------------
+void getPropertyContents(cmTarget *tgt, const char *prop,
+         std::set<std::string> &ifaceProperties)
+{
+  const char *p = tgt->GetProperty(prop);
+  if (!p)
+    {
+    return;
+    }
+  std::vector<std::string> content;
+  cmSystemTools::ExpandListArgument(p, content);
+  for (std::vector<std::string>::const_iterator ci = content.begin();
+    ci != content.end(); ++ci)
+    {
+    ifaceProperties.insert(*ci);
+    }
+}
+
+//----------------------------------------------------------------------------
+void getCompatibleInterfaceProperties(cmTarget *target,
+                                      std::set<std::string> &ifaceProperties,
+                                      const char *config)
+{
+  cmComputeLinkInformation *info = target->GetLinkInformation(config);
+
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    if (!li->Target)
+      {
+      continue;
+      }
+    getPropertyContents(li->Target,
+                        "COMPATIBLE_INTERFACE_BOOL",
+                        ifaceProperties);
+    getPropertyContents(li->Target,
+                        "COMPATIBLE_INTERFACE_STRING",
+                        ifaceProperties);
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
+                                cmTarget *target,
+                                ImportPropertyMap &properties)
+{
+  this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
+                                target, properties);
+  this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
+                                target, properties);
+
+  std::set<std::string> ifaceProperties;
+
+  getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
+  getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
+
+  getCompatibleInterfaceProperties(target, ifaceProperties, 0);
+
+  std::vector<std::string> configNames;
+  target->GetMakefile()->GetConfigurations(configNames);
+
+  for (std::vector<std::string>::const_iterator ci = configNames.begin();
+    ci != configNames.end(); ++ci)
+    {
+    getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
+    }
+
+  for (std::set<std::string>::const_iterator it = ifaceProperties.begin();
+    it != ifaceProperties.end(); ++it)
+    {
+    this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(),
+                                    target, properties);
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
+                                        std::ostream& os,
+                                        const ImportPropertyMap &properties)
+{
+  if (!properties.empty())
+    {
+    std::string targetName = this->Namespace;
+    targetName += target->GetName();
+    os << "set_target_properties(" << targetName << " PROPERTIES\n";
+    for(ImportPropertyMap::const_iterator pi = properties.begin();
+        pi != properties.end(); ++pi)
+      {
+      os << "  " << pi->first << " \"" << pi->second << "\"\n";
+      }
+    os << ")\n\n";
+    }
+}
+
+//----------------------------------------------------------------------------
+bool
+cmExportFileGenerator::AddTargetNamespace(std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets)
+{
+  cmMakefile *mf = target->GetMakefile();
+
+  cmTarget *tgt = mf->FindTargetToUse(input.c_str());
+  if (!tgt)
+    {
+    return false;
+    }
+
+  if(tgt->IsImported())
+    {
+    return true;
+    }
+  if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
+    {
+    input = this->Namespace + input;
+    }
+  else
+    {
+    std::string namespacedTarget;
+    this->HandleMissingTarget(namespacedTarget, missingTargets,
+                              mf, target, tgt);
+    if (!namespacedTarget.empty())
+      {
+      input = namespacedTarget;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
+                                    std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets,
+                                    FreeTargetsReplace replace)
+{
+  if (replace == NoReplaceFreeTargets)
+    {
+    this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
+    return;
+    }
+  std::vector<std::string> parts;
+  cmGeneratorExpression::Split(input, parts);
+
+  std::string sep;
+  input = "";
+  for(std::vector<std::string>::iterator li = parts.begin();
+      li != parts.end(); ++li)
+    {
+    if (cmGeneratorExpression::Find(*li) == std::string::npos)
+      {
+      this->AddTargetNamespace(*li, target, missingTargets);
+      }
+    else
+      {
+      this->ResolveTargetsInGeneratorExpression(
+                                    *li,
+                                    target,
+                                    missingTargets);
+      }
+    input += sep + *li;
+    sep = ";";
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
+                                    std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets)
+{
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+
+  cmMakefile *mf = target->GetMakefile();
+
+  while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos)
+    {
+    std::string::size_type nameStartPos = pos +
+                                            sizeof("$<TARGET_PROPERTY:") - 1;
+    std::string::size_type closePos = input.find(">", nameStartPos);
+    std::string::size_type commaPos = input.find(",", nameStartPos);
+    std::string::size_type nextOpenPos = input.find("$<", nameStartPos);
+    if (commaPos == input.npos // Implied 'this' target
+        || closePos == input.npos // Imcomplete expression.
+        || closePos < commaPos // Implied 'this' target
+        || nextOpenPos < commaPos) // Non-literal
+      {
+      lastPos = nameStartPos;
+      continue;
+      }
+
+    std::string targetName = input.substr(nameStartPos,
+                                                commaPos - nameStartPos);
+
+    if (this->AddTargetNamespace(targetName, target, missingTargets))
+      {
+      input.replace(nameStartPos, commaPos - nameStartPos, targetName);
+      }
+    lastPos = nameStartPos + targetName.size() + 1;
+    }
+
+  std::string errorString;
+  pos = 0;
+  lastPos = pos;
+  while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos)
+    {
+    std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1;
+    std::string::size_type endPos = input.find(">", nameStartPos);
+    if (endPos == input.npos)
+      {
+      errorString = "$<TARGET_NAME:...> expression incomplete";
+      break;
+      }
+    std::string targetName = input.substr(nameStartPos,
+                                                endPos - nameStartPos);
+    if(targetName.find("$<") != input.npos)
+      {
+      errorString = "$<TARGET_NAME:...> requires its parameter to be a "
+                    "literal.";
+      break;
+      }
+    if (!this->AddTargetNamespace(targetName, target, missingTargets))
+      {
+      errorString = "$<TARGET_NAME:...> requires its parameter to be a "
+                    "reachable target.";
+      break;
+      }
+    input.replace(pos, endPos - pos + 1, targetName);
+    lastPos = endPos;
+    }
+
+  this->ReplaceInstallPrefix(input);
+
+  if (!errorString.empty())
+    {
+    mf->IssueMessage(cmake::FATAL_ERROR, errorString);
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ReplaceInstallPrefix(std::string &)
+{
+  // Do nothing
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::SetImportLinkInterface(const char* config, std::string const& suffix,
+                    cmGeneratorExpression::PreprocessContext preprocessRule,
+                    cmTarget* target, ImportPropertyMap& properties,
+                    std::vector<std::string>& missingTargets)
+{
+  // Add the transitive link dependencies for this configuration.
+  cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+                                                                  target);
+  if (!iface)
+    {
+    return;
+    }
+
+  if (iface->ImplementationIsInterface)
+    {
+    this->SetImportLinkProperty(suffix, target,
+                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
+                                iface->Libraries, properties, missingTargets);
+    return;
+    }
+
+  const char *propContent;
+
+  if (const char *prop_suffixed = target->GetProperty(
+                    ("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
+    {
+    propContent = prop_suffixed;
+    }
+  else if (const char *prop = target->GetProperty(
+                    "LINK_INTERFACE_LIBRARIES"))
+    {
+    propContent = prop;
+    }
+  else
+    {
+    return;
+    }
+
+  if (!*propContent)
+    {
+    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
+    return;
+    }
+
+  std::string prepro = cmGeneratorExpression::Preprocess(propContent,
+                                                         preprocessRule);
+  if (!prepro.empty())
+    {
+    this->ResolveTargetsInGeneratorExpressions(prepro, target,
+                                               missingTargets,
+                                               ReplaceFreeTargets);
+    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -162,14 +638,13 @@ cmExportFileGenerator
     }
 
   // Add the transitive link dependencies for this configuration.
-  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
+  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+                                                                     target))
     {
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
                                 iface->Languages, properties, missingTargets);
-    this->SetImportLinkProperty(suffix, target,
-                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
-                                iface->Libraries, properties, missingTargets);
+
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_DEPENDENT_LIBRARIES",
                                 iface->SharedDeps, properties, missingTargets);
@@ -201,9 +676,6 @@ cmExportFileGenerator
     return;
     }
 
-  // Get the makefile in which to lookup target information.
-  cmMakefile* mf = target->GetMakefile();
-
   // Construct the property value.
   std::string link_libs;
   const char* sep = "";
@@ -214,33 +686,9 @@ cmExportFileGenerator
     link_libs += sep;
     sep = ";";
 
-    // Append this entry.
-    if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
-      {
-      // This is a target.
-      if(tgt->IsImported())
-        {
-        // The target is imported (and therefore is not in the
-        // export).  Append the raw name.
-        link_libs += *li;
-        }
-      else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
-        {
-        // The target is in the export.  Append it with the export
-        // namespace.
-        link_libs += this->Namespace;
-        link_libs += *li;
-        }
-      else
-        {
-        this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
-        }
-      }
-    else
-      {
-      // Append the raw name.
-      link_libs += *li;
-      }
+    std::string temp = *li;
+    this->AddTargetNamespace(temp, target, missingTargets);
+    link_libs += temp;
     }
 
   // Store the property.
@@ -273,7 +721,7 @@ void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
 void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
 {
   os << "# Commands beyond this point should not need to know the version.\n"
-     << "SET(CMAKE_IMPORT_FILE_VERSION)\n";
+     << "set(CMAKE_IMPORT_FILE_VERSION)\n";
 }
 
 //----------------------------------------------------------------------------
@@ -282,11 +730,42 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
   // Store an import file format version.  This will let us change the
   // format later while still allowing old import files to work.
   os << "# Commands may need to know the format version.\n"
-     << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
+     << "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
      << "\n";
 }
 
 //----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
+                                            const std::string &expectedTargets)
+{
+  os << "set(_targetsDefined)\n"
+        "set(_targetsNotDefined)\n"
+        "set(_expectedTargets)\n"
+        "foreach(_expectedTarget " << expectedTargets << ")\n"
+        "  list(APPEND _expectedTargets ${_expectedTarget})\n"
+        "  if(NOT TARGET ${_expectedTarget})\n"
+        "    list(APPEND _targetsNotDefined ${_expectedTarget})\n"
+        "  endif()\n"
+        "  if(TARGET ${_expectedTarget})\n"
+        "    list(APPEND _targetsDefined ${_expectedTarget})\n"
+        "  endif()\n"
+        "endforeach()\n"
+        "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
+        "  set(CMAKE_IMPORT_FILE_VERSION)\n"
+        "  cmake_policy(POP)\n"
+        "  return()\n"
+        "endif()\n"
+        "if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
+        "  message(FATAL_ERROR \"Some (but not all) targets in this export "
+        "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
+        "Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
+        "endif()\n"
+        "unset(_targetsDefined)\n"
+        "unset(_targetsNotDefined)\n"
+        "unset(_expectedTargets)\n"
+        "\n\n";
+}
+//----------------------------------------------------------------------------
 void
 cmExportFileGenerator
 ::GenerateImportTargetCode(std::ostream& os, cmTarget* target)
@@ -300,16 +779,19 @@ cmExportFileGenerator
   switch(target->GetType())
     {
     case cmTarget::EXECUTABLE:
-      os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
+      os << "add_executable(" << targetName << " IMPORTED)\n";
       break;
     case cmTarget::STATIC_LIBRARY:
-      os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
+      os << "add_library(" << targetName << " STATIC IMPORTED)\n";
       break;
     case cmTarget::SHARED_LIBRARY:
-      os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
+      os << "add_library(" << targetName << " SHARED IMPORTED)\n";
       break;
     case cmTarget::MODULE_LIBRARY:
-      os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
+      os << "add_library(" << targetName << " MODULE IMPORTED)\n";
+      break;
+    case cmTarget::UNKNOWN_LIBRARY:
+      os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
       break;
     default:  // should never happen
       break;
@@ -318,27 +800,27 @@ cmExportFileGenerator
   // Mark the imported executable if it has exports.
   if(target->IsExecutableWithExports())
     {
-    os << "SET_PROPERTY(TARGET " << targetName
+    os << "set_property(TARGET " << targetName
        << " PROPERTY ENABLE_EXPORTS 1)\n";
     }
 
   // Mark the imported library if it is a framework.
   if(target->IsFrameworkOnApple())
     {
-    os << "SET_PROPERTY(TARGET " << targetName
+    os << "set_property(TARGET " << targetName
        << " PROPERTY FRAMEWORK 1)\n";
     }
 
   // Mark the imported executable if it is an application bundle.
   if(target->IsAppBundleOnApple())
     {
-    os << "SET_PROPERTY(TARGET " << targetName
+    os << "set_property(TARGET " << targetName
        << " PROPERTY MACOSX_BUNDLE 1)\n";
     }
 
   if (target->IsCFBundleOnApple())
     {
-    os << "SET_PROPERTY(TARGET " << targetName
+    os << "set_property(TARGET " << targetName
        << " PROPERTY BUNDLE 1)\n";
     }
   os << "\n";
@@ -358,7 +840,7 @@ cmExportFileGenerator
   // Set the import properties.
   os << "# Import target \"" << targetName << "\" for configuration \""
      << config << "\"\n";
-  os << "SET_PROPERTY(TARGET " << targetName
+  os << "set_property(TARGET " << targetName
      << " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
   if(config && *config)
     {
@@ -369,7 +851,7 @@ cmExportFileGenerator
     os << "NOCONFIG";
     }
   os << ")\n";
-  os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
+  os << "set_target_properties(" << targetName << " PROPERTIES\n";
   for(ImportPropertyMap::const_iterator pi = properties.begin();
       pi != properties.end(); ++pi)
     {
@@ -384,23 +866,48 @@ cmExportFileGenerator
 void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
                                 const std::vector<std::string>& missingTargets)
 {
+  if (missingTargets.empty())
+    {
+    os << "# This file does not depend on other imported targets which have\n"
+          "# been exported from the same project but in a separate "
+            "export set.\n\n";
+    return;
+    }
   os << "# Make sure the targets which have been exported in some other \n"
-        "# export set exist.\n";
+        "# export set exist.\n"
+        "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
+        "foreach(_target ";
+  std::set<std::string> emitted;
   for(unsigned int i=0; i<missingTargets.size(); ++i)
     {
-    os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
-       << "  IF(CMAKE_FIND_PACKAGE_NAME)\n"
-       << "    SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
-       << "    SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
-       << "\"Required imported target \\\"" << missingTargets[i]
-       << "\\\" not found ! \")\n"
-       << "  ELSE()\n"
-       << "    MESSAGE(FATAL_ERROR \"Required imported target \\\""
-       << missingTargets[i] << "\\\" not found ! \")\n"
-       << "  ENDIF()\n"
-       << "ENDIF()\n";
+    if (emitted.insert(missingTargets[i]).second)
+      {
+      os << "\"" << missingTargets[i] <<  "\" ";
+      }
     }
-  os << "\n";
+  os << ")\n"
+        "  if(NOT TARGET \"${_target}\" )\n"
+        "    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets \""
+        "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}\")"
+        "\n"
+        "  endif()\n"
+        "endforeach()\n"
+        "\n"
+        "if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
+        "  if(CMAKE_FIND_PACKAGE_NAME)\n"
+        "    set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
+        "    set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
+        "\"The following imported targets are "
+        "referenced, but are missing: "
+                 "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n"
+        "  else()\n"
+        "    message(FATAL_ERROR \"The following imported targets are "
+        "referenced, but are missing: "
+                "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n"
+        "  endif()\n"
+        "endif()\n"
+        "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
+        "\n";
 }
 
 
@@ -416,10 +923,10 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
   // on SUSE with a mysql pkg-config file, which claimed everything is fine,
   // but the development package was not installed.).
   os << "# Loop over all imported files and verify that they actually exist\n"
-        "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
-        "  FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
-        "    IF(NOT EXISTS \"${file}\" )\n"
-        "      MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
+        "foreach(target ${_IMPORT_CHECK_TARGETS} )\n"
+        "  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
+        "    if(NOT EXISTS \"${file}\" )\n"
+        "      message(FATAL_ERROR \"The imported target \\\"${target}\\\""
         " references the file\n"
         "   \\\"${file}\\\"\n"
         "but this file does not exist.  Possible reasons include:\n"
@@ -429,11 +936,11 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
         "   \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
         "but not all the files it references.\n"
         "\")\n"
-        "    ENDIF()\n"
-        "  ENDFOREACH()\n"
-        "  UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
-        "ENDFOREACH()\n"
-        "UNSET(_IMPORT_CHECK_TARGETS)\n"
+        "    endif()\n"
+        "  endforeach()\n"
+        "  unset(_IMPORT_CHECK_FILES_FOR_${target})\n"
+        "endforeach()\n"
+        "unset(_IMPORT_CHECK_TARGETS)\n"
         "\n";
 }
 
@@ -449,8 +956,8 @@ cmExportFileGenerator
   std::string targetName = this->Namespace;
   targetName += target->GetName();
 
-  os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
-        "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
+  os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
+        "list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
 
   for(std::set<std::string>::const_iterator li = importedLocations.begin();
       li != importedLocations.end();
index 70bc65d..9f958a2 100644 (file)
@@ -13,6 +13,7 @@
 #define cmExportFileGenerator_h
 
 #include "cmCommand.h"
+#include "cmGeneratorExpression.h"
 
 /** \class cmExportFileGenerator
  * \brief Generate a file exporting targets from a build or install tree.
@@ -46,7 +47,8 @@ protected:
 
   // Generate per-configuration target information to the given output
   // stream.
-  void GenerateImportConfig(std::ostream& os, const char* config);
+  void GenerateImportConfig(std::ostream& os, const char* config,
+                            std::vector<std::string> &missingTargets);
 
   // Methods to implement export file code generation.
   void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
@@ -63,6 +65,8 @@ protected:
   void GenerateMissingTargetsCheckCode(std::ostream& os,
                                const std::vector<std::string>& missingTargets);
 
+  void GenerateExpectedTargetsCode(std::ostream& os,
+                                          const std::string &expectedTargets);
 
   // Collect properties with detailed information about targets beyond
   // their location on disk.
@@ -82,7 +86,8 @@ protected:
   /** Each subclass knows where the target files are located.  */
   virtual void GenerateImportTargetsConfig(std::ostream& os,
                                            const char* config,
-                                           std::string const& suffix) = 0;
+                                           std::string const& suffix,
+                            std::vector<std::string> &missingTargets) = 0;
 
   /** Each subclass knows how to deal with a target that is  missing from an
    *  export set.  */
@@ -91,6 +96,37 @@ protected:
                                    cmMakefile* mf,
                                    cmTarget* depender,
                                    cmTarget* dependee) = 0;
+  void PopulateInterfaceProperty(const char *,
+                                 cmTarget *target,
+                                 cmGeneratorExpression::PreprocessContext,
+                                 ImportPropertyMap &properties,
+                                 std::vector<std::string> &missingTargets);
+  void PopulateInterfaceProperty(const char *propName, cmTarget *target,
+                                 ImportPropertyMap &properties);
+  void PopulateCompatibleInterfaceProperties(cmTarget *target,
+                                 ImportPropertyMap &properties);
+  void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
+                                   const ImportPropertyMap &properties);
+  void PopulateIncludeDirectoriesInterface(
+                      cmTarget *target,
+                      cmGeneratorExpression::PreprocessContext preprocessRule,
+                      ImportPropertyMap &properties,
+                      std::vector<std::string> &missingTargets);
+
+  void SetImportLinkInterface(const char* config, std::string const& suffix,
+                    cmGeneratorExpression::PreprocessContext preprocessRule,
+                    cmTarget* target, ImportPropertyMap& properties,
+                    std::vector<std::string>& missingTargets);
+
+  enum FreeTargetsReplace {
+    ReplaceFreeTargets,
+    NoReplaceFreeTargets
+  };
+
+  void ResolveTargetsInGeneratorExpressions(std::string &input,
+                          cmTarget* target,
+                          std::vector<std::string> &missingTargets,
+                          FreeTargetsReplace replace = NoReplaceFreeTargets);
 
   // The namespace in which the exports are placed in the generated file.
   std::string Namespace;
@@ -107,6 +143,22 @@ protected:
 
   // The set of targets included in the export.
   std::set<cmTarget*> ExportedTargets;
+
+private:
+  void PopulateInterfaceProperty(const char *, const char *,
+                                 cmTarget *target,
+                                 cmGeneratorExpression::PreprocessContext,
+                                 ImportPropertyMap &properties,
+                                 std::vector<std::string> &missingTargets);
+
+  bool AddTargetNamespace(std::string &input, cmTarget* target,
+                          std::vector<std::string> &missingTargets);
+
+  void ResolveTargetsInGeneratorExpression(std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets);
+
+  virtual void ReplaceInstallPrefix(std::string &input);
 };
 
 #endif
index 7841731..ad12b5a 100644 (file)
@@ -39,20 +39,25 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
 //----------------------------------------------------------------------------
 bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
 {
-  // Create all the imported targets.
+  std::vector<cmTarget*> allTargets;
+  {
+  std::string expectedTargets;
+  std::string sep;
   for(std::vector<cmTargetExport*>::const_iterator
         tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
       tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei)
     {
+    expectedTargets += sep + this->Namespace + (*tei)->Target->GetName();
+    sep = " ";
     cmTargetExport const* te = *tei;
     if(this->ExportedTargets.insert(te->Target).second)
       {
-      this->GenerateImportTargetCode(os, te->Target);
+      allTargets.push_back(te->Target);
       }
     else
       {
       cmOStringStream e;
-      e << "INSTALL(EXPORT \""
+      e << "install(EXPORT \""
         << this->IEGen->GetExportSet()->GetName()
         << "\" ...) " << "includes target \"" << te->Target->GetName()
         << "\" more than once in the export set.";
@@ -61,33 +66,133 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
       }
     }
 
+  this->GenerateExpectedTargetsCode(os, expectedTargets);
+  }
+
+  // Add code to compute the installation prefix relative to the
+  // import file location.
+  const char* installDest = this->IEGen->GetDestination();
+  if(!cmSystemTools::FileIsFullPath(installDest))
+    {
+    std::string installPrefix =
+      this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+    std::string absDest = installPrefix + "/" + installDest;
+    std::string absDestS = absDest + "/";
+    os << "# Compute the installation prefix relative to this file.\n"
+       << "get_filename_component(_IMPORT_PREFIX"
+       << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+    if(strncmp(absDestS.c_str(), "/lib/", 5) == 0 ||
+       strncmp(absDestS.c_str(), "/lib64/", 7) == 0 ||
+       strncmp(absDestS.c_str(), "/usr/lib/", 9) == 0 ||
+       strncmp(absDestS.c_str(), "/usr/lib64/", 11) == 0)
+      {
+      // Handle "/usr move" symlinks created by some Linux distros.
+      os <<
+        "# Use original install prefix when loaded through a\n"
+        "# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
+        "get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
+        "get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
+        "if(_realCurr STREQUAL _realOrig)\n"
+        "  set(_IMPORT_PREFIX \"" << absDest << "\")\n"
+        "endif()\n"
+        "unset(_realOrig)\n"
+        "unset(_realCurr)\n";
+      }
+    std::string dest = installDest;
+    while(!dest.empty())
+      {
+      os <<
+        "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+      dest = cmSystemTools::GetFilenamePath(dest);
+      }
+    os << "\n";
+
+    // Import location properties may reference this variable.
+    this->ImportPrefix = "${_IMPORT_PREFIX}/";
+    }
+
+  std::vector<std::string> missingTargets;
+
+  // Create all the imported targets.
+  for(std::vector<cmTarget*>::const_iterator
+        tei = allTargets.begin();
+      tei != allTargets.end(); ++tei)
+    {
+    cmTarget* te = *tei;
+    this->GenerateImportTargetCode(os, te);
+
+    ImportPropertyMap properties;
+
+    this->PopulateIncludeDirectoriesInterface(te,
+                                  cmGeneratorExpression::InstallInterface,
+                                  properties, missingTargets);
+    this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
+                                  te,
+                                  cmGeneratorExpression::InstallInterface,
+                                  properties, missingTargets);
+    this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
+                                  te, properties);
+    this->PopulateCompatibleInterfaceProperties(te, properties);
+
+    this->GenerateInterfaceProperties(te, os, properties);
+    }
+
+
   // Now load per-configuration properties for them.
   os << "# Load information for each installed configuration.\n"
-     << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
-     << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
+     << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
+     << "file(GLOB CONFIG_FILES \"${_DIR}/"
      << this->GetConfigImportFileGlob() << "\")\n"
-     << "FOREACH(f ${CONFIG_FILES})\n"
-     << "  INCLUDE(${f})\n"
-     << "ENDFOREACH(f)\n"
+     << "foreach(f ${CONFIG_FILES})\n"
+     << "  include(${f})\n"
+     << "endforeach()\n"
      << "\n";
 
+  // Cleanup the import prefix variable.
+  if(!this->ImportPrefix.empty())
+    {
+    os << "# Cleanup temporary variables.\n"
+       << "set(_IMPORT_PREFIX)\n"
+       << "\n";
+    }
+  this->GenerateImportedFileCheckLoop(os);
+
   // Generate an import file for each configuration.
   bool result = true;
   for(std::vector<std::string>::const_iterator
         ci = this->Configurations.begin();
       ci != this->Configurations.end(); ++ci)
     {
-    if(!this->GenerateImportFileConfig(ci->c_str()))
+    if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
       {
       result = false;
       }
     }
+
+  this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
   return result;
 }
 
 //----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input)
+{
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+
+  while((pos = input.find("$<INSTALL_PREFIX>", lastPos)) != input.npos)
+    {
+    std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+    input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
+    lastPos = endPos;
+    }
+}
+
+//----------------------------------------------------------------------------
 bool
-cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
+cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
+                                    std::vector<std::string> &missingTargets)
 {
   // Skip configurations not enabled for this export.
   if(!this->IEGen->InstallsForConfig(config))
@@ -127,7 +232,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
   this->GenerateImportHeaderCode(os, config);
 
   // Generate the per-config target information.
-  this->GenerateImportConfig(os, config);
+  this->GenerateImportConfig(os, config, missingTargets);
 
   // End with the import file footer.
   this->GenerateImportFooterCode(os);
@@ -142,29 +247,9 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
 void
 cmExportInstallFileGenerator
 ::GenerateImportTargetsConfig(std::ostream& os,
-                              const char* config, std::string const& suffix)
+                              const char* config, std::string const& suffix,
+                              std::vector<std::string> &missingTargets)
 {
-  // Add code to compute the installation prefix relative to the
-  // import file location.
-  const char* installDest = this->IEGen->GetDestination();
-  if(!cmSystemTools::FileIsFullPath(installDest))
-    {
-    std::string dest = installDest;
-    os << "# Compute the installation prefix relative to this file.\n"
-       << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
-       << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
-    while(!dest.empty())
-      {
-      os <<
-        "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
-      dest = cmSystemTools::GetFilenamePath(dest);
-      }
-    os << "\n";
-
-    // Import location properties may reference this variable.
-    this->ImportPrefix = "${_IMPORT_PREFIX}/";
-    }
-
   // Add each target in the set to the export.
   for(std::vector<cmTargetExport*>::const_iterator
         tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
@@ -191,10 +276,13 @@ cmExportInstallFileGenerator
     if(!properties.empty())
       {
       // Get the rest of the target details.
-      std::vector<std::string> missingTargets;
       this->SetImportDetailProperties(config, suffix,
                                       te->Target, properties, missingTargets);
 
+      this->SetImportLinkInterface(config, suffix,
+                                   cmGeneratorExpression::InstallInterface,
+                                   te->Target, properties, missingTargets);
+
       // TOOD: PUBLIC_HEADER_LOCATION
       // This should wait until the build feature propagation stuff
       // is done.  Then this can be a propagated include directory.
@@ -202,22 +290,11 @@ cmExportInstallFileGenerator
       //                              properties);
 
       // Generate code in the export file.
-      this->GenerateMissingTargetsCheckCode(os, missingTargets);
       this->GenerateImportPropertyCode(os, config, te->Target, properties);
       this->GenerateImportedFileChecksCode(os, te->Target, properties,
                                            importedLocations);
       }
     }
-
-  this->GenerateImportedFileCheckLoop(os);
-
-  // Cleanup the import prefix variable.
-  if(!this->ImportPrefix.empty())
-    {
-    os << "# Cleanup temporary variables.\n"
-       << "SET(_IMPORT_PREFIX)\n"
-       << "\n";
-    }
 }
 
 //----------------------------------------------------------------------------
@@ -385,7 +462,7 @@ cmExportInstallFileGenerator
 {
   const char* installDest = this->IEGen->GetDestination();
   cmOStringStream e;
-  e << "INSTALL(EXPORT \""
+  e << "install(EXPORT \""
     << this->IEGen->GetExportSet()->GetName()
     << "\") given absolute "
     << "DESTINATION \"" << installDest << "\" but the export "
@@ -403,7 +480,7 @@ cmExportInstallFileGenerator
                              int occurrences)
 {
   cmOStringStream e;
-  e << "INSTALL(EXPORT \""
+  e << "install(EXPORT \""
     << this->IEGen->GetExportSet()->GetName()
     << "\" ...) "
     << "includes target \"" << depender->GetName()
index e719ecc..20dd57a 100644 (file)
 #include "cmExportFileGenerator.h"
 
 class cmInstallExportGenerator;
-class cmInstallFilesGenerator;
 class cmInstallTargetGenerator;
-class cmTargetExport;
-class cmExportSet;
 
 /** \class cmExportInstallFileGenerator
  * \brief Generate a file exporting targets from an install tree.
@@ -56,13 +53,16 @@ protected:
   virtual bool GenerateMainFile(std::ostream& os);
   virtual void GenerateImportTargetsConfig(std::ostream& os,
                                            const char* config,
-                                           std::string const& suffix);
+                                           std::string const& suffix,
+                            std::vector<std::string> &missingTargets);
   virtual void HandleMissingTarget(std::string& link_libs,
                                    std::vector<std::string>& missingTargets,
                                    cmMakefile* mf,
                                    cmTarget* depender,
                                    cmTarget* dependee);
 
+  virtual void ReplaceInstallPrefix(std::string &input);
+
   void ComplainAboutMissingTarget(cmTarget* depender,
                                   cmTarget* dependee,
                                   int occurrences);
@@ -72,7 +72,8 @@ protected:
 
 
   /** Generate a per-configuration file for the targets.  */
-  bool GenerateImportFileConfig(const char* config);
+  bool GenerateImportFileConfig(const char* config,
+                            std::vector<std::string> &missingTargets);
 
   /** Fill in properties indicating installed file locations.  */
   void SetImportLocationProperty(const char* config,
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
new file mode 100644 (file)
index 0000000..75f2651
--- /dev/null
@@ -0,0 +1,114 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 "cmExportTryCompileFileGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpressionDAGChecker.h"
+
+//----------------------------------------------------------------------------
+bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
+{
+  std::set<cmTarget*> emitted;
+  std::set<cmTarget*> emittedDeps;
+  while(!this->Exports.empty())
+    {
+    cmTarget* te = this->Exports.back();
+    this->Exports.pop_back();
+    if (emitted.insert(te).second)
+      {
+      emittedDeps.insert(te);
+      this->GenerateImportTargetCode(os, te);
+
+      ImportPropertyMap properties;
+
+      this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps);
+      this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps);
+
+      this->PopulateProperties(te, properties, emittedDeps);
+
+      this->GenerateInterfaceProperties(te, os, properties);
+      }
+    }
+  return true;
+}
+
+std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName,
+                                                cmTarget *tgt,
+                                                std::set<cmTarget*> &emitted)
+{
+  const char *prop = tgt->GetProperty(propName);
+  if(!prop)
+    {
+    return std::string();
+    }
+
+  cmListFileBacktrace lfbt;
+  cmGeneratorExpression ge(lfbt);
+
+  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                      tgt->GetName(),
+                                      propName, 0, 0);
+
+  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+
+  cmTarget dummyHead;
+  dummyHead.SetType(cmTarget::EXECUTABLE, "try_compile_dummy_exe");
+  dummyHead.SetMakefile(tgt->GetMakefile());
+
+  std::string result = cge->Evaluate(tgt->GetMakefile(), this->Config,
+                                     false, &dummyHead, tgt, &dagChecker);
+
+  const std::set<cmTarget*> &allTargets = cge->GetAllTargetsSeen();
+  for(std::set<cmTarget*>::const_iterator li = allTargets.begin();
+      li != allTargets.end(); ++li)
+    {
+    if(emitted.insert(*li).second)
+      {
+      this->Exports.push_back(*li);
+      }
+    }
+  return result;
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target,
+                                                ImportPropertyMap& properties,
+                                                std::set<cmTarget*> &emitted)
+{
+  cmPropertyMap props = target->GetProperties();
+  for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
+    {
+    properties[i->first] = i->second.GetValue();
+
+    if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0)
+      {
+      const std::string libs = i->second.GetValue();
+
+      std::string evalResult = this->FindTargets(i->first.c_str(),
+                                                 target, emitted);
+
+      std::vector<std::string> depends;
+      cmSystemTools::ExpandListArgument(evalResult, depends);
+      for(std::vector<std::string>::const_iterator li = depends.begin();
+          li != depends.end(); ++li)
+        {
+        cmTarget *tgt = target->GetMakefile()->FindTargetToUse(li->c_str());
+        if(tgt && emitted.insert(tgt).second)
+          {
+          this->Exports.push_back(tgt);
+          }
+        }
+      }
+    }
+}
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
new file mode 100644 (file)
index 0000000..ed393ab
--- /dev/null
@@ -0,0 +1,55 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 cmExportInstallFileGenerator_h
+#define cmExportInstallFileGenerator_h
+
+#include "cmExportFileGenerator.h"
+
+class cmInstallExportGenerator;
+class cmInstallTargetGenerator;
+
+class cmExportTryCompileFileGenerator: public cmExportFileGenerator
+{
+public:
+  /** Set the list of targets to export.  */
+  void SetExports(const std::vector<cmTarget*> &exports)
+    { this->Exports = exports; }
+  void SetConfig(const char *config) { this->Config = config; }
+protected:
+
+  // Implement virtual methods from the superclass.
+  virtual bool GenerateMainFile(std::ostream& os);
+
+  virtual void GenerateImportTargetsConfig(std::ostream&,
+                                           const char*,
+                                           std::string const&,
+                            std::vector<std::string>&) {}
+  virtual void HandleMissingTarget(std::string&,
+                                   std::vector<std::string>&,
+                                   cmMakefile*,
+                                   cmTarget*,
+                                   cmTarget*) {}
+
+  void PopulateProperties(cmTarget* target,
+                          ImportPropertyMap& properties,
+                          std::set<cmTarget*> &emitted);
+
+private:
+  std::string FindTargets(const char *prop, cmTarget *tgt,
+                   std::set<cmTarget*> &emitted);
+
+
+  std::vector<cmTarget*> Exports;
+  const char *Config;
+};
+
+#endif
index 25b13e5..f6f4cef 100644 (file)
@@ -621,7 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
                                   ->GetGeneratorTarget(target);
 
     // the compilerdefines for this target
-    std::string cdefs = gtgt->GetCompileDefinitions();
+    std::string cdefs = target->GetCompileDefinitions(buildType);
 
     if(!cdefs.empty())
       {
@@ -640,10 +640,8 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
     std::set<std::string> uniqIncludeDirs;
 
     std::vector<std::string> includes;
-    const char *config = target->GetMakefile()
-                               ->GetDefinition("CMAKE_BUILD_TYPE");
     target->GetMakefile()->GetLocalGenerator()->
-      GetIncludeDirectories(includes, gtgt, "C", config);
+      GetIncludeDirectories(includes, gtgt, "C", buildType);
     for(std::vector<std::string>::const_iterator dirIt=includes.begin();
         dirIt != includes.end();
         ++dirIt)
@@ -811,6 +809,11 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
     command += " VERBOSE=1 ";
     command += target;
     }
+  else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+    {
+    command += " -v ";
+    command += target;
+    }
   else
     {
     std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
index 96b8a09..97ab086 100644 (file)
@@ -38,6 +38,7 @@ cmExtraEclipseCDT4Generator
   this->SupportedGlobalGenerators.push_back("Unix Makefiles");
 
   this->SupportsVirtualFolders = true;
+  this->GenerateLinkedResources = true;
 }
 
 //----------------------------------------------------------------------------
@@ -83,6 +84,9 @@ void cmExtraEclipseCDT4Generator::Generate()
   this->HomeDirectory       = mf->GetHomeDirectory();
   this->HomeOutputDirectory = mf->GetHomeOutputDirectory();
 
+  this->GenerateLinkedResources = mf->IsOn(
+                                    "CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES");
+
   this->IsOutOfSourceBuild = (this->HomeDirectory!=this->HomeOutputDirectory);
 
   this->GenerateSourceProject = (this->IsOutOfSourceBuild &&
@@ -501,6 +505,10 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
           linkName2 += ti->first;
           this->AppendLinkedResource(fout, linkName2, "virtual:/virtual",
                                      VirtualFolder);
+          if (!this->GenerateLinkedResources)
+            {
+            break; // skip generating the linked resources to the source files
+            }
           std::vector<cmSourceGroup> sourceGroups=makefile->GetSourceGroups();
           // get the files from the source lists then add them to the groups
           cmTarget* tgt = const_cast<cmTarget*>(&ti->second);
@@ -555,6 +563,11 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
 void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
                        cmGeneratedFileStream& fout, const std::string& baseDir)
 {
+  if (!this->GenerateLinkedResources)
+    {
+    return;
+    }
+
   // for each sub project create a linked resource to the source dir
   // - only if it is an out-of-source build
   this->AppendLinkedResource(fout, "[Subprojects]",
@@ -579,7 +592,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
                                  this->GetEclipsePath(linkSourceDirectory),
                                  LinkToFolder
                                 );
-      this->SrcLinkedResources.push_back(it->first);
+      // Don't add it to the srcLinkedResources, because listing multiple
+      // directories confuses the Eclipse indexer (#13596).
       }
     }
 }
@@ -730,15 +744,16 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 /* I don't know what the pathentry kind="src" are good for, e.g. autocompletion
  * works also without them. Done wrong, the indexer complains, see #12417
  * and #12213.
+ * According to #13596, this entry at least limits the directories the
+ * indexer is searching for files. So now the "src" entry contains only
+ * the linked resource to CMAKE_SOURCE_DIR.
  * The CDT documentation is very terse on that:
  * "CDT_SOURCE: Entry kind constant describing a path entry identifying a
  * folder containing source code to be compiled."
  * Also on the cdt-dev list didn't bring any information:
  * http://web.archiveorange.com/archive/v/B4NlJDNIpYoOS1SbxFNy
- * So I'm disabling them for now, hoping that somebody will report if something
- * is not workging anymore.
  * Alex */
-#ifdef DO_CREATE_SRC_PATH_ENTRIES
+
   for (std::vector<std::string>::const_iterator
        it = this->SrcLinkedResources.begin();
        it != this->SrcLinkedResources.end();
@@ -755,7 +770,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
       excludeFromOut += this->EscapeForXML(*it) + "/|";
       }
     }
-#endif
+
   excludeFromOut += "**/CMakeFiles/";
   fout << "<pathentry excluding=\"" << excludeFromOut
        << "\" kind=\"out\" path=\"\"/>\n";
index 37ce65e..31ad68d 100644 (file)
@@ -109,6 +109,7 @@ private:
   std::string HomeOutputDirectory;
   bool IsOutOfSourceBuild;
   bool GenerateSourceProject;
+  bool GenerateLinkedResources;
   bool SupportsVirtualFolders;
 
 };
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
new file mode 100644 (file)
index 0000000..e4802d5
--- /dev/null
@@ -0,0 +1,503 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2004-2009 Kitware, Inc.
+  Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+
+  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 "cmExtraSublimeTextGenerator.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/SystemTools.hxx>
+
+/*
+Sublime Text 2 Generator
+Author: Morné Chamberlain
+This generator was initially based off of the CodeBlocks generator.
+
+Some useful URLs:
+Homepage:
+http://www.sublimetext.com/
+
+File format docs:
+http://www.sublimetext.com/docs/2/projects.html
+http://sublimetext.info/docs/en/reference/build_systems.html
+*/
+
+//----------------------------------------------------------------------------
+void cmExtraSublimeTextGenerator
+::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+{
+  entry.Name = this->GetName();
+  entry.Brief = "Generates Sublime Text 2 project files.";
+  entry.Full =
+    "Project files for Sublime Text 2 will be created in the top directory "
+    "and in every subdirectory which features a CMakeLists.txt file "
+    "containing a PROJECT() call. "
+    "Additionally Makefiles (or build.ninja files) are generated into the "
+    "build tree.  The appropriate make program can build the project through "
+    "the default make target.  A \"make install\" target is also provided.";
+}
+
+cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
+:cmExternalMakefileProjectGenerator()
+{
+#if defined(_WIN32)
+  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
+  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+// disable until somebody actually tests it:
+//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
+#endif
+  this->SupportedGlobalGenerators.push_back("Ninja");
+  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+}
+
+
+void cmExtraSublimeTextGenerator::Generate()
+{
+  // for each sub project in the project create a sublime text 2 project
+  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+       it = this->GlobalGenerator->GetProjectMap().begin();
+      it!= this->GlobalGenerator->GetProjectMap().end();
+      ++it)
+    {
+    // create a project file
+    this->CreateProjectFile(it->second);
+    }
+}
+
+
+void cmExtraSublimeTextGenerator::CreateProjectFile(
+                                     const std::vector<cmLocalGenerator*>& lgs)
+{
+  const cmMakefile* mf=lgs[0]->GetMakefile();
+  std::string outputDir=mf->GetStartOutputDirectory();
+  std::string projectName=mf->GetProjectName();
+
+  const std::string filename =
+                     outputDir + "/" + projectName + ".sublime-project";
+
+  this->CreateNewProjectFile(lgs, filename);
+}
+
+void cmExtraSublimeTextGenerator
+  ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+                         const std::string& filename)
+{
+  const cmMakefile* mf=lgs[0]->GetMakefile();
+  cmGeneratedFileStream fout(filename.c_str());
+  if(!fout)
+    {
+    return;
+    }
+
+  const std::string &sourceRootRelativeToOutput = cmSystemTools::RelativePath(
+                     mf->GetHomeOutputDirectory(),
+                     mf->GetHomeDirectory());
+  // Write the folder entries to the project file
+  fout << "{\n";
+  fout << "\t\"folders\":\n\t[\n\t";
+  if (!sourceRootRelativeToOutput.empty())
+    {
+      fout << "\t{\n\t\t\t\"path\": \"" << sourceRootRelativeToOutput << "\"";
+      const std::string &outputRelativeToSourceRoot =
+        cmSystemTools::RelativePath(mf->GetHomeDirectory(),
+                                    mf->GetHomeOutputDirectory());
+      if ((!outputRelativeToSourceRoot.empty()) &&
+        ((outputRelativeToSourceRoot.length() < 3) ||
+          (outputRelativeToSourceRoot.substr(0, 3) != "../")))
+        {
+        fout << ",\n\t\t\t\"folder_exclude_patterns\": [\"" <<
+                outputRelativeToSourceRoot << "\"]";
+        }
+    }
+  else
+    {
+      fout << "\t{\n\t\t\t\"path\": \"./\"";
+    }
+  fout << "\n\t\t}";
+  // End of the folders section
+  fout << "\n\t]";
+
+  // Write the beginning of the build systems section to the project file
+  fout << ",\n\t\"build_systems\":\n\t[\n\t";
+
+  // Set of include directories over all targets (sublime text/sublimeclang
+  // doesn't currently support these settings per build system, only project
+  // wide
+  MapSourceFileFlags sourceFileFlags;
+  AppendAllTargets(lgs, mf, fout, sourceFileFlags);
+
+  // End of build_systems
+  fout << "\n\t]";
+  fout << "\n\t}";
+}
+
+
+void cmExtraSublimeTextGenerator::
+  AppendAllTargets(const std::vector<cmLocalGenerator*>& lgs,
+                   const cmMakefile* mf,
+                   cmGeneratedFileStream& fout,
+                   MapSourceFileFlags& sourceFileFlags)
+{
+  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+  std::string compiler = "";
+  if (!lgs.empty())
+    {
+      this->AppendTarget(fout, "all", lgs[0], 0, make.c_str(), mf,
+                         compiler.c_str(), sourceFileFlags, true);
+      this->AppendTarget(fout, "clean", lgs[0], 0, make.c_str(), mf,
+                         compiler.c_str(), sourceFileFlags, false);
+    }
+
+  // add all executable and library targets and some of the GLOBAL
+  // and UTILITY targets
+  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
+       lg!=lgs.end(); lg++)
+    {
+    cmMakefile* makefile=(*lg)->GetMakefile();
+    cmTargets& targets=makefile->GetTargets();
+    for (cmTargets::iterator ti = targets.begin();
+         ti != targets.end(); ti++)
+      {
+      switch(ti->second.GetType())
+        {
+        case cmTarget::GLOBAL_TARGET:
+          {
+          bool insertTarget = false;
+          // Only add the global targets from CMAKE_BINARY_DIR,
+          // not from the subdirs
+          if (strcmp(makefile->GetStartOutputDirectory(),
+                     makefile->GetHomeOutputDirectory())==0)
+            {
+            insertTarget = true;
+            // only add the "edit_cache" target if it's not ccmake, because
+            // this will not work within the IDE
+            if (ti->first == "edit_cache")
+              {
+              const char* editCommand = makefile->GetDefinition
+                                                        ("CMAKE_EDIT_COMMAND");
+              if (editCommand == 0)
+                {
+                insertTarget = false;
+                }
+              else if (strstr(editCommand, "ccmake")!=NULL)
+                {
+                insertTarget = false;
+                }
+              }
+            }
+          if (insertTarget)
+            {
+            this->AppendTarget(fout, ti->first.c_str(), *lg, 0,
+                               make.c_str(), makefile, compiler.c_str(),
+                               sourceFileFlags, false);
+            }
+          }
+          break;
+        case cmTarget::UTILITY:
+          // Add all utility targets, except the Nightly/Continuous/
+          // Experimental-"sub"targets as e.g. NightlyStart
+          if (((ti->first.find("Nightly")==0)   &&(ti->first!="Nightly"))
+             || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
+             || ((ti->first.find("Experimental")==0)
+                                               && (ti->first!="Experimental")))
+            {
+            break;
+            }
+
+          this->AppendTarget(fout, ti->first.c_str(), *lg, 0,
+                             make.c_str(), makefile, compiler.c_str(),
+                             sourceFileFlags, false);
+          break;
+        case cmTarget::EXECUTABLE:
+        case cmTarget::STATIC_LIBRARY:
+        case cmTarget::SHARED_LIBRARY:
+        case cmTarget::MODULE_LIBRARY:
+        case cmTarget::OBJECT_LIBRARY:
+          {
+          this->AppendTarget(fout, ti->first.c_str(), *lg, &ti->second,
+                             make.c_str(), makefile, compiler.c_str(),
+                             sourceFileFlags, false);
+          std::string fastTarget = ti->first;
+          fastTarget += "/fast";
+          this->AppendTarget(fout, fastTarget.c_str(), *lg, &ti->second,
+                             make.c_str(), makefile, compiler.c_str(),
+                             sourceFileFlags, false);
+          }
+          break;
+        default:
+          break;
+        }
+      }
+    }
+}
+
+void cmExtraSublimeTextGenerator::
+  AppendTarget(cmGeneratedFileStream& fout,
+               const char* targetName,
+               cmLocalGenerator* lg,
+               cmTarget* target,
+               const char* make,
+               const cmMakefile* makefile,
+               const char*, //compiler
+               MapSourceFileFlags& sourceFileFlags,
+               bool firstTarget)
+{
+
+  if (target != 0)
+    {
+      cmGeneratorTarget *gtgt = this->GlobalGenerator
+                                    ->GetGeneratorTarget(target);
+      std::vector<cmSourceFile*> const& sourceFiles = target->GetSourceFiles();
+      std::vector<cmSourceFile*>::const_iterator sourceFilesEnd =
+        sourceFiles.end();
+      for (std::vector<cmSourceFile*>::const_iterator iter =
+        sourceFiles.begin(); iter != sourceFilesEnd; ++iter)
+        {
+          cmSourceFile* sourceFile = *iter;
+          MapSourceFileFlags::iterator sourceFileFlagsIter =
+            sourceFileFlags.find(sourceFile->GetFullPath());
+          if (sourceFileFlagsIter == sourceFileFlags.end())
+            {
+            sourceFileFlagsIter =
+              sourceFileFlags.insert(MapSourceFileFlags::value_type(
+                sourceFile->GetFullPath(), std::vector<std::string>())).first;
+            }
+          std::vector<std::string>& flags = sourceFileFlagsIter->second;
+          std::string flagsString =
+            this->ComputeFlagsForObject(*iter, lg, target, gtgt);
+          std::string definesString =
+            this->ComputeDefines(*iter, lg, target, gtgt);
+          flags.clear();
+          cmsys::RegularExpression flagRegex;
+          // Regular expression to extract compiler flags from a string
+          // https://gist.github.com/3944250
+          const char* regexString =
+            "(^|[ ])-[DIOUWfgs][^= ]+(=\\\"[^\"]+\\\"|=[^\"][^ ]+)?";
+          flagRegex.compile(regexString);
+          std::string workString = flagsString + " " + definesString;
+          while (flagRegex.find(workString))
+            {
+              std::string::size_type start = flagRegex.start();
+              if (workString[start] == ' ')
+                {
+                  start++;
+                }
+              flags.push_back(workString.substr(start,
+                flagRegex.end() - start));
+              if (flagRegex.end() < workString.size())
+                {
+                workString = workString.substr(flagRegex.end());
+                }
+                else
+                {
+                workString = "";
+                }
+            }
+        }
+    }
+
+  // Ninja uses ninja.build files (look for a way to get the output file name
+  // from cmMakefile or something)
+  std::string makefileName;
+  if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+    {
+      makefileName = "build.ninja";
+    }
+    else
+    {
+      makefileName = "Makefile";
+    }
+  if (!firstTarget)
+    {
+    fout << ",\n\t";
+    }
+  fout << "\t{\n\t\t\t\"name\": \"" << makefile->GetProjectName() << " - " <<
+          targetName << "\",\n";
+  fout << "\t\t\t\"cmd\": [" <<
+          this->BuildMakeCommand(make, makefileName.c_str(), targetName) <<
+          "],\n";
+  fout << "\t\t\t\"working_dir\": \"${project_path}\",\n";
+  fout << "\t\t\t\"file_regex\": \"^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$\"\n";
+  fout << "\t\t}";
+}
+
+// Create the command line for building the given target using the selected
+// make
+std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
+             const std::string& make, const char* makefile, const char* target)
+{
+  std::string command = "\"";
+  command += make + "\"";
+  if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)
+    {
+    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
+    command += ", \"/NOLOGO\", \"/f\", \"";
+    command += makefileName + "\"";
+    command += ", \"VERBOSE=1\", \"";
+    command += target;
+    command += "\"";
+    }
+  else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
+    {
+    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
+    command += ", \"-f\", \"";
+    command += makefileName + "\"";
+    command += ", \"-v\", \"";
+    command += target;
+    command += "\"";
+    }
+  else
+    {
+    std::string makefileName;
+    if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0)
+      {
+        // no escaping of spaces in this case, see
+        // http://public.kitware.com/Bug/view.php?id=10014
+        makefileName = makefile;
+      }
+      else
+      {
+        makefileName = cmSystemTools::ConvertToOutputPath(makefile);
+      }
+    command += ", \"-f\", \"";
+    command += makefileName + "\"";
+    command += ", \"VERBOSE=1\", \"";
+    command += target;
+    command += "\"";
+    }
+  return command;
+}
+
+// TODO: Most of the code is picked up from the Ninja generator, refactor it.
+std::string
+cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
+                                                   cmLocalGenerator* lg,
+                                                   cmTarget *target,
+                                                   cmGeneratorTarget* gtgt)
+{
+  std::string flags;
+
+  cmMakefile *makefile = lg->GetMakefile();
+  const char* language = source->GetLanguage();
+  if (language == NULL)
+   {
+   language = "C";
+   }
+  const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  // Add language-specific flags.
+  lg->AddLanguageFlags(flags, language, config);
+
+  lg->AddArchitectureFlags(flags, gtgt, language, config);
+
+  // TODO: Fortran support.
+  // // Fortran-specific flags computed for this target.
+  // if(*l == "Fortran")
+  //   {
+  //   this->AddFortranFlags(flags);
+  //   }
+
+  // Add shared-library flags if needed.
+  lg->AddCMP0018Flags(flags, target, language, config);
+
+  // Add include directory flags.
+  {
+  std::vector<std::string> includes;
+  lg->GetIncludeDirectories(includes, gtgt, language, config);
+  std::string includeFlags =
+    lg->GetIncludeFlags(includes, language, true); // full include paths
+  lg->AppendFlags(flags, includeFlags.c_str());
+  }
+
+  // Append old-style preprocessor definition flags.
+  lg->AppendFlags(flags, makefile->GetDefineFlags());
+
+  // Add target-specific flags.
+  if(target->GetProperty("COMPILE_FLAGS"))
+    {
+    std::string langIncludeExpr = "CMAKE_";
+    langIncludeExpr += language;
+    langIncludeExpr += "_FLAG_REGEX";
+    const char* regex = makefile->GetDefinition(langIncludeExpr.c_str());
+    if(regex)
+      {
+      cmsys::RegularExpression r(regex);
+      std::vector<std::string> args;
+      cmSystemTools::
+        ParseWindowsCommandLine(target->GetProperty("COMPILE_FLAGS"), args);
+      for(std::vector<std::string>::iterator i = args.begin();
+          i != args.end(); ++i)
+        {
+        if(r.find(i->c_str()))
+          {
+          lg->AppendFlags(flags, i->c_str());
+          }
+        }
+      }
+    else
+      {
+      lg->AppendFlags(flags, target->GetProperty("COMPILE_FLAGS"));
+      }
+    }
+
+  // Add source file specific flags.
+  lg->AppendFlags(flags, target->GetProperty("COMPILE_FLAGS"));
+
+  // TODO: Handle Apple frameworks.
+
+  return flags;
+}
+
+// TODO: Refactor with
+// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
+std::string
+cmExtraSublimeTextGenerator::
+ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target,
+               cmGeneratorTarget*)
+
+{
+  std::set<std::string> defines;
+  cmMakefile *makefile = lg->GetMakefile();
+  const char* language = source->GetLanguage();
+  if (language == NULL)
+   {
+   language = "";
+   }
+  const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+
+  // Add the export symbol definition for shared library objects.
+  if(const char* exportMacro = target->GetExportMacro())
+    {
+    lg->AppendDefines(defines, exportMacro);
+    }
+
+  // Add preprocessor definitions for this target and configuration.
+  lg->AppendDefines(defines, target->GetCompileDefinitions(config));
+  lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
+  {
+  std::string defPropName = "COMPILE_DEFINITIONS_";
+  defPropName += cmSystemTools::UpperCase(config);
+  lg->AppendDefines(defines, source->GetProperty(defPropName.c_str()));
+  }
+
+  std::string definesString;
+  lg->JoinDefines(defines, definesString, language);
+
+  return definesString;
+}
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
new file mode 100644 (file)
index 0000000..7902593
--- /dev/null
@@ -0,0 +1,89 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2004-2009 Kitware, Inc.
+  Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+
+  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 cmExtraSublimeTextGenerator_h
+#define cmExtraSublimeTextGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+#include "cmSourceFile.h"
+
+class cmLocalGenerator;
+class cmMakefile;
+class cmTarget;
+class cmGeneratedFileStream;
+class cmGeneratorTarget;
+
+/** \class cmExtraSublimeTextGenerator
+ * \brief Write Sublime Text 2 project files for Makefile based projects
+ */
+class cmExtraSublimeTextGenerator : public cmExternalMakefileProjectGenerator
+{
+public:
+  typedef std::map<std::string, std::vector<std::string> > MapSourceFileFlags;
+  cmExtraSublimeTextGenerator();
+
+  virtual const char* GetName() const
+                        { return cmExtraSublimeTextGenerator::GetActualName();}
+  static const char* GetActualName()
+                        { return "Sublime Text 2";}
+  static cmExternalMakefileProjectGenerator* New()
+                                    { return new cmExtraSublimeTextGenerator; }
+  /** Get the documentation entry for this generator.  */
+  virtual void GetDocumentation(cmDocumentationEntry& entry,
+                                const char* fullName) const;
+
+  virtual void Generate();
+private:
+
+  void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
+
+  void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+                                const std::string& filename);
+
+  /** Appends all targets as build systems to the project file and get all
+   * include directories and compiler definitions used.
+   */
+  void AppendAllTargets(const std::vector<cmLocalGenerator*>& lgs,
+                        const cmMakefile* mf,
+                        cmGeneratedFileStream& fout,
+                        MapSourceFileFlags& sourceFileFlags);
+  /** Returns the build command that needs to be executed to build the
+   *  specified target.
+   */
+  std::string BuildMakeCommand(const std::string& make, const char* makefile,
+                               const char* target);
+  /** Appends the specified target to the generated project file as a Sublime
+   *  Text build system.
+   */
+  void AppendTarget(cmGeneratedFileStream& fout,
+                    const char* targetName,
+                    cmLocalGenerator* lg,
+                    cmTarget* target,
+                    const char* make,
+                    const cmMakefile* makefile,
+                    const char* compiler,
+                    MapSourceFileFlags& sourceFileFlags, bool firstTarget);
+  /**
+   * Compute the flags for compilation of object files for a given @a language.
+   * @note Generally it is the value of the variable whose name is computed
+   *       by LanguageFlagsVarName().
+   */
+  std::string ComputeFlagsForObject(cmSourceFile *source,
+                                    cmLocalGenerator* lg,
+                                    cmTarget *target,
+                                    cmGeneratorTarget* gtgt);
+
+  std::string ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg,
+                             cmTarget *target, cmGeneratorTarget* gtgt);
+};
+
+#endif
index a4aa75a..b08c335 100644 (file)
@@ -37,9 +37,13 @@ bool cmFLTKWrapUICommand
   // get the list of GUI files from which .cxx and .h will be generated
   std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();
 
+  {
   // Some of the generated files are *.h so the directory "GUI"
   // where they are created have to be added to the include path
-  this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );
+  std::vector<std::string> outputDirectories;
+  outputDirectories.push_back(outputDirectory);
+  this->Makefile->AddIncludeDirectories( outputDirectories );
+  }
 
   for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
       i != newArgs.end(); i++)
index 8de24b3..018ce7e 100644 (file)
 #include "cmFileTimeComparison.h"
 #include "cmCryptoHash.h"
 
+#include "cmTimestamp.h"
+
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 #include "cm_curl.h"
 #endif
 
 #undef GetCurrentDirectory
+#include <assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -160,6 +163,10 @@ bool cmFileCommand
     {
     return this->HandleCMakePathCommand(args, true);
     }
+  else if ( subCommand == "TIMESTAMP" )
+    {
+    return this->HandleTimestampCommand(args);
+    }
 
   std::string e = "does not recognize sub-command "+subCommand;
   this->SetError(e.c_str());
@@ -705,11 +712,8 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
 bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
   bool recurse)
 {
-  if ( args.size() < 2 )
-    {
-    this->SetError("GLOB requires at least a variable name");
-    return false;
-    }
+  // File commands has at least one argument
+  assert(args.size() > 1);
 
   std::vector<std::string>::const_iterator i = args.begin();
 
@@ -843,11 +847,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
 bool cmFileCommand::HandleMakeDirectoryCommand(
   std::vector<std::string> const& args)
 {
-  if(args.size() < 2 )
-    {
-    this->SetError("called with incorrect number of arguments");
-    return false;
-    }
+  // File command has at least one argument
+  assert(args.size() > 1);
 
   std::vector<std::string>::const_iterator i = args.begin();
 
@@ -2408,7 +2409,8 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
       fileName += "/" + *i;
       }
 
-    if(cmSystemTools::FileIsDirectory(fileName.c_str()) && recurse)
+    if(cmSystemTools::FileIsDirectory(fileName.c_str()) &&
+       !cmSystemTools::FileIsSymlink(fileName.c_str()) && recurse)
       {
       cmSystemTools::RemoveADirectory(fileName.c_str());
       }
@@ -3246,3 +3248,54 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
   return false;
 #endif
 }
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleTimestampCommand(
+  std::vector<std::string> const& args)
+{
+  if(args.size() < 3)
+    {
+    this->SetError("sub-command TIMESTAMP requires at least two arguments.");
+    return false;
+    }
+  else if(args.size() > 5)
+    {
+    this->SetError("sub-command TIMESTAMP takes at most four arguments.");
+    return false;
+    }
+
+  unsigned int argsIndex = 1;
+
+  const std::string& filename = args[argsIndex++];
+
+  const std::string& outputVariable = args[argsIndex++];
+
+  std::string formatString;
+  if(args.size() > argsIndex && args[argsIndex] != "UTC")
+    {
+    formatString = args[argsIndex++];
+    }
+
+  bool utcFlag = false;
+  if(args.size() > argsIndex)
+    {
+    if(args[argsIndex] == "UTC")
+      {
+      utcFlag = true;
+      }
+    else
+      {
+      std::string e = " TIMESTAMP sub-command does not recognize option " +
+          args[argsIndex] + ".";
+      this->SetError(e.c_str());
+      return false;
+      }
+    }
+
+  cmTimestamp timestamp;
+  std::string result = timestamp.FileModificationTime(
+    filename.c_str(), formatString, utcFlag);
+  this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
+
+  return true;
+}
index b4aa903..5973fa7 100644 (file)
@@ -87,9 +87,11 @@ public:
       "       [TLS_VERIFY on|off] [TLS_CAINFO file])\n"
       "  file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
       "       [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
+      "  file(TIMESTAMP filename variable [<format string>] [UTC])\n"
       "WRITE will write a message into a file called 'filename'. It "
       "overwrites the file if it already exists, and creates the file "
-      "if it does not exist.\n"
+      "if it does not exist. (If the file is a build input, use "
+      "configure_file to update the file only when its content changes.)\n"
       "APPEND will write a message into a file same as WRITE, except "
       "it will append it to the end of the file\n"
       "READ will read the content of a file and store it into the "
@@ -199,6 +201,12 @@ public:
       "If SHOW_PROGRESS is specified, progress information will be printed "
       "as status messages until the operation is complete."
       "\n"
+      "TIMESTAMP will write a string representation of "
+      "the modification time of filename to variable.\n"
+      "Should the command be unable to obtain a timestamp "
+      "variable will be set to the empty string \"\".\n"
+      "See documentation of the string TIMESTAMP sub-command for more details."
+      "\n"
       "The file() command also provides COPY and INSTALL signatures:\n"
       "  file(<COPY|INSTALL> files... DESTINATION <dir>\n"
       "       [FILE_PERMISSIONS permissions...]\n"
@@ -259,6 +267,8 @@ protected:
   bool HandleInstallCommand(std::vector<std::string> const& args);
   bool HandleDownloadCommand(std::vector<std::string> const& args);
   bool HandleUploadCommand(std::vector<std::string> const& args);
+
+  bool HandleTimestampCommand(std::vector<std::string> const& args);
 };
 
 
index a54bf7c..7ce0032 100644 (file)
@@ -15,6 +15,8 @@ cmFindBase::cmFindBase()
 {
   this->AlreadyInCache = false;
   this->AlreadyInCacheWithoutMetaInfo = false;
+  this->NamesPerDir = false;
+  this->NamesPerDirAllowed = false;
 }
 
 //----------------------------------------------------------------------------
@@ -213,6 +215,19 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
       compatibility = false;
       newStyle = true;
       }
+    else if (args[j] == "NAMES_PER_DIR")
+      {
+      doing = DoingNone;
+      if(this->NamesPerDirAllowed)
+        {
+        this->NamesPerDir = true;
+        }
+      else
+        {
+        this->SetError("does not support NAMES_PER_DIR");
+        return false;
+        }
+      }
     else if (args[j] == "NO_SYSTEM_PATH")
       {
       doing = DoingNone;
@@ -345,13 +360,13 @@ void cmFindBase::AddPrefixPaths(std::vector<std::string> const& in_paths,
       {
       dir += "/";
       }
-    if(subdir == "lib")
+    if(subdir == "include" || subdir == "lib")
       {
       const char* arch =
         this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
       if(arch && *arch)
         {
-        this->AddPathInternal(dir+"lib/"+arch, pathType);
+        this->AddPathInternal(dir+subdir+"/"+arch, pathType);
         }
       }
     std::string add = dir + subdir;
index eac1885..84b0330 100644 (file)
@@ -49,6 +49,8 @@ protected:
   cmStdString VariableDocumentation;
   cmStdString VariableName;
   std::vector<std::string> Names;
+  bool NamesPerDir;
+  bool NamesPerDirAllowed;
 
   // CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
   cmStdString EnvironmentPath; // LIB,INCLUDE
index 0080e55..4af7e11 100644 (file)
@@ -17,6 +17,7 @@
 cmFindLibraryCommand::cmFindLibraryCommand()
 {
   this->EnvironmentPath = "LIB";
+  this->NamesPerDirAllowed = true;
 }
 
 //----------------------------------------------------------------------------
@@ -44,6 +45,9 @@ void cmFindLibraryCommand::GenerateDocumentation()
                                "SEARCH_XXX", "library");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "XXX_SUBDIR", "lib");
+  cmSystemTools::ReplaceString(this->GenericDocumentation,
+                               "NAMES name1 [name2 ...]",
+                               "NAMES name1 [name2 ...] [NAMES_PER_DIR]");
   cmSystemTools::ReplaceString(
     this->GenericDocumentation,
     "XXX_EXTRA_PREFIX_ENTRY",
@@ -53,6 +57,12 @@ void cmFindLibraryCommand::GenerateDocumentation()
                                "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
   this->GenericDocumentation +=
     "\n"
+    "When more than one value is given to the NAMES option this command "
+    "by default will consider one name at a time and search every directory "
+    "for it.  "
+    "The NAMES_PER_DIR option tells this command to consider one directory "
+    "at a time and search for all names in it."
+    "\n"
     "If the library found is a framework, then VAR will be set to "
     "the full path to the framework <fullPath>/A.framework. "
     "When a full path to a framework is used as a library, "
@@ -220,18 +230,19 @@ struct cmFindLibraryHelper
   // Keep track of the best library file found so far.
   typedef std::vector<std::string>::size_type size_type;
   std::string BestPath;
-  size_type BestPrefix;
-  size_type BestSuffix;
 
   // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
   bool OpenBSD;
-  unsigned int BestMajor;
-  unsigned int BestMinor;
 
-  // Current name under consideration.
-  cmsys::RegularExpression NameRegex;
-  bool TryRawName;
-  std::string RawName;
+  // Current names under consideration.
+  struct Name
+  {
+    bool TryRaw;
+    std::string Raw;
+    cmsys::RegularExpression Regex;
+    Name(): TryRaw(false) {}
+  };
+  std::vector<Name> Names;
 
   // Current full path under consideration.
   std::string TestPath;
@@ -249,8 +260,9 @@ struct cmFindLibraryHelper
                            suffix) - this->Suffixes.begin();
     }
   bool HasValidSuffix(std::string const& name);
-  void SetName(std::string const& name);
+  void AddName(std::string const& name);
   bool CheckDirectory(std::string const& path);
+  bool CheckDirectoryForName(std::string const& path, Name& name);
 };
 
 //----------------------------------------------------------------------------
@@ -273,14 +285,6 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
   this->OpenBSD =
     this->Makefile->GetCMakeInstance()
     ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
-
-  this->TryRawName = false;
-
-  // No library file has yet been found.
-  this->BestPrefix = this->Prefixes.size();
-  this->BestSuffix = this->Suffixes.size();
-  this->BestMajor = 0;
-  this->BestMinor = 0;
 }
 
 //----------------------------------------------------------------------------
@@ -353,11 +357,13 @@ bool cmFindLibraryHelper::HasValidSuffix(std::string const& name)
 }
 
 //----------------------------------------------------------------------------
-void cmFindLibraryHelper::SetName(std::string const& name)
+void cmFindLibraryHelper::AddName(std::string const& name)
 {
+  Name entry;
+
   // Consider checking the raw name too.
-  this->TryRawName = this->HasValidSuffix(name);
-  this->RawName = name;
+  entry.TryRaw = this->HasValidSuffix(name);
+  entry.Raw = name;
 
   // Build a regular expression to match library names.
   std::string regex = "^";
@@ -369,21 +375,37 @@ void cmFindLibraryHelper::SetName(std::string const& name)
     regex += "(\\.[0-9]+\\.[0-9]+)?";
     }
   regex += "$";
-  this->NameRegex.compile(regex.c_str());
+  entry.Regex.compile(regex.c_str());
+  this->Names.push_back(entry);
 }
 
 //----------------------------------------------------------------------------
 bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
 {
+  for(std::vector<Name>::iterator i = this->Names.begin();
+      i != this->Names.end(); ++i)
+    {
+    if(this->CheckDirectoryForName(path, *i))
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
+                                                Name& name)
+{
   // If the original library name provided by the user matches one of
   // the suffixes, try it first.  This allows users to search
   // specifically for a static library on some platforms (on MS tools
   // one cannot tell just from the library name whether it is a static
   // library or an import library).
-  if(this->TryRawName)
+  if(name.TryRaw)
     {
     this->TestPath = path;
-    this->TestPath += this->RawName;
+    this->TestPath += name.Raw;
     if(cmSystemTools::FileExists(this->TestPath.c_str(), true))
       {
       this->BestPath =
@@ -393,6 +415,12 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
       }
     }
 
+  // No library file has yet been found.
+  size_type bestPrefix = this->Prefixes.size();
+  size_type bestSuffix = this->Suffixes.size();
+  unsigned int bestMajor = 0;
+  unsigned int bestMinor = 0;
+
   // Search for a file matching the library name regex.
   std::string dir = path;
   cmSystemTools::ConvertToUnixSlashes(dir);
@@ -406,7 +434,7 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
 #else
     std::string const& testName = origName;
 #endif
-    if(this->NameRegex.find(testName))
+    if(name.Regex.find(testName))
       {
       this->TestPath = path;
       this->TestPath += origName;
@@ -416,25 +444,25 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
         // best name found so far.  Earlier prefixes are preferred,
         // followed by earlier suffixes.  For OpenBSD, shared library
         // version extensions are compared.
-        size_type prefix = this->GetPrefixIndex(this->NameRegex.match(1));
-        size_type suffix = this->GetSuffixIndex(this->NameRegex.match(2));
+        size_type prefix = this->GetPrefixIndex(name.Regex.match(1));
+        size_type suffix = this->GetSuffixIndex(name.Regex.match(2));
         unsigned int major = 0;
         unsigned int minor = 0;
         if(this->OpenBSD)
           {
-          sscanf(this->NameRegex.match(3).c_str(), ".%u.%u", &major, &minor);
+          sscanf(name.Regex.match(3).c_str(), ".%u.%u", &major, &minor);
           }
-        if(this->BestPath.empty() || prefix < this->BestPrefix ||
-           (prefix == this->BestPrefix && suffix < this->BestSuffix) ||
-           (prefix == this->BestPrefix && suffix == this->BestSuffix &&
-            (major > this->BestMajor ||
-             (major == this->BestMajor && minor > this->BestMinor))))
+        if(this->BestPath.empty() || prefix < bestPrefix ||
+           (prefix == bestPrefix && suffix < bestSuffix) ||
+           (prefix == bestPrefix && suffix == bestSuffix &&
+            (major > bestMajor ||
+             (major == bestMajor && minor > bestMinor))))
           {
           this->BestPath = this->TestPath;
-          this->BestPrefix = prefix;
-          this->BestSuffix = suffix;
-          this->BestMajor = major;
-          this->BestMinor = minor;
+          bestPrefix = prefix;
+          bestSuffix = suffix;
+          bestMajor = major;
+          bestMinor = minor;
           }
         }
       }
@@ -447,6 +475,42 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
 //----------------------------------------------------------------------------
 std::string cmFindLibraryCommand::FindNormalLibrary()
 {
+  if(this->NamesPerDir)
+    {
+    return this->FindNormalLibraryNamesPerDir();
+    }
+  else
+    {
+    return this->FindNormalLibraryDirsPerName();
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
+{
+  // Search for all names in each directory.
+  cmFindLibraryHelper helper(this->Makefile);
+  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+      ni != this->Names.end() ; ++ni)
+    {
+    helper.AddName(*ni);
+    }
+  // Search every directory.
+  for(std::vector<std::string>::const_iterator
+        p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
+    {
+    if(helper.CheckDirectory(*p))
+      {
+      return helper.BestPath;
+      }
+    }
+  // Couldn't find the library.
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
+{
   // Search the entire path for each name.
   cmFindLibraryHelper helper(this->Makefile);
   for(std::vector<std::string>::const_iterator ni = this->Names.begin();
@@ -454,7 +518,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
     {
     // Switch to searching for this name.
     std::string const& name = *ni;
-    helper.SetName(name);
+    helper.AddName(name);
 
     // Search every directory.
     for(std::vector<std::string>::const_iterator
@@ -474,19 +538,60 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
 //----------------------------------------------------------------------------
 std::string cmFindLibraryCommand::FindFrameworkLibrary()
 {
-  // Search for a framework of each name in the entire search path.
+  if(this->NamesPerDir)
+    {
+    return this->FindFrameworkLibraryNamesPerDir();
+    }
+  else
+    {
+    return this->FindFrameworkLibraryDirsPerName();
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
+{
+  std::string fwPath;
+  // Search for all names in each search path.
+  for(std::vector<std::string>::const_iterator di = this->SearchPaths.begin();
+      di != this->SearchPaths.end(); ++di)
+    {
+    for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+        ni != this->Names.end() ; ++ni)
+      {
+      fwPath = *di;
+      fwPath += *ni;
+      fwPath += ".framework";
+      if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+        {
+        return cmSystemTools::CollapseFullPath(fwPath.c_str());
+        }
+      }
+    }
+
+  // No framework found.
+  return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
+{
+  std::string fwPath;
+  // Search for each name in all search paths.
   for(std::vector<std::string>::const_iterator ni = this->Names.begin();
       ni != this->Names.end() ; ++ni)
     {
-    // Search the paths for a framework with this name.
-    std::string fwName = *ni;
-    fwName += ".framework";
-    std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(),
-                                                      this->SearchPaths,
-                                                      true);
-    if(!fwPath.empty())
+    for(std::vector<std::string>::const_iterator
+          di = this->SearchPaths.begin();
+        di != this->SearchPaths.end(); ++di)
       {
-      return fwPath;
+      fwPath = *di;
+      fwPath += *ni;
+      fwPath += ".framework";
+      if(cmSystemTools::FileIsDirectory(fwPath.c_str()))
+        {
+        return cmSystemTools::CollapseFullPath(fwPath.c_str());
+        }
       }
     }
 
index 455348a..cd0fce8 100644 (file)
@@ -70,7 +70,11 @@ protected:
   virtual void GenerateDocumentation();
 private:
   std::string FindNormalLibrary();
+  std::string FindNormalLibraryNamesPerDir();
+  std::string FindNormalLibraryDirsPerName();
   std::string FindFrameworkLibrary();
+  std::string FindFrameworkLibraryNamesPerDir();
+  std::string FindFrameworkLibraryDirsPerName();
 };
 
 
index 470ceca..aa3a73d 100644 (file)
@@ -95,7 +95,8 @@ void cmFindPackageCommand::GenerateDocumentation()
     "Finds and loads settings from an external project.  "
     "<package>_FOUND will be set to indicate whether the package was found.  "
     "When the package is found package-specific information is provided "
-    "through variables documented by the package itself.  "
+    "through variables and imported targets documented by the package "
+    "itself.  "
     "The QUIET option disables messages if the package cannot be found.  "
     "The MODULE option disables the second signature documented below.  "
     "The REQUIRED option stops processing with an error message if the "
index 9524924..6a43298 100644 (file)
@@ -45,8 +45,10 @@ void cmFindPathCommand::GenerateDocumentation()
                                "SEARCH_XXX", "file in a directory");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "XXX_SUBDIR", "include");
-  cmSystemTools::ReplaceString(this->GenericDocumentation,
-                               "XXX_EXTRA_PREFIX_ENTRY", "");
+  cmSystemTools::ReplaceString(
+    this->GenericDocumentation,
+    "XXX_EXTRA_PREFIX_ENTRY",
+    "   <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n");
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                "CMAKE_FIND_ROOT_PATH_MODE_XXX",
                                "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
index 730a7a7..0a029dc 100644 (file)
@@ -90,7 +90,9 @@ public:
       "will have the actual values of the arguments passed in. This "
       "facilitates creating functions with optional arguments. Additionally "
       "ARGV holds the list of all arguments given to the function and ARGN "
-      "holds the list of argument past the last expected argument."
+      "holds the list of arguments past the last expected argument."
+      "\n"
+      "A function opens a new scope: see set(var PARENT_SCOPE) for details."
       "\n"
       "See the cmake_policy() command documentation for the behavior of "
       "policies inside functions."
index 7d8df37..ab8bd13 100644 (file)
 //----------------------------------------------------------------------------
 cmGeneratorExpression::cmGeneratorExpression(
   cmListFileBacktrace const& backtrace):
-  Backtrace(backtrace), CompiledExpression(0)
+  Backtrace(backtrace)
 {
 }
 
 //----------------------------------------------------------------------------
-const cmCompiledGeneratorExpression &
+cmsys::auto_ptr<cmCompiledGeneratorExpression>
 cmGeneratorExpression::Parse(std::string const& input)
 {
   return this->Parse(input.c_str());
 }
 
 //----------------------------------------------------------------------------
-const cmCompiledGeneratorExpression &
+cmsys::auto_ptr<cmCompiledGeneratorExpression>
 cmGeneratorExpression::Parse(const char* input)
 {
-  cmGeneratorExpressionLexer l;
-  std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input);
-  bool needsParsing = l.GetSawGeneratorExpression();
-  std::vector<cmGeneratorExpressionEvaluator*> evaluators;
-
-  if (needsParsing)
-    {
-    cmGeneratorExpressionParser p(tokens);
-    p.Parse(evaluators);
-    }
-
-  delete this->CompiledExpression;
-  this->CompiledExpression = new cmCompiledGeneratorExpression(
-                                      this->Backtrace,
-                                      evaluators,
-                                      input,
-                                      needsParsing);
-  return *this->CompiledExpression;
+  return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
+                                      new cmCompiledGeneratorExpression(
+                                        this->Backtrace,
+                                        input));
 }
 
 cmGeneratorExpression::~cmGeneratorExpression()
 {
-  delete this->CompiledExpression;
 }
 
 //----------------------------------------------------------------------------
 const char *cmCompiledGeneratorExpression::Evaluate(
   cmMakefile* mf, const char* config, bool quiet,
-  cmGeneratorTarget *target,
+  cmTarget *headTarget,
+  cmGeneratorExpressionDAGChecker *dagChecker) const
+{
+  return this->Evaluate(mf,
+                        config,
+                        quiet,
+                        headTarget,
+                        headTarget,
+                        dagChecker);
+}
+
+//----------------------------------------------------------------------------
+const char *cmCompiledGeneratorExpression::Evaluate(
+  cmMakefile* mf, const char* config, bool quiet,
+  cmTarget *headTarget,
+  cmTarget *currentTarget,
   cmGeneratorExpressionDAGChecker *dagChecker) const
 {
   if (!this->NeedsParsing)
     {
-    return this->Input;
+    return this->Input.c_str();
     }
 
   this->Output = "";
@@ -88,32 +88,54 @@ const char *cmCompiledGeneratorExpression::Evaluate(
   context.Config = config;
   context.Quiet = quiet;
   context.HadError = false;
-  context.Target = target;
+  context.HadContextSensitiveCondition = false;
+  context.HeadTarget = headTarget;
+  context.CurrentTarget = currentTarget ? currentTarget : headTarget;
   context.Backtrace = this->Backtrace;
 
   for ( ; it != end; ++it)
     {
     this->Output += (*it)->Evaluate(&context, dagChecker);
+
+    for(std::set<cmStdString>::const_iterator
+          p = context.SeenTargetProperties.begin();
+          p != context.SeenTargetProperties.end(); ++p)
+      {
+      this->SeenTargetProperties.insert(*p);
+      }
     if (context.HadError)
       {
       this->Output = "";
       break;
       }
     }
+  if (!context.HadError)
+    {
+    this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
+    }
 
-  this->Targets = context.Targets;
+  this->DependTargets = context.DependTargets;
+  this->AllTargetsSeen = context.AllTargets;
   // TODO: Return a std::string from here instead?
   return this->Output.c_str();
 }
 
 cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
               cmListFileBacktrace const& backtrace,
-              const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
-              const char *input, bool needsParsing)
-  : Backtrace(backtrace), Evaluators(evaluators), Input(input),
-    NeedsParsing(needsParsing)
+              const char *input)
+  : Backtrace(backtrace), Input(input ? input : ""),
+    HadContextSensitiveCondition(false)
 {
+  cmGeneratorExpressionLexer l;
+  std::vector<cmGeneratorExpressionToken> tokens =
+                                              l.Tokenize(this->Input.c_str());
+  this->NeedsParsing = l.GetSawGeneratorExpression();
 
+  if (this->NeedsParsing)
+    {
+    cmGeneratorExpressionParser p(tokens);
+    p.Parse(this->Evaluators);
+    }
 }
 
 
@@ -131,15 +153,42 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
     }
 }
 
-std::string cmGeneratorExpression::Preprocess(const std::string &input,
-                                              PreprocessContext context)
+//----------------------------------------------------------------------------
+std::string cmGeneratorExpression::StripEmptyListElements(
+                                                    const std::string &input)
 {
-  if (context != StripAllGeneratorExpressions)
-  {
-    assert(!"cmGeneratorExpression::Preprocess called with invalid args");
-    return std::string();
-  }
+  std::string result;
+
+  const char *c = input.c_str();
+  bool skipSemiColons = true;
+  for ( ; *c; ++c)
+    {
+    if(c[0] == ';')
+      {
+      if(skipSemiColons)
+        {
+        continue;
+        }
+      skipSemiColons = true;
+      }
+    else
+      {
+      skipSemiColons = false;
+      }
+    result += *c;
+    }
+
+  if (!result.empty() && *(result.end() - 1) == ';')
+    {
+    result.resize(result.size() - 1);
+    }
+
+  return result;
+}
 
+//----------------------------------------------------------------------------
+static std::string stripAllGeneratorExpressions(const std::string &input)
+{
   std::string result;
   std::string::size_type pos = 0;
   std::string::size_type lastPos = pos;
@@ -176,5 +225,195 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input,
     lastPos = pos;
     }
   result += input.substr(lastPos);
-  return result;
+  return cmGeneratorExpression::StripEmptyListElements(result);
+}
+
+//----------------------------------------------------------------------------
+static std::string stripExportInterface(const std::string &input,
+                          cmGeneratorExpression::PreprocessContext context)
+{
+  std::string result;
+
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+  while (true)
+    {
+    std::string::size_type bPos = input.find("$<BUILD_INTERFACE:", lastPos);
+    std::string::size_type iPos = input.find("$<INSTALL_INTERFACE:", lastPos);
+
+    if (bPos == std::string::npos && iPos == std::string::npos)
+      {
+      break;
+      }
+
+    if (bPos == std::string::npos)
+      {
+      pos = iPos;
+      }
+    else if (iPos == std::string::npos)
+      {
+      pos = bPos;
+      }
+    else
+      {
+      pos = (bPos < iPos) ? bPos : iPos;
+      }
+
+    result += input.substr(lastPos, pos - lastPos);
+    const bool gotInstallInterface = input[pos + 2] == 'I';
+    pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1
+                               : sizeof("$<BUILD_INTERFACE:") - 1;
+    int nestingLevel = 1;
+    const char *c = input.c_str() + pos;
+    const char * const cStart = c;
+    for ( ; *c; ++c)
+      {
+      if(c[0] == '$' && c[1] == '<')
+        {
+        ++nestingLevel;
+        ++c;
+        continue;
+        }
+      if(c[0] == '>')
+        {
+        --nestingLevel;
+        if (nestingLevel != 0)
+          {
+          continue;
+          }
+        if(context == cmGeneratorExpression::BuildInterface
+            && !gotInstallInterface)
+          {
+          result += input.substr(pos, c - cStart);
+          }
+        else if(context == cmGeneratorExpression::InstallInterface
+            && gotInstallInterface)
+          {
+          result += input.substr(pos, c - cStart);
+          }
+        break;
+        }
+      }
+    const std::string::size_type traversed = (c - cStart) + 1;
+    if (!*c)
+      {
+      result += std::string(gotInstallInterface ? "$<INSTALL_INTERFACE:"
+                                                : "$<BUILD_INTERFACE:")
+             + input.substr(pos, traversed);
+      }
+    pos += traversed;
+    lastPos = pos;
+    }
+  result += input.substr(lastPos);
+
+  return cmGeneratorExpression::StripEmptyListElements(result);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorExpression::Split(const std::string &input,
+                                  std::vector<std::string> &output)
+{
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+  while((pos = input.find("$<", lastPos)) != input.npos)
+    {
+    std::string part = input.substr(lastPos, pos - lastPos);
+    std::string preGenex;
+    if (!part.empty())
+      {
+      std::string::size_type startPos = input.rfind(";", pos);
+      if (startPos == std::string::npos)
+        {
+        preGenex = part;
+        part = "";
+        }
+      else if (startPos != pos - 1 && startPos >= lastPos)
+        {
+        part = input.substr(lastPos, startPos - lastPos);
+        preGenex = input.substr(startPos + 1, pos - startPos - 1);
+        }
+      if(!part.empty())
+        {
+        cmSystemTools::ExpandListArgument(part.c_str(), output);
+        }
+      }
+    pos += 2;
+    int nestingLevel = 1;
+    const char *c = input.c_str() + pos;
+    const char * const cStart = c;
+    for ( ; *c; ++c)
+      {
+      if(c[0] == '$' && c[1] == '<')
+        {
+        ++nestingLevel;
+        ++c;
+        continue;
+        }
+      if(c[0] == '>')
+        {
+        --nestingLevel;
+        if (nestingLevel == 0)
+          {
+          break;
+          }
+        }
+      }
+    for ( ; *c; ++c)
+      {
+      // Capture the part after the genex and before the next ';'
+      if(c[0] == ';')
+        {
+        --c;
+        break;
+        }
+      }
+    const std::string::size_type traversed = (c - cStart) + 1;
+    output.push_back(preGenex + "$<" + input.substr(pos, traversed));
+    pos += traversed;
+    lastPos = pos;
+    }
+  if (lastPos < input.size())
+    {
+    cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorExpression::Preprocess(const std::string &input,
+                                              PreprocessContext context)
+{
+  if (context == StripAllGeneratorExpressions)
+    {
+    return stripAllGeneratorExpressions(input);
+    }
+  else if (context == BuildInterface || context == InstallInterface)
+    {
+    return stripExportInterface(input, context);
+    }
+
+  assert(!"cmGeneratorExpression::Preprocess called with invalid args");
+  return std::string();
+}
+
+//----------------------------------------------------------------------------
+std::string::size_type cmGeneratorExpression::Find(const std::string &input)
+{
+  const std::string::size_type openpos = input.find("$<");
+  if (openpos != std::string::npos
+      && input.find(">", openpos) != std::string::npos)
+    {
+    return openpos;
+    }
+  return std::string::npos;
+}
+
+//----------------------------------------------------------------------------
+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_.:+-]+$");
+
+  return targetNameValidator.find(input.c_str());
 }
index 29d3f44..86b6f25 100644 (file)
 #define cmGeneratorExpression_h
 
 #include "cmStandardIncludes.h"
+#include "cmListFileCache.h"
 
 #include <stack>
 
 #include <cmsys/RegularExpression.hxx>
+#include <cmsys/auto_ptr.hxx>
 
 class cmTarget;
-class cmGeneratorTarget;
 class cmMakefile;
 class cmListFileBacktrace;
 
@@ -45,22 +46,32 @@ public:
   cmGeneratorExpression(cmListFileBacktrace const& backtrace);
   ~cmGeneratorExpression();
 
-  const cmCompiledGeneratorExpression& Parse(std::string const& input);
-  const cmCompiledGeneratorExpression& Parse(const char* input);
+  cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
+                                                std::string const& input);
+  cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
 
   enum PreprocessContext {
-    StripAllGeneratorExpressions
+    StripAllGeneratorExpressions,
+    BuildInterface,
+    InstallInterface
   };
 
   static std::string Preprocess(const std::string &input,
                                 PreprocessContext context);
 
+  static void Split(const std::string &input,
+                    std::vector<std::string> &output);
+
+  static std::string::size_type Find(const std::string &input);
+
+  static bool IsValidTargetName(const std::string &input);
+
+  static std::string StripEmptyListElements(const std::string &input);
 private:
   cmGeneratorExpression(const cmGeneratorExpression &);
   void operator=(const cmGeneratorExpression &);
 
   cmListFileBacktrace const& Backtrace;
-  cmCompiledGeneratorExpression *CompiledExpression;
 };
 
 class cmCompiledGeneratorExpression
@@ -68,32 +79,59 @@ class cmCompiledGeneratorExpression
 public:
   const char* Evaluate(cmMakefile* mf, const char* config,
                        bool quiet = false,
-                       cmGeneratorTarget *target = 0,
+                       cmTarget *headTarget = 0,
+                       cmTarget *currentTarget = 0,
                        cmGeneratorExpressionDAGChecker *dagChecker = 0) const;
+  const char* Evaluate(cmMakefile* mf, const char* config,
+                       bool quiet,
+                       cmTarget *headTarget,
+                       cmGeneratorExpressionDAGChecker *dagChecker) const;
 
   /** Get set of targets found during evaluations.  */
   std::set<cmTarget*> const& GetTargets() const
-    { return this->Targets; }
+    { return this->DependTargets; }
+
+  std::set<cmStdString> const& GetSeenTargetProperties() const
+    { return this->SeenTargetProperties; }
+
+  std::set<cmTarget*> const& GetAllTargetsSeen() const
+    { return this->AllTargetsSeen; }
 
   ~cmCompiledGeneratorExpression();
 
+  std::string GetInput() const
+  {
+    return this->Input;
+  }
+
+  cmListFileBacktrace GetBacktrace() const
+  {
+    return this->Backtrace;
+  }
+  bool GetHadContextSensitiveCondition() const
+  {
+    return this->HadContextSensitiveCondition;
+  }
+
 private:
   cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
-              const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
-              const char *input, bool needsParsing);
+              const char *input);
 
   friend class cmGeneratorExpression;
 
   cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &);
   void operator=(const cmCompiledGeneratorExpression &);
 
-  cmListFileBacktrace const& Backtrace;
-  const std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
-  const char* const Input;
-  const bool NeedsParsing;
+  cmListFileBacktrace Backtrace;
+  std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
+  const std::string Input;
+  bool NeedsParsing;
 
-  mutable std::set<cmTarget*> Targets;
+  mutable std::set<cmTarget*> DependTargets;
+  mutable std::set<cmTarget*> AllTargetsSeen;
+  mutable std::set<cmStdString> SeenTargetProperties;
   mutable std::string Output;
+  mutable bool HadContextSensitiveCondition;
 };
 
 #endif
index bfb0ddf..5cb50b9 100644 (file)
@@ -24,13 +24,40 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
   : Parent(parent), Target(target), Property(property),
     Content(content), Backtrace(backtrace)
 {
-  this->IsDAG = this->isDAG();
+  const cmGeneratorExpressionDAGChecker *top = this;
+  const cmGeneratorExpressionDAGChecker *p = this->Parent;
+  while (p)
+    {
+    top = p;
+    p = p->Parent;
+    }
+  this->CheckResult = this->checkGraph();
+
+  if (CheckResult == DAG && (top->EvaluatingIncludeDirectories()
+      || top->EvaluatingCompileDefinitions()))
+    {
+    std::map<cmStdString, std::set<cmStdString> >::const_iterator it
+                                                    = top->Seen.find(target);
+    if (it != top->Seen.end())
+      {
+      const std::set<cmStdString> &propSet = it->second;
+      const std::set<cmStdString>::const_iterator i = propSet.find(property);
+      if (i != propSet.end())
+        {
+        this->CheckResult = ALREADY_SEEN;
+        return;
+        }
+      }
+    const_cast<cmGeneratorExpressionDAGChecker *>(top)
+                                            ->Seen[target].insert(property);
+    }
 }
 
 //----------------------------------------------------------------------------
-bool cmGeneratorExpressionDAGChecker::check() const
+cmGeneratorExpressionDAGChecker::Result
+cmGeneratorExpressionDAGChecker::check() const
 {
-  return this->IsDAG;
+  return this->CheckResult;
 }
 
 //----------------------------------------------------------------------------
@@ -38,7 +65,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
                   cmGeneratorExpressionContext *context,
                   const std::string &expr)
 {
-  if (this->IsDAG)
+  if (this->CheckResult == DAG)
     {
     return;
     }
@@ -57,7 +84,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
     e << "Error evaluating generator expression:\n"
       << "  " << expr << "\n"
       << "Self reference on target \""
-      << context->Target->GetName() << "\".\n";
+      << context->HeadTarget->GetName() << "\".\n";
     context->Makefile->GetCMakeInstance()
       ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
                       parent->Backtrace);
@@ -91,16 +118,53 @@ void cmGeneratorExpressionDAGChecker::reportError(
 }
 
 //----------------------------------------------------------------------------
-bool cmGeneratorExpressionDAGChecker::isDAG() const
+cmGeneratorExpressionDAGChecker::Result
+cmGeneratorExpressionDAGChecker::checkGraph() const
 {
   const cmGeneratorExpressionDAGChecker *parent = this->Parent;
   while (parent)
     {
     if (this->Target == parent->Target && this->Property == parent->Property)
       {
-      return false;
+      return (parent == this->Parent) ? SELF_REFERENCE : CYCLIC_REFERENCE;
       }
     parent = parent->Parent;
     }
-  return true;
+  return DAG;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
+{
+  const cmGeneratorExpressionDAGChecker *top = this;
+  const cmGeneratorExpressionDAGChecker *parent = this->Parent;
+  while (parent)
+    {
+    top = parent;
+    parent = parent->Parent;
+    }
+
+  const char *prop = top->Property.c_str();
+  return (strcmp(prop, "LINK_LIBRARIES") == 0
+       || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
+       || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
+       || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0
+       || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const
+{
+  const char *prop = this->Property.c_str();
+  return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
+       || strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const
+{
+  const char *prop = this->Property.c_str();
+  return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
+       || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0
+       || strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0);
 }
index ffc84f8..62a5cdf 100644 (file)
@@ -25,20 +25,33 @@ struct cmGeneratorExpressionDAGChecker
                                   const GeneratorExpressionContent *content,
                                   cmGeneratorExpressionDAGChecker *parent);
 
-  bool check() const;
+  enum Result {
+    DAG,
+    SELF_REFERENCE,
+    CYCLIC_REFERENCE,
+    ALREADY_SEEN
+  };
+
+  Result check() const;
 
   void reportError(cmGeneratorExpressionContext *context,
                    const std::string &expr);
+
+  bool EvaluatingLinkLibraries();
+  bool EvaluatingIncludeDirectories() const;
+  bool EvaluatingCompileDefinitions() const;
+
 private:
-  bool isDAG() const;
+  Result checkGraph() const;
 
 private:
   const cmGeneratorExpressionDAGChecker * const Parent;
   const std::string Target;
   const std::string Property;
+  std::map<cmStdString, std::set<cmStdString> > Seen;
   const GeneratorExpressionContent * const Content;
   const cmListFileBacktrace Backtrace;
-  bool IsDAG;
+  Result CheckResult;
 };
 
 #endif
index 2e123a4..a01a0f8 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <cmsys/String.h>
 
+#include <assert.h>
+
 //----------------------------------------------------------------------------
 #if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510
 static
@@ -47,6 +49,8 @@ struct cmGeneratorExpressionNode
 
   virtual bool GeneratesContent() const { return true; }
 
+  virtual bool RequiresLiteralInput() const { return false; }
+
   virtual bool AcceptsSingleArbitraryContentParameter() const
     { return false; }
 
@@ -66,6 +70,8 @@ static const struct ZeroNode : public cmGeneratorExpressionNode
 
   virtual bool GeneratesContent() const { return false; }
 
+  virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+
   std::string Evaluate(const std::vector<std::string> &,
                        cmGeneratorExpressionContext *,
                        const GeneratorExpressionContent *,
@@ -94,6 +100,12 @@ static const struct OneNode : public cmGeneratorExpressionNode
 } oneNode;
 
 //----------------------------------------------------------------------------
+static const struct OneNode buildInterfaceNode;
+
+//----------------------------------------------------------------------------
+static const struct ZeroNode installInterfaceNode;
+
+//----------------------------------------------------------------------------
 #define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \
 static const struct OP ## Node : public cmGeneratorExpressionNode \
 { \
@@ -215,6 +227,22 @@ static const struct CommaNode : public cmGeneratorExpressionNode
 } commaNode;
 
 //----------------------------------------------------------------------------
+static const struct SemicolonNode : public cmGeneratorExpressionNode
+{
+  SemicolonNode() {}
+
+  virtual int NumExpectedParameters() const { return 0; }
+
+  std::string Evaluate(const std::vector<std::string> &,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    return ";";
+  }
+} semicolonNode;
+
+//----------------------------------------------------------------------------
 static const struct ConfigurationNode : public cmGeneratorExpressionNode
 {
   ConfigurationNode() {}
@@ -226,6 +254,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
                        const GeneratorExpressionContent *,
                        cmGeneratorExpressionDAGChecker *) const
   {
+    context->HadContextSensitiveCondition = true;
     return context->Config ? context->Config : "";
   }
 } configurationNode;
@@ -250,16 +279,94 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
                   "Expression syntax not recognized.");
       return std::string();
       }
+    context->HadContextSensitiveCondition = true;
     if (!context->Config)
       {
       return parameters.front().empty() ? "1" : "0";
       }
 
-    return cmsysString_strcasecmp(parameters.begin()->c_str(),
-                                  context->Config) == 0 ? "1" : "0";
+    if (cmsysString_strcasecmp(parameters.begin()->c_str(),
+                                  context->Config) == 0)
+      {
+      return "1";
+      }
+
+    if (context->CurrentTarget
+        && context->CurrentTarget->IsImported())
+      {
+      const char* loc = 0;
+      const char* imp = 0;
+      std::string suffix;
+      return context->CurrentTarget->GetMappedConfig(context->Config,
+                                                  &loc,
+                                                  &imp,
+                                                  suffix) ? "1" : "0";
+      }
+    return "0";
   }
 } configurationTestNode;
 
+
+//----------------------------------------------------------------------------
+static const char* targetPropertyTransitiveWhitelist[] = {
+    "INTERFACE_INCLUDE_DIRECTORIES"
+  , "INTERFACE_COMPILE_DEFINITIONS"
+};
+
+std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
+                                  cmTarget *target,
+                                  cmTarget *headTarget,
+                                  cmGeneratorExpressionContext *context,
+                                  cmGeneratorExpressionDAGChecker *dagChecker,
+                                  const std::string &interfacePropertyName)
+{
+  cmGeneratorExpression ge(context->Backtrace);
+
+  std::string sep;
+  std::string depString;
+  for (std::vector<std::string>::const_iterator
+      it = libraries.begin();
+      it != libraries.end(); ++it)
+    {
+    if (*it == target->GetName())
+      {
+      // 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;
+      }
+    if (context->Makefile->FindTargetToUse(it->c_str()))
+      {
+      depString +=
+        sep + "$<TARGET_PROPERTY:" + *it + "," + 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())
+    {
+    context->HadContextSensitiveCondition = true;
+    }
+  return linkedTargetsContent;
+}
+
+//----------------------------------------------------------------------------
+struct TransitiveWhitelistCompare
+{
+  explicit TransitiveWhitelistCompare(const std::string &needle)
+    : Needle(needle) {}
+  bool operator() (const char *item)
+  { return strcmp(item, this->Needle.c_str()) == 0; }
+private:
+  std::string Needle;
+};
+
 //----------------------------------------------------------------------------
 static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 {
@@ -280,15 +387,22 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
           "$<TARGET_PROPERTY:...> expression requires one or two parameters");
       return std::string();
       }
-    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_.:-]+$");
     cmsys::RegularExpression propertyNameValidator;
     propertyNameValidator.compile("^[A-Za-z0-9_]+$");
 
-    cmGeneratorTarget* target = context->Target;
+    cmTarget* target = context->HeadTarget;
     std::string propertyName = *parameters.begin();
+
+    if (!target && parameters.size() == 1)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<TARGET_PROPERTY:prop> may only be used with targets.  It may not "
+          "be used with add_custom_command.  Specify the target to read a "
+          "property from using the $<TARGET_PROPERTY:tgt,prop> signature "
+          "instead.");
+      return std::string();
+      }
+
     if (parameters.size() == 2)
       {
       if (parameters.begin()->empty() && parameters[1].empty())
@@ -308,7 +422,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
       std::string targetName = parameters.front();
       propertyName = parameters[1];
-      if (!targetNameValidator.find(targetName.c_str()))
+      if (!cmGeneratorExpression::IsValidTargetName(targetName))
         {
         if (!propertyNameValidator.find(propertyName.c_str()))
           {
@@ -320,7 +434,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                       "Target name not supported.");
         return std::string();
         }
-      target = context->Makefile->FindGeneratorTargetToUse(
+      target = context->Makefile->FindTargetToUse(
                                                 targetName.c_str());
 
       if (!target)
@@ -332,6 +446,16 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
         reportError(context, content->GetOriginalExpression(), e.str());
         return std::string();
         }
+        context->AllTargets.insert(target);
+      }
+
+    if (target == context->HeadTarget)
+      {
+      // Keep track of the properties seen while processing.
+      // The evaluation of the LINK_LIBRARIES generator expressions
+      // will check this to ensure that properties have one consistent
+      // value for all evaluations.
+      context->SeenTargetProperties.insert(propertyName);
       }
 
     if (propertyName.empty())
@@ -349,24 +473,317 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       return std::string();
       }
 
+    assert(target);
+
     cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
                                                target->GetName(),
                                                propertyName,
                                                content,
                                                dagCheckerParent);
 
-    if (!dagChecker.check())
+    switch (dagChecker.check())
       {
+    case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
       dagChecker.reportError(context, content->GetOriginalExpression());
       return std::string();
+    case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+      // No error. We just skip cyclic references.
+      return std::string();
+    case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+      for (size_t i = 0;
+          i < (sizeof(targetPropertyTransitiveWhitelist) /
+                sizeof(*targetPropertyTransitiveWhitelist));
+          ++i)
+        {
+        if (targetPropertyTransitiveWhitelist[i] == propertyName)
+          {
+          // No error. We're not going to find anything new here.
+          return std::string();
+          }
+        }
+    case cmGeneratorExpressionDAGChecker::DAG:
+      break;
       }
 
     const char *prop = target->GetProperty(propertyName.c_str());
-    return prop ? prop : "";
+
+    if (dagCheckerParent)
+      {
+      if (dagCheckerParent->EvaluatingLinkLibraries())
+        {
+        if(!prop)
+          {
+          return std::string();
+          }
+        }
+      else
+        {
+        assert(dagCheckerParent->EvaluatingIncludeDirectories()
+            || dagCheckerParent->EvaluatingCompileDefinitions());
+        }
+      }
+
+    std::string linkedTargetsContent;
+
+    std::string interfacePropertyName;
+
+    if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES"
+        || propertyName == "INCLUDE_DIRECTORIES")
+      {
+      interfacePropertyName = "INTERFACE_INCLUDE_DIRECTORIES";
+      }
+    else if (propertyName == "INTERFACE_COMPILE_DEFINITIONS"
+        || propertyName == "COMPILE_DEFINITIONS"
+        || strncmp(propertyName.c_str(), "COMPILE_DEFINITIONS_", 20) == 0)
+      {
+      interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
+      }
+
+    cmTarget *headTarget = context->HeadTarget ? context->HeadTarget : target;
+
+    const char **transBegin = targetPropertyTransitiveWhitelist;
+    const char **transEnd = targetPropertyTransitiveWhitelist
+              + (sizeof(targetPropertyTransitiveWhitelist) /
+              sizeof(*targetPropertyTransitiveWhitelist));
+    if (std::find_if(transBegin, transEnd,
+              TransitiveWhitelistCompare(propertyName)) != transEnd)
+      {
+      const cmTarget::LinkInterface *iface = target->GetLinkInterface(
+                                                    context->Config,
+                                                    headTarget);
+      if(iface)
+        {
+        linkedTargetsContent =
+                  getLinkedTargetsContent(iface->Libraries, target,
+                                          headTarget,
+                                          context, &dagChecker,
+                                          interfacePropertyName);
+        }
+      }
+    else if (std::find_if(transBegin, transEnd,
+              TransitiveWhitelistCompare(interfacePropertyName)) != transEnd)
+      {
+      const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
+                                                    context->Config,
+                                                    headTarget);
+      if(impl)
+        {
+        linkedTargetsContent =
+                  getLinkedTargetsContent(impl->Libraries, target,
+                                          headTarget,
+                                          context, &dagChecker,
+                                          interfacePropertyName);
+        }
+      }
+
+    linkedTargetsContent =
+          cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
+
+    if (!prop)
+      {
+      if (target->IsImported())
+        {
+        return linkedTargetsContent;
+        }
+      if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
+                                                       context->Config))
+        {
+        context->HadContextSensitiveCondition = true;
+        return target->GetLinkInterfaceDependentBoolProperty(
+                                                propertyName,
+                                                context->Config) ? "1" : "0";
+        }
+      if (target->IsLinkInterfaceDependentStringProperty(propertyName,
+                                                         context->Config))
+        {
+        context->HadContextSensitiveCondition = true;
+        const char *propContent =
+                              target->GetLinkInterfaceDependentStringProperty(
+                                                propertyName,
+                                                context->Config);
+        return propContent ? propContent : "";
+        }
+
+      return linkedTargetsContent;
+      }
+
+    for (size_t i = 0;
+         i < (sizeof(targetPropertyTransitiveWhitelist) /
+              sizeof(*targetPropertyTransitiveWhitelist));
+         ++i)
+      {
+      if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName)
+        {
+        cmGeneratorExpression ge(context->Backtrace);
+        cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+        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;
+        }
+      }
+    return prop;
   }
 } targetPropertyNode;
 
 //----------------------------------------------------------------------------
+static const struct TargetNameNode : public cmGeneratorExpressionNode
+{
+  TargetNameNode() {}
+
+  virtual bool GeneratesContent() const { return true; }
+
+  virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+  virtual bool RequiresLiteralInput() const { return true; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    return parameters.front();
+  }
+
+  virtual int NumExpectedParameters() const { return 1; }
+
+} targetNameNode;
+
+//----------------------------------------------------------------------------
+static const char* targetPolicyWhitelist[] = {
+    "CMP0003"
+  , "CMP0004"
+  , "CMP0008"
+  , "CMP0020"
+};
+
+cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
+{
+#define RETURN_POLICY(POLICY) \
+  if (strcmp(policy, #POLICY) == 0) \
+  { \
+    return tgt->GetPolicyStatus ## POLICY (); \
+  } \
+
+  RETURN_POLICY(CMP0003)
+  RETURN_POLICY(CMP0004)
+  RETURN_POLICY(CMP0008)
+  RETURN_POLICY(CMP0020)
+
+#undef RETURN_POLICY
+
+  assert("!Unreachable code. Not a valid policy");
+  return cmPolicies::WARN;
+}
+
+cmPolicies::PolicyID policyForString(const char *policy_id)
+{
+#define RETURN_POLICY_ID(POLICY_ID) \
+  if (strcmp(policy_id, #POLICY_ID) == 0) \
+  { \
+    return cmPolicies:: POLICY_ID; \
+  } \
+
+  RETURN_POLICY_ID(CMP0003)
+  RETURN_POLICY_ID(CMP0004)
+  RETURN_POLICY_ID(CMP0008)
+  RETURN_POLICY_ID(CMP0020)
+
+#undef RETURN_POLICY_ID
+
+  assert("!Unreachable code. Not a valid policy");
+  return cmPolicies::CMP0002;
+}
+
+//----------------------------------------------------------------------------
+static const struct TargetPolicyNode : public cmGeneratorExpressionNode
+{
+  TargetPolicyNode() {}
+
+  virtual int NumExpectedParameters() const { return 1; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context ,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    if (!context->HeadTarget)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<TARGET_POLICY:prop> may only be used with targets.  It may not "
+          "be used with add_custom_command.");
+      return std::string();
+      }
+
+    context->HadContextSensitiveCondition = true;
+
+    for (size_t i = 0;
+         i < (sizeof(targetPolicyWhitelist) /
+              sizeof(*targetPolicyWhitelist));
+         ++i)
+      {
+      const char *policy = targetPolicyWhitelist[i];
+      if (parameters.front() == policy)
+        {
+        cmMakefile *mf = context->HeadTarget->GetMakefile();
+        switch(statusForTarget(context->HeadTarget, policy))
+          {
+          case cmPolicies::WARN:
+            mf->IssueMessage(cmake::AUTHOR_WARNING,
+                             mf->GetPolicies()->
+                             GetPolicyWarning(policyForString(policy)));
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::OLD:
+            return "0";
+          case cmPolicies::NEW:
+            return "1";
+          }
+        }
+      }
+    reportError(context, content->GetOriginalExpression(),
+      "$<TARGET_POLICY:prop> may only be used with a limited number of "
+      "policies.  Currently it may be used with policies CMP0003, CMP0004, "
+      "CMP0008 and CMP0020."
+      );
+    return std::string();
+  }
+
+} targetPolicyNode;
+
+//----------------------------------------------------------------------------
+static const struct InstallPrefixNode : public cmGeneratorExpressionNode
+{
+  InstallPrefixNode() {}
+
+  virtual bool GeneratesContent() const { return true; }
+  virtual int NumExpectedParameters() const { return 0; }
+
+  std::string Evaluate(const std::vector<std::string> &,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    reportError(context, content->GetOriginalExpression(),
+                "INSTALL_PREFIX is a marker for install(EXPORT) only.  It "
+                "should never be evaluated.");
+    return std::string();
+  }
+
+} installPrefixNode;
+
+//----------------------------------------------------------------------------
 template<bool linker, bool soname>
 struct TargetFilesystemArtifactResultCreator
 {
@@ -486,10 +903,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
     // Lookup the referenced target.
     std::string name = *parameters.begin();
 
-    cmsys::RegularExpression targetValidator;
-    // The ':' is supported to allow use with IMPORTED targets.
-    targetValidator.compile("^[A-Za-z0-9_.:-]+$");
-    if (!targetValidator.find(name.c_str()))
+    if (!cmGeneratorExpression::IsValidTargetName(name))
       {
       ::reportError(context, content->GetOriginalExpression(),
                     "Expression syntax not recognized.");
@@ -509,7 +923,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
                   "Target \"" + name + "\" is not an executable or library.");
       return std::string();
       }
-    context->Targets.insert(target);
+    context->DependTargets.insert(target);
+    context->AllTargets.insert(target);
 
     std::string result =
                 TargetFilesystemArtifactResultCreator<linker, soname>::Create(
@@ -551,13 +966,13 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
 {
   if (identifier == "0")
     return &zeroNode;
-  if (identifier == "1")
+  else if (identifier == "1")
     return &oneNode;
-  if (identifier == "AND")
+  else if (identifier == "AND")
     return &andNode;
-  if (identifier == "OR")
+  else if (identifier == "OR")
     return &orNode;
-  if (identifier == "NOT")
+  else if (identifier == "NOT")
     return &notNode;
   else if (identifier == "CONFIGURATION")
     return &configurationNode;
@@ -589,8 +1004,20 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &angle_rNode;
   else if (identifier == "COMMA")
     return &commaNode;
+  else if (identifier == "SEMICOLON")
+    return &semicolonNode;
   else if (identifier == "TARGET_PROPERTY")
     return &targetPropertyNode;
+  else if (identifier == "TARGET_NAME")
+    return &targetNameNode;
+  else if (identifier == "TARGET_POLICY")
+    return &targetPolicyNode;
+  else if (identifier == "BUILD_INTERFACE")
+    return &buildInterfaceNode;
+  else if (identifier == "INSTALL_INTERFACE")
+    return &installInterfaceNode;
+  else if (identifier == "INSTALL_PREFIX")
+    return &installPrefixNode;
   return 0;
 
 }
@@ -642,6 +1069,20 @@ std::string GeneratorExpressionContent::Evaluate(
 
   if (!node->GeneratesContent())
     {
+    if (node->AcceptsSingleArbitraryContentParameter())
+      {
+      if (this->ParamChildren.empty())
+        {
+        reportError(context, this->GetOriginalExpression(),
+                  "$<" + identifier + "> expression requires a parameter.");
+        }
+      }
+    else
+      {
+      std::vector<std::string> parameters;
+      this->EvaluateParameters(node, identifier, context, dagChecker,
+                               parameters);
+      }
     return std::string();
     }
 
@@ -666,6 +1107,15 @@ std::string GeneratorExpressionContent::Evaluate(
                                                                 = pit->end();
       for ( ; it != end; ++it)
         {
+        if (node->RequiresLiteralInput())
+          {
+          if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
+            {
+            reportError(context, this->GetOriginalExpression(),
+                  "$<" + identifier + "> expression requires literal input.");
+            return std::string();
+            }
+          }
         result += (*it)->Evaluate(context, dagChecker);
         if (context->HadError)
           {
@@ -673,10 +1123,33 @@ std::string GeneratorExpressionContent::Evaluate(
           }
         }
       }
+    if (node->RequiresLiteralInput())
+      {
+      std::vector<std::string> parameters;
+      parameters.push_back(result);
+      return node->Evaluate(parameters, context, this, dagChecker);
+      }
     return result;
     }
 
   std::vector<std::string> parameters;
+  this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
+  if (context->HadError)
+    {
+    return std::string();
+    }
+
+  return node->Evaluate(parameters, context, this, dagChecker);
+}
+
+//----------------------------------------------------------------------------
+std::string GeneratorExpressionContent::EvaluateParameters(
+                                const cmGeneratorExpressionNode *node,
+                                const std::string &identifier,
+                                cmGeneratorExpressionContext *context,
+                                cmGeneratorExpressionDAGChecker *dagChecker,
+                                std::vector<std::string> &parameters) const
+{
   {
   std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
                                         pit = this->ParamChildren.begin();
@@ -732,10 +1205,8 @@ std::string GeneratorExpressionContent::Evaluate(
     {
     reportError(context, this->GetOriginalExpression(), "$<" + identifier
                       + "> expression requires at least one parameter.");
-    return std::string();
     }
-
-  return node->Evaluate(parameters, context, this, dagChecker);
+  return std::string();
 }
 
 //----------------------------------------------------------------------------
index 04a2acd..ce7ad69 100644 (file)
 #include "cmListFileCache.h"
 
 class cmTarget;
-class cmGeneratorTarget;
 
 //----------------------------------------------------------------------------
 struct cmGeneratorExpressionContext
 {
   cmListFileBacktrace Backtrace;
-  std::set<cmTarget*> Targets;
+  std::set<cmTarget*> DependTargets;
+  std::set<cmTarget*> AllTargets;
+  std::set<cmStdString> SeenTargetProperties;
   cmMakefile *Makefile;
   const char *Config;
-  cmGeneratorTarget *Target;
+  cmTarget *HeadTarget; // The target whose property is being evaluated.
+  cmTarget *CurrentTarget; // The dependent of HeadTarget which appears
+                           // directly or indirectly in the property.
   bool Quiet;
   bool HadError;
+  bool HadContextSensitiveCondition;
 };
 
 struct cmGeneratorExpressionDAGChecker;
+struct cmGeneratorExpressionNode;
 
 //----------------------------------------------------------------------------
 struct cmGeneratorExpressionEvaluator
@@ -118,6 +123,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
   ~GeneratorExpressionContent();
 
 private:
+  std::string EvaluateParameters(const cmGeneratorExpressionNode *node,
+                                 const std::string &identifier,
+                                 cmGeneratorExpressionContext *context,
+                                 cmGeneratorExpressionDAGChecker *dagChecker,
+                                 std::vector<std::string> &parameters) const;
+
+private:
   std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
   std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren;
   const char *StartContent;
index 7a8fc51..a619cec 100644 (file)
@@ -88,7 +88,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
   while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression
       && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator)
     {
-    this->ParseContent(identifier);
+    if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
+      {
+      extendText(identifier, this->it);
+      ++this->it;
+      }
+    else
+      {
+      this->ParseContent(identifier);
+      }
     if (this->it == this->Tokens.end())
       {
       break;
index 19b55c6..335ba0f 100644 (file)
 #include "cmTarget.h"
 #include "cmMakefile.h"
 #include "cmLocalGenerator.h"
-#include "cmComputeLinkInformation.h"
 #include "cmGlobalGenerator.h"
 #include "cmSourceFile.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 
-#include <assert.h>
-
 //----------------------------------------------------------------------------
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
 {
@@ -32,15 +29,6 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
   this->LookupObjectLibraries();
 }
 
-cmGeneratorTarget::~cmGeneratorTarget()
-{
-  for(std::map<cmStdString, cmComputeLinkInformation*>::iterator i
-                  = LinkInformation.begin(); i != LinkInformation.end(); ++i)
-    {
-    delete i->second;
-    }
-}
-
 //----------------------------------------------------------------------------
 int cmGeneratorTarget::GetType() const
 {
@@ -221,32 +209,6 @@ void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
 }
 
 //----------------------------------------------------------------------------
-cmComputeLinkInformation*
-cmGeneratorTarget::GetLinkInformation(const char* config)
-{
-  // Lookup any existing information for this configuration.
-  std::map<cmStdString, cmComputeLinkInformation*>::iterator
-    i = this->LinkInformation.find(config?config:"");
-  if(i == this->LinkInformation.end())
-    {
-    // Compute information for this configuration.
-    cmComputeLinkInformation* info =
-      new cmComputeLinkInformation(this->Target, config);
-    if(!info || !info->Compute())
-      {
-      delete info;
-      info = 0;
-      }
-
-    // Store the information for this configuration.
-    std::map<cmStdString, cmComputeLinkInformation*>::value_type
-      entry(config?config:"", info);
-    i = this->LinkInformation.insert(entry).first;
-    }
-  return i->second;
-}
-
-//----------------------------------------------------------------------------
 void cmGeneratorTarget::GetAppleArchs(const char* config,
                              std::vector<std::string>& archVec)
 {
@@ -290,72 +252,5 @@ const char* cmGeneratorTarget::GetCreateRuleVariable()
 std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
                                                           const char *config)
 {
-  std::vector<std::string> includes;
-  const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES");
-  if(!prop)
-    {
-    return includes;
-    }
-
-  cmListFileBacktrace lfbt;
-  cmGeneratorExpression ge(lfbt);
-
-  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
-                                              this->GetName(),
-                                              "INCLUDE_DIRECTORIES", 0, 0);
-
-  cmSystemTools::ExpandListArgument(ge.Parse(prop)
-                                    .Evaluate(this->Makefile,
-                                              config,
-                                              false,
-                                              this,
-                                              &dagChecker),
-                                    includes);
-
-  std::set<std::string> uniqueIncludes;
-  std::vector<std::string> orderedAndUniqueIncludes;
-  for(std::vector<std::string>::const_iterator
-      li = includes.begin(); li != includes.end(); ++li)
-    {
-    std::string inc = *li;
-    if (!cmSystemTools::IsOff(inc.c_str()))
-      {
-      cmSystemTools::ConvertToUnixSlashes(inc);
-      }
-    if(uniqueIncludes.insert(inc).second)
-      {
-      orderedAndUniqueIncludes.push_back(inc);
-      }
-    }
-
-  return orderedAndUniqueIncludes;
-}
-
-//----------------------------------------------------------------------------
-std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
-{
-  std::string defPropName = "COMPILE_DEFINITIONS";
-  if (config)
-    {
-    defPropName += "_" + cmSystemTools::UpperCase(config);
-    }
-
-  const char *prop = this->Target->GetProperty(defPropName.c_str());
-
-  if (!prop)
-    {
-    return "";
-    }
-
-  cmListFileBacktrace lfbt;
-  cmGeneratorExpression ge(lfbt);
-
-  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
-                                             this->GetName(),
-                                             defPropName, 0, 0);
-  return ge.Parse(prop).Evaluate(this->Makefile,
-                                 config,
-                                 false,
-                                 this,
-                                 &dagChecker);
+  return this->Target->GetIncludeDirectories(config);
 }
index a29a9f9..cbcd8a5 100644 (file)
@@ -14,7 +14,6 @@
 
 #include "cmStandardIncludes.h"
 
-class cmComputeLinkInformation;
 class cmCustomCommand;
 class cmGlobalGenerator;
 class cmLocalGenerator;
@@ -26,7 +25,6 @@ class cmGeneratorTarget
 {
 public:
   cmGeneratorTarget(cmTarget*);
-  ~cmGeneratorTarget();
 
   int GetType() const;
   const char *GetName() const;
@@ -60,10 +58,6 @@ public:
 
   void UseObjectLibraries(std::vector<std::string>& objs);
 
-  std::map<cmStdString, cmComputeLinkInformation*> LinkInformation;
-
-  cmComputeLinkInformation* GetLinkInformation(const char* config);
-
   void GetAppleArchs(const char* config,
                      std::vector<std::string>& archVec);
 
@@ -74,8 +68,6 @@ public:
   /** Get the include directories for this target.  */
   std::vector<std::string> GetIncludeDirectories(const char *config);
 
-  std::string GetCompileDefinitions(const char *config = 0);
-
 private:
   void ClassifySources();
   void LookupObjectLibraries();
index c461016..f294daa 100644 (file)
@@ -62,15 +62,16 @@ public:
   virtual const char* GetFullDocumentation() const
     {
     return
-      "  get_filename_component(<VAR> FileName\n"
-      "                         PATH|ABSOLUTE|NAME|EXT|NAME_WE|REALPATH\n"
-      "                         [CACHE])\n"
-      "Set <VAR> to be the path (PATH), file name (NAME), file "
-      "extension (EXT), file name without extension (NAME_WE) of FileName, "
-      "the full path (ABSOLUTE), or the full path with all symlinks "
-      "resolved (REALPATH).  "
-      "Note that the path is converted to Unix slashes format and has no "
-      "trailing slashes. The longest file extension is always considered. "
+      "  get_filename_component(<VAR> <FileName> <COMP> [CACHE])\n"
+      "Set <VAR> to a component of <FileName>, where <COMP> is one of:\n"
+      " PATH      = Directory without file name\n"
+      " NAME      = File name without directory\n"
+      " EXT       = File name longest extension (.b.c from d/a.b.c)\n"
+      " NAME_WE   = File name without directory or longest extension\n"
+      " ABSOLUTE  = Full path to file\n"
+      " REALPATH  = Full path to existing file with symlinks resolved\n"
+      "Paths are returned with forward slashes and have no trailing slahes. "
+      "The longest file extension is always considered. "
       "If the optional CACHE argument is specified, the result variable is "
       "added to the cache.\n"
       "  get_filename_component(<VAR> FileName\n"
index 8c6787a..2a7d61d 100644 (file)
@@ -55,9 +55,9 @@ cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalBorlandMakefileGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalBorlandMakefileGenerator::GetActualName();
   entry.Brief = "Generates Borland makefiles.";
   entry.Full = "";
 }
index c0cb8a6..bd3db3e 100644 (file)
@@ -23,8 +23,9 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalNMakeMakefileGenerator
 {
 public:
   cmGlobalBorlandMakefileGenerator();
-  static cmGlobalGenerator* New()
-    { return new cmGlobalBorlandMakefileGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalBorlandMakefileGenerator>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -32,7 +33,7 @@ public:
   static const char* GetActualName() {return "Borland Makefiles";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index 6c95ea8..df14331 100644 (file)
@@ -79,6 +79,20 @@ cmGlobalGenerator::~cmGlobalGenerator()
   this->ClearGeneratorTargets();
 }
 
+bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts)
+{
+  cmOStringStream e;
+  e <<
+    "Generator\n"
+    "  " << this->GetName() << "\n"
+    "does not support toolset specification, but toolset\n"
+    "  " << ts << "\n"
+    "was specified.";
+  this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+                                    cmListFileBacktrace());
+  return false;
+}
+
 void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
                                                 cmMakefile *mf,
                                                 bool optional)
@@ -938,6 +952,11 @@ void cmGlobalGenerator::Generate()
       (*targets)[tit->first] = tit->second;
       (*targets)[tit->first].SetMakefile(mf);
       }
+
+    for ( tit = targets->begin(); tit != targets->end(); ++ tit )
+      {
+        tit->second.AppendBuildInterfaceIncludes();
+      }
     }
 
   // Add generator specific helper commands
@@ -975,6 +994,7 @@ void cmGlobalGenerator::Generate()
   // Generate project files
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
+    this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
     this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
     this->LocalGenerators[i]->Generate();
     this->LocalGenerators[i]->GenerateInstallRules();
@@ -1047,6 +1067,8 @@ bool cmGlobalGenerator::CheckTargets()
 void cmGlobalGenerator::CreateAutomocTargets()
 {
 #ifdef CMAKE_BUILD_WITH_CMAKE
+  typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs;
+  Automocs automocs;
   for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
     {
     cmTargets& targets =
@@ -1058,16 +1080,25 @@ void cmGlobalGenerator::CreateAutomocTargets()
       if(target.GetType() == cmTarget::EXECUTABLE ||
          target.GetType() == cmTarget::STATIC_LIBRARY ||
          target.GetType() == cmTarget::SHARED_LIBRARY ||
-         target.GetType() == cmTarget::MODULE_LIBRARY)
+         target.GetType() == cmTarget::MODULE_LIBRARY ||
+         target.GetType() == cmTarget::OBJECT_LIBRARY)
         {
         if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
           {
           cmQtAutomoc automoc;
-          automoc.SetupAutomocTarget(&target);
+          if(automoc.InitializeMocSourceFile(&target))
+            {
+            automocs.push_back(std::make_pair(automoc, &target));
+            }
           }
         }
       }
     }
+  for (Automocs::iterator it = automocs.begin(); it != automocs.end();
+       ++it)
+    {
+    it->first.SetupAutomocTarget(it->second);
+    }
 #endif
 }
 
@@ -1556,14 +1587,6 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
     }
 }
 
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "";
-  entry.Full = "";
-}
-
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
                                    cmLocalGenerator* gen)
 {
@@ -2055,12 +2078,44 @@ bool cmGlobalGenerator::UseFolderProperty()
     }
 
   // By default, this feature is OFF, since it is not supported in the
-  // Visual Studio Express editions:
+  // Visual Studio Express editions until VS11:
   //
   return false;
 }
 
 //----------------------------------------------------------------------------
+void cmGlobalGenerator::EnableMinGWLanguage(cmMakefile *mf)
+{
+  this->FindMakeProgram(mf);
+  std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+  std::vector<std::string> locations;
+  locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str()));
+  locations.push_back("/mingw/bin");
+  locations.push_back("c:/mingw/bin");
+  std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
+  std::string gcc = "gcc.exe";
+  if(tgcc.size())
+    {
+    gcc = tgcc;
+    }
+  std::string tgxx = cmSystemTools::FindProgram("g++", locations);
+  std::string gxx = "g++.exe";
+  if(tgxx.size())
+    {
+    gxx = tgxx;
+    }
+  std::string trc = cmSystemTools::FindProgram("windres", locations);
+  std::string rc = "windres.exe";
+  if(trc.size())
+    {
+    rc = trc;
+    }
+  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
+  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
+  mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+}
+
+//----------------------------------------------------------------------------
 cmTarget cmGlobalGenerator::CreateGlobalTarget(
   const char* name, const char* message,
   const cmCustomCommandLines* commandLines,
index 0aab2d6..11616e0 100644 (file)
@@ -49,8 +49,9 @@ public:
   ///! Get the name for this generator
   virtual const char *GetName() const { return "Generic"; };
 
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  /** Set the generator-specific toolset name.  Returns true if toolset
+      is supported and false otherwise.  */
+  virtual bool SetGeneratorToolset(std::string const& ts);
 
   /**
    * Create LocalGenerators and process the CMakeLists files. This does not
@@ -339,6 +340,7 @@ protected:
 
   virtual const char* GetPredefinedTargetsFolder();
   virtual bool UseFolderProperty();
+  void EnableMinGWLanguage(cmMakefile *mf);
 
 private:
   cmMakefile* TryCompileOuterMakefile;
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
new file mode 100644 (file)
index 0000000..fd1d65f
--- /dev/null
@@ -0,0 +1,59 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmGlobalGeneratorFactory_h
+#define cmGlobalGeneratorFactory_h
+
+#include "cmStandardIncludes.h"
+
+class cmGlobalGenerator;
+struct cmDocumentationEntry;
+
+/** \class cmGlobalGeneratorFactory
+ * \brief Responable for creating cmGlobalGenerator instances
+ *
+ * Subclasses of this class generate instances of cmGlobalGenerator.
+ */
+class cmGlobalGeneratorFactory
+{
+public:
+  virtual ~cmGlobalGeneratorFactory() {}
+
+  /** Create a GlobalGenerator */
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* n) const = 0;
+
+  /** Get the documentation entry for this factory */
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
+
+  /** Get the names of the current registered generators */
+  virtual void GetGenerators(std::vector<std::string>& names) const = 0;
+};
+
+template<class T>
+class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory
+{
+public:
+  /** Create a GlobalGenerator */
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if (strcmp(name, T::GetActualName())) return 0;
+    return new T; }
+
+  /** Get the documentation entry for this factory */
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    T::GetDocumentation(entry); }
+
+  /** Get the names of the current registered generators */
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(T::GetActualName()); }
+};
+
+#endif
index ef42bd4..4af0607 100644 (file)
@@ -61,9 +61,9 @@ cmLocalGenerator *cmGlobalJOMMakefileGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalJOMMakefileGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalJOMMakefileGenerator::GetActualName();
   entry.Brief = "Generates JOM makefiles.";
   entry.Full = "";
 }
index 691ebdb..28893bf 100644 (file)
@@ -23,8 +23,9 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
 {
 public:
   cmGlobalJOMMakefileGenerator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalJOMMakefileGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalJOMMakefileGenerator>(); }
   ///! Get the name for the generator.
   virtual const char* GetName() const {
     return cmGlobalJOMMakefileGenerator::GetActualName();}
@@ -33,7 +34,7 @@ public:
   static const char* GetActualName() {return "NMake Makefiles JOM";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index 80526aa..d49639b 100644 (file)
@@ -106,9 +106,9 @@ cmLocalGenerator *cmGlobalMSYSMakefileGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalMSYSMakefileGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalMSYSMakefileGenerator::GetActualName();
   entry.Brief = "Generates MSYS makefiles.";
   entry.Full = "The makefiles use /bin/sh as the shell.  "
     "They require msys to be installed on the machine.";
index b76a5bf..659de11 100644 (file)
@@ -23,8 +23,9 @@ class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3
 {
 public:
   cmGlobalMSYSMakefileGenerator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalMSYSMakefileGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalMSYSMakefileGenerator>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -32,7 +33,7 @@ public:
   static const char* GetActualName() {return "MSYS Makefiles";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index d6045c8..1f374d3 100644 (file)
@@ -26,33 +26,7 @@ void cmGlobalMinGWMakefileGenerator
                  cmMakefile *mf,
                  bool optional)
 {
-  this->FindMakeProgram(mf);
-  std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
-  std::vector<std::string> locations;
-  locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str()));
-  locations.push_back("/mingw/bin");
-  locations.push_back("c:/mingw/bin");
-  std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
-  std::string gcc = "gcc.exe";
-  if(tgcc.size())
-    {
-    gcc = tgcc;
-    }
-  std::string tgxx = cmSystemTools::FindProgram("g++", locations);
-  std::string gxx = "g++.exe";
-  if(tgxx.size())
-    {
-    gxx = tgxx;
-    }
-  std::string trc = cmSystemTools::FindProgram("windres", locations);
-  std::string rc = "windres.exe";
-  if(trc.size())
-    {
-    rc = trc;
-    }
-  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+  this->EnableMinGWLanguage(mf);
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 }
 
@@ -71,9 +45,9 @@ cmLocalGenerator *cmGlobalMinGWMakefileGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalMinGWMakefileGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalMinGWMakefileGenerator::GetActualName();
   entry.Brief = "Generates a make file for use with mingw32-make.";
   entry.Full = "The makefiles generated use cmd.exe as the shell.  "
     "They do not require msys or a unix shell.";
index 9a6a513..7951e98 100644 (file)
@@ -23,15 +23,16 @@ class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3
 {
 public:
   cmGlobalMinGWMakefileGenerator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalMinGWMakefileGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalMinGWMakefileGenerator>(); }
   ///! Get the name for the generator.
   virtual const char* GetName() const {
     return cmGlobalMinGWMakefileGenerator::GetActualName();}
   static const char* GetActualName() {return "MinGW Makefiles";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index 57a26c8..7af4ee3 100644 (file)
@@ -61,9 +61,9 @@ cmLocalGenerator *cmGlobalNMakeMakefileGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalNMakeMakefileGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalNMakeMakefileGenerator::GetActualName();
   entry.Brief = "Generates NMake makefiles.";
   entry.Full = "";
 }
index de33b8f..5756fbd 100644 (file)
@@ -23,15 +23,16 @@ class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3
 {
 public:
   cmGlobalNMakeMakefileGenerator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalNMakeMakefileGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalNMakeMakefileGenerator>(); }
   ///! Get the name for the generator.
   virtual const char* GetName() const {
     return cmGlobalNMakeMakefileGenerator::GetActualName();}
   static const char* GetActualName() {return "NMake Makefiles";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index 05f5b4c..fa277b1 100644 (file)
@@ -17,6 +17,8 @@
 #include "cmGeneratorTarget.h"
 #include "cmVersion.h"
 
+#include <algorithm>
+
 const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
 const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
 const char* cmGlobalNinjaGenerator::INDENT = "  ";
@@ -83,6 +85,7 @@ std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string &lit)
 {
   std::string result = lit;
   cmSystemTools::ReplaceString(result, "$", "$$");
+  cmSystemTools::ReplaceString(result, "\n", "$\n");
   return result;
 }
 
@@ -452,9 +455,9 @@ cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator()
 }
 
 void cmGlobalNinjaGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalNinjaGenerator::GetActualName();
   entry.Brief = "Generates build.ninja files (experimental).";
   entry.Full =
     "A build.ninja file is generated into the build tree. Recent "
@@ -491,69 +494,20 @@ void cmGlobalNinjaGenerator::Generate()
 // Used in:
 //   Source/cmMakefile.cxx:
 void cmGlobalNinjaGenerator
-::EnableLanguage(std::vector<std::string>const& languages,
-                 cmMakefile *mf,
+::EnableLanguage(std::vector<std::string>const& langs,
+                 cmMakefile* makefile,
                  bool optional)
 {
-  std::string path;
-  for(std::vector<std::string>::const_iterator l = languages.begin();
-      l != languages.end(); ++l)
+  if (makefile->IsOn("CMAKE_COMPILER_IS_MINGW"))
     {
-    std::vector<std::string> language;
-    language.push_back(*l);
-
-    if(*l == "NONE")
-      {
-      this->cmGlobalGenerator::EnableLanguage(language, mf, optional);
-      continue;
-      }
-    else if(*l == "Fortran")
-      {
-      std::string message = "The \"";
-      message += this->GetName();
-      message += "\" generator does not support the language \"";
-      message += *l;
-      message += "\" yet.";
-      cmSystemTools::Error(message.c_str());
-      }
-    else if(*l == "RC")
-      {
-      // check if mingw is used
-      if(mf->IsOn("CMAKE_COMPILER_IS_MINGW"))
-        {
-        UsingMinGW = true;
-        if(!mf->GetDefinition("CMAKE_RC_COMPILER"))
-          {
-          std::string windres = cmSystemTools::FindProgram("windres");
-          if(windres.empty())
-            {
-            std::string compiler_path;
-            std::string::size_type prefix = std::string::npos;
-            if (mf->GetDefinition("CMAKE_C_COMPILER"))
-              {
-              compiler_path = mf->GetDefinition("CMAKE_C_COMPILER");
-              prefix = compiler_path.rfind("gcc");
-              }
-            else if (mf->GetDefinition("CMAKE_CXX_COMPILER"))
-              {
-              compiler_path = mf->GetDefinition("CMAKE_CXX_COMPILER");
-              prefix = compiler_path.rfind("++");
-              prefix--;
-              }
-            if (prefix != std::string::npos)
-              {
-              windres = compiler_path.substr(0, prefix) + "windres";
-              windres = cmSystemTools::FindProgram(windres.c_str());
-              }
-            }
-          if(!windres.empty())
-            mf->AddDefinition("CMAKE_RC_COMPILER", windres.c_str());
-          }
-        }
-      }
-    this->cmGlobalGenerator::EnableLanguage(language, mf, optional);
-    this->ResolveLanguageCompiler(*l, mf, optional);
+    UsingMinGW = true;
+    this->EnableMinGWLanguage(makefile);
+    }
+  if (std::find(langs.begin(), langs.end(), "Fortran") != langs.end())
+    {
+    cmSystemTools::Error("The Ninja generator does not support Fortran yet.");
     }
+  this->cmGlobalGenerator::EnableLanguage(langs, makefile, optional);
 }
 
 bool cmGlobalNinjaGenerator::UsingMinGW = false;
index 24c3916..c3df7d9 100644 (file)
@@ -14,6 +14,7 @@
 #  define cmGlobalNinjaGenerator_h
 
 #  include "cmGlobalGenerator.h"
+#  include "cmGlobalGeneratorFactory.h"
 #  include "cmNinjaTypes.h"
 
 //#define NINJA_GEN_VERBOSE_FILES
@@ -160,8 +161,8 @@ public:
   cmGlobalNinjaGenerator();
 
   /// Convenience method for creating an instance of this class.
-  static cmGlobalGenerator* New() {
-    return new cmGlobalNinjaGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); }
 
   /// Destructor.
   virtual ~cmGlobalNinjaGenerator() { }
@@ -177,7 +178,7 @@ public:
   static const char* GetActualName() { return "Ninja"; }
 
   /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   /// Overloaded methods. @see cmGlobalGenerator::Generate()
   virtual void Generate();
index ebd8219..e26cca9 100644 (file)
@@ -61,9 +61,9 @@ cmLocalGenerator *cmGlobalUnixMakefileGenerator3::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalUnixMakefileGenerator3
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalUnixMakefileGenerator3::GetActualName();
   entry.Brief = "Generates standard UNIX makefiles.";
   entry.Full =
     "A hierarchy of UNIX makefiles is generated into the build tree.  Any "
index e6dd09d..385cdc4 100644 (file)
@@ -13,6 +13,7 @@
 #define cmGlobalUnixMakefileGenerator3_h
 
 #include "cmGlobalGenerator.h"
+#include "cmGlobalGeneratorFactory.h"
 
 class cmGeneratedFileStream;
 class cmMakefileTargetGenerator;
@@ -54,8 +55,9 @@ class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator
 {
 public:
   cmGlobalUnixMakefileGenerator3();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalUnixMakefileGenerator3; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalUnixMakefileGenerator3>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -63,7 +65,7 @@ public:
   static const char* GetActualName() {return "Unix Makefiles";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator3
   virtual cmLocalGenerator *CreateLocalGenerator();
index 480c577..ee7c56f 100644 (file)
 #include "cmSourceFile.h"
 #include "cmake.h"
 
+static const char vs10Win32generatorName[] = "Visual Studio 10";
+static const char vs10Win64generatorName[] = "Visual Studio 10 Win64";
+static const char vs10IA64generatorName[] = "Visual Studio 10 IA64";
 
-cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator()
+class cmGlobalVisualStudio10Generator::Factory
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if(!strcmp(name, vs10Win32generatorName))
+      {
+      return new cmGlobalVisualStudio10Generator(
+        vs10Win32generatorName, NULL, NULL);
+      }
+    if(!strcmp(name, vs10Win64generatorName))
+      {
+      return new cmGlobalVisualStudio10Generator(
+        vs10Win64generatorName, "x64", "CMAKE_FORCE_WIN64");
+      }
+    if(!strcmp(name, vs10IA64generatorName))
+      {
+      return new cmGlobalVisualStudio10Generator(
+        vs10IA64generatorName, "Itanium", "CMAKE_FORCE_IA64");
+      }
+    return 0;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    entry.Name = "Visual Studio 10";
+    entry.Brief = "Generates Visual Studio 10 (2010) project files.";
+    entry.Full =
+      "It is possible to append a space followed by the platform name "
+      "to create project files for a specific target platform. E.g. "
+      "\"Visual Studio 10 Win64\" will create project files for "
+      "the x64 processor; \"Visual Studio 10 IA64\" for Itanium.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(vs10Win32generatorName);
+    names.push_back(vs10Win64generatorName);
+    names.push_back(vs10IA64generatorName); }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
+{
+  return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
+  const char* name, const char* architectureId,
+  const char* additionalPlatformDefinition)
+  : cmGlobalVisualStudio8Generator(name, architectureId,
+                                   additionalPlatformDefinition)
 {
   this->FindMakeProgramFile = "CMakeVS10FindMake.cmake";
   std::string vc10Express;
@@ -27,6 +80,14 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator()
 }
 
 //----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts)
+{
+  this->PlatformToolset = ts;
+  return true;
+}
+
+//----------------------------------------------------------------------------
 void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
 {
   cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
@@ -41,7 +102,14 @@ void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
 void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
 {
   fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n";
-  fout << "# Visual Studio 2010\n";
+  if (this->ExpressEdition)
+    {
+    fout << "# Visual C++ Express 2010\n";
+    }
+  else
+    {
+    fout << "# Visual Studio 2010\n";
+    }
 }
 
 ///! Create a local generator appropriate to this Global Generator
@@ -88,18 +156,16 @@ void cmGlobalVisualStudio10Generator::Generate()
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio10Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 10 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator
 ::EnableLanguage(std::vector<std::string>const &  lang,
                  cmMakefile *mf, bool optional)
 {
+  if(this->ArchitectureId == "Itanium" || this->ArchitectureId == "x64")
+    {
+    if(this->IsExpressEdition() && !this->Find64BitTools(mf))
+      {
+      return;
+      }
+    }
   cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
 }
 
index 47ce790..5926e0f 100644 (file)
@@ -24,9 +24,11 @@ class cmGlobalVisualStudio10Generator :
   public cmGlobalVisualStudio8Generator
 {
 public:
-  cmGlobalVisualStudio10Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio10Generator; }
+  cmGlobalVisualStudio10Generator(const char* name,
+    const char* architectureId, const char* additionalPlatformDefinition);
+  static cmGlobalGeneratorFactory* NewFactory();
+
+  virtual bool SetGeneratorToolset(std::string const& ts);
 
   virtual std::string
   GenerateBuildCommand(const char* makeProgram,
@@ -34,15 +36,8 @@ public:
                        const char* additionalOptions, const char *targetName,
                        const char* config, bool ignoreErrors, bool);
 
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio10Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 10";}
   virtual void AddPlatformDefinitions(cmMakefile* mf);
 
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
   ///! create the correct local generator
   virtual cmLocalGenerator *CreateLocalGenerator();
 
@@ -92,6 +87,7 @@ protected:
   bool UseFolderProperty();
 
 private:
+  class Factory;
   struct LongestSourcePath
   {
     LongestSourcePath(): Length(0), Target(0), SourceFile(0) {}
diff --git a/Source/cmGlobalVisualStudio10IA64Generator.cxx b/Source/cmGlobalVisualStudio10IA64Generator.cxx
deleted file mode 100644 (file)
index 25dd88f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*============================================================================
-  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 "cmGlobalVisualStudio10IA64Generator.h"
-#include "cmMakefile.h"
-#include "cmake.h"
-
-//----------------------------------------------------------------------------
-cmGlobalVisualStudio10IA64Generator::cmGlobalVisualStudio10IA64Generator()
-{
-  this->ArchitectureId = "x64";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10IA64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 10 Itanium project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10IA64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10IA64Generator
-::EnableLanguage(std::vector<std::string> const& languages,
-                 cmMakefile* mf, bool optional)
-{
-  if(this->IsExpressEdition() && !this->Find64BitTools(mf))
-    {
-    return;
-    }
-  this->cmGlobalVisualStudio10Generator
-    ::EnableLanguage(languages, mf, optional);
-}
diff --git a/Source/cmGlobalVisualStudio10IA64Generator.h b/Source/cmGlobalVisualStudio10IA64Generator.h
deleted file mode 100644 (file)
index a088272..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*============================================================================
-  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 cmGlobalVisualStudio10IA64Generator_h
-#define cmGlobalVisualStudio10IA64Generator_h
-
-#include "cmGlobalVisualStudio10Generator.h"
-
-class cmGlobalVisualStudio10IA64Generator :
-  public cmGlobalVisualStudio10Generator
-{
-public:
-  cmGlobalVisualStudio10IA64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio10IA64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio10IA64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 10 IA64";}
-
-  virtual const char* GetPlatformName() const {return "Itanium";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  virtual void AddPlatformDefinitions(cmMakefile* mf);
-
-  virtual void EnableLanguage(std::vector<std::string>const& languages,
-                              cmMakefile *, bool optional);
-};
-#endif
diff --git a/Source/cmGlobalVisualStudio10Win64Generator.cxx b/Source/cmGlobalVisualStudio10Win64Generator.cxx
deleted file mode 100644 (file)
index d0a0c49..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*============================================================================
-  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 "cmGlobalVisualStudio10Win64Generator.h"
-#include "cmMakefile.h"
-#include "cmake.h"
-
-//----------------------------------------------------------------------------
-cmGlobalVisualStudio10Win64Generator::cmGlobalVisualStudio10Win64Generator()
-{
-  this->ArchitectureId = "x64";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Win64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 10 Win64 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Win64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Win64Generator
-::EnableLanguage(std::vector<std::string> const& languages,
-                 cmMakefile* mf, bool optional)
-{
-  if(this->IsExpressEdition() && !this->Find64BitTools(mf))
-    {
-    return;
-    }
-  this->cmGlobalVisualStudio10Generator
-    ::EnableLanguage(languages, mf, optional);
-}
diff --git a/Source/cmGlobalVisualStudio10Win64Generator.h b/Source/cmGlobalVisualStudio10Win64Generator.h
deleted file mode 100644 (file)
index 8a2de4c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*============================================================================
-  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 cmGlobalVisualStudio10Win64Generator_h
-#define cmGlobalVisualStudio10Win64Generator_h
-
-#include "cmGlobalVisualStudio10Generator.h"
-
-class cmGlobalVisualStudio10Win64Generator :
-  public cmGlobalVisualStudio10Generator
-{
-public:
-  cmGlobalVisualStudio10Win64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio10Win64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio10Win64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 10 Win64";}
-
-  virtual const char* GetPlatformName() const {return "x64";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  virtual void AddPlatformDefinitions(cmMakefile* mf);
-
-  virtual void EnableLanguage(std::vector<std::string>const& languages,
-                              cmMakefile *, bool optional);
-};
-#endif
diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.cxx b/Source/cmGlobalVisualStudio11ARMGenerator.cxx
deleted file mode 100644 (file)
index efd71c6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2011 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 "cmGlobalVisualStudio11ARMGenerator.h"
-#include "cmMakefile.h"
-#include "cmake.h"
-
-//----------------------------------------------------------------------------
-cmGlobalVisualStudio11ARMGenerator::cmGlobalVisualStudio11ARMGenerator()
-{
-  this->ArchitectureId = "ARM";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio11ARMGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 11 ARM project files.";
-  entry.Full = "";
-}
diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.h b/Source/cmGlobalVisualStudio11ARMGenerator.h
deleted file mode 100644 (file)
index 71dbf2e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2011 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 cmGlobalVisualStudio11ARMGenerator_h
-#define cmGlobalVisualStudio11ARMGenerator_h
-
-#include "cmGlobalVisualStudio11Generator.h"
-
-class cmGlobalVisualStudio11ARMGenerator :
-  public cmGlobalVisualStudio11Generator
-{
-public:
-  cmGlobalVisualStudio11ARMGenerator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio11ARMGenerator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio11ARMGenerator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 11 ARM";}
-
-  virtual const char* GetPlatformName() const {return "ARM";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-};
-#endif
index 23a1204..624d01d 100644 (file)
 #include "cmLocalVisualStudio10Generator.h"
 #include "cmMakefile.h"
 
+static const char vs11Win32generatorName[] = "Visual Studio 11";
+static const char vs11Win64generatorName[] = "Visual Studio 11 Win64";
+static const char vs11ARMgeneratorName[] = "Visual Studio 11 ARM";
+
+class cmGlobalVisualStudio11Generator::Factory
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if(!strcmp(name, vs11Win32generatorName))
+      {
+      return new cmGlobalVisualStudio11Generator(
+        vs11Win32generatorName, NULL, NULL);
+      }
+    if(!strcmp(name, vs11Win64generatorName))
+      {
+      return new cmGlobalVisualStudio11Generator(
+        vs11Win64generatorName, "x64", "CMAKE_FORCE_WIN64");
+      }
+    if(!strcmp(name, vs11ARMgeneratorName))
+      {
+      return new cmGlobalVisualStudio11Generator(
+        vs11ARMgeneratorName, "ARM", NULL);
+      }
+    return 0;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    entry.Name = "Visual Studio 11";
+    entry.Brief = "Generates Visual Studio 11 (2012) project files.";
+    entry.Full =
+      "It is possible to append a space followed by the platform name "
+      "to create project files for a specific target platform. E.g. "
+      "\"Visual Studio 11 Win64\" will create project files for "
+      "the x64 processor; \"Visual Studio 11 ARM\" for ARM.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(vs11Win32generatorName);
+    names.push_back(vs11Win64generatorName);
+    names.push_back(vs11ARMgeneratorName); }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
+{
+  return new Factory;
+}
+
 //----------------------------------------------------------------------------
-cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator()
+cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
+  const char* name, const char* architectureId,
+  const char* additionalPlatformDefinition)
+  : cmGlobalVisualStudio10Generator(name, architectureId,
+                                   additionalPlatformDefinition)
 {
   this->FindMakeProgramFile = "CMakeVS11FindMake.cmake";
   std::string vc11Express;
@@ -28,7 +81,14 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator()
 void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
 {
   fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
-  fout << "# Visual Studio 11\n";
+  if (this->ExpressEdition)
+    {
+    fout << "# Visual Studio Express 2012 for Windows Desktop\n";
+    }
+  else
+    {
+    fout << "# Visual Studio 2012\n";
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -42,10 +102,10 @@ cmLocalGenerator *cmGlobalVisualStudio11Generator::CreateLocalGenerator()
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalVisualStudio11Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
+bool cmGlobalVisualStudio11Generator::UseFolderProperty()
 {
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 11 project files.";
-  entry.Full = "";
+  // Intentionally skip over the parent class implementation and call the
+  // grand-parent class's implementation. Folders are not supported by the
+  // Express editions in VS10 and earlier, but they are in VS11 Express.
+  return cmGlobalVisualStudio8Generator::UseFolderProperty();
 }
index 56337a4..174f1cc 100644 (file)
@@ -20,20 +20,12 @@ class cmGlobalVisualStudio11Generator:
   public cmGlobalVisualStudio10Generator
 {
 public:
-  cmGlobalVisualStudio11Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio11Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio11Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 11";}
+  cmGlobalVisualStudio11Generator(const char* name,
+    const char* architectureId, const char* additionalPlatformDefinition);
+  static cmGlobalGeneratorFactory* NewFactory();
 
   virtual void WriteSLNHeader(std::ostream& fout);
 
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
   ///! create the correct local generator
   virtual cmLocalGenerator *CreateLocalGenerator();
 
@@ -41,5 +33,8 @@ public:
   virtual std::string GetUserMacrosDirectory() { return ""; }
 protected:
   virtual const char* GetIDEVersion() { return "11.0"; }
+  bool UseFolderProperty();
+private:
+  class Factory;
 };
 #endif
diff --git a/Source/cmGlobalVisualStudio11Win64Generator.cxx b/Source/cmGlobalVisualStudio11Win64Generator.cxx
deleted file mode 100644 (file)
index 94e07bf..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2011 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 "cmGlobalVisualStudio11Win64Generator.h"
-#include "cmMakefile.h"
-#include "cmake.h"
-
-//----------------------------------------------------------------------------
-cmGlobalVisualStudio11Win64Generator::cmGlobalVisualStudio11Win64Generator()
-{
-  this->ArchitectureId = "x64";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio11Win64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 11 Win64 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio11Win64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  this->cmGlobalVisualStudio11Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
-}
diff --git a/Source/cmGlobalVisualStudio11Win64Generator.h b/Source/cmGlobalVisualStudio11Win64Generator.h
deleted file mode 100644 (file)
index 9445d15..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*============================================================================
-  CMake - Cross Platform Makefile Generator
-  Copyright 2000-2011 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 cmGlobalVisualStudio11Win64Generator_h
-#define cmGlobalVisualStudio11Win64Generator_h
-
-#include "cmGlobalVisualStudio11Generator.h"
-
-class cmGlobalVisualStudio11Win64Generator :
-  public cmGlobalVisualStudio11Generator
-{
-public:
-  cmGlobalVisualStudio11Win64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio11Win64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio11Win64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 11 Win64";}
-
-  virtual const char* GetPlatformName() const {return "x64";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  virtual void AddPlatformDefinitions(cmMakefile* mf);
-};
-#endif
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
new file mode 100644 (file)
index 0000000..d77b84d
--- /dev/null
@@ -0,0 +1,111 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2011 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 "cmGlobalVisualStudio12Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
+#include "cmMakefile.h"
+
+static const char vs12Win32generatorName[] = "Visual Studio 12";
+static const char vs12Win64generatorName[] = "Visual Studio 12 Win64";
+static const char vs12ARMgeneratorName[] = "Visual Studio 12 ARM";
+
+class cmGlobalVisualStudio12Generator::Factory
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if(!strcmp(name, vs12Win32generatorName))
+      {
+      return new cmGlobalVisualStudio12Generator(
+        vs12Win32generatorName, NULL, NULL);
+      }
+    if(!strcmp(name, vs12Win64generatorName))
+      {
+      return new cmGlobalVisualStudio12Generator(
+        vs12Win64generatorName, "x64", "CMAKE_FORCE_WIN64");
+      }
+    if(!strcmp(name, vs12ARMgeneratorName))
+      {
+      return new cmGlobalVisualStudio12Generator(
+        vs12ARMgeneratorName, "ARM", NULL);
+      }
+    return 0;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    entry.Name = "Visual Studio 12";
+    entry.Brief = "Generates Visual Studio 12 (2013) project files.";
+    entry.Full =
+      "It is possible to append a space followed by the platform name "
+      "to create project files for a specific target platform. E.g. "
+      "\"Visual Studio 12 Win64\" will create project files for "
+      "the x64 processor; \"Visual Studio 12 ARM\" for ARM.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(vs12Win32generatorName);
+    names.push_back(vs12Win64generatorName);
+    names.push_back(vs12ARMgeneratorName); }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
+{
+  return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
+  const char* name, const char* architectureId,
+  const char* additionalPlatformDefinition)
+  : cmGlobalVisualStudio11Generator(name, architectureId,
+                                   additionalPlatformDefinition)
+{
+  this->FindMakeProgramFile = "CMakeVS12FindMake.cmake";
+  std::string vc12Express;
+  this->ExpressEdition = cmSystemTools::ReadRegistryValue(
+    "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\12.0\\Setup\\VC;"
+    "ProductDir", vc12Express, cmSystemTools::KeyWOW64_32);
+  this->PlatformToolset = "v120";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout)
+{
+  fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+  if (this->ExpressEdition)
+    {
+    fout << "# Visual Studio Express 2013 for Windows Desktop\n";
+    }
+  else
+    {
+    fout << "# Visual Studio 2013\n";
+    }
+}
+
+//----------------------------------------------------------------------------
+cmLocalGenerator *cmGlobalVisualStudio12Generator::CreateLocalGenerator()
+{
+  cmLocalVisualStudio10Generator* lg =
+    new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS12);
+  lg->SetPlatformName(this->GetPlatformName());
+  lg->SetGlobalGenerator(this);
+  return lg;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio12Generator::UseFolderProperty()
+{
+  // Intentionally skip over the parent class implementation and call the
+  // grand-parent class's implementation. Folders are not supported by the
+  // Express editions in VS10 and earlier, but they are in VS12 Express.
+  return cmGlobalVisualStudio8Generator::UseFolderProperty();
+}
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
new file mode 100644 (file)
index 0000000..5844ee0
--- /dev/null
@@ -0,0 +1,40 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2011 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 cmGlobalVisualStudio12Generator_h
+#define cmGlobalVisualStudio12Generator_h
+
+#include "cmGlobalVisualStudio11Generator.h"
+
+
+/** \class cmGlobalVisualStudio12Generator  */
+class cmGlobalVisualStudio12Generator:
+  public cmGlobalVisualStudio11Generator
+{
+public:
+  cmGlobalVisualStudio12Generator(const char* name,
+    const char* architectureId, const char* additionalPlatformDefinition);
+  static cmGlobalGeneratorFactory* NewFactory();
+
+  virtual void WriteSLNHeader(std::ostream& fout);
+
+  ///! create the correct local generator
+  virtual cmLocalGenerator *CreateLocalGenerator();
+
+  /** TODO: VS 12 user macro support. */
+  virtual std::string GetUserMacrosDirectory() { return ""; }
+protected:
+  virtual const char* GetIDEVersion() { return "12.0"; }
+  bool UseFolderProperty();
+private:
+  class Factory;
+};
+#endif
index e8ca788..9f3af71 100644 (file)
@@ -41,11 +41,8 @@ void cmGlobalVisualStudio6Generator
                  bool optional)
 {
   cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
   mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
-  mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort");
   this->GenerateConfigurations(mf);
   this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
 }
@@ -200,7 +197,6 @@ void cmGlobalVisualStudio6Generator
       tt != orderedProjectTargets.end(); ++tt)
     {
     cmTarget* target = *tt;
-    cmMakefile* mf = target->GetMakefile();
     // Write the project into the DSW file
     const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if(expath)
@@ -398,9 +394,9 @@ cmGlobalVisualStudio6Generator::WriteUtilityDepend(cmTarget* target)
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio6Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalVisualStudio6Generator::GetActualName();
   entry.Brief = "Generates Visual Studio 6 project files.";
   entry.Full = "";
 }
index 259aa8d..40149e9 100644 (file)
@@ -13,6 +13,7 @@
 #define cmGlobalVisualStudio6Generator_h
 
 #include "cmGlobalVisualStudioGenerator.h"
+#include "cmGlobalGeneratorFactory.h"
 
 class cmTarget;
 
@@ -25,8 +26,9 @@ class cmGlobalVisualStudio6Generator : public cmGlobalVisualStudioGenerator
 {
 public:
   cmGlobalVisualStudio6Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio6Generator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalVisualStudio6Generator>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -34,7 +36,7 @@ public:
   static const char* GetActualName() {return "Visual Studio 6";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index ab2308f..2494f55 100644 (file)
@@ -128,6 +128,9 @@ void cmGlobalVisualStudio71Generator
     fout << "\tEndGlobalSection\n";
     }
 
+  // Write out global sections
+  this->WriteSLNGlobalSections(fout, root);
+
   // Write the footer for the SLN file
   this->WriteSLNFooter(fout);
 }
@@ -273,9 +276,10 @@ void cmGlobalVisualStudio71Generator
 // Write a dsp file into the SLN file, Note, that dependencies from
 // executables to the libraries it uses are also done here
 void cmGlobalVisualStudio71Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name, cmTarget::TargetType,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -284,7 +288,9 @@ void cmGlobalVisualStudio71Generator
     fout << "\t\t{" << guid << "}." << *i
          << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : "Win32") << std::endl;
-    if(partOfDefaultBuild)
+    std::set<std::string>::const_iterator
+      ci = configsPartOfDefaultBuild.find(*i);
+    if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << ".Build.0 = " << *i << "|"
@@ -294,17 +300,6 @@ void cmGlobalVisualStudio71Generator
 }
 
 //----------------------------------------------------------------------------
-// Standard end of dsw file
-void cmGlobalVisualStudio71Generator::WriteSLNFooter(std::ostream& fout)
-{
-  fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
-       << "\tEndGlobalSection\n"
-       << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
-       << "\tEndGlobalSection\n"
-       << "EndGlobal\n";
-}
-
-//----------------------------------------------------------------------------
 // ouput standard header for dsw file
 void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
 {
@@ -313,9 +308,9 @@ void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio71Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalVisualStudio71Generator::GetActualName();
   entry.Brief = "Generates Visual Studio .NET 2003 project files.";
   entry.Full = "";
 }
index a8daad6..6d91f97 100644 (file)
@@ -24,8 +24,9 @@ class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator
 {
 public:
   cmGlobalVisualStudio71Generator();
-  static cmGlobalGenerator* New()
-    { return new cmGlobalVisualStudio71Generator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalVisualStudio71Generator>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -33,7 +34,7 @@ public:
   static const char* GetActualName() {return "Visual Studio 7 .NET 2003";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
@@ -61,16 +62,15 @@ protected:
                             const char* name, const char* path, cmTarget &t);
   virtual void WriteProjectDepends(std::ostream& fout,
                            const char* name, const char* path, cmTarget &t);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name, cmTarget::TargetType type,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
   virtual void WriteExternalProject(std::ostream& fout,
                                     const char* name,
                                     const char* path,
                                     const char* typeGuid,
                                     const std::set<cmStdString>& depends);
-  virtual void WriteSLNFooter(std::ostream& fout);
   virtual void WriteSLNHeader(std::ostream& fout);
 
   std::string ProjectConfigurationSectionName;
index b6eea5d..63cbdb8 100644 (file)
@@ -10,6 +10,7 @@
   See the License for more information.
 ============================================================================*/
 #include "windows.h" // this must be first to define GetCurrentDirectory
+#include <assert.h>
 #include "cmGlobalVisualStudio7Generator.h"
 #include "cmGeneratedFileStream.h"
 #include "cmLocalVisualStudio7Generator.h"
@@ -26,8 +27,6 @@ void cmGlobalVisualStudio7Generator
 ::EnableLanguage(std::vector<std::string>const &  lang,
                  cmMakefile *mf, bool optional)
 {
-  mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
   mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
   mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort");
@@ -243,20 +242,23 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
     const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if(expath)
       {
+      std::set<std::string> allConfigurations(this->Configurations.begin(),
+                                              this->Configurations.end());
       this->WriteProjectConfigurations(
-        fout, target->GetName(),
-        true, target->GetProperty("VS_PLATFORM_MAPPING"));
+        fout, target->GetName(), target->GetType(),
+        allConfigurations, target->GetProperty("VS_PLATFORM_MAPPING"));
       }
     else
       {
-      bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
-        root->GetMakefile()->GetProjectName(), target);
+      const std::set<std::string>& configsPartOfDefaultBuild =
+        this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(),
+                                   target);
       const char *vcprojName =
         target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName)
         {
-        this->WriteProjectConfigurations(fout, vcprojName,
-                                         partOfDefaultBuild);
+        this->WriteProjectConfigurations(fout, vcprojName, target->GetType(),
+                                         configsPartOfDefaultBuild);
         }
       }
     }
@@ -268,6 +270,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
     cmLocalGenerator* root,
     OrderedTargetDependSet const& projectTargets)
 {
+  VisualStudioFolders.clear();
+
   for(OrderedTargetDependSet::const_iterator tt =
         projectTargets.begin(); tt != projectTargets.end(); ++tt)
     {
@@ -429,6 +433,9 @@ void cmGlobalVisualStudio7Generator
   this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
   fout << "\tEndGlobalSection\n";
 
+  // Write out global sections
+  this->WriteSLNGlobalSections(fout, root);
+
   // Write the footer for the SLN file
   this->WriteSLNFooter(fout);
 }
@@ -577,9 +584,10 @@ cmGlobalVisualStudio7Generator
 // Write a dsp file into the SLN file, Note, that dependencies from
 // executables to the libraries it uses are also done here
 void cmGlobalVisualStudio7Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name, cmTarget::TargetType,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -588,7 +596,9 @@ void cmGlobalVisualStudio7Generator
     fout << "\t\t{" << guid << "}." << *i
          << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : "Win32") << "\n";
-    if(partOfDefaultBuild)
+      std::set<std::string>::const_iterator
+        ci = configsPartOfDefaultBuild.find(*i);
+      if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << ".Build.0 = " << *i << "|"
@@ -622,14 +632,73 @@ void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
 
 
 
+void cmGlobalVisualStudio7Generator
+::WriteSLNGlobalSections(std::ostream& fout,
+                         cmLocalGenerator* root)
+{
+  bool extensibilityGlobalsOverridden = false;
+  bool extensibilityAddInsOverridden = false;
+  const cmPropertyMap& props = root->GetMakefile()->GetProperties();
+  for(cmPropertyMap::const_iterator itProp = props.begin();
+      itProp != props.end(); ++itProp)
+    {
+    if(itProp->first.find("VS_GLOBAL_SECTION_") == 0)
+      {
+      std::string sectionType;
+      std::string name = itProp->first.substr(18);
+      if(name.find("PRE_") == 0)
+        {
+        name = name.substr(4);
+        sectionType = "preSolution";
+        }
+      else if(name.find("POST_") == 0)
+        {
+        name = name.substr(5);
+        sectionType = "postSolution";
+        }
+      else
+        continue;
+      if(!name.empty())
+        {
+        if(name == "ExtensibilityGlobals" && sectionType == "postSolution")
+          extensibilityGlobalsOverridden = true;
+        else if(name == "ExtensibilityAddIns" && sectionType == "postSolution")
+          extensibilityAddInsOverridden = true;
+        fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
+        std::vector<std::string> keyValuePairs;
+        cmSystemTools::ExpandListArgument(itProp->second.GetValue(),
+                                          keyValuePairs);
+        for(std::vector<std::string>::const_iterator itPair =
+            keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair)
+          {
+          const std::string::size_type posEqual = itPair->find('=');
+          if(posEqual != std::string::npos)
+            {
+            const std::string key =
+              cmSystemTools::TrimWhitespace(itPair->substr(0, posEqual));
+            const std::string value =
+              cmSystemTools::TrimWhitespace(itPair->substr(posEqual + 1));
+            fout << "\t\t" << key << " = " << value << "\n";
+            }
+          }
+        fout << "\tEndGlobalSection\n";
+        }
+      }
+    }
+  if(!extensibilityGlobalsOverridden)
+    fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
+         << "\tEndGlobalSection\n";
+  if(!extensibilityAddInsOverridden)
+    fout << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
+         << "\tEndGlobalSection\n";
+}
+
+
+
 // Standard end of dsw file
 void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout)
 {
-  fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
-       << "\tEndGlobalSection\n"
-       << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
-       << "\tEndGlobalSection\n"
-       << "EndGlobal\n";
+  fout << "EndGlobal\n";
 }
 
 
@@ -738,9 +807,9 @@ std::vector<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations()
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio7Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalVisualStudio7Generator::GetActualName();
   entry.Brief = "Generates Visual Studio .NET 2002 project files.";
   entry.Full = "";
 }
@@ -761,26 +830,34 @@ cmGlobalVisualStudio7Generator
     }
 }
 
-bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
-                                                          cmTarget* target)
+std::set<std::string>
+cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
+                                                     cmTarget* target)
 {
-  if(target->GetPropertyAsBool("EXCLUDE_FROM_DEFAULT_BUILD"))
-    {
-    return false;
-    }
+  std::set<std::string> activeConfigs;
   // if it is a utilitiy target then only make it part of the
   // default build if another target depends on it
   int type = target->GetType();
   if (type == cmTarget::GLOBAL_TARGET)
     {
-    return false;
+    return activeConfigs;
     }
-  if(type == cmTarget::UTILITY)
+  if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target))
     {
-    return this->IsDependedOn(project, target);
+    return activeConfigs;
+    }
+  // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
+  for(std::vector<std::string>::iterator i = this->Configurations.begin();
+      i != this->Configurations.end(); ++i)
+    {
+    const char* propertyValue =
+      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
+    if(cmSystemTools::IsOff(propertyValue))
+      {
+      activeConfigs.insert(*i);
+      }
     }
-  // default is to be part of the build
-  return true;
+  return activeConfigs;
 }
 
 //----------------------------------------------------------------------------
index 1df58f9..6e78620 100644 (file)
@@ -13,6 +13,7 @@
 #define cmGlobalVisualStudio7Generator_h
 
 #include "cmGlobalVisualStudioGenerator.h"
+#include "cmGlobalGeneratorFactory.h"
 
 class cmTarget;
 struct cmIDEFlagTable;
@@ -26,8 +27,9 @@ class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator
 {
 public:
   cmGlobalVisualStudio7Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio7Generator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalVisualStudio7Generator>(); }
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -38,7 +40,7 @@ public:
   virtual cmLocalGenerator *CreateLocalGenerator();
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   /**
    * Try to determine system infomation such as shared library
@@ -105,10 +107,12 @@ protected:
                             const char* name, const char* path, cmTarget &t);
   virtual void WriteProjectDepends(std::ostream& fout,
                            const char* name, const char* path, cmTarget &t);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name, cmTarget::TargetType type,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
+  virtual void WriteSLNGlobalSections(std::ostream& fout,
+                                      cmLocalGenerator* root);
   virtual void WriteSLNFooter(std::ostream& fout);
   virtual void WriteSLNHeader(std::ostream& fout);
   virtual std::string WriteUtilityDepend(cmTarget* target);
@@ -136,8 +140,8 @@ protected:
 
   std::string ConvertToSolutionPath(const char* path);
 
-  bool IsPartOfDefaultBuild(const char* project,
-                            cmTarget* target);
+  std::set<std::string> IsPartOfDefaultBuild(const char* project,
+                                             cmTarget* target);
   std::vector<std::string> Configurations;
   std::map<cmStdString, cmStdString> GUIDMap;
 
index bca1754..864e8db 100644 (file)
 #include "cmGlobalVisualStudio8Generator.h"
 #include "cmLocalVisualStudio7Generator.h"
 #include "cmMakefile.h"
+#include "cmVisualStudioWCEPlatformParser.h"
 #include "cmake.h"
 #include "cmGeneratedFileStream.h"
 
+static const char vs8generatorName[] = "Visual Studio 8 2005";
+
+class cmGlobalVisualStudio8Generator::Factory
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if(strstr(name, vs8generatorName) != name)
+      {
+      return 0;
+      }
+
+    const char* p = name + sizeof(vs8generatorName) - 1;
+    if(p[0] == '\0')
+      {
+      return new cmGlobalVisualStudio8Generator(
+        name, NULL, NULL);
+      }
+
+    if(p[0] != ' ')
+      {
+      return 0;
+      }
+
+    ++p;
+
+    if(!strcmp(p, "Win64"))
+      {
+      return new cmGlobalVisualStudio8Generator(
+        name, "x64", "CMAKE_FORCE_WIN64");
+      }
+
+    cmVisualStudioWCEPlatformParser parser(p);
+    parser.ParseVersion("8.0");
+    if (!parser.Found())
+      {
+      return 0;
+      }
+
+    cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator(
+      name, parser.GetArchitectureFamily(), NULL);
+    ret->PlatformName = p;
+    ret->WindowsCEVersion = parser.GetOSVersion();
+    return ret;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    entry.Name = vs8generatorName;
+    entry.Brief = "Generates Visual Studio 8 2005 project files.";
+    entry.Full =
+      "It is possible to append a space followed by the platform name "
+      "to create project files for a specific target platform. E.g. "
+      "\"Visual Studio 8 2005 Win64\" will create project files for "
+      "the x64 processor.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(vs8generatorName);
+    names.push_back(vs8generatorName + std::string(" Win64"));
+    cmVisualStudioWCEPlatformParser parser;
+    parser.ParseVersion("8.0");
+    const std::vector<std::string>& availablePlatforms =
+      parser.GetAvailablePlatforms();
+    for(std::vector<std::string>::const_iterator i =
+        availablePlatforms.begin(); i != availablePlatforms.end(); ++i)
+      {
+      names.push_back("Visual Studio 8 2005 " + *i);
+      }
+  }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio8Generator::NewFactory()
+{
+  return new Factory;
+}
+
 //----------------------------------------------------------------------------
-cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator()
+cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(
+  const char* name, const char* architectureId,
+  const char* additionalPlatformDefinition)
 {
   this->FindMakeProgramFile = "CMakeVS8FindMake.cmake";
   this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms";
+  this->Name = name;
+  if (architectureId)
+    {
+    this->ArchitectureId = architectureId;
+    }
+  if (additionalPlatformDefinition)
+    {
+    this->AdditionalPlatformDefinition = additionalPlatformDefinition;
+    }
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalVisualStudio8Generator::GetPlatformName() const
+{
+  if (!this->PlatformName.empty())
+    {
+    return this->PlatformName.c_str();
+    }
+  if (this->ArchitectureId == "X86")
+    {
+    return "Win32";
+    }
+  return this->ArchitectureId.c_str();
 }
 
 //----------------------------------------------------------------------------
@@ -36,6 +139,19 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator()
 }
 
 //----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+  cmGlobalVisualStudio71Generator::AddPlatformDefinitions(mf);
+  mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
+
+  if(this->TargetsWindowsCE())
+  {
+    mf->AddDefinition("CMAKE_VS_WINCE_VERSION",
+      this->WindowsCEVersion.c_str());
+  }
+}
+
+//----------------------------------------------------------------------------
 // ouput standard header for dsw file
 void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
 {
@@ -45,9 +161,9 @@ void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio8Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalVisualStudio8Generator::GetActualName();
   entry.Brief = "Generates Visual Studio 8 2005 project files.";
   entry.Full = "";
 }
@@ -204,7 +320,6 @@ void cmGlobalVisualStudio8Generator::AddCheckTarget()
   // overwritten by the CreateVCProjBuildRule.
   // (this could be avoided with per-target source files)
   const char* no_main_dependency = 0;
-  const char* no_working_directory = 0;
   if(cmSourceFile* file =
      mf->AddCustomCommandToOutput(
        stamps, listFiles,
@@ -258,9 +373,10 @@ cmGlobalVisualStudio8Generator
 //----------------------------------------------------------------------------
 void
 cmGlobalVisualStudio8Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name, cmTarget::TargetType type,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -270,13 +386,24 @@ cmGlobalVisualStudio8Generator
          << "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : this->GetPlatformName())
          << "\n";
-    if(partOfDefaultBuild)
+      std::set<std::string>::const_iterator
+        ci = configsPartOfDefaultBuild.find(*i);
+      if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << "|" << this->GetPlatformName() << ".Build.0 = " << *i << "|"
            << (platformMapping ? platformMapping : this->GetPlatformName())
            << "\n";
       }
+    bool needsDeploy = (type == cmTarget::EXECUTABLE ||
+                        type == cmTarget::SHARED_LIBRARY);
+    if(this->TargetsWindowsCE() && needsDeploy)
+      {
+      fout << "\t\t{" << guid << "}." << *i
+           << "|" << this->GetPlatformName() << ".Deploy.0 = " << *i << "|"
+           << (platformMapping ? platformMapping : this->GetPlatformName())
+           << "\n";
+      }
     }
 }
 
index 5009f29..bcbd7a0 100644 (file)
 class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator
 {
 public:
-  cmGlobalVisualStudio8Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio8Generator; }
+  cmGlobalVisualStudio8Generator(const char* name,
+    const char* architectureId, const char* additionalPlatformDefinition);
+  static cmGlobalGeneratorFactory* NewFactory();
 
   ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio8Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 8 2005";}
+  virtual const char* GetName() const {return this->Name.c_str();}
 
-  virtual const char* GetPlatformName() const {return "Win32";}
+  const char* GetPlatformName() const;
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
 
+  virtual void AddPlatformDefinitions(cmMakefile* mf);
+
   /**
    * Override Configure and Generate to add the build-system check
    * target.
@@ -64,6 +64,10 @@ public:
       LinkLibraryDependencies and link to .sln dependencies. */
   virtual bool NeedLinkLibraryDependencies(cmTarget& target);
 
+  /** Return true if building for Windows CE */
+  virtual bool TargetsWindowsCE() const {
+    return !this->WindowsCEVersion.empty(); }
+
 protected:
   virtual const char* GetIDEVersion() { return "8.0"; }
 
@@ -74,12 +78,20 @@ protected:
   static cmIDEFlagTable const* GetExtraFlagTableVS8();
   virtual void WriteSLNHeader(std::ostream& fout);
   virtual void WriteSolutionConfigurations(std::ostream& fout);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name, cmTarget::TargetType type,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
   virtual bool ComputeTargetDepends();
   virtual void WriteProjectDepends(std::ostream& fout, const char* name,
                                    const char* path, cmTarget &t);
+
+  std::string Name;
+  std::string PlatformName;
+  std::string WindowsCEVersion;
+
+private:
+  class Factory;
+  friend class Factory;
 };
 #endif
diff --git a/Source/cmGlobalVisualStudio8Win64Generator.cxx b/Source/cmGlobalVisualStudio8Win64Generator.cxx
deleted file mode 100644 (file)
index 4cbc275..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*============================================================================
-  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 "windows.h" // this must be first to define GetCurrentDirectory
-#include "cmGlobalVisualStudio8Win64Generator.h"
-#include "cmLocalVisualStudio7Generator.h"
-#include "cmMakefile.h"
-#include "cmake.h"
-
-
-
-cmGlobalVisualStudio8Win64Generator::cmGlobalVisualStudio8Win64Generator()
-{
-  this->ArchitectureId = "x64";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Win64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 8 2005 Win64 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Win64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  this->cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
-}
diff --git a/Source/cmGlobalVisualStudio8Win64Generator.h b/Source/cmGlobalVisualStudio8Win64Generator.h
deleted file mode 100644 (file)
index 12f8012..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*============================================================================
-  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 cmGlobalVisualStudio8Win64Generator_h
-#define cmGlobalVisualStudio8Win64Generator_h
-
-#include "cmGlobalVisualStudio8Generator.h"
-
-
-/** \class cmGlobalVisualStudio8Win64Generator
- * \brief Write a Unix makefiles.
- *
- * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree
- */
-class cmGlobalVisualStudio8Win64Generator :
-  public cmGlobalVisualStudio8Generator
-{
-public:
-  cmGlobalVisualStudio8Win64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio8Win64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio8Win64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 8 2005 Win64";}
-
-  virtual const char* GetPlatformName() const {return "x64";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  /**
-   * Try to determine system infomation such as shared library
-   * extension, pthreads, byte order etc.
-   */
-  virtual void AddPlatformDefinitions(cmMakefile *);
-};
-#endif
index 70af50d..2082384 100644 (file)
 #include "cmGlobalVisualStudio9Generator.h"
 #include "cmLocalVisualStudio7Generator.h"
 #include "cmMakefile.h"
+#include "cmVisualStudioWCEPlatformParser.h"
 #include "cmake.h"
 
+static const char vs9generatorName[] = "Visual Studio 9 2008";
 
+class cmGlobalVisualStudio9Generator::Factory
+  : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
+    if(strstr(name, vs9generatorName) != name)
+      {
+      return 0;
+      }
+
+    const char* p = name + sizeof(vs9generatorName) - 1;
+    if(p[0] == '\0')
+      {
+      return new cmGlobalVisualStudio9Generator(
+        name, NULL, NULL);
+      }
+
+    if(p[0] != ' ')
+      {
+      return 0;
+      }
+
+    ++p;
+
+    if(!strcmp(p, "IA64"))
+      {
+      return new cmGlobalVisualStudio9Generator(
+        name, "Itanium", "CMAKE_FORCE_IA64");
+      }
+
+    if(!strcmp(p, "Win64"))
+      {
+      return new cmGlobalVisualStudio9Generator(
+        name, "x64", "CMAKE_FORCE_WIN64");
+      }
+
+    cmVisualStudioWCEPlatformParser parser(p);
+    parser.ParseVersion("9.0");
+    if (!parser.Found())
+      {
+      return 0;
+      }
+
+    cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator(
+      name, parser.GetArchitectureFamily(), NULL);
+    ret->PlatformName = p;
+    ret->WindowsCEVersion = parser.GetOSVersion();
+    return ret;
+  }
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    entry.Name = vs9generatorName;
+    entry.Brief = "Generates Visual Studio 9 2008 project files.";
+    entry.Full =
+      "It is possible to append a space followed by the platform name "
+      "to create project files for a specific target platform. E.g. "
+      "\"Visual Studio 9 2008 Win64\" will create project files for "
+      "the x64 processor; \"Visual Studio 9 2008 IA64\" for Itanium.";
+  }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(vs9generatorName);
+    names.push_back(vs9generatorName + std::string(" Win64"));
+    names.push_back(vs9generatorName + std::string(" IA64"));
+    cmVisualStudioWCEPlatformParser parser;
+    parser.ParseVersion("9.0");
+    const std::vector<std::string>& availablePlatforms =
+      parser.GetAvailablePlatforms();
+    for(std::vector<std::string>::const_iterator i =
+        availablePlatforms.begin(); i != availablePlatforms.end(); ++i)
+      {
+      names.push_back("Visual Studio 9 2008 " + *i);
+      }
+  }
+};
 
-cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator()
+//----------------------------------------------------------------------------
+cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
+{
+  return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
+  const char* name, const char* architectureId,
+  const char* additionalPlatformDefinition)
+  : cmGlobalVisualStudio8Generator(name, architectureId,
+                                   additionalPlatformDefinition)
 {
   this->FindMakeProgramFile = "CMakeVS9FindMake.cmake";
 }
@@ -42,15 +130,6 @@ cmLocalGenerator *cmGlobalVisualStudio9Generator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio9Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 9 2008 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9Generator
 ::EnableLanguage(std::vector<std::string>const &  lang,
                  cmMakefile *mf, bool optional)
 {
index 0b0d143..1310a93 100644 (file)
@@ -24,17 +24,9 @@ class cmGlobalVisualStudio9Generator :
   public cmGlobalVisualStudio8Generator
 {
 public:
-  cmGlobalVisualStudio9Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio9Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio9Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 9 2008";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  cmGlobalVisualStudio9Generator(const char* name,
+    const char* architectureId, const char* additionalPlatformDefinition);
+  static cmGlobalGeneratorFactory* NewFactory();
 
   ///! create the correct local generator
   virtual cmLocalGenerator *CreateLocalGenerator();
@@ -61,5 +53,8 @@ public:
   virtual std::string GetUserMacrosRegKeyBase();
 protected:
   virtual const char* GetIDEVersion() { return "9.0"; }
+private:
+  class Factory;
+  friend class Factory;
 };
 #endif
diff --git a/Source/cmGlobalVisualStudio9IA64Generator.cxx b/Source/cmGlobalVisualStudio9IA64Generator.cxx
deleted file mode 100644 (file)
index 38dbfac..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*============================================================================
-  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 "cmGlobalVisualStudio9IA64Generator.h"
-#include "cmLocalVisualStudio7Generator.h"
-#include "cmMakefile.h"
-
-
-cmGlobalVisualStudio9IA64Generator::cmGlobalVisualStudio9IA64Generator()
-{
-  this->ArchitectureId = "Itanium";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9IA64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 9 2008 Itanium project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9IA64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  cmGlobalVisualStudio9Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
-}
diff --git a/Source/cmGlobalVisualStudio9IA64Generator.h b/Source/cmGlobalVisualStudio9IA64Generator.h
deleted file mode 100644 (file)
index 989b0d1..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*============================================================================
-  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 cmGlobalVisualStudio9IA64Generator_h
-#define cmGlobalVisualStudio9IA64Generator_h
-
-#include "cmGlobalVisualStudio9Generator.h"
-
-
-/** \class cmGlobalVisualStudio8IA64Generator
- * \brief Write a Unix makefiles.
- *
- * cmGlobalVisualStudio8IA64Generator manages UNIX build process for a tree
- */
-class cmGlobalVisualStudio9IA64Generator :
-  public cmGlobalVisualStudio9Generator
-{
-public:
-  cmGlobalVisualStudio9IA64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio9IA64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio9IA64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 9 2008 IA64";}
-
-  virtual const char* GetPlatformName() const {return "Itanium";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  /**
-   * Try to determine system infomation such as shared library
-   * extension, pthreads, byte order etc.
-   */
-  virtual void AddPlatformDefinitions(cmMakefile *);
-};
-#endif
diff --git a/Source/cmGlobalVisualStudio9Win64Generator.cxx b/Source/cmGlobalVisualStudio9Win64Generator.cxx
deleted file mode 100644 (file)
index 4d8a646..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*============================================================================
-  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 "cmGlobalVisualStudio9Win64Generator.h"
-#include "cmLocalVisualStudio7Generator.h"
-#include "cmMakefile.h"
-
-
-cmGlobalVisualStudio9Win64Generator::cmGlobalVisualStudio9Win64Generator()
-{
-  this->ArchitectureId = "x64";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9Win64Generator
-::GetDocumentation(cmDocumentationEntry& entry) const
-{
-  entry.Name = this->GetName();
-  entry.Brief = "Generates Visual Studio 9 2008 Win64 project files.";
-  entry.Full = "";
-}
-
-//----------------------------------------------------------------------------
-void cmGlobalVisualStudio9Win64Generator
-::AddPlatformDefinitions(cmMakefile* mf)
-{
-  cmGlobalVisualStudio9Generator::AddPlatformDefinitions(mf);
-  mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
-}
diff --git a/Source/cmGlobalVisualStudio9Win64Generator.h b/Source/cmGlobalVisualStudio9Win64Generator.h
deleted file mode 100644 (file)
index 7c20cf4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*============================================================================
-  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 cmGlobalVisualStudio9Win64Generator_h
-#define cmGlobalVisualStudio9Win64Generator_h
-
-#include "cmGlobalVisualStudio9Generator.h"
-
-
-/** \class cmGlobalVisualStudio8Win64Generator
- * \brief Write a Unix makefiles.
- *
- * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree
- */
-class cmGlobalVisualStudio9Win64Generator :
-  public cmGlobalVisualStudio9Generator
-{
-public:
-  cmGlobalVisualStudio9Win64Generator();
-  static cmGlobalGenerator* New() {
-    return new cmGlobalVisualStudio9Win64Generator; }
-
-  ///! Get the name for the generator.
-  virtual const char* GetName() const {
-    return cmGlobalVisualStudio9Win64Generator::GetActualName();}
-  static const char* GetActualName() {return "Visual Studio 9 2008 Win64";}
-
-  virtual const char* GetPlatformName() const {return "x64";}
-
-  /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
-
-  /**
-   * Try to determine system infomation such as shared library
-   * extension, pthreads, byte order etc.
-   */
-  virtual void AddPlatformDefinitions(cmMakefile *);
-};
-#endif
index 0968b77..808664d 100644 (file)
@@ -22,6 +22,7 @@
 cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
 {
   this->ArchitectureId = "X86";
+  this->AdditionalPlatformDefinition = NULL;
 }
 
 //----------------------------------------------------------------------------
@@ -32,9 +33,16 @@ cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator()
 //----------------------------------------------------------------------------
 std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
 {
+  return cmGlobalVisualStudioGenerator::GetRegistryBase(
+    this->GetIDEVersion());
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudioGenerator::GetRegistryBase(
+  const char* version)
+{
   std::string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\";
-  key += this->GetIDEVersion();
-  return key;
+  return key + version;
 }
 
 //----------------------------------------------------------------------------
@@ -75,7 +83,6 @@ void cmGlobalVisualStudioGenerator::Generate()
 #endif
 
       // Now make all targets depend on the ALL_BUILD target
-      cmTargets targets;
       for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
           i != gen.end(); ++i)
         {
@@ -492,8 +499,13 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf)
 {
-  mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId);
-  mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId);
+  mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId.c_str());
+  mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId.c_str());
+
+  if(this->AdditionalPlatformDefinition)
+    {
+    mf->AddDefinition(this->AdditionalPlatformDefinition, "TRUE");
+    }
 }
 
 //----------------------------------------------------------------------------
index cebf7d7..9d81170 100644 (file)
@@ -65,10 +65,16 @@ public:
   /** Get the top-level registry key for this VS version.  */
   std::string GetRegistryBase();
 
+  /** Get the top-level registry key for the given VS version.  */
+  static std::string GetRegistryBase(const char* version);
+
   /** Return true if the generated build tree may contain multiple builds.
       i.e. "Can I build Debug and Release in the same tree?" */
   virtual bool IsMultiConfig() { return true; }
 
+  /** Return true if building for Windows CE */
+  virtual bool TargetsWindowsCE() const { return false; }
+
   class TargetSet: public std::set<cmTarget*> {};
   struct TargetCompare
   {
@@ -98,7 +104,8 @@ protected:
   std::string GetUtilityDepend(cmTarget* target);
   typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
   UtilityDependsMap UtilityDepends;
-  const char* ArchitectureId;
+  std::string ArchitectureId;
+  const char* AdditionalPlatformDefinition;
 
 private:
   void ComputeTargetObjects(cmGeneratorTarget* gt) const;
index 45b171f..e3cebc4 100644 (file)
@@ -58,9 +58,9 @@ cmLocalGenerator *cmGlobalWatcomWMakeGenerator::CreateLocalGenerator()
 
 //----------------------------------------------------------------------------
 void cmGlobalWatcomWMakeGenerator
-::GetDocumentation(cmDocumentationEntry& entry) const
+::GetDocumentation(cmDocumentationEntry& entry)
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalWatcomWMakeGenerator::GetActualName();
   entry.Brief = "Generates Watcom WMake makefiles.";
   entry.Full = "";
 }
index ee16eae..23e60a1 100644 (file)
@@ -23,14 +23,16 @@ class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3
 {
 public:
   cmGlobalWatcomWMakeGenerator();
-  static cmGlobalGenerator* New() { return new cmGlobalWatcomWMakeGenerator; }
+  static cmGlobalGeneratorFactory* NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory
+      <cmGlobalWatcomWMakeGenerator>(); }
   ///! Get the name for the generator.
   virtual const char* GetName() const {
     return cmGlobalWatcomWMakeGenerator::GetActualName();}
   static const char* GetActualName() {return "Watcom WMake";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
index 30d8f18..3092abf 100644 (file)
@@ -20,6 +20,7 @@
 #include "cmSourceFile.h"
 #include "cmCustomCommandGenerator.h"
 #include "cmGeneratorTarget.h"
+#include "cmGlobalGeneratorFactory.h"
 
 #include <cmsys/auto_ptr.hxx>
 
@@ -112,6 +113,18 @@ public:
     }
 };
 
+class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory
+{
+public:
+  virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const;
+
+  virtual void GetDocumentation(cmDocumentationEntry& entry) const {
+    cmGlobalXCodeGenerator::GetDocumentation(entry); }
+
+  virtual void GetGenerators(std::vector<std::string>& names) const {
+    names.push_back(cmGlobalXCodeGenerator::GetActualName()); }
+};
+
 //----------------------------------------------------------------------------
 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
 {
@@ -132,8 +145,17 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
 }
 
 //----------------------------------------------------------------------------
-cmGlobalGenerator* cmGlobalXCodeGenerator::New()
+cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory()
 {
+  return new Factory;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalGenerator* cmGlobalXCodeGenerator::Factory
+::CreateGlobalGenerator(const char* name) const
+{
+  if (strcmp(name, GetActualName()))
+    return 0;
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   cmXcodeVersionParser parser;
   std::string versionFile;
@@ -179,6 +201,20 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::New()
 }
 
 //----------------------------------------------------------------------------
+bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts)
+{
+  if(this->XcodeVersion >= 30)
+    {
+    this->PlatformToolset = ts;
+    return true;
+    }
+  else
+    {
+    return cmGlobalGenerator::SetGeneratorToolset(ts);
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
                                             lang,
                                             cmMakefile * mf, bool optional)
@@ -201,9 +237,12 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
         cmCacheManager::STRING);
       }
     }
-  mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc");
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++");
   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
+  if(!this->PlatformToolset.empty())
+    {
+    mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
+                      this->PlatformToolset.c_str());
+    }
   this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
     const char* osxArch =
       mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -495,8 +534,12 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
     (this->CurrentReRunCMakeMakefile.c_str());
   makefileStream.SetCopyIfDifferent(true);
   makefileStream << "# Generated by CMake, DO NOT EDIT\n";
-  makefileStream << cmake::GetCMakeFilesDirectoryPostSlash();
-  makefileStream << "cmake.check_cache: ";
+  std::string checkCache = mf->GetHomeOutputDirectory();
+  checkCache += "/";
+  checkCache += cmake::GetCMakeFilesDirectoryPostSlash();
+  checkCache += "cmake.check_cache";
+  makefileStream << this->ConvertToRelativeForMake(checkCache.c_str())
+                 << ": ";
   for(std::vector<std::string>::const_iterator i = lfiles.begin();
       i !=  lfiles.end(); ++i)
     {
@@ -911,6 +954,15 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
 }
 
 //----------------------------------------------------------------------------
+struct cmSourceFilePathCompare
+{
+  bool operator()(cmSourceFile* l, cmSourceFile* r)
+  {
+    return l->GetFullPath() < r->GetFullPath();
+  }
+};
+
+//----------------------------------------------------------------------------
 void
 cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
                                            std::vector<cmXCodeObject*>&
@@ -936,7 +988,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       }
 
     // organize the sources
-    std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles();
+    std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
+    std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+
     std::vector<cmXCodeObject*> externalObjFiles;
     std::vector<cmXCodeObject*> headerFiles;
     std::vector<cmXCodeObject*> resourceFiles;
@@ -1180,7 +1234,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.GetLinkImplementation("NOCONFIG", &cmtarget);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -1341,16 +1395,18 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
 }
 
 //----------------------------------------------------------------------------
-// This function removes each occurence of the flag and returns the last one
+// This function removes each occurrence of the flag and returns the last one
 // (i.e., the dominant flag in GCC)
 std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
                                                 std::string& flags)
 {
   std::string retFlag;
-  std::string::size_type pos = flags.rfind(flag);
+  std::string::size_type lastOccurancePos = flags.rfind(flag);
   bool saved = false;
-  while(pos != flags.npos)
+  while(lastOccurancePos != flags.npos)
     {
+    //increment pos, we use lastOccurancePos to reduce search space on next inc
+    std::string::size_type pos = lastOccurancePos;
     if(pos == 0 || flags[pos-1]==' ')
       {
       while(pos < flags.size() && flags[pos] != ' ')
@@ -1362,9 +1418,12 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
         flags[pos] = ' ';
         pos++;
         }
-      }
       saved = true;
-      pos = flags.rfind(flag);
+      }
+    //decrement lastOccurancePos while making sure we don't loop around
+    //and become a very large positive number since size_type is unsigned
+    lastOccurancePos = lastOccurancePos == 0 ? 0 : lastOccurancePos-1;
+    lastOccurancePos = flags.rfind(flag,lastOccurancePos);
     }
   return retFlag;
 }
@@ -1613,14 +1672,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     if(strcmp(lang, "CXX") == 0)
       {
       this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
-      this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C");
+      this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
+                                                   "C", configName);
       }
 
     // Add language-specific flags.
     this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
 
     // Add shared-library flags if needed.
-    this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang);
+    this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
+                                                 lang, configName);
     }
   else if(binary)
   {
@@ -1648,12 +1709,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     this->AppendDefines(ppDefs, exportMacro);
     }
   cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
-  this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str());
-  if(configName)
-    {
-    this->AppendDefines(ppDefs,
-                        gtgt->GetCompileDefinitions(configName).c_str());
-    }
+  this->AppendDefines(ppDefs,
+                      target.GetCompileDefinitions(configName).c_str());
   buildSettings->AddAttribute
     ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
 
@@ -1971,15 +2028,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       dirs.Add(incpath.c_str());
       }
     }
-  std::vector<std::string>& frameworks = target.GetFrameworks();
-  if(frameworks.size())
+  // Add framework search paths needed for linking.
+  if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
     {
-    for(std::vector<std::string>::iterator fmIt = frameworks.begin();
-        fmIt != frameworks.end(); ++fmIt)
+    std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
+    for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
+        fdi != fwDirs.end(); ++fdi)
       {
-      if(emitted.insert(*fmIt).second)
+      if(emitted.insert(*fdi).second)
         {
-        fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str());
+        fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str());
         }
       }
     }
@@ -2044,6 +2102,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     debugStr = "NO";
     }
 
+  buildSettings->AddAttribute("COMBINE_HIDPI_IMAGES",
+                              this->CreateString("YES"));
   buildSettings->AddAttribute("GCC_GENERATE_DEBUGGING_SYMBOLS",
                               this->CreateString(debugStr));
   buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL",
@@ -2460,47 +2520,25 @@ std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
 void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
                                              cmXCodeObject* dependTarget)
 {
-  // make sure a target does not depend on itself
-  if(target == dependTarget)
-    {
-    return;
-    }
-  // now avoid circular references if dependTarget already
-  // depends on target then skip it.  Circular references crashes
-  // xcode
-  cmXCodeObject* dependTargetDepends =
-    dependTarget->GetObject("dependencies");
-  if(dependTargetDepends)
-    {
-    if(dependTargetDepends->HasObject(target->GetPBXTargetDependency()))
-      {
-      return;
-      }
-    }
-
-  cmXCodeObject* targetdep = dependTarget->GetPBXTargetDependency();
-  if(!targetdep)
-    {
-    cmXCodeObject* container =
-      this->CreateObject(cmXCodeObject::PBXContainerItemProxy);
-    container->SetComment("PBXContainerItemProxy");
-    container->AddAttribute("containerPortal",
-                            this->CreateObjectReference(this->RootObject));
-    container->AddAttribute("proxyType", this->CreateString("1"));
-    container->AddAttribute("remoteGlobalIDString",
-                            this->CreateObjectReference(dependTarget));
-    container->AddAttribute("remoteInfo",
-                            this->CreateString(
-                              dependTarget->GetTarget()->GetName()));
-    targetdep =
-      this->CreateObject(cmXCodeObject::PBXTargetDependency);
-    targetdep->SetComment("PBXTargetDependency");
-    targetdep->AddAttribute("target",
-                            this->CreateObjectReference(dependTarget));
-    targetdep->AddAttribute("targetProxy",
-                            this->CreateObjectReference(container));
-    dependTarget->SetPBXTargetDependency(targetdep);
-    }
+  // This is called once for every edge in the target dependency graph.
+  cmXCodeObject* container =
+    this->CreateObject(cmXCodeObject::PBXContainerItemProxy);
+  container->SetComment("PBXContainerItemProxy");
+  container->AddAttribute("containerPortal",
+                          this->CreateObjectReference(this->RootObject));
+  container->AddAttribute("proxyType", this->CreateString("1"));
+  container->AddAttribute("remoteGlobalIDString",
+                          this->CreateObjectReference(dependTarget));
+  container->AddAttribute("remoteInfo",
+                          this->CreateString(
+                            dependTarget->GetTarget()->GetName()));
+  cmXCodeObject* targetdep =
+    this->CreateObject(cmXCodeObject::PBXTargetDependency);
+  targetdep->SetComment("PBXTargetDependency");
+  targetdep->AddAttribute("target",
+                          this->CreateObjectReference(dependTarget));
+  targetdep->AddAttribute("targetProxy",
+                          this->CreateObjectReference(container));
 
   cmXCodeObject* depends = target->GetObject("dependencies");
   if(!depends)
@@ -2623,8 +2661,7 @@ void cmGlobalXCodeGenerator
       }
 
     // Compute the link library and directory information.
-    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget);
-    cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
+    cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
     if(!pcli)
       {
       continue;
@@ -2666,25 +2703,6 @@ void cmGlobalXCodeGenerator
                                       linkDirs.c_str(), configName);
     }
 
-    // add the framework search paths
-    {
-    const char* sep = "";
-    std::string fdirs;
-    std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
-    for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
-        fdi != fwDirs.end(); ++fdi)
-      {
-      fdirs += sep;
-      sep = " ";
-      fdirs += this->XCodeEscapePath(fdi->c_str());
-      }
-    if(!fdirs.empty())
-      {
-      this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
-                                        fdirs.c_str(), configName);
-      }
-    }
-
     // now add the link libraries
     {
     std::string linkLibs;
@@ -2877,7 +2895,7 @@ cmXCodeObject* cmGlobalXCodeGenerator
     {
     std::vector<std::string> folders =
       cmSystemTools::tokenize(sg->GetFullName(), "\\");
-    cmStdString curr_folder = cmtarget.GetName();
+    cmStdString curr_folder = target;
     curr_folder += "/";
     for(std::vector<std::string>::size_type i = 0; i < folders.size();i++)
       {
@@ -3145,6 +3163,11 @@ void cmGlobalXCodeGenerator
     buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET",
                                 this->CreateString(deploymentTarget));
     }
+  if(!this->PlatformToolset.empty())
+    {
+    buildSettings->AddAttribute("GCC_VERSION",
+      this->CreateString(this->PlatformToolset.c_str()));
+    }
 
   // Put this last so it can override existing settings
   // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
@@ -3470,9 +3493,8 @@ const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
 
 //----------------------------------------------------------------------------
 void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
-  const
 {
-  entry.Name = this->GetName();
+  entry.Name = cmGlobalXCodeGenerator::GetActualName();
   entry.Brief = "Generate Xcode project files.";
   entry.Full = "";
 }
index afa1ca2..131a6e6 100644 (file)
@@ -15,6 +15,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmXCodeObject.h"
 #include "cmCustomCommand.h"
+class cmGlobalGeneratorFactory;
 class cmTarget;
 class cmSourceFile;
 class cmSourceGroup;
@@ -29,7 +30,7 @@ class cmGlobalXCodeGenerator : public cmGlobalGenerator
 {
 public:
   cmGlobalXCodeGenerator(std::string const& version);
-  static cmGlobalGenerator* New();
+  static cmGlobalGeneratorFactory* NewFactory();
 
   ///! Get the name for the generator.
   virtual const char* GetName() const {
@@ -37,7 +38,7 @@ public:
   static const char* GetActualName() {return "Xcode";}
 
   /** Get the documentation entry for this generator.  */
-  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+  static void GetDocumentation(cmDocumentationEntry& entry);
 
   ///! Create a local generator appropriate to this Global Generator
   virtual cmLocalGenerator *CreateLocalGenerator();
@@ -82,6 +83,7 @@ public:
       i.e. "Can I build Debug and Release in the same tree?" */
   virtual bool IsMultiConfig();
 
+  virtual bool SetGeneratorToolset(std::string const& ts);
 private:
   cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
                                      cmSourceGroup* sg);
@@ -186,6 +188,7 @@ private:
                           const char* varNameSuffix,
                           const char* default_flags);
 
+  class Factory;
   class BuildObjectListOrString;
   friend class BuildObjectListOrString;
 
@@ -234,6 +237,7 @@ private:
   std::map<cmStdString, cmXCodeObject* > TargetGroup;
   std::map<cmStdString, cmXCodeObject* > FileRefs;
   std::vector<std::string> Architectures;
+  std::string PlatformToolset;
 };
 
 #endif
index 15bad52..4816da9 100644 (file)
@@ -15,8 +15,6 @@
 #include "cmGlobalGenerator.h"
 #include "cmGeneratedFileStream.h"
 
-#include <memory>
-
 
 
 static const char* getShapeForTarget(const cmTarget* target)
@@ -67,7 +65,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
   cmake cm;
   cmGlobalGenerator ggi;
   ggi.SetCMakeInstance(&cm);
-  std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
+  cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
   cmMakefile *mf = lg->GetMakefile();
 
   const char* inFileName = settingsFileName;
index d9c0e87..76a60cf 100644 (file)
@@ -177,3 +177,14 @@ void cmIDEOptions::RemoveFlag(const char* flag)
 {
   this->FlagMap.erase(flag);
 }
+
+//----------------------------------------------------------------------------
+const char* cmIDEOptions::GetFlag(const char* flag)
+{
+  std::map<cmStdString, cmStdString>::iterator i = this->FlagMap.find(flag);
+  if(i != this->FlagMap.end())
+    {
+    return i->second.c_str();
+    }
+  return 0;
+}
index a5be8fb..e556bde 100644 (file)
@@ -29,6 +29,7 @@ public:
   void AddDefines(const char* defines);
   void AddFlag(const char* flag, const char* value);
   void RemoveFlag(const char* flag);
+  const char* GetFlag(const char* flag);
 
 protected:
   // create a map of xml tags to the values they should have in the output
index ba81849..30c1743 100644 (file)
@@ -36,6 +36,10 @@ bool cmIncludeDirectoryCommand
     ++i;
     }
 
+  std::vector<std::string> beforeIncludes;
+  std::vector<std::string> afterIncludes;
+  std::set<cmStdString> systemIncludes;
+
   for(; i != args.end(); ++i)
     {
     if(*i == "SYSTEM")
@@ -49,9 +53,37 @@ bool cmIncludeDirectoryCommand
       return false;
       }
 
-    this->AddDirectory(i->c_str(),before,system);
+    std::vector<std::string> includes;
+
+    GetIncludes(*i, includes);
 
+    if (before)
+      {
+      beforeIncludes.insert(beforeIncludes.end(),
+                            includes.begin(),
+                            includes.end());
+      }
+    else
+      {
+      afterIncludes.insert(afterIncludes.end(),
+                           includes.begin(),
+                           includes.end());
+      }
+    if (system)
+      {
+      for (std::vector<std::string>::const_iterator li = includes.begin();
+        li != includes.end(); ++li)
+        {
+        systemIncludes.insert(*li);
+        }
+      }
     }
+  std::reverse(beforeIncludes.begin(), beforeIncludes.end());
+
+  this->Makefile->AddIncludeDirectories(afterIncludes);
+  this->Makefile->AddIncludeDirectories(beforeIncludes, before);
+  this->Makefile->AddSystemIncludeDirectories(systemIncludes);
+
   return true;
 }
 
@@ -72,57 +104,60 @@ static bool StartsWithGeneratorExpression(const std::string &input)
 // output from a program and passing it into a command the cleanup doesn't
 // always happen
 //
-void cmIncludeDirectoryCommand::AddDirectory(const char *i,
-                                             bool before,
-                                             bool system)
+void cmIncludeDirectoryCommand::GetIncludes(const std::string &arg,
+                                            std::vector<std::string> &incs)
 {
   // break apart any line feed arguments
-  std::string ret = i;
   std::string::size_type pos = 0;
-  if((pos = ret.find('\n', pos)) != std::string::npos)
+  std::string::size_type lastPos = 0;
+  while((pos = arg.find('\n', lastPos)) != std::string::npos)
     {
     if (pos)
       {
-      this->AddDirectory(ret.substr(0,pos).c_str(), before, system);
-      }
-    if (ret.size()-pos-1)
-      {
-      this->AddDirectory(ret.substr(pos+1,ret.size()-pos-1).c_str(),
-                         before, system);
+      std::string inc = arg.substr(lastPos,pos);
+      this->NormalizeInclude(inc);
+      if (!inc.empty())
+        {
+        incs.push_back(inc);
+        }
       }
-    return;
+    lastPos = pos + 1;
     }
+  std::string inc = arg.substr(lastPos);
+  this->NormalizeInclude(inc);
+  if (!inc.empty())
+    {
+    incs.push_back(inc);
+    }
+}
 
-  // remove any leading or trailing spaces and \r
-  std::string::size_type b = ret.find_first_not_of(" \r");
-  std::string::size_type e = ret.find_last_not_of(" \r");
-  if ((b!=ret.npos) && (e!=ret.npos))
+void cmIncludeDirectoryCommand::NormalizeInclude(std::string &inc)
+{
+  std::string::size_type b = inc.find_first_not_of(" \r");
+  std::string::size_type e = inc.find_last_not_of(" \r");
+  if ((b!=inc.npos) && (e!=inc.npos))
     {
-    ret.assign(ret, b, 1+e-b);   // copy the remaining substring
+    inc.assign(inc, b, 1+e-b);   // copy the remaining substring
     }
   else
     {
-    return;         // if we get here, we had only whitespace in the string
+    inc = "";
+    return;
     }
 
-  if (!cmSystemTools::IsOff(ret.c_str()))
+  if (!cmSystemTools::IsOff(inc.c_str()))
     {
-    cmSystemTools::ConvertToUnixSlashes(ret);
-    if(!cmSystemTools::FileIsFullPath(ret.c_str()))
+    cmSystemTools::ConvertToUnixSlashes(inc);
+
+    if(!cmSystemTools::FileIsFullPath(inc.c_str()))
       {
-      if(!StartsWithGeneratorExpression(ret))
+      if(!StartsWithGeneratorExpression(inc))
         {
         std::string tmp = this->Makefile->GetStartDirectory();
         tmp += "/";
-        tmp += ret;
-        ret = tmp;
+        tmp += inc;
+        inc = tmp;
         }
       }
     }
-  this->Makefile->AddIncludeDirectory(ret.c_str(), before);
-  if(system)
-    {
-    this->Makefile->AddSystemIncludeDirectory(ret.c_str());
-    }
 }
-
index 6751fc0..77a340a 100644 (file)
@@ -59,8 +59,9 @@ public:
     return
       "  include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n"
       "Add the given directories to those the compiler uses to search "
-      "for include files. "
-      "These directories are added to the directory property "
+      "for include files.  Relative paths are interpreted as relative to "
+      "the current source directory. \n"
+      "The include directories are added to the directory property "
       "INCLUDE_DIRECTORIES for the current CMakeLists file. "
       "They are also added to the target property INCLUDE_DIRECTORIES "
       "for each target in the current CMakeLists file. "
@@ -72,16 +73,20 @@ public:
       "CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. "
       "By using AFTER or BEFORE explicitly, you can select between "
       "appending and prepending, independent of the default. "
+      "\n"
       "If the SYSTEM option is given, the compiler will be told the "
       "directories are meant as system include directories on some "
-      "platforms.";
+      "platforms (signalling this setting might achieve effects such as "
+      "the compiler skipping warnings, or these fixed-install system files "
+      "not being considered in dependency calculations - see compiler docs).";
     }
 
   cmTypeMacro(cmIncludeDirectoryCommand, cmCommand);
 
 protected:
   // used internally
-  void AddDirectory(const char *arg, bool before, bool system);
+  void GetIncludes(const std::string &arg, std::vector<std::string> &incs);
+  void NormalizeInclude(std::string &inc);
 };
 
 
index ee92906..7aff731 100644 (file)
@@ -36,6 +36,8 @@ public:
 
   cmExportSet* GetExportSet() {return this->ExportSet;}
 
+  cmMakefile* GetMakefile() const { return this->Makefile; }
+
   const std::string& GetNamespace() const { return this->Namespace; }
 
 protected:
index 347ad3e..5f9b658 100644 (file)
@@ -16,7 +16,6 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmake.h"
-#include "cmGeneratorTarget.h"
 
 #include <assert.h>
 
@@ -27,8 +26,7 @@ cmInstallTargetGenerator
                            std::vector<std::string> const& configurations,
                            const char* component, bool optional):
   cmInstallGenerator(dest, configurations, component), Target(&t),
-  ImportLibrary(implib), FilePermissions(file_permissions),
-  Optional(optional), GeneratorTarget(0)
+  ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
 {
   this->ActionsPerConfig = true;
   this->NamelinkMode = NamelinkModeNone;
@@ -486,17 +484,6 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
   this->AddStripRule(os, indent, file);
 }
 
-void cmInstallTargetGenerator::CreateGeneratorTarget()
-{
-  if (!this->GeneratorTarget)
-    {
-    this->GeneratorTarget = this->Target->GetMakefile()
-                                        ->GetLocalGenerator()
-                                        ->GetGlobalGenerator()
-                                        ->GetGeneratorTarget(this->Target);
-    }
-}
-
 //----------------------------------------------------------------------------
 void
 cmInstallTargetGenerator
@@ -520,13 +507,10 @@ cmInstallTargetGenerator
     return;
     }
 
-  this->CreateGeneratorTarget();
-
   // Build a map of build-tree install_name to install-tree install_name for
   // shared libraries linked to this target.
   std::map<cmStdString, cmStdString> install_name_remap;
-  if(cmComputeLinkInformation* cli =
-                            this->GeneratorTarget->GetLinkInformation(config))
+  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config))
     {
     std::set<cmTarget*> const& sharedLibs = cli->GetSharedLibrariesLinked();
     for(std::set<cmTarget*>::const_iterator j = sharedLibs.begin();
@@ -624,12 +608,9 @@ cmInstallTargetGenerator
     return;
     }
 
-  this->CreateGeneratorTarget();
-
   // Get the link information for this target.
   // It can provide the RPATH.
-  cmComputeLinkInformation* cli =
-                            this->GeneratorTarget->GetLinkInformation(config);
+  cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
   if(!cli)
     {
     return;
@@ -658,12 +639,9 @@ cmInstallTargetGenerator
     return;
     }
 
-  this->CreateGeneratorTarget();
-
   // Get the link information for this target.
   // It can provide the RPATH.
-  cmComputeLinkInformation* cli =
-                            this->GeneratorTarget->GetLinkInformation(config);
+  cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
   if(!cli)
     {
     return;
index cab3e90..8cf72f9 100644 (file)
@@ -14,8 +14,7 @@
 
 #include "cmInstallGenerator.h"
 #include "cmTarget.h"
-
-class cmGeneratorTarget;
+#include "cmGeneratorTarget.h"
 
 /** \class cmInstallTargetGenerator
  * \brief Generate target installation rules.
@@ -94,8 +93,6 @@ protected:
   void AddRanlibRule(std::ostream& os, Indent const& indent,
                      const std::string& toDestDirPath);
 
-  void CreateGeneratorTarget();
-
   cmTarget* Target;
   bool ImportLibrary;
   std::string FilePermissions;
index 889118c..9218f44 100644 (file)
@@ -62,10 +62,8 @@ public:
       "  link_directories(directory1 directory2 ...)\n"
       "Specify the paths in which the linker should search for libraries. "
       "The command will apply only to targets created after it is called. "
-      "For historical reasons, relative paths given to this command are "
-      "passed to the linker unchanged "
-      "(unlike many CMake commands which interpret them relative to the "
-      "current source directory).\n"
+      "Relative paths given to this command are interpreted as relative to "
+      "the current source directory, see CMP0015. \n"
       "Note that this command is rarely necessary.  Library locations "
       "returned by find_package() and find_library() are absolute paths.  "
       "Pass these absolute library file paths directly to the "
index 7848424..df64695 100644 (file)
 
 #include <stdlib.h> // required for atoi
 #include <ctype.h>
+#include <assert.h>
 //----------------------------------------------------------------------------
 bool cmListCommand
 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
 {
-  if(args.size() < 1)
+  if(args.size() < 2)
     {
-    this->SetError("must be called with at least one argument.");
+    this->SetError("must be called with at least two arguments.");
     return false;
     }
 
@@ -243,11 +244,7 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
 //----------------------------------------------------------------------------
 bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
 {
-  if(args.size() < 2)
-    {
-    this->SetError("sub-command APPEND requires at least one argument.");
-    return false;
-    }
+  assert(args.size() >= 2);
 
   // Skip if nothing to append.
   if(args.size() < 3)
@@ -424,12 +421,8 @@ bool cmListCommand
 bool cmListCommand
 ::HandleReverseCommand(std::vector<std::string> const& args)
 {
-  if(args.size() < 2)
-    {
-    this->SetError("sub-command REVERSE requires a list as an argument.");
-    return false;
-    }
-  else if(args.size() > 2)
+  assert(args.size() >= 2);
+  if(args.size() > 2)
     {
     this->SetError(
       "sub-command REVERSE only takes one argument.");
@@ -463,13 +456,8 @@ bool cmListCommand
 bool cmListCommand
 ::HandleRemoveDuplicatesCommand(std::vector<std::string> const& args)
 {
-  if(args.size() < 2)
-    {
-    this->SetError(
-      "sub-command REMOVE_DUPLICATES requires a list as an argument.");
-    return false;
-    }
-  else if(args.size() > 2)
+  assert(args.size() >= 2);
+  if(args.size() > 2)
     {
     this->SetError(
       "sub-command REMOVE_DUPLICATES only takes one argument.");
@@ -513,12 +501,8 @@ bool cmListCommand
 bool cmListCommand
 ::HandleSortCommand(std::vector<std::string> const& args)
 {
-  if(args.size() < 2)
-    {
-    this->SetError("sub-command SORT requires a list as an argument.");
-    return false;
-    }
-  else if(args.size() > 2)
+  assert(args.size() >= 2);
+  if(args.size() > 2)
     {
     this->SetError(
       "sub-command SORT only takes one argument.");
index c057754..fec3d07 100644 (file)
@@ -76,4 +76,13 @@ struct cmListFile
   std::vector<cmListFileFunction> Functions;
 };
 
+struct cmValueWithOrigin {
+  cmValueWithOrigin(const std::string &value,
+                          const cmListFileBacktrace &bt)
+    : Value(value), Backtrace(bt)
+  {}
+  std::string Value;
+  cmListFileBacktrace Backtrace;
+};
+
 #endif
index 4952a8c..ee5b9d8 100644 (file)
@@ -1212,7 +1212,8 @@ cmLocalGenerator::ConvertToIncludeReference(std::string const& path)
 //----------------------------------------------------------------------------
 std::string cmLocalGenerator::GetIncludeFlags(
                                      const std::vector<std::string> &includes,
-                                     const char* lang, bool forResponseFile)
+                                     const char* lang, bool forResponseFile,
+                                     const char *config)
 {
   if(!lang)
     {
@@ -1285,7 +1286,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
     if(!flagUsed || repeatFlag)
       {
       if(sysIncludeFlag &&
-         this->Makefile->IsSystemIncludeDirectory(i->c_str()))
+         this->Makefile->IsSystemIncludeDirectory(i->c_str(), config))
         {
         includeFlags << sysIncludeFlag;
         }
@@ -1329,7 +1330,9 @@ std::string cmLocalGenerator::GetIncludeFlags(
 void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
                                              cmGeneratorTarget* target,
                                              const char* lang,
-                                             const char *config)
+                                             const char *config,
+                                             bool stripImplicitInclDirs
+                                            )
 {
   // Need to decide whether to automatically include the source and
   // binary directories at the beginning of the include path.
@@ -1404,6 +1407,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
     return;
     }
 
+  std::vector<std::string> implicitDirs;
   // Load implicit include directories for this language.
   std::string impDirVar = "CMAKE_";
   impDirVar += lang;
@@ -1416,6 +1420,10 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
         i != impDirVec.end(); ++i)
       {
       emitted.insert(*i);
+      if (!stripImplicitInclDirs)
+        {
+        implicitDirs.push_back(*i);
+        }
       }
     }
 
@@ -1457,6 +1465,15 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
       dirs.push_back(*i);
       }
     }
+
+  for(std::vector<std::string>::const_iterator i = implicitDirs.begin();
+      i != implicitDirs.end(); ++i)
+    {
+    if(std::find(includes.begin(), includes.end(), *i) != includes.end())
+      {
+      dirs.push_back(*i);
+      }
+    }
 }
 
 void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
@@ -1671,7 +1688,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
 {
   cmOStringStream fout;
   const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
-  cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
+  cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config);
   if(!pcli)
     {
     return;
@@ -1703,7 +1720,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
   for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
       fdi != fwDirs.end(); ++fdi)
     {
-    frameworkPath = " -F";
+    frameworkPath += "-F";
     frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false);
     frameworkPath += " ";
     }
@@ -1875,6 +1892,14 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
   // modify the name so stripping down to just the file name should
   // produce the target name in this case.
   std::string name = cmSystemTools::GetFilenameName(inName);
+
+  // If the input name is the empty string, there is no real
+  // dependency. Short-circuit the other checks:
+  if(name == "")
+    {
+    return false;
+    }
+
   if(cmSystemTools::GetFilenameLastExtension(name) == ".exe")
     {
     name = cmSystemTools::GetFilenameWithoutLastExtension(name);
@@ -1971,7 +1996,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
 
 //----------------------------------------------------------------------------
 void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
-                                       std::string const& lang)
+                                       std::string const& lang,
+                                       const char *config)
 {
   int targetType = target->GetType();
 
@@ -1984,8 +2010,18 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
     }
   else
     {
-    // Add position independendent flags, if needed.
-    if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
+    if (target->GetType() == cmTarget::OBJECT_LIBRARY)
+    {
+      if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
+        {
+        this->AddPositionIndependentFlags(flags, lang, targetType);
+        }
+      return;
+    }
+
+    if (target->GetLinkInterfaceDependentBoolProperty(
+                                                "POSITION_INDEPENDENT_CODE",
+                                                config))
       {
       this->AddPositionIndependentFlags(flags, lang, targetType);
       }
index bd58218..a1c34f0 100644 (file)
@@ -49,29 +49,29 @@ public:
   /**
    * Calls TraceVSDependencies() on all targets of this generator.
    */
-  virtual void TraceDependencies();
+  void TraceDependencies();
 
   virtual void AddHelperCommands() {}
 
   /**
    * Perform any final calculations prior to generation
    */
-  virtual void ConfigureFinalPass();
+  void ConfigureFinalPass();
 
   /**
    * Generate the install rules files in this directory.
    */
-  virtual void GenerateInstallRules();
+  void GenerateInstallRules();
 
   /**
    * Generate the test files for tests.
    */
-  virtual void GenerateTestFiles();
+  void GenerateTestFiles();
 
   /**
    * Generate a manifest of target files that will be built.
    */
-  virtual void GenerateTargetManifest();
+  void GenerateTargetManifest();
 
   ///! Get the makefile for this generator
   cmMakefile *GetMakefile() {
@@ -142,14 +142,15 @@ public:
   void AddLanguageFlags(std::string& flags, const char* lang,
                         const char* config);
   void AddCMP0018Flags(std::string &flags, cmTarget* target,
-                       std::string const& lang);
+                       std::string const& lang, const char *config);
   void AddConfigVariableFlags(std::string& flags, const char* var,
                               const char* config);
   ///! Append flags to a string.
   virtual void AppendFlags(std::string& flags, const char* newFlags);
   ///! Get the include flags for the current makefile and language
   std::string GetIncludeFlags(const std::vector<std::string> &includes,
-                              const char* lang, bool forResponseFile = false);
+                              const char* lang, bool forResponseFile = false,
+                              const char *config = 0);
 
   /**
    * Encode a list of preprocessor definitions for the compiler
@@ -212,7 +213,8 @@ public:
   /** Get the include flags for the current makefile and language.  */
   void GetIncludeDirectories(std::vector<std::string>& dirs,
                              cmGeneratorTarget* target,
-                             const char* lang = "C", const char *config = 0);
+                             const char* lang = "C", const char *config = 0,
+                             bool stripImplicitInclDirs = true);
 
   /** Compute the language used to compile the given source file.  */
   const char* GetSourceFileLanguage(const cmSourceFile& source);
index db93529..0f680f6 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <cmsys/auto_ptr.hxx>
 
-#include <memory> // auto_ptr
 #include <queue>
 
 //----------------------------------------------------------------------------
@@ -1939,8 +1938,12 @@ void cmLocalUnixMakefileGenerator3
     for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin();
         pi != implicitPairs.end(); ++pi)
       {
-      cmakefileStream << "  \"" << pi->second << "\" ";
-      cmakefileStream << "\"" << pi->first << "\"\n";
+      for(cmDepends::DependencyVector::const_iterator di = pi->second.begin();
+          di != pi->second.end(); ++ di)
+        {
+        cmakefileStream << "  \"" << *di << "\" ";
+        cmakefileStream << "\"" << pi->first << "\"\n";
+        }
       }
     cmakefileStream << "  )\n";
 
@@ -1958,34 +1961,16 @@ void cmLocalUnixMakefileGenerator3
     }
 
   // Build a list of preprocessor definitions for the target.
-  std::vector<std::string> defines;
-  {
-  std::string defPropName = "COMPILE_DEFINITIONS_";
-  defPropName += cmSystemTools::UpperCase(this->ConfigurationName);
-  if(const char* ddefs = this->Makefile->GetProperty("COMPILE_DEFINITIONS"))
-    {
-    cmSystemTools::ExpandListArgument(ddefs, defines);
-    }
-  if(const char* cdefs = target.GetProperty("COMPILE_DEFINITIONS"))
-    {
-    cmSystemTools::ExpandListArgument(cdefs, defines);
-    }
-  if(const char* dcdefs = this->Makefile->GetProperty(defPropName.c_str()))
-    {
-    cmSystemTools::ExpandListArgument(dcdefs, defines);
-    }
-  if(const char* ccdefs = target.GetProperty(defPropName.c_str()))
-    {
-    cmSystemTools::ExpandListArgument(ccdefs, defines);
-    }
-  }
+  std::set<std::string> defines;
+  this->AppendDefines(defines, target.GetCompileDefinitions(
+                                            this->ConfigurationName.c_str()));
   if(!defines.empty())
     {
     cmakefileStream
       << "\n"
       << "# Preprocessor definitions for this target.\n"
       << "SET(CMAKE_TARGET_DEFINITIONS\n";
-    for(std::vector<std::string>::const_iterator di = defines.begin();
+    for(std::set<std::string>::const_iterator di = defines.begin();
         di != defines.end(); ++di)
       {
       cmakefileStream
@@ -2204,7 +2189,7 @@ cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt,
                                                   const char* obj,
                                                   const char* src)
 {
-  this->ImplicitDepends[tgt.GetName()][lang][obj] = src;
+  this->ImplicitDepends[tgt.GetName()][lang][obj].push_back(src);
 }
 
 //----------------------------------------------------------------------------
index e374959..703369e 100644 (file)
@@ -209,7 +209,8 @@ public:
 
   // File pairs for implicit dependency scanning.  The key of the map
   // is the depender and the value is the explicit dependee.
-  struct ImplicitDependFileMap: public std::map<cmStdString, cmStdString> {};
+  struct ImplicitDependFileMap:
+    public std::map<cmStdString, cmDepends::DependencyVector> {};
   struct ImplicitDependLanguageMap:
     public std::map<cmStdString, ImplicitDependFileMap> {};
   struct ImplicitDependTargetMap:
index f15322b..dc94476 100644 (file)
@@ -325,19 +325,22 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
       if(!cmSystemTools::FileExists(source.c_str()))
         {
         cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
+        // Make sure the path exists for the file
+        std::string path = cmSystemTools::GetFilenamePath(source);
+        cmSystemTools::MakeDirectory(path.c_str());
 #if defined(_WIN32) || defined(__CYGWIN__)
-        std::ofstream fout(source.c_str(),
+        std::ofstream sourceFout(source.c_str(),
                            std::ios::binary | std::ios::out
                            | std::ios::trunc);
 #else
-        std::ofstream fout(source.c_str(),
+        std::ofstream sourceFout(source.c_str(),
                            std::ios::out | std::ios::trunc);
 #endif
-        if(fout)
+        if(sourceFout)
           {
-          fout.write("# generated from CMake",22);
-          fout.flush();
-          fout.close();
+          sourceFout.write("# generated from CMake",22);
+          sourceFout.flush();
+          sourceFout.close();
           }
         }
       }
@@ -710,6 +713,8 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
 
   switch(b)
     {
+    case WIN32_EXECUTABLE:
+      break;
     case STATIC_LIBRARY:
       this->DSPHeaderTemplate = root;
       this->DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
@@ -1695,25 +1700,21 @@ void cmLocalVisualStudio6Generator
     std::set<std::string> minsizeDefinesSet;
     std::set<std::string> debugrelDefinesSet;
 
-
-    cmGeneratorTarget* gt =
-      this->GlobalGenerator->GetGeneratorTarget(&target);
-
     this->AppendDefines(
       definesSet,
-      gt->GetCompileDefinitions());
+      target.GetCompileDefinitions(0));
     this->AppendDefines(
       debugDefinesSet,
-      gt->GetCompileDefinitions("DEBUG"));
+      target.GetCompileDefinitions("DEBUG"));
     this->AppendDefines(
       releaseDefinesSet,
-      gt->GetCompileDefinitions("RELEASE"));
+      target.GetCompileDefinitions("RELEASE"));
     this->AppendDefines(
       minsizeDefinesSet,
-      gt->GetCompileDefinitions("MINSIZEREL"));
+      target.GetCompileDefinitions("MINSIZEREL"));
     this->AppendDefines(
       debugrelDefinesSet,
-      gt->GetCompileDefinitions("RELWITHDEBINFO"));
+      target.GetCompileDefinitions("RELWITHDEBINFO"));
 
     std::string defines = " ";
     std::string debugDefines = " ";
@@ -1783,10 +1784,8 @@ void cmLocalVisualStudio6Generator
                      const std::string extraOptions,
                      std::string& options)
 {
-  cmGeneratorTarget* gt =
-    this->GlobalGenerator->GetGeneratorTarget(&target);
   // Compute the link information for this configuration.
-  cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
+  cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
   if(!pcli)
     {
     return;
index f9a2d32..7d0bc67 100644 (file)
@@ -229,6 +229,9 @@ void cmLocalVisualStudio7Generator
   this->FortranProject =
     static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
     ->TargetIsFortranOnly(target);
+  this->WindowsCEProject =
+    static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
+    ->TargetsWindowsCE();
 
   // Intel Fortran for VS10 uses VS9 format ".vfproj" files.
   VSVersion realVersion = this->Version;
@@ -742,8 +745,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   targetOptions.ParseFinish();
   cmGeneratorTarget* gt =
     this->GlobalGenerator->GetGeneratorTarget(&target);
-  targetOptions.AddDefines(gt->GetCompileDefinitions().c_str());
-  targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str());
+  targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str());
   targetOptions.SetVerboseMakefile(
     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
 
@@ -914,12 +916,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
       // for FAT32 file systems, which can cause an empty manifest
       // to be embedded into the resulting executable.  See CMake
       // bug #2617.
-      const char* tool  = "VCManifestTool";
+      const char* manifestTool  = "VCManifestTool";
       if(this->FortranProject)
         {
-        tool = "VFManifestTool";
+        manifestTool = "VFManifestTool";
         }
-      fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
+      fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
            << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
            << "\t\t\t/>\n";
       }
@@ -1003,6 +1005,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     }
   switch(target.GetType())
     {
+    case cmTarget::UNKNOWN_LIBRARY:
+      break;
     case cmTarget::OBJECT_LIBRARY:
       {
       std::string libpath = this->GetTargetDirectory(target);
@@ -1074,9 +1078,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
                            targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmGeneratorTarget* gt =
-      this->GlobalGenerator->GetGeneratorTarget(&target);
-    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
+    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
     if(!pcli)
       {
       return;
@@ -1131,6 +1133,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       {
       fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
       }
+    if(this->WindowsCEProject)
+      {
+      if(this->GetVersion() < VS9)
+        {
+        fout << "\t\t\t\tSubSystem=\"9\"\n";
+        }
+      else
+        {
+        fout << "\t\t\t\tSubSystem=\"8\"\n";
+        }
+      }
     std::string stackVar = "CMAKE_";
     stackVar += linkLanguage;
     stackVar += "_STACK_SIZE";
@@ -1161,9 +1174,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
                               targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmGeneratorTarget* gt =
-      this->GlobalGenerator->GetGeneratorTarget(&target);
-    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
+    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
     if(!pcli)
       {
       return;
@@ -1171,6 +1182,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     cmComputeLinkInformation& cli = *pcli;
     const char* linkLanguage = cli.GetLinkLanguage();
 
+    bool isWin32Executable = target.GetPropertyAsBool("WIN32_EXECUTABLE");
+
     // Compute the variable name to lookup standard libraries for this
     // language.
     std::string standardLibsVar = "CMAKE_";
@@ -1218,15 +1231,31 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       {
       fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
       }
-    if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+    if ( this->WindowsCEProject )
+      {
+      if(this->GetVersion() < VS9)
+        {
+        fout << "\t\t\t\tSubSystem=\"9\"\n";
+        }
+      else
+        {
+        fout << "\t\t\t\tSubSystem=\"8\"\n";
+        }
+      fout << "\t\t\t\tEntryPointSymbol=\""
+           << (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup")
+           << "\"\n";
+      }
+    else if ( this->FortranProject )
       {
       fout << "\t\t\t\tSubSystem=\""
-           << (this->FortranProject? "subSystemWindows" : "2") << "\"\n";
+           << (isWin32Executable ? "subSystemWindows" : "subSystemConsole")
+           << "\"\n";
       }
     else
       {
       fout << "\t\t\t\tSubSystem=\""
-           << (this->FortranProject? "subSystemConsole" : "1") << "\"\n";
+           << (isWin32Executable ? "2" : "1")
+           << "\"\n";
       }
     std::string stackVar = "CMAKE_";
     stackVar += linkLanguage;
@@ -1591,17 +1620,30 @@ cmLocalVisualStudio7Generator
   return dir_max;
 }
 
-void cmLocalVisualStudio7Generator
+bool cmLocalVisualStudio7Generator
 ::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
              std::ostream &fout, const char *libName,
              std::vector<std::string> *configs)
 {
   const std::vector<const cmSourceFile *> &sourceFiles =
     sg->GetSourceFiles();
+  std::vector<cmSourceGroup> const& children  = sg->GetGroupChildren();
+
+  // Write the children to temporary output.
+  bool hasChildrenWithSources = false;
+  cmOStringStream tmpOut;
+  for(unsigned int i=0;i<children.size();++i)
+    {
+    if(this->WriteGroup(&children[i], target, tmpOut, libName, configs))
+      {
+      hasChildrenWithSources = true;
+      }
+    }
+
   // If the group is empty, don't write it at all.
-  if(sourceFiles.empty() && sg->GetGroupChildren().empty())
+  if(sourceFiles.empty() && !hasChildrenWithSources)
     {
-    return;
+    return false;
     }
 
   // If the group has a name, write the header.
@@ -1722,11 +1764,10 @@ void cmLocalVisualStudio7Generator
       }
     }
 
-  std::vector<cmSourceGroup> const& children  = sg->GetGroupChildren();
-
-  for(unsigned int i=0;i<children.size();++i)
+  // If the group has children with source files, write the children.
+  if(hasChildrenWithSources)
     {
-    this->WriteGroup(&children[i], target, fout, libName, configs);
+    fout << tmpOut.str();
     }
 
   // If the group has a name, write the footer.
@@ -1734,6 +1775,8 @@ void cmLocalVisualStudio7Generator
     {
     this->WriteVCProjEndGroup(fout);
     }
+
+  return true;
 }
 
 void cmLocalVisualStudio7Generator::
index 95db2cc..d9e2ef0 100644 (file)
@@ -109,7 +109,7 @@ private:
                        FCInfo& fcinfo);
   void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
 
-  void WriteGroup(const cmSourceGroup *sg,
+  bool WriteGroup(const cmSourceGroup *sg,
                   cmTarget& target, std::ostream &fout,
                   const char *libName, std::vector<std::string> *configs);
 
@@ -122,6 +122,7 @@ private:
   cmVS7FlagTable const* ExtraFlagTable;
   std::string ModuleDefinitionFile;
   bool FortranProject;
+  bool WindowsCEProject;
   std::string PlatformName; // Win32 or x64
   cmLocalVisualStudio7GeneratorInternals* Internal;
 };
index 4bcf4de..ef2bb1d 100644 (file)
@@ -84,7 +84,6 @@ cmLocalVisualStudioGenerator
                   const char* newline_text)
 {
   bool useLocal = this->CustomCommandUseLocal();
-  const cmCustomCommandLines& commandLines = cc.GetCommandLines();
   const char* workingDirectory = cc.GetWorkingDirectory();
   cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
   RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
index 9968592..1a3499a 100644 (file)
@@ -38,7 +38,8 @@ public:
     VS8 = 80,
     VS9 = 90,
     VS10 = 100,
-    VS11 = 110
+    VS11 = 110,
+    VS12 = 120
   };
 
   cmLocalVisualStudioGenerator(VSVersion v);
index f8c40c0..aedbb4d 100644 (file)
@@ -92,12 +92,12 @@ public:
       "facilitates creating macros with optional arguments. Additionally "
       "${ARGV} holds the list of all arguments given to the macro and "
       "${ARGN} "
-      "holds the list of argument past the last expected argument. "
+      "holds the list of arguments past the last expected argument. "
       "Note that the parameters to a macro and values such as ARGN "
       "are not variables in the usual CMake sense. They are string "
-      "replacements much like the c preprocessor would do with a "
-      "macro. If you want true CMake variables you should look at "
-      "the function command."
+      "replacements much like the C preprocessor would do with a macro. "
+      "If you want true CMake variables and/or better CMake scope control "
+      "you should look at the function command."
       "\n"
       "See the cmake_policy() command documentation for the behavior of "
       "policies inside macros."
index f067da4..47a6d2e 100644 (file)
@@ -23,6 +23,7 @@
 #include "cmListFileCache.h"
 #include "cmCommandArgumentParserHelper.h"
 #include "cmDocumentCompileDefinitions.h"
+#include "cmGeneratorExpression.h"
 #include "cmTest.h"
 #ifdef CMAKE_BUILD_WITH_CMAKE
 #  include "cmVariableWatch.h"
@@ -99,6 +100,7 @@ cmMakefile::cmMakefile(): Internal(new Internals)
   this->AddDefaultDefinitions();
   this->Initialize();
   this->PreOrder = false;
+  this->GeneratingBuildSystem = false;
 }
 
 cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
@@ -814,7 +816,7 @@ bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
 void cmMakefile::FinalPass()
 {
   // do all the variable expansions here
-  this->ExpandVariables();
+  this->ExpandVariablesCMP0019();
 
   // give all the commands a chance to do something
   // after the file has been parsed before generation
@@ -1485,9 +1487,12 @@ void cmMakefile::InitializeFromParent()
   // Initialize definitions with the closure of the parent scope.
   this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
 
-  // copy include paths
-  this->SetProperty("INCLUDE_DIRECTORIES",
-                    parent->GetProperty("INCLUDE_DIRECTORIES"));
+  const std::vector<cmValueWithOrigin> parentIncludes =
+                                        parent->GetIncludeDirectoriesEntries();
+  this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
+                                       parentIncludes.begin(),
+                                       parentIncludes.end());
+
   this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
 
   // define flags
@@ -1613,74 +1618,72 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
 }
 
 //----------------------------------------------------------------------------
-void AddStringToProperty(cmProperty *prop, const char* name, const char* s,
-                         bool before)
+void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
+                                       bool before)
 {
-  if (!prop)
+  if (incs.empty())
     {
     return;
     }
 
-  // Don't worry about duplicates at this point. We eliminate them when
-  // we convert the property to a vector in GetIncludeDirectories.
-
-  if (before)
-    {
-    const char *val = prop->GetValue();
-    cmOStringStream oss;
-
-    if(val && *val)
-      {
-      oss << s << ";" << val;
-      }
-    else
-      {
-      oss << s;
-      }
+  std::string incString;
+  std::string sep;
 
-    std::string newVal = oss.str();
-    prop->Set(name, newVal.c_str());
-    }
-  else
+  for(std::vector<std::string>::const_iterator li = incs.begin();
+      li != incs.end(); ++li)
     {
-    prop->Append(name, s);
+    incString += sep + *li;
+    sep = ";";
     }
-}
 
-//----------------------------------------------------------------------------
-void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
-{
-  if (!inc)
-    {
-    return;
-    }
+  std::vector<cmValueWithOrigin>::iterator position =
+                              before ? this->IncludeDirectoriesEntries.begin()
+                                    : this->IncludeDirectoriesEntries.end();
 
-  // Directory property:
-  cmProperty *prop =
-    this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
-  AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
+  cmListFileBacktrace lfbt;
+  this->GetBacktrace(lfbt);
+  cmValueWithOrigin entry(incString, lfbt);
+  this->IncludeDirectoriesEntries.insert(position, entry);
 
   // Property on each target:
   for (cmTargets::iterator l = this->Targets.begin();
        l != this->Targets.end(); ++l)
     {
     cmTarget &t = l->second;
-    prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
-    AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
+    t.InsertInclude(entry, before);
     }
 }
 
 //----------------------------------------------------------------------------
-void cmMakefile::AddSystemIncludeDirectory(const char* dir)
+void
+cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
 {
-  this->SystemIncludeDirectories.insert(dir);
+  for(std::set<cmStdString>::const_iterator li = incs.begin();
+      li != incs.end(); ++li)
+    {
+    this->SystemIncludeDirectories.insert(*li);
+    }
 }
 
 //----------------------------------------------------------------------------
-bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
+bool cmMakefile::IsSystemIncludeDirectory(const char* dir, const char *config)
 {
-  return (this->SystemIncludeDirectories.find(dir) !=
-          this->SystemIncludeDirectories.end());
+  for (std::set<cmStdString>::const_iterator
+      it = this->SystemIncludeDirectories.begin();
+      it != this->SystemIncludeDirectories.end(); ++it)
+    {
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+
+    std::vector<std::string> incs;
+    cmSystemTools::ExpandListArgument(ge.Parse(*it)
+                                       ->Evaluate(this, config, false), incs);
+    if (std::find(incs.begin(), incs.end(), dir) != incs.end())
+      {
+      return true;
+      }
+    }
+  return false;
 }
 
 void cmMakefile::AddDefinition(const char* name, const char* value)
@@ -2122,21 +2125,33 @@ void cmMakefile::AddExtraDirectory(const char* dir)
   this->AuxSourceDirectories.push_back(dir);
 }
 
+static bool mightExpandVariablesCMP0019(const char* s)
+{
+  return s && *s && strstr(s,"${") && strchr(s,'}');
+}
 
-// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
-// include and library directories.
-
-void cmMakefile::ExpandVariables()
+void cmMakefile::ExpandVariablesCMP0019()
 {
-  // Now expand variables in the include and link strings
+  // Drop this ancient compatibility behavior with a policy.
+  cmPolicies::PolicyStatus pol = this->GetPolicyStatus(cmPolicies::CMP0019);
+  if(pol != cmPolicies::OLD && pol != cmPolicies::WARN)
+    {
+    return;
+    }
+  cmOStringStream w;
 
-  // May not be necessary anymore... But may need a policy for strict
-  // backwards compatibility
   const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
-  if (includeDirs)
+  if(mightExpandVariablesCMP0019(includeDirs))
     {
     std::string dirs = includeDirs;
     this->ExpandVariablesInString(dirs, true, true);
+    if(pol == cmPolicies::WARN && dirs != includeDirs)
+      {
+      w << "Evaluated directory INCLUDE_DIRECTORIES\n"
+        << "  " << includeDirs << "\n"
+        << "as\n"
+        << "  " << dirs << "\n";
+      }
     this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
     }
 
@@ -2146,10 +2161,17 @@ void cmMakefile::ExpandVariables()
     {
     cmTarget &t = l->second;
     includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
-    if (includeDirs)
+    if(mightExpandVariablesCMP0019(includeDirs))
       {
       std::string dirs = includeDirs;
       this->ExpandVariablesInString(dirs, true, true);
+      if(pol == cmPolicies::WARN && dirs != includeDirs)
+        {
+        w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
+          << "  " << includeDirs << "\n"
+          << "as\n"
+          << "  " << dirs << "\n";
+        }
       t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
       }
     }
@@ -2157,13 +2179,45 @@ void cmMakefile::ExpandVariables()
   for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
       d != this->LinkDirectories.end(); ++d)
     {
-    this->ExpandVariablesInString(*d, true, true);
+    if(mightExpandVariablesCMP0019(d->c_str()))
+      {
+      std::string orig = *d;
+      this->ExpandVariablesInString(*d, true, true);
+      if(pol == cmPolicies::WARN && *d != orig)
+        {
+        w << "Evaluated link directory\n"
+          << "  " << orig << "\n"
+          << "as\n"
+          << "  " << *d << "\n";
+        }
+      }
     }
   for(cmTarget::LinkLibraryVectorType::iterator l =
         this->LinkLibraries.begin();
       l != this->LinkLibraries.end(); ++l)
     {
-    this->ExpandVariablesInString(l->first, true, true);
+    if(mightExpandVariablesCMP0019(l->first.c_str()))
+      {
+      std::string orig = l->first;
+      this->ExpandVariablesInString(l->first, true, true);
+      if(pol == cmPolicies::WARN && l->first != orig)
+        {
+        w << "Evaluated link library\n"
+          << "  " << orig << "\n"
+          << "as\n"
+          << "  " << l->first << "\n";
+        }
+      }
+    }
+
+  if(!w.str().empty())
+    {
+    cmOStringStream m;
+    m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019)
+      << "\n"
+      << "The following variable evaluations were encountered:\n"
+      << w.str();
+    this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
     }
 }
 
@@ -2221,7 +2275,7 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
     {
     return true;
     }
-  // If we are doing an in-source build, than the test will always fail
+  // If we are doing an in-source build, then the test will always fail
   if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
                                this->GetHomeOutputDirectory()) )
     {
@@ -2232,8 +2286,8 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
     return true;
     }
 
-  // Check if this is subdirectory of the source tree but not a
-  // subdirectory of a build tree
+  // Check if this is subdirectory of the source tree but not a
+  // subdirectory of the build tree
   if ( cmSystemTools::IsSubDirectory(fileName,
       this->GetHomeDirectory()) &&
     !cmSystemTools::IsSubDirectory(fileName,
@@ -2951,6 +3005,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
   cm.SetStartDirectory(srcdir);
   cm.SetStartOutputDirectory(bindir);
   cm.SetCMakeCommand(cmakeCommand.c_str());
+  cm.SetGeneratorToolset(this->GetCMakeInstance()->GetGeneratorToolset());
   cm.LoadCache();
   if(!gg->IsMultiConfig())
     {
@@ -3400,6 +3455,19 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
     this->SetLinkDirectories(varArgsExpanded);
     return;
     }
+  if (propname == "INCLUDE_DIRECTORIES")
+    {
+    this->IncludeDirectoriesEntries.clear();
+      if (!value)
+        {
+        return;
+        }
+    cmListFileBacktrace lfbt;
+    this->GetBacktrace(lfbt);
+    this->IncludeDirectoriesEntries.push_back(
+                                        cmValueWithOrigin(value, lfbt));
+    return;
+    }
 
   if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
     {
@@ -3431,6 +3499,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value,
   // handle special props
   std::string propname = prop;
 
+  if (propname == "INCLUDE_DIRECTORIES")
+    {
+    cmListFileBacktrace lfbt;
+    this->GetBacktrace(lfbt);
+    this->IncludeDirectoriesEntries.push_back(
+                                        cmValueWithOrigin(value, lfbt));
+    return;
+    }
   if ( propname == "LINK_DIRECTORIES" )
     {
     std::vector<std::string> varArgsExpanded;
@@ -3542,6 +3618,20 @@ const char *cmMakefile::GetProperty(const char* prop,
     output = str.str();
     return output.c_str();
     }
+  else if (!strcmp("INCLUDE_DIRECTORIES",prop))
+    {
+    std::string sep;
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->IncludeDirectoriesEntries.begin(),
+        end = this->IncludeDirectoriesEntries.end();
+        it != end; ++it)
+      {
+      output += sep;
+      output += it->Value;
+      sep = ";";
+      }
+    return output.c_str();
+    }
 
   bool chain = false;
   const char *retVal =
@@ -3937,6 +4027,46 @@ void cmMakefile::DefineProperties(cmake *cm)
      "See the global property of the same name for details.  "
      "This overrides the global property for a directory.",
      true);
+
+  cm->DefineProperty
+    ("VS_GLOBAL_SECTION_PRE_<section>", cmProperty::DIRECTORY,
+     "Specify a preSolution global section in Visual Studio.",
+     "Setting a property like this generates an entry of the following form "
+     "in the solution file:\n"
+     "  GlobalSection(<section>) = preSolution\n"
+     "    <contents based on property value>\n"
+     "  EndGlobalSection\n"
+     "The property must be set to a semicolon-separated list of key=value "
+     "pairs. Each such pair will be transformed into an entry in the solution "
+     "global section. Whitespace around key and value is ignored. List "
+     "elements which do not contain an equal sign are skipped."
+     "\n"
+     "This property only works for Visual Studio 7 and above; it is ignored "
+     "on other generators. The property only applies when set on a directory "
+     "whose CMakeLists.txt conatins a project() command.");
+  cm->DefineProperty
+    ("VS_GLOBAL_SECTION_POST_<section>", cmProperty::DIRECTORY,
+     "Specify a postSolution global section in Visual Studio.",
+     "Setting a property like this generates an entry of the following form "
+     "in the solution file:\n"
+     "  GlobalSection(<section>) = postSolution\n"
+     "    <contents based on property value>\n"
+     "  EndGlobalSection\n"
+     "The property must be set to a semicolon-separated list of key=value "
+     "pairs. Each such pair will be transformed into an entry in the solution "
+     "global section. Whitespace around key and value is ignored. List "
+     "elements which do not contain an equal sign are skipped."
+     "\n"
+     "This property only works for Visual Studio 7 and above; it is ignored "
+     "on other generators. The property only applies when set on a directory "
+     "whose CMakeLists.txt conatins a project() command."
+     "\n"
+     "Note that CMake generates postSolution sections ExtensibilityGlobals "
+     "and ExtensibilityAddIns by default. If you set the corresponding "
+     "property, it will override the default section. For example, setting "
+     "VS_GLOBAL_SECTION_POST_ExtensibilityGlobals will override the default "
+     "contents of the ExtensibilityGlobals section, while keeping "
+     "ExtensibilityAddIns on its default.");
 }
 
 //----------------------------------------------------------------------------
index 70cfe54..74a731d 100644 (file)
@@ -286,7 +286,8 @@ public:
   /**
    * Add an include directory to the build.
    */
-  void AddIncludeDirectory(const char*, bool before = false);
+  void AddIncludeDirectories(const std::vector<std::string> &incs,
+                             bool before = false);
 
   /**
    * Add a variable definition to the build. This variable
@@ -544,8 +545,8 @@ public:
   /**
    * Mark include directories as system directories.
    */
-  void AddSystemIncludeDirectory(const char* dir);
-  bool IsSystemIncludeDirectory(const char* dir);
+  void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
+  bool IsSystemIncludeDirectory(const char* dir, const char *config);
 
   /** Expand out any arguements in the vector that have ; separated
    *  strings into multiple arguements.  A new vector is created
@@ -693,7 +694,7 @@ public:
   /**
    * Expand variables in the makefiles ivars such as link directories etc
    */
-  void ExpandVariables();
+  void ExpandVariablesCMP0019();
 
   /**
    * Replace variables and #cmakedefine lines in the given string.
@@ -861,6 +862,14 @@ public:
   /** Set whether or not to report a CMP0000 violation.  */
   void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
 
+  std::vector<cmValueWithOrigin> GetIncludeDirectoriesEntries() const
+  {
+    return this->IncludeDirectoriesEntries;
+  }
+
+  bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
+  void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+
 protected:
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -909,6 +918,8 @@ protected:
   std::vector<std::string> HeaderFileExtensions;
   std::string DefineFlags;
 
+  std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
+
   // Track the value of the computed DEFINITIONS property.
   void AddDefineFlag(const char*, std::string&);
   void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
@@ -1008,6 +1019,9 @@ private:
 
   // Enforce rules about CMakeLists.txt files.
   void EnforceDirectoryLevelRules();
+
+  bool GeneratingBuildSystem;
+
 };
 
 //----------------------------------------------------------------------------
index e7004d6..5b4e4d7 100644 (file)
@@ -19,8 +19,6 @@
 #include "cmTarget.h"
 #include "cmake.h"
 
-#include <memory> // auto_ptr
-
 //----------------------------------------------------------------------------
 cmMakefileLibraryTargetGenerator
 ::cmMakefileLibraryTargetGenerator(cmTarget* target):
index 3d02d6a..4220ae1 100644 (file)
@@ -268,7 +268,8 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
       this->AddFortranFlags(flags);
       }
 
-    this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang);
+    this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
+                                          lang, this->ConfigName);
 
     // Add include directory flags.
     this->AddIncludeFlags(flags, lang);
@@ -302,10 +303,7 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
 
     // Add preprocessor definitions for this target and configuration.
     this->LocalGenerator->AppendDefines
-      (defines, this->GeneratorTarget->GetCompileDefinitions());
-
-    this->LocalGenerator->AppendDefines
-      (defines, this->GeneratorTarget->GetCompileDefinitions(
+      (defines, this->Target->GetCompileDefinitions(
                             this->LocalGenerator->ConfigurationName.c_str()));
 
     std::string definesString;
@@ -639,18 +637,25 @@ cmMakefileTargetGenerator
       (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
     }
 
+  std::string targetOutPathReal;
   std::string targetOutPathPDB;
   {
+  std::string targetFullPathReal;
   std::string targetFullPathPDB;
   if(this->Target->GetType() == cmTarget::EXECUTABLE ||
      this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
      this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
      this->Target->GetType() == cmTarget::MODULE_LIBRARY)
     {
+    targetFullPathReal =
+      this->Target->GetFullPath(this->ConfigName, false, true);
     targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
     targetFullPathPDB += "/";
     targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
     }
+  targetOutPathReal = this->Convert(targetFullPathReal.c_str(),
+                                    cmLocalGenerator::START_OUTPUT,
+                                    cmLocalGenerator::SHELL);
   targetOutPathPDB =
     this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
                   cmLocalGenerator::SHELL);
@@ -659,6 +664,7 @@ cmMakefileTargetGenerator
   vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
   vars.CMTarget = this->Target;
   vars.Language = lang;
+  vars.Target = targetOutPathReal.c_str();
   vars.TargetPDB = targetOutPathPDB.c_str();
   vars.Source = sourceFile.c_str();
   std::string shellObj =
@@ -1017,8 +1023,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
     << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n";
   std::set<cmTarget const*> emitted;
   const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
-  if(cmComputeLinkInformation* cli =
-                              this->GeneratorTarget->GetLinkInformation(cfg))
+  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
     {
     cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
     for(cmComputeLinkInformation::ItemVector::const_iterator
@@ -1551,10 +1556,10 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags()
   this->LocalGenerator->GetIncludeDirectories(includes,
                                               this->GeneratorTarget,
                                               "C", config);
-  std::vector<std::string>::iterator i;
   // check all include directories for frameworks as this
   // will already have added a -F for the framework
-  for(i = includes.begin(); i != includes.end(); ++i)
+  for(std::vector<std::string>::iterator i = includes.begin();
+      i != includes.end(); ++i)
     {
     if(this->Target->NameResolvesToFramework(i->c_str()))
       {
@@ -1566,17 +1571,21 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags()
     }
 
   std::string flags;
-  std::vector<std::string>& frameworks = this->Target->GetFrameworks();
-  for(i = frameworks.begin();
-      i != frameworks.end(); ++i)
+  const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
+  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
     {
-    if(emitted.insert(*i).second)
+    std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
+    for(std::vector<std::string>::const_iterator i = frameworks.begin();
+        i != frameworks.end(); ++i)
       {
-      flags += "-F";
-      flags += this->Convert(i->c_str(),
-                             cmLocalGenerator::START_OUTPUT,
-                             cmLocalGenerator::SHELL, true);
-      flags += " ";
+      if(emitted.insert(*i).second)
+        {
+        flags += "-F";
+        flags += this->Convert(i->c_str(),
+                               cmLocalGenerator::START_OUTPUT,
+                               cmLocalGenerator::SHELL, true);
+        flags += " ";
+        }
       }
     }
   return flags;
@@ -1594,8 +1603,7 @@ void cmMakefileTargetGenerator
 
   // Loop over all library dependencies.
   const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
-  if(cmComputeLinkInformation* cli =
-                              this->GeneratorTarget->GetLinkInformation(cfg))
+  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
     {
     std::vector<std::string> const& libDeps = cli->GetDepends();
     for(std::vector<std::string>::const_iterator j = libDeps.begin();
index 27c5b6a..dc0ceb3 100644 (file)
@@ -58,11 +58,11 @@ public:
     {
     return
       "  math(EXPR <output variable> <math expression>)\n"
-      "EXPR evaluates mathematical expression and return result in the "
+      "EXPR evaluates mathematical expression and returns result in the "
       "output variable. Example mathematical expression is "
       "'5 * ( 10 + 13 )'.  Supported operators are "
       "+ - * / % | & ^ ~ << >> * / %.  They have the same meaning "
-      " as they do in c code.";
+      " as they do in C code.";
     }
 
   cmTypeMacro(cmMathCommand, cmCommand);
index 9f01eaf..fc61810 100644 (file)
@@ -67,8 +67,9 @@ public:
       "  STATUS         = Incidental information\n"
       "  WARNING        = CMake Warning, continue processing\n"
       "  AUTHOR_WARNING = CMake Warning (dev), continue processing\n"
-      "  SEND_ERROR     = CMake Error, continue but skip generation\n"
-      "  FATAL_ERROR    = CMake Error, stop all processing\n"
+      "  SEND_ERROR     = CMake Error, continue processing,\n"
+      "                                but skip generation\n"
+      "  FATAL_ERROR    = CMake Error, stop processing and generation\n"
       "The CMake command-line tool displays STATUS messages on stdout "
       "and all other message types on stderr.  "
       "The CMake GUI displays all messages in its log area.  "
index 6c54ced..7e48cd7 100644 (file)
@@ -190,7 +190,7 @@ cmNinjaNormalTargetGenerator
         linkOptionVar += cmTarget::GetTargetTypeName(targetType);
         const std::string linkOption =
                 GetMakefile()->GetSafeDefinition(linkOptionVar.c_str());
-        rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES";
+        rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
         vars.Objects = responseFlag.c_str();
         vars.LinkLibraries = "";
     }
@@ -439,6 +439,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                                             this->GetGeneratorTarget());
 
   this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
+  vars["LINK_FLAGS"] = cmGlobalNinjaGenerator
+                        ::EncodeLiteral(vars["LINK_FLAGS"]);
+
   vars["LINK_PATH"] = frameworkPath + linkPath;
 
   // Compute architecture specific link flags.  Yes, these go into a different
@@ -564,6 +567,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
     commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000;
 #else
+    (void)linkRuleLength;
     commandLineLengthLimit = -1;
 #endif
   }
index 0f10152..3fb823c 100644 (file)
@@ -147,7 +147,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
 
   // Add shared-library flags if needed.
   this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
-                                        language.c_str());
+                                        language.c_str(),
+                                        this->GetConfigName());
 
   // Add include directory flags.
   {
@@ -227,7 +228,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
   // Add preprocessor definitions for this target and configuration.
   this->LocalGenerator->AppendDefines
     (defines,
-     this->GeneratorTarget->GetCompileDefinitions());
+     this->Target->GetCompileDefinitions(this->GetConfigName()));
   this->LocalGenerator->AppendDefines
     (defines,
      source->GetProperty("COMPILE_DEFINITIONS"));
@@ -236,9 +237,6 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
   defPropName += cmSystemTools::UpperCase(this->GetConfigName());
   this->LocalGenerator->AppendDefines
     (defines,
-     this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName()));
-  this->LocalGenerator->AppendDefines
-    (defines,
      source->GetProperty(defPropName.c_str()));
   }
 
@@ -257,7 +255,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
     return cmNinjaDeps();
 
   cmComputeLinkInformation* cli =
-    this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
+    this->Target->GetLinkInformation(this->GetConfigName());
   if(!cli)
     return cmNinjaDeps();
 
@@ -423,17 +421,19 @@ cmNinjaTargetGenerator
   std::vector<std::string> compileCmds;
   cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
 
+  if(useClDeps)
+    {
+    std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " +
+                            clShowPrefix + clBinary;
+    compileCmds.front().insert(0, cmdPrefix);
+    }
+
   for (std::vector<std::string>::iterator i = compileCmds.begin();
        i != compileCmds.end(); ++i)
     this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
 
-  std::string cmdLine;
-  if(useClDeps)
-    {
-    cmdLine = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " +
-              clShowPrefix + clBinary;
-    }
-  cmdLine += this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+  std::string cmdLine =
+    this->GetLocalGenerator()->BuildCommandLine(compileCmds);
 
 
   // Write the rule for compiling file of the given language.
@@ -549,7 +549,7 @@ cmNinjaTargetGenerator
     cmCustomCommand const* cc = (*si)->GetCustomCommand();
     const std::vector<std::string>& ccoutputs = cc->GetOutputs();
     std::transform(ccoutputs.begin(), ccoutputs.end(),
-                   std::back_inserter(implicitDeps), MapToNinjaPath());
+                   std::back_inserter(orderOnlyDeps), MapToNinjaPath());
     }
 
   // If the source file is GENERATED and does not have a custom command
index 79af4d7..831e92e 100644 (file)
@@ -457,7 +457,7 @@ cmPolicies::cmPolicies()
     "This makes sure that the modules belonging to "
     "CMake always get those files included which they expect, and against "
     "which they were developed and tested.  "
-    "In call other cases, the files found in "
+    "In all other cases, the files found in "
     "CMAKE_MODULE_PATH still take precedence over the ones in "
     "the CMake module directory.  "
     "The OLD behaviour is to always prefer files from CMAKE_MODULE_PATH over "
@@ -491,6 +491,44 @@ cmPolicies::cmPolicies()
     "CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
     "honor the POSITION_INDEPENDENT_CODE target property.",
     2,8,9,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0019, "CMP0019",
+    "Do not re-expand variables in include and link information.",
+    "CMake 2.8.10 and lower re-evaluated values given to the "
+    "include_directories, link_directories, and link_libraries "
+    "commands to expand any leftover variable references at the "
+    "end of the configuration step.  "
+    "This was for strict compatibility with VERY early CMake versions "
+    "because all variable references are now normally evaluated during "
+    "CMake language processing.  "
+    "CMake 2.8.11 and higher prefer to skip the extra evaluation."
+    "\n"
+    "The OLD behavior for this policy is to re-evaluate the values "
+    "for strict compatibility.  "
+    "The NEW behavior for this policy is to leave the values untouched.",
+    2,8,11,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0020, "CMP0020",
+    "Automatically link Qt executables to qtmain target on Windows.",
+    "CMake 2.8.10 and lower required users of Qt to always specify a link "
+    "dependency to the qtmain.lib static library manually on Windows.  CMake "
+    "2.8.11 gained the ability to evaluate generator expressions while "
+    "determining the link dependencies from IMPORTED targets.  This allows "
+    "CMake itself to automatically link executables which link to Qt to the "
+    "qtmain.lib library when using IMPORTED Qt targets.  For applications "
+    "already linking to qtmain.lib, this should have little impact.  For "
+    "applications which supply their own alternative WinMain implementation "
+    "and for applications which use the QAxServer library, this automatic "
+    "linking will need to be disabled as per the documentation."
+    "\n"
+    "The OLD behavior for this policy is not to link executables to "
+    "qtmain.lib automatically when they link to the QtCore IMPORTED"
+    "target.  "
+    "The NEW behavior for this policy is to link executables to "
+    "qtmain.lib automatically when they link to QtCore IMPORTED target.",
+    2,8,11,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()
index 6932565..c11af07 100644 (file)
@@ -68,6 +68,8 @@ public:
     CMP0018, ///< Ignore language flags for shared libs, and adhere to
     /// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
     /// instead.
+    CMP0019, ///< No variable re-expansion in include and link info
+    CMP0020, ///< Automatically link Qt executables to qtmain target
 
     /** \brief Always the last entry.
      *
index 25614b8..a1fa31f 100644 (file)
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
 
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include "cmLocalVisualStudioGenerator.h"
+#endif
+
 #include <cmsys/Terminal.h>
 #include <cmsys/ios/sstream>
 
@@ -44,14 +48,14 @@ static bool containsQ_OBJECT(const std::string& text)
 static std::string findMatchingHeader(const std::string& absPath,
                                       const std::string& mocSubDir,
                                       const std::string& basename,
-                                const std::list<std::string>& headerExtensions)
+                              const std::vector<std::string>& headerExtensions)
 {
   std::string header;
-  for(std::list<std::string>::const_iterator ext = headerExtensions.begin();
+  for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
       ext != headerExtensions.end();
       ++ext)
     {
-    std::string sourceFilePath = absPath + basename + (*ext);
+    std::string sourceFilePath = absPath + basename + "." + (*ext);
     if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
       {
       header = sourceFilePath;
@@ -59,7 +63,7 @@ static std::string findMatchingHeader(const std::string& absPath,
       }
     if (!mocSubDir.empty())
       {
-      sourceFilePath = mocSubDir + basename + (*ext);
+      sourceFilePath = mocSubDir + basename + "." + (*ext);
       if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
         {
         header = sourceFilePath;
@@ -85,6 +89,18 @@ static std::string extractSubDir(const std::string& absPath,
 }
 
 
+static void copyTargetProperty(cmTarget* destinationTarget,
+                               cmTarget* sourceTarget,
+                               const char* propertyName)
+{
+  const char* propertyValue = sourceTarget->GetProperty(propertyName);
+  if (propertyValue)
+    {
+    destinationTarget->SetProperty(propertyName, propertyValue);
+    }
+}
+
+
 cmQtAutomoc::cmQtAutomoc()
 :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
 ,ColorOutput(true)
@@ -107,12 +123,9 @@ cmQtAutomoc::cmQtAutomoc()
     }
 }
 
-
-void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
+bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target)
 {
   cmMakefile* makefile = target->GetMakefile();
-  cmLocalGenerator* localGen = makefile->GetLocalGenerator();
-  const char* targetName = target->GetName();
   // don't do anything if there is no Qt4 or Qt5Core (which contains moc):
   std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
   if (qtMajorVersion == "")
@@ -121,9 +134,30 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
     }
   if (qtMajorVersion != "4" && qtMajorVersion != "5")
     {
-    return;
+    return false;
     }
 
+  std::string automocTargetName = target->GetName();
+  automocTargetName += "_automoc";
+  std::string mocCppFile = makefile->GetCurrentOutputDirectory();
+  mocCppFile += "/";
+  mocCppFile += automocTargetName;
+  mocCppFile += ".cpp";
+  cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(),
+                                                         true);
+  makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+                           mocCppFile.c_str(), false);
+
+  target->AddSourceFile(mocCppSource);
+  return true;
+}
+
+void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
+{
+  cmMakefile* makefile = target->GetMakefile();
+  cmLocalGenerator* localGen = makefile->GetLocalGenerator();
+  const char* targetName = target->GetName();
+
   bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
 
   // create a custom target for running automoc at buildtime:
@@ -152,10 +186,44 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
   std::string automocComment = "Automoc for target ";
   automocComment += targetName;
 
-  makefile->AddUtilityCommand(automocTargetName.c_str(), true,
-                              workingDirectory.c_str(), depends,
-                              commandLines, false, automocComment.c_str());
-  target->AddUtility(automocTargetName.c_str());
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  bool usePRE_BUILD = false;
+  cmGlobalGenerator* gg = localGen->GetGlobalGenerator();
+  if(strstr(gg->GetName(), "Visual Studio"))
+    {
+    cmLocalVisualStudioGenerator* vslg =
+      static_cast<cmLocalVisualStudioGenerator*>(localGen);
+    // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
+    // reduce the number of targets loaded into the IDE.
+    // This also works around a VS 11 bug that may skip updating the target:
+    //  https://connect.microsoft.com/VisualStudio/feedback/details/769495
+    usePRE_BUILD = vslg->GetVersion() >= cmLocalVisualStudioGenerator::VS7;
+    }
+  if(usePRE_BUILD)
+    {
+    // Add the pre-build command directly to bypass the OBJECT_LIBRARY
+    // rejection in cmMakefile::AddCustomCommandToTarget because we know
+    // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
+    std::vector<std::string> no_output;
+    cmCustomCommand cc(makefile, no_output, depends,
+                       commandLines, automocComment.c_str(),
+                       workingDirectory.c_str());
+    cc.SetEscapeOldStyle(false);
+    cc.SetEscapeAllowMakeVars(true);
+    target->GetPreBuildCommands().push_back(cc);
+    }
+  else
+#endif
+    {
+    cmTarget* automocTarget = makefile->AddUtilityCommand(
+                                automocTargetName.c_str(), true,
+                                workingDirectory.c_str(), depends,
+                                commandLines, false, automocComment.c_str());
+    // inherit FOLDER property from target (#13688)
+    copyTargetProperty(automocTarget, target, "FOLDER");
+
+    target->AddUtility(automocTargetName.c_str());
+    }
 
   // configure a file to get all information to automoc at buildtime:
   std::string _moc_files;
@@ -196,36 +264,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
     }
 
 
-  const char* qtIncDir = 0;
-  const char* qtCoreIncDir = 0;
-
-  // check whether ${QT_INCLUDE_DIR} is part of the implicit include dirs,
-  // see http://public.kitware.com/Bug/view.php?id=13667
-  bool qtIncludeDirMayHaveBeenRemoved = false;
-  if (makefile->IsSet("QT_INCLUDE_DIR"))
-    {
-    qtIncDir = makefile->GetDefinition("QT_INCLUDE_DIR");
-    std::string s =
-         makefile->GetSafeDefinition("CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES");
-    std::vector<std::string> implIncDirs;
-    cmSystemTools::ExpandListArgument(s, implIncDirs);
-    if (std::find(implIncDirs.begin(), implIncDirs.end(),std::string(qtIncDir))
-                                                          != implIncDirs.end())
-      {
-      qtIncludeDirMayHaveBeenRemoved = true;
-      if (makefile->IsSet("QT_QTCORE_INCLUDE_DIR"))
-        {
-        qtCoreIncDir = makefile->GetDefinition("QT_QTCORE_INCLUDE_DIR");
-        }
-      }
-    }
-
-  bool haveQtCoreIncDir = false;
-  bool haveQtIncDir = false;
-
   std::vector<std::string> includeDirs;
   cmGeneratorTarget gtgt(target);
-  localGen->GetIncludeDirectories(includeDirs, &gtgt, "CXX");
+  // Get the include dirs for this target, without stripping the implicit
+  // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
+  localGen->GetIncludeDirectories(includeDirs, &gtgt, "CXX", 0, false);
   std::string _moc_incs = "";
   const char* sep = "";
   for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin();
@@ -235,41 +278,14 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
     _moc_incs += sep;
     sep = ";";
     _moc_incs += *incDirIt;
-
-    if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir) // #13667
-      {
-      if (*incDirIt == qtIncDir)
-        {
-        haveQtIncDir = true;
-        qtIncludeDirMayHaveBeenRemoved = false; // it's here, i.e. not removed
-        }
-      if (*incDirIt == qtCoreIncDir)
-        {
-        haveQtCoreIncDir = true;
-        }
-      }
     }
 
-  // Some projects (kdelibs, phonon) query the compiler for its default
-  // include search dirs, and add those to
-  // CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES.
-  // These may include e.g./usr/lib/qt/include . This is typically also part
-  // of ${QT_INCLUDES}. If this directory is then contained in the implicit
-  // include dirs, it is removed from the include dirs returned from the
-  // target above. So we add ${QT_INCLUDE_DIR} manually for moc if we detected
-  // that ${QT_QTCORE_INCLUDE_DIR} is among the include dirs (there shouldn't
-  // be a way to use Qt4 without using ${QT_QTCORE_INCLUDE_DIR} I think.
-  // See #13646 and #13667.
-  if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir
-      && (haveQtCoreIncDir == true) && (haveQtIncDir == false))
+  const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
+  std::string _moc_compile_defs;
+  if (tmp)
     {
-    _moc_incs += sep;
-    sep = ";";
-    _moc_incs += qtIncDir;
+    _moc_compile_defs = target->GetCompileDefinitions(0);
     }
-
-  const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
-  std::string _moc_compile_defs = (tmp!=0 ? tmp : "");
   tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
   if (tmp)
     {
@@ -304,17 +320,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
   outputFile += "/AutomocInfo.cmake";
   makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
                           false, true, false);
-
-  std::string mocCppFile =  makefile->GetCurrentOutputDirectory();
-  mocCppFile += "/";
-  mocCppFile += automocTargetName;
-  mocCppFile += ".cpp";
-  cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(),
-                                                         true);
-  target->AddSourceFile(mocCppSource);
-
-  makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
-                           mocCppFile.c_str(), false);
 }
 
 
@@ -332,7 +337,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory)
 
   if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
     {
-    success = this->RunAutomoc();
+    success = this->RunAutomoc(makefile);
     }
 
   this->WriteOldMocDefinitionsFile(targetDirectory);
@@ -540,7 +545,7 @@ void cmQtAutomoc::Init()
 }
 
 
-bool cmQtAutomoc::RunAutomoc()
+bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile)
 {
   if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str())
     || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr))
@@ -564,22 +569,8 @@ bool cmQtAutomoc::RunAutomoc()
   std::vector<std::string> sourceFiles;
   cmSystemTools::ExpandListArgument(this->Sources, sourceFiles);
 
-  std::list<std::string> headerExtensions;
-  headerExtensions.push_back(".h");
-  headerExtensions.push_back(".hpp");
-  headerExtensions.push_back(".hxx");
-#if defined(_WIN32)
-  // not case sensitive, don't add ".H"
-#elif defined(__APPLE__)
-  // detect case-sensitive filesystem
-  long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE);
-  if (caseSensitive == 1)
-  {
-    headerExtensions.push_back(".H");
-  }
-#else
-  headerExtensions.push_back(".H");
-#endif
+  const std::vector<std::string>& headerExtensions =
+                                               makefile->GetHeaderExtensions();
 
   for (std::vector<std::string>::const_iterator it = sourceFiles.begin();
        it != sourceFiles.end();
@@ -679,7 +670,7 @@ bool cmQtAutomoc::RunAutomoc()
 
 
 void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
-                              const std::list<std::string>& headerExtensions,
+                              const std::vector<std::string>& headerExtensions,
                               std::map<std::string, std::string>& includedMocs)
 {
   cmsys::RegularExpression mocIncludeRegExp(
@@ -857,7 +848,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
 
 
 void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename,
-                              const std::list<std::string>& headerExtensions,
+                              const std::vector<std::string>& headerExtensions,
                               std::map<std::string, std::string>& includedMocs)
 {
   cmsys::RegularExpression mocIncludeRegExp(
@@ -968,8 +959,8 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename,
 
 
 void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename,
-                                const std::list<std::string>& headerExtensions,
-                                std::set<std::string>& absHeaders)
+                              const std::vector<std::string>& headerExtensions,
+                              std::set<std::string>& absHeaders)
 {
   // search for header files and private header files we may need to moc:
   const std::string basename =
@@ -977,22 +968,22 @@ void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename,
   const std::string absPath = cmsys::SystemTools::GetFilenamePath(
                    cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
 
-  for(std::list<std::string>::const_iterator ext = headerExtensions.begin();
+  for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
       ext != headerExtensions.end();
       ++ext)
     {
-    const std::string headerName = absPath + basename + (*ext);
+    const std::string headerName = absPath + basename + "." + (*ext);
     if (cmsys::SystemTools::FileExists(headerName.c_str()))
       {
       absHeaders.insert(headerName);
       break;
       }
     }
-  for(std::list<std::string>::const_iterator ext = headerExtensions.begin();
+  for(std::vector<std::string>::const_iterator ext = headerExtensions.begin();
       ext != headerExtensions.end();
       ++ext)
     {
-    const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
+    const std::string privateHeaderName = absPath+basename+"_p."+(*ext);
     if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()))
       {
       absHeaders.insert(privateHeaderName);
@@ -1113,7 +1104,8 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
 }
 
 
-std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator)
+std::string cmQtAutomoc::Join(const std::vector<std::string>& lst,
+                              char separator)
 {
     if (lst.empty())
       {
@@ -1121,11 +1113,11 @@ std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator)
       }
 
     std::string result;
-    for (std::list<std::string>::const_iterator it = lst.begin();
+    for (std::vector<std::string>::const_iterator it = lst.begin();
          it != lst.end();
          ++it)
       {
-      result += (*it) + separator;
+      result += "." + (*it) + separator;
       }
     result.erase(result.end() - 1);
     return result;
index a737477..01b68fc 100644 (file)
@@ -23,6 +23,7 @@ public:
   cmQtAutomoc();
   bool Run(const char* targetDirectory);
 
+  bool InitializeMocSourceFile(cmTarget* target);
   void SetupAutomocTarget(cmTarget* target);
 
 private:
@@ -37,18 +38,18 @@ private:
 
   std::string MakeCompileSettingsString(cmMakefile* makefile);
 
-  bool RunAutomoc();
+  bool RunAutomoc(cmMakefile* makefile);
   bool GenerateMoc(const std::string& sourceFile,
                    const std::string& mocFileName);
   void ParseCppFile(const std::string& absFilename,
-                    const std::list<std::string>& headerExtensions,
+                    const std::vector<std::string>& headerExtensions,
                     std::map<std::string, std::string>& includedMocs);
   void StrictParseCppFile(const std::string& absFilename,
-                          const std::list<std::string>& headerExtensions,
+                          const std::vector<std::string>& headerExtensions,
                           std::map<std::string, std::string>& includedMocs);
   void SearchHeadersForCppFile(const std::string& absFilename,
-                               const std::list<std::string>& headerExtensions,
-                               std::set<std::string>& absHeaders);
+                              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,
@@ -56,7 +57,7 @@ private:
 
   void Init();
 
-  std::string Join(const std::list<std::string>& lst, char separator);
+  std::string Join(const std::vector<std::string>& lst, char separator);
   bool EndsWith(const std::string& str, const std::string& with);
   bool StartsWith(const std::string& str, const std::string& with);
   std::string ReadAll(const std::string& filename);
index 65c89fa..9dd7848 100644 (file)
@@ -156,7 +156,9 @@ public:
         "\n"
         "The EXCLUDE_FROM_DEFAULT_BUILD property is used by the visual "
         "studio generators.  If it is set to 1 the target will not be "
-        "part of the default build when you select \"Build Solution\"."
+        "part of the default build when you select \"Build Solution\". "
+        "This can also be set on a per-configuration basis using "
+        "EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>."
         ;
     }
 
index cc3b6d6..1d4b0c8 100644 (file)
@@ -458,7 +458,7 @@ void cmSourceFile::DefineProperties(cmake *cm)
      "A property on a source file that indicates if the source file "
      "is a header file with no associated implementation. This is "
      "set automatically based on the file extension and is used by "
-     "CMake to determine is certain dependency information should be "
+     "CMake to determine if certain dependency information should be "
      "computed.");
 
   cm->DefineProperty
index 4fd9851..f09976f 100644 (file)
@@ -182,10 +182,6 @@ cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name)
   std::vector<cmSourceGroup>::iterator end =
     this->Internal->GroupChildren.end();
 
-  if(this->MatchesRegex(name))
-    {
-    return this;
-    }
   for(;iter!=end; ++iter)
     {
     cmSourceGroup *result = iter->MatchChildrenRegex(name);
@@ -194,6 +190,11 @@ cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name)
       return result;
       }
     }
+  if(this->MatchesRegex(name))
+    {
+    return this;
+    }
+
   return 0;
 }
 
index 6c87b71..9f6b7e4 100644 (file)
@@ -68,7 +68,7 @@ public:
       "expression matches the file will be favored.\n"
       "The name of the group may contain backslashes to specify subgroups:\n"
       "  source_group(outer\\\\inner ...)\n"
-      "For backwards compatibility, this command is also supports the "
+      "For backwards compatibility, this command also supports the "
       "format:\n"
       "  source_group(name regex)";
     }
index 0193dc9..e49edd8 100644 (file)
@@ -19,6 +19,8 @@
 #include <ctype.h>
 #include <time.h>
 
+#include <cmTimestamp.h>
+
 //----------------------------------------------------------------------------
 bool cmStringCommand
 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -87,6 +89,10 @@ bool cmStringCommand
     {
     return this->HandleFindCommand(args);
     }
+  else if(subCommand == "TIMESTAMP")
+    {
+    return this->HandleTimestampCommand(args);
+    }
 
   std::string e = "does not recognize sub-command "+subCommand;
   this->SetError(e.c_str());
@@ -879,3 +885,51 @@ bool cmStringCommand
   this->Makefile->AddDefinition(variableName.c_str(), &*result.begin());
   return true;
 }
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleTimestampCommand(std::vector<std::string> const& args)
+{
+  if(args.size() < 2)
+    {
+    this->SetError("sub-command TIMESTAMP requires at least one argument.");
+    return false;
+    }
+  else if(args.size() > 4)
+    {
+    this->SetError("sub-command TIMESTAMP takes at most three arguments.");
+    return false;
+    }
+
+  unsigned int argsIndex = 1;
+
+  const std::string &outputVariable = args[argsIndex++];
+
+  std::string formatString;
+  if(args.size() > argsIndex && args[argsIndex] != "UTC")
+    {
+    formatString = args[argsIndex++];
+    }
+
+  bool utcFlag = false;
+  if(args.size() > argsIndex)
+    {
+    if(args[argsIndex] == "UTC")
+      {
+      utcFlag = true;
+      }
+    else
+      {
+      std::string e = " TIMESTAMP sub-command does not recognize option " +
+          args[argsIndex] + ".";
+      this->SetError(e.c_str());
+      return false;
+      }
+    }
+
+  cmTimestamp timestamp;
+  std::string result = timestamp.CurrentTime(formatString, utcFlag);
+  this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
+
+  return true;
+}
index 728b1bc..802e0b8 100644 (file)
@@ -93,6 +93,7 @@ public:
       "  string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n"
       "         [RANDOM_SEED <seed>] <output variable>)\n"
       "  string(FIND <string> <substring> <output variable> [REVERSE])\n"
+      "  string(TIMESTAMP <output variable> [<format string>] [UTC])\n"
       "REGEX MATCH will match the regular expression once and store the "
       "match in the output variable.\n"
       "REGEX MATCHALL will match the regular expression as many times as "
@@ -128,13 +129,16 @@ public:
       "will search for the position of the last occurrence of the "
       "specified substring.\n"
       "The following characters have special meaning in regular expressions:\n"
-      "   ^         Matches at beginning of a line\n"
-      "   $         Matches at end of a line\n"
+      "   ^         Matches at beginning of input\n"
+      "   $         Matches at end of input\n"
       "   .         Matches any single character\n"
       "   [ ]       Matches any character(s) inside the brackets\n"
       "   [^ ]      Matches any character(s) not inside the brackets\n"
       "    -        Inside brackets, specifies an inclusive range between\n"
       "             characters on either side e.g. [a-f] is [abcdef]\n"
+      "             To match a literal - using brackets, make it the first\n"
+      "             or the last character e.g. [+*/-] matches basic\n"
+      "             mathematical operators.\n"
       "   *         Matches preceding pattern zero or more times\n"
       "   +         Matches preceding pattern one or more times\n"
       "   ?         Matches preceding pattern zero or once only\n"
@@ -142,7 +146,37 @@ public:
       "   ()        Saves a matched subexpression, which can be referenced \n"
       "             in the REGEX REPLACE operation. Additionally it is saved\n"
       "             by all regular expression-related commands, including \n"
-      "             e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).";
+      "             e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n"
+      "*, + and ? have higher precedence than concatenation. | has lower "
+      "precedence than concatenation. This means that the regular expression "
+      "\"^ab+d$\" matches \"abbd\" but not \"ababd\", and the regular "
+      "expression \"^(ab|cd)$\" matches \"ab\" but not \"abd\".\n"
+      "TIMESTAMP will write a string representation of "
+      "the current date and/or time to the output variable.\n"
+      "Should the command be unable to obtain a timestamp "
+      "the output variable will be set to the empty string \"\".\n"
+      "The optional UTC flag requests the current date/time "
+      "representation to be in Coordinated Universal Time (UTC) "
+      "rather than local time.\n"
+      "The optional <format string> may contain the following "
+      "format specifiers: \n"
+      "   %d        The day of the current month (01-31).\n"
+      "   %H        The hour on a 24-hour clock (00-23).\n"
+      "   %I        The hour on a 12-hour clock (01-12).\n"
+      "   %j        The day of the current year (001-366).\n"
+      "   %m        The month of the current year (01-12).\n"
+      "   %M        The minute of the current hour (00-59).\n"
+      "   %S        The second of the current minute.\n"
+      "             60 represents a leap second. (00-60)\n"
+      "   %U        The week number of the current year (00-53).\n"
+      "   %w        The day of the current week. 0 is Sunday. (0-6)\n"
+      "   %y        The last two digits of the current year (00-99)\n"
+      "   %Y        The current year. \n"
+      "Unknown format specifiers will be ignored "
+      "and copied to the output as-is.\n"
+      "If no explicit <format string> is given it will default to:\n"
+      "   %Y-%m-%dT%H:%M:%S    for local time.\n"
+      "   %Y-%m-%dT%H:%M:%SZ   for UTC.";
     }
 
   cmTypeMacro(cmStringCommand, cmCommand);
@@ -165,6 +199,7 @@ protected:
   bool HandleStripCommand(std::vector<std::string> const& args);
   bool HandleRandomCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
+  bool HandleTimestampCommand(std::vector<std::string> const& args);
 
   class RegexReplacement
   {
index 544f7e4..67f3023 100644 (file)
@@ -52,7 +52,6 @@
 #endif
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-#  include <memory> // auto_ptr
 #  include <fcntl.h>
 #  include "cmCryptoHash.h"
 #endif
@@ -204,13 +203,13 @@ std::string cmSystemTools::EscapeQuotes(const char* str)
 std::string cmSystemTools::TrimWhitespace(const std::string& s)
 {
   std::string::const_iterator start = s.begin();
-  while(start != s.end() && *start == ' ')
+  while(start != s.end() && *start <= ' ')
     ++start;
   if (start == s.end())
     return "";
 
   std::string::const_iterator stop = s.end()-1;
-  while(*stop == ' ')
+  while(*stop <= ' ')
     --stop;
   return std::string(start, stop+1);
 }
@@ -1181,46 +1180,35 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
 bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
 {
 #ifdef _WIN32
-  /* On Windows the move functions will not replace existing files.
-     Check if the destination exists.  */
-  struct stat newFile;
-  if(stat(newname, &newFile) == 0)
+# ifndef INVALID_FILE_ATTRIBUTES
+#  define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# endif
+  /* Windows MoveFileEx may not replace read-only or in-use files.  If it
+     fails then remove the read-only attribute from any existing destination.
+     Try multiple times since we may be racing against another process
+     creating/opening the destination file just before our MoveFileEx.  */
+  int tries = 5;
+  while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
     {
-    /* The destination exists.  We have to replace it carefully.  The
-       MoveFileEx function does what we need but is not available on
-       Win9x.  */
-    OSVERSIONINFO osv;
-    DWORD attrs;
-
-    /* Make sure the destination is not read only.  */
-    attrs = GetFileAttributes(newname);
-    if(attrs & FILE_ATTRIBUTE_READONLY)
+    // Try again only if failure was due to access permissions.
+    if(GetLastError() != ERROR_ACCESS_DENIED)
       {
-      SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
+      return false;
       }
-
-    /* Check the windows version number.  */
-    osv.dwOSVersionInfoSize = sizeof(osv);
-    GetVersionEx(&osv);
-    if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+    DWORD attrs = GetFileAttributes(newname);
+    if((attrs != INVALID_FILE_ATTRIBUTES) &&
+       (attrs & FILE_ATTRIBUTE_READONLY))
       {
-      /* This is Win9x.  There is no MoveFileEx implementation.  We
-         cannot quite rename the file atomically.  Just delete the
-         destination and then move the file.  */
-      DeleteFile(newname);
-      return MoveFile(oldname, newname) != 0;
+      // Remove the read-only attribute from the destination file.
+      SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
       }
     else
       {
-      /* This is not Win9x.  Use the MoveFileEx implementation.  */
-      return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
+      // The file may be temporarily in use so wait a bit.
+      cmSystemTools::Delay(100);
       }
     }
-  else
-    {
-    /* The destination does not exist.  Just move the file.  */
-    return MoveFile(oldname, newname) != 0;
-    }
+  return tries > 0;
 #else
   /* On UNIX we have an OS-provided call to do this atomically.  */
   return rename(oldname, newname) == 0;
index f3eb52b..d14bfca 100644 (file)
 #include "cmSourceFile.h"
 #include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
+#include "cmComputeLinkInformation.h"
 #include "cmDocumentCompileDefinitions.h"
 #include "cmDocumentGeneratorExpressions.h"
 #include "cmDocumentLocationUndefined.h"
 #include "cmListFileCache.h"
 #include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionDAGChecker.h"
 #include <cmsys/RegularExpression.hxx>
 #include <map>
 #include <set>
@@ -70,6 +72,11 @@ struct cmTarget::ImportInfo
   cmTarget::LinkInterface LinkInterface;
 };
 
+struct TargetConfigPair : public std::pair<cmTarget*, std::string> {
+  TargetConfigPair(cmTarget* tgt, const std::string &config)
+    : std::pair<cmTarget*, std::string>(tgt, config) {}
+};
+
 //----------------------------------------------------------------------------
 class cmTargetInternals
 {
@@ -85,6 +92,7 @@ public:
     // Others not copied here are result caches.
     this->SourceEntries = r.SourceEntries;
     }
+  ~cmTargetInternals();
   typedef cmTarget::SourceFileFlags SourceFileFlags;
   std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
   bool SourceFileFlagsConstructed;
@@ -98,39 +106,98 @@ public:
     OptionalLinkInterface(): Exists(false) {}
     bool Exists;
   };
-  typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
+  typedef std::map<TargetConfigPair, OptionalLinkInterface>
+                                                          LinkInterfaceMapType;
   LinkInterfaceMapType LinkInterfaceMap;
 
   typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
 
-  typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
+  typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
+                                                            ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
   // Cache link implementation computation from each configuration.
-  typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
+  typedef std::map<TargetConfigPair,
+                   cmTarget::LinkImplementation> LinkImplMapType;
   LinkImplMapType LinkImplMap;
 
-  typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
+  typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
+                                                          LinkClosureMapType;
   LinkClosureMapType LinkClosureMap;
 
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
   typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
   SourceEntriesType SourceEntries;
+
+  struct IncludeDirectoriesEntry {
+    IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+      const std::string &targetName = std::string())
+      : ge(cge), TargetName(targetName)
+    {}
+    const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+    std::vector<std::string> CachedIncludes;
+    const std::string TargetName;
+  };
+  std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
+  std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries;
+
+  std::map<std::string, std::vector<IncludeDirectoriesEntry*> >
+                                CachedLinkInterfaceIncludeDirectoriesEntries;
+  std::map<std::string, std::string> CachedLinkInterfaceCompileDefinitions;
+
+  std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
+  std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
 };
 
 //----------------------------------------------------------------------------
+void deleteAndClear(
+      std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries)
+{
+  for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
+      it = entries.begin(),
+      end = entries.end();
+      it != end; ++it)
+    {
+      delete *it;
+    }
+  entries.clear();
+}
+
+//----------------------------------------------------------------------------
+void deleteAndClear(
+  std::map<std::string,
+          std::vector<cmTargetInternals::IncludeDirectoriesEntry*> > &entries)
+{
+  for (std::map<std::string,
+          std::vector<cmTargetInternals::IncludeDirectoriesEntry*> >::iterator
+        it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    deleteAndClear(it->second);
+    }
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternals::~cmTargetInternals()
+{
+  deleteAndClear(CachedLinkInterfaceIncludeDirectoriesEntries);
+}
+
+//----------------------------------------------------------------------------
 cmTarget::cmTarget()
 {
   this->Makefile = 0;
   this->PolicyStatusCMP0003 = cmPolicies::WARN;
   this->PolicyStatusCMP0004 = cmPolicies::WARN;
   this->PolicyStatusCMP0008 = cmPolicies::WARN;
+  this->PolicyStatusCMP0020 = cmPolicies::WARN;
   this->LinkLibrariesAnalyzed = false;
   this->HaveInstallRule = false;
   this->DLLPlatform = false;
   this->IsApple = false;
   this->IsImportedTarget = false;
+  this->BuildInterfaceIncludesAppended = false;
+  this->DebugIncludesDone = false;
 }
 
 //----------------------------------------------------------------------------
@@ -141,7 +208,8 @@ void cmTarget::DefineProperties(cmake *cm)
      "Should the target be processed with automoc (for Qt projects).",
      "AUTOMOC is a boolean specifying whether CMake will handle "
      "the Qt moc preprocessor automatically, i.e. without having to use "
-     "the QT4_WRAP_CPP() macro. Currently Qt4 is supported. "
+     "the QT4_WRAP_CPP() or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are "
+     "supported.  "
      "When this property is set to TRUE, CMake will scan the source files "
      "at build time and invoke moc accordingly. "
      "If an #include statement like #include \"moc_foo.cpp\" is found, "
@@ -266,6 +334,21 @@ void cmTarget::DefineProperties(cmake *cm)
      "bundle.");
 
   cm->DefineProperty
+    ("EXCLUDE_FROM_DEFAULT_BUILD", cmProperty::TARGET,
+     "Exclude target from \"Build Solution\".",
+     "This property is only used by Visual Studio generators 7 and above. "
+     "When set to TRUE, the target will not be built when you press "
+     "\"Build Solution\".");
+
+  cm->DefineProperty
+    ("EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>", cmProperty::TARGET,
+     "Per-configuration version of target exclusion from \"Build Solution\". ",
+     "This is the configuration-specific version of "
+     "EXCLUDE_FROM_DEFAULT_BUILD. If the generic EXCLUDE_FROM_DEFAULT_BUILD "
+     "is also set on a target, EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> takes "
+     "precedence in configurations for which it has a value.");
+
+  cm->DefineProperty
     ("FRAMEWORK", cmProperty::TARGET,
      "This target is a framework on the Mac.",
      "If a shared library target has this property set to true it will "
@@ -486,6 +569,22 @@ void cmTarget::DefineProperties(cmake *cm)
      "undefined behavior.");
 
   cm->DefineProperty
+    ("LINK_LIBRARIES", cmProperty::TARGET,
+     "List of direct link dependencies.",
+     "This property specifies the list of libraries or targets which will be "
+     "used for linking. "
+     "In addition to accepting values from the target_link_libraries "
+     "command, values may be set directly on any target using the "
+     "set_property command. "
+     "\n"
+     "The target property values are used by the generators to set "
+     "the link libraries for the compiler.  "
+     "See also the target_link_libraries command.\n"
+     "Contents of LINK_LIBRARIES may use \"generator expressions\" with "
+     "the syntax \"$<...>\".  "
+     CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+  cm->DefineProperty
     ("INCLUDE_DIRECTORIES", cmProperty::TARGET,
      "List of preprocessor include file search directories.",
      "This property specifies the list of directories given "
@@ -651,6 +750,22 @@ void cmTarget::DefineProperties(cmake *cm)
      "custom Makefile link rules.");
 
   cm->DefineProperty
+    ("LINK_DEPENDS_NO_SHARED", cmProperty::TARGET,
+     "Do not depend on linked shared library files.",
+     "Set this property to true to tell CMake generators not to add "
+     "file-level dependencies on the shared library files linked by "
+     "this target.  "
+     "Modification to the shared libraries will not be sufficient to "
+     "re-link this target.  "
+     "Logical target-level dependencies will not be affected so the "
+     "linked shared libraries will still be brought up to date before "
+     "this target is built."
+     "\n"
+     "This property is initialized by the value of the variable "
+     "CMAKE_LINK_DEPENDS_NO_SHARED if it is set when a target is "
+     "created.");
+
+  cm->DefineProperty
     ("LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
      "List public interface libraries for a shared library or executable.",
      "By default linking to a shared library target transitively "
@@ -679,6 +794,28 @@ void cmTarget::DefineProperties(cmake *cm)
      "for the named configuration.");
 
   cm->DefineProperty
+    ("INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET,
+     "List of public include directories for a library.",
+     "Targets may populate this property to publish the include directories "
+     "required to compile against the headers for the target.  Consuming "
+     "targets can add entries to their own INCLUDE_DIRECTORIES property such "
+     "as $<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES> to use the "
+     "include directories specified in the interface of 'foo'."
+     "\n"
+     CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+  cm->DefineProperty
+    ("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET,
+     "List of public compile definitions for a library.",
+     "Targets may populate this property to publish the compile definitions "
+     "required to compile against the headers for the target.  Consuming "
+     "targets can add entries to their own COMPILE_DEFINITIONS property such "
+     "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS> to use the "
+     "compile definitions specified in the interface of 'foo'."
+     "\n"
+     CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+  cm->DefineProperty
     ("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
      "Repetition count for STATIC libraries with cyclic dependencies.",
      "When linking to a STATIC library target with cyclic dependencies the "
@@ -790,6 +927,50 @@ void cmTarget::DefineProperties(cmake *cm)
      "created.");
 
   cm->DefineProperty
+    ("INTERFACE_POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
+     "Whether consumers need to create a position-independent target",
+     "The INTERFACE_POSITION_INDEPENDENT_CODE property informs consumers of "
+     "this target whether they must set their POSITION_INDEPENDENT_CODE "
+     "property to ON.  If this property is set to ON, then the "
+     "POSITION_INDEPENDENT_CODE property on all consumers will be set to "
+     "ON.  Similarly, if this property is set to OFF, then the "
+     "POSITION_INDEPENDENT_CODE property on all consumers will be set to "
+     "OFF.  If this property is undefined, then consumers will determine "
+     "their POSITION_INDEPENDENT_CODE property by other means.  Consumers "
+     "must ensure that the targets that they link to have a consistent "
+     "requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
+
+  cm->DefineProperty
+    ("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
+     "Properties which must be compatible with their link interface",
+     "The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
+     "for this target which must be consistent when evaluated as a boolean "
+     "in the INTERFACE of all linked dependees.  For example, if a "
+     "property \"FOO\" appears in the list, then for each dependee, the "
+     "\"INTERFACE_FOO\" property content in all of its dependencies must be "
+     "consistent with each other, and with the \"FOO\" property in the "
+     "dependee.  Consistency in this sense has the meaning that if the "
+     "property is set, then it must have the same boolean value as all "
+     "others, and if the property is not set, then it is ignored.  Note that "
+     "for each dependee, the set of properties from this property must not "
+     "intersect with the set of properties from the "
+     "COMPATIBLE_INTERFACE_STRING property.");
+
+  cm->DefineProperty
+    ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
+     "Properties which must be string-compatible with their link interface",
+     "The COMPATIBLE_INTERFACE_STRING property may contain a list of "
+     "properties for this target which must be the same when evaluated as "
+     "a string in the INTERFACE of all linked dependees.  For example, "
+     "if a property \"FOO\" appears in the list, then for each dependee, the "
+     "\"INTERFACE_FOO\" property content in all of its dependencies must be "
+     "equal with each other, and with the \"FOO\" property in the dependee.  "
+     "If the property is not set, then it is ignored.  Note that for each "
+     "dependee, the set of properties from this property must not intersect "
+     "with the set of properties from the COMPATIBLE_INTERFACE_BOOL "
+     "property.");
+
+  cm->DefineProperty
     ("POST_INSTALL_SCRIPT", cmProperty::TARGET,
      "Deprecated install support.",
      "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
@@ -1067,7 +1248,9 @@ void cmTarget::DefineProperties(cmake *cm)
     ("GENERATOR_FILE_NAME", cmProperty::TARGET,
      "Generator's file for this target.",
      "An internal property used by some generators to record the name of "
-     "project or dsp file associated with this target.");
+     "project or dsp file associated with this target. Note that at configure "
+     "time, this property is only set for targets created by "
+     "include_external_msproject().");
 
   cm->DefineProperty
     ("SOURCES", cmProperty::TARGET,
@@ -1314,6 +1497,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
   this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
   this->SetPropertyDefault("AUTOMOC", 0);
   this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
+  this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
   this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
   this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
   this->SetPropertyDefault("MACOSX_BUNDLE", 0);
@@ -1359,8 +1543,14 @@ void cmTarget::SetMakefile(cmMakefile* mf)
 
   // Initialize the INCLUDE_DIRECTORIES property based on the current value
   // of the same directory property:
-  this->SetProperty("INCLUDE_DIRECTORIES",
-                    this->Makefile->GetProperty("INCLUDE_DIRECTORIES"));
+  const std::vector<cmValueWithOrigin> parentIncludes =
+                              this->Makefile->GetIncludeDirectoriesEntries();
+
+  for (std::vector<cmValueWithOrigin>::const_iterator it
+              = parentIncludes.begin(); it != parentIncludes.end(); ++it)
+    {
+    this->InsertInclude(*it);
+    }
 
   if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
       || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
@@ -1376,6 +1566,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
   this->PolicyStatusCMP0008 =
     this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
+  this->PolicyStatusCMP0020 =
+    this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
 }
 
 //----------------------------------------------------------------------------
@@ -1397,6 +1589,13 @@ void cmTarget::ClearLinkMaps()
   this->Internal->LinkImplMap.clear();
   this->Internal->LinkInterfaceMap.clear();
   this->Internal->LinkClosureMap.clear();
+  for (cmTargetLinkInformationMap::const_iterator it
+      = this->LinkInformation.begin();
+      it != this->LinkInformation.end(); ++it)
+    {
+    delete it->second;
+    }
+  this->LinkInformation.clear();
 }
 
 //----------------------------------------------------------------------------
@@ -1695,9 +1894,10 @@ cmTargetTraceDependencies
     for(cmCustomCommandLine::const_iterator cli = cit->begin();
         cli != cit->end(); ++cli)
       {
-      const cmCompiledGeneratorExpression &cge = ge.Parse(*cli);
-      cge.Evaluate(this->Makefile, 0, true);
-      std::set<cmTarget*> geTargets = cge.GetTargets();
+      const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+                                                              = ge.Parse(*cli);
+      cge->Evaluate(this->Makefile, 0, true);
+      std::set<cmTarget*> geTargets = cge->GetTargets();
       for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
           it != geTargets.end(); ++it)
         {
@@ -2060,23 +2260,74 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname)
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType)
+void cmTarget::GetDirectLinkLibraries(const char *config,
+                            std::vector<std::string> &libs, cmTarget *head)
 {
-  if(this->NameResolvesToFramework(libname.c_str()))
+  const char *prop = this->GetProperty("LINK_LIBRARIES");
+  if (prop)
+    {
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+    const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                        this->GetName(),
+                                        "LINK_LIBRARIES", 0, 0);
+    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
+                                        config,
+                                        false,
+                                        head,
+                                        &dagChecker),
+                                      libs);
+
+    std::set<cmStdString> seenProps = cge->GetSeenTargetProperties();
+    for (std::set<cmStdString>::const_iterator it = seenProps.begin();
+        it != seenProps.end(); ++it)
+      {
+      if (!this->GetProperty(it->c_str()))
+        {
+        this->LinkImplicitNullProperties.insert(*it);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
+                                  cmTarget::LinkLibraryType llt)
+{
+  if (llt == GENERAL)
+    {
+    return value;
+    }
+
+  // Get the list of configurations considered to be DEBUG.
+  std::vector<std::string> const& debugConfigs =
+                      this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+
+  std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
+
+  if (debugConfigs.size() > 1)
     {
-    std::string frameworkDir = libname;
-    frameworkDir += "/../";
-    frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
-    std::vector<std::string>::iterator i =
-      std::find(this->Frameworks.begin(),
-                this->Frameworks.end(), frameworkDir);
-    if(i == this->Frameworks.end())
+    for(std::vector<std::string>::const_iterator
+          li = debugConfigs.begin() + 1; li != debugConfigs.end(); ++li)
       {
-      this->Frameworks.push_back(frameworkDir);
+      configString += ",$<CONFIG:" + *li + ">";
       }
-    return true;
+    configString = "$<OR:" + configString + ">";
     }
-  return false;
+
+  if (llt == OPTIMIZED)
+    {
+    configString = "$<NOT:" + configString + ">";
+    }
+  return "$<" + configString + ":" + value + ">";
+}
+
+//----------------------------------------------------------------------------
+static std::string targetNameGenex(const char *lib)
+{
+  return std::string("$<TARGET_NAME:") + lib + ">";
 }
 
 //----------------------------------------------------------------------------
@@ -2089,7 +2340,24 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
     {
     return;
     }
-  this->AddFramework(lib, llt);
+
+  {
+  cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
+  const bool isNonImportedTarget = tgt && !tgt->IsImported();
+
+  const std::string libName = (isNonImportedTarget && llt != GENERAL)
+                                                        ? targetNameGenex(lib)
+                                                        : std::string(lib);
+  this->AppendProperty("LINK_LIBRARIES",
+                       this->GetDebugGeneratorExpressions(libName,
+                                                          llt).c_str());
+  }
+
+  if (cmGeneratorExpression::Find(lib) != std::string::npos)
+    {
+    return;
+    }
+
   cmTarget::LibraryID tmp;
   tmp.first = lib;
   tmp.second = llt;
@@ -2440,6 +2708,30 @@ void cmTarget::SetProperty(const char* prop, const char* value)
     return;
     }
 
+  if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+    {
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    deleteAndClear(this->Internal->IncludeDirectoriesEntries);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+    this->Internal->IncludeDirectoriesEntries.push_back(
+                          new cmTargetInternals::IncludeDirectoriesEntry(cge));
+    return;
+    }
+  if (strcmp(prop, "LINK_LIBRARIES") == 0)
+    {
+    this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear();
+    if (cmGeneratorExpression::IsValidTargetName(value)
+        || cmGeneratorExpression::Find(value) != std::string::npos)
+      {
+      cmListFileBacktrace lfbt;
+      this->Makefile->GetBacktrace(lfbt);
+      cmValueWithOrigin entry(value, lfbt);
+      this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry);
+      }
+    // Fall through
+    }
   this->Properties.SetProperty(prop, value, cmProperty::TARGET);
   this->MaybeInvalidatePropertyCache(prop);
 }
@@ -2452,11 +2744,368 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
     {
     return;
     }
+  if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+    {
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    this->Internal->IncludeDirectoriesEntries.push_back(
+              new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value)));
+    return;
+    }
+  if (strcmp(prop, "LINK_LIBRARIES") == 0)
+    {
+    if (cmGeneratorExpression::IsValidTargetName(value)
+        || cmGeneratorExpression::Find(value) != std::string::npos)
+      {
+      cmListFileBacktrace lfbt;
+      this->Makefile->GetBacktrace(lfbt);
+      cmValueWithOrigin entry(value, lfbt);
+      this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry);
+      }
+    // Fall through
+    }
   this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
   this->MaybeInvalidatePropertyCache(prop);
 }
 
 //----------------------------------------------------------------------------
+void cmTarget::AppendBuildInterfaceIncludes()
+{
+  if(this->GetType() != cmTarget::SHARED_LIBRARY &&
+     this->GetType() != cmTarget::STATIC_LIBRARY &&
+     this->GetType() != cmTarget::MODULE_LIBRARY &&
+     !this->IsExecutableWithExports())
+    {
+    return;
+    }
+  if (this->BuildInterfaceIncludesAppended)
+    {
+    return;
+    }
+  this->BuildInterfaceIncludesAppended = true;
+
+  if (this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE"))
+    {
+    const char *binDir = this->Makefile->GetStartOutputDirectory();
+    const char *srcDir = this->Makefile->GetStartDirectory();
+    const std::string dirs = std::string(binDir ? binDir : "")
+                            + std::string(binDir ? ";" : "")
+                            + std::string(srcDir ? srcDir : "");
+    if (!dirs.empty())
+      {
+      this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+                            ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::InsertInclude(const cmValueWithOrigin &entry,
+                     bool before)
+{
+  cmGeneratorExpression ge(entry.Backtrace);
+
+  std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::iterator position
+                = before ? this->Internal->IncludeDirectoriesEntries.begin()
+                         : this->Internal->IncludeDirectoriesEntries.end();
+
+  this->Internal->IncludeDirectoriesEntries.insert(position,
+      new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value)));
+}
+
+//----------------------------------------------------------------------------
+static void processIncludeDirectories(cmTarget *tgt,
+      const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries,
+      std::vector<std::string> &includes,
+      std::set<std::string> &uniqueIncludes,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const char *config, bool debugIncludes)
+{
+  cmMakefile *mf = tgt->GetMakefile();
+
+  for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    bool testIsOff = true;
+    bool cacheIncludes = false;
+    std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
+    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;
+        }
+      }
+    std::string usedIncludes;
+    for(std::vector<std::string>::iterator
+          li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+      {
+      cmTarget *dependentTarget =
+                              mf->FindTargetToUse((*it)->TargetName.c_str());
+
+      const bool fromImported = dependentTarget
+                             && dependentTarget->IsImported();
+
+      if (fromImported && !cmSystemTools::FileExists(li->c_str()))
+        {
+        cmOStringStream e;
+        e << "Imported target \"" << (*it)->TargetName << "\" includes "
+             "non-existent path\n  \"" << *li << "\"\nin its "
+             "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
+             "* The path was deleted, renamed, or moved to another "
+             "location.\n"
+             "* An install or uninstall procedure did not complete "
+             "successfully.\n"
+             "* The installation package was faulty and references files it "
+             "does not provide.\n";
+        tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+        return;
+        }
+
+      if (!cmSystemTools::FileIsFullPath(li->c_str()))
+        {
+        if (!(*it)->TargetName.empty())
+          {
+          cmOStringStream e;
+          e << "Target \"" << (*it)->TargetName << "\" contains relative "
+            "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
+            "  \"" << *li << "\" ";
+          tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR,
+                                           e.str().c_str());
+          return;
+          }
+        }
+
+      if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
+        {
+        cmSystemTools::ConvertToUnixSlashes(*li);
+        }
+      std::string inc = *li;
+
+      if(uniqueIncludes.insert(inc).second)
+        {
+        includes.push_back(inc);
+        if (debugIncludes)
+          {
+          usedIncludes += " * " + inc + "\n";
+          }
+        }
+      }
+    if (cacheIncludes)
+      {
+      (*it)->CachedIncludes = entryIncludes;
+      }
+    if (!usedIncludes.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used includes for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedIncludes, (*it)->ge->GetBacktrace());
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
+{
+  std::vector<std::string> includes;
+  std::set<std::string> uniqueIncludes;
+  cmListFileBacktrace lfbt;
+
+  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                              this->GetName(),
+                                              "INCLUDE_DIRECTORIES", 0, 0);
+
+  this->AppendBuildInterfaceIncludes();
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugIncludes = !this->DebugIncludesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "INCLUDE_DIRECTORIES")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsGeneratingBuildSystem())
+    {
+    this->DebugIncludesDone = true;
+    }
+
+  processIncludeDirectories(this,
+                            this->Internal->IncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes);
+
+  std::string configString = config ? config : "";
+  if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString])
+    {
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(),
+        end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end();
+        it != end; ++it)
+      {
+      {
+      cmGeneratorExpression ge(lfbt);
+      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.c_str()))
+        {
+        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[configString].push_back(
+                        new cmTargetInternals::IncludeDirectoriesEntry(cge,
+                                                              it->Value));
+      }
+    }
+
+  processIncludeDirectories(this,
+    this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries[configString],
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes);
+
+  if (!this->Makefile->IsGeneratingBuildSystem())
+    {
+    deleteAndClear(
+                this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries);
+    }
+  else
+    {
+    this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]
+                                                                      = true;
+    }
+
+  return includes;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetCompileDefinitions(const char *config)
+{
+  const char *configProp = 0;
+  if (config)
+    {
+    std::string configPropName;
+    configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
+    configProp = this->GetProperty(configPropName.c_str());
+    }
+
+  const char *noconfigProp = this->GetProperty("COMPILE_DEFINITIONS");
+  cmListFileBacktrace lfbt;
+  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                            this->GetName(),
+                                            "COMPILE_DEFINITIONS", 0, 0);
+
+  std::string defsString = (noconfigProp ? noconfigProp : "");
+  if (configProp && noconfigProp)
+    {
+    defsString += ";";
+    }
+  defsString += (configProp ? configProp : "");
+
+  cmGeneratorExpression ge(lfbt);
+  std::string result = ge.Parse(defsString.c_str())->Evaluate(this->Makefile,
+                                config,
+                                false,
+                                this,
+                                &dagChecker);
+
+  std::vector<std::string> libs;
+  this->GetDirectLinkLibraries(config, libs, this);
+
+  if (libs.empty())
+    {
+    return result;
+    }
+
+  std::string sep;
+  std::string depString;
+  for (std::vector<std::string>::const_iterator it = libs.begin();
+      it != libs.end(); ++it)
+    {
+    if ((cmGeneratorExpression::IsValidTargetName(it->c_str())
+          || cmGeneratorExpression::Find(it->c_str()) != std::string::npos)
+        && this->Makefile->FindTargetToUse(it->c_str()))
+      {
+      depString += sep + "$<TARGET_PROPERTY:"
+                + *it + ",INTERFACE_COMPILE_DEFINITIONS>";
+      sep = ";";
+      }
+    }
+
+  std::string configString = config ? config : "";
+  if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString])
+    {
+    cmGeneratorExpression ge2(lfbt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 =
+                                                        ge2.Parse(depString);
+    this->Internal->CachedLinkInterfaceCompileDefinitions[configString] =
+                                                cge2->Evaluate(this->Makefile,
+                                                               config,
+                                                               false,
+                                                               this,
+                                                               &dagChecker);
+    }
+  if (!this->Internal->CachedLinkInterfaceCompileDefinitions[configString]
+                                                                    .empty())
+    {
+    result += (result.empty() ? "" : ";")
+        + this->Internal->CachedLinkInterfaceCompileDefinitions[configString];
+    }
+
+  if (!this->Makefile->IsGeneratingBuildSystem())
+    {
+    this->Internal->CachedLinkInterfaceCompileDefinitions[configString] = "";
+    }
+  else
+    {
+    this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]
+                                                                      = true;
+    }
+
+  return result;
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
 {
   // Wipe out maps caching information affected by this property.
@@ -2783,6 +3432,24 @@ const char *cmTarget::GetProperty(const char* prop,
         }
       }
     }
+  if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+    {
+    static std::string output;
+    output = "";
+    std::string sep;
+    typedef cmTargetInternals::IncludeDirectoriesEntry
+                                IncludeDirectoriesEntry;
+    for (std::vector<IncludeDirectoriesEntry*>::const_iterator
+        it = this->Internal->IncludeDirectoriesEntries.begin(),
+        end = this->Internal->IncludeDirectoriesEntries.end();
+        it != end; ++it)
+      {
+      output += sep;
+      output += (*it)->ge->GetInput();
+      sep = ";";
+      }
+    return output.c_str();
+    }
 
   if (strcmp(prop,"IMPORTED") == 0)
     {
@@ -2842,8 +3509,11 @@ class cmTargetCollectLinkLanguages
 {
 public:
   cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
-                               std::set<cmStdString>& languages):
-    Config(config), Languages(languages) { this->Visited.insert(target); }
+                               std::set<cmStdString>& languages,
+                               cmTarget* head):
+    Config(config), Languages(languages), HeadTarget(head)
+  { this->Visited.insert(target); }
+
   void Visit(cmTarget* target)
     {
     if(!target || !this->Visited.insert(target).second)
@@ -2852,7 +3522,7 @@ public:
       }
 
     cmTarget::LinkInterface const* iface =
-      target->GetLinkInterface(this->Config);
+      target->GetLinkInterface(this->Config, this->HeadTarget);
     if(!iface) { return; }
 
     for(std::vector<std::string>::const_iterator
@@ -2871,26 +3541,30 @@ public:
 private:
   const char* Config;
   std::set<cmStdString>& Languages;
+  cmTarget* HeadTarget;
   std::set<cmTarget*> Visited;
 };
 
 //----------------------------------------------------------------------------
-const char* cmTarget::GetLinkerLanguage(const char* config)
+const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head)
 {
-  const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str();
+  cmTarget *headTarget = head ? head : this;
+  const char* lang = this->GetLinkClosure(config, headTarget)
+                                                    ->LinkerLanguage.c_str();
   return *lang? lang : 0;
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
+cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config,
+                                                      cmTarget *head)
 {
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : ""));
   cmTargetInternals::LinkClosureMapType::iterator
     i = this->Internal->LinkClosureMap.find(key);
   if(i == this->Internal->LinkClosureMap.end())
     {
     LinkClosure lc;
-    this->ComputeLinkClosure(config, lc);
+    this->ComputeLinkClosure(config, lc, head);
     cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
     i = this->Internal->LinkClosureMap.insert(entry).first;
     }
@@ -2951,11 +3625,12 @@ public:
 };
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
+void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
+                                  cmTarget *head)
 {
   // Get languages built in this target.
   std::set<cmStdString> languages;
-  LinkImplementation const* impl = this->GetLinkImplementation(config);
+  LinkImplementation const* impl = this->GetLinkImplementation(config, head);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -2963,7 +3638,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
     }
 
   // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages);
+  cmTargetCollectLinkLanguages cll(this, config, languages, head);
   for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
@@ -3102,7 +3777,8 @@ bool cmTarget::HasSOName(const char* config)
   return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
            this->GetType() == cmTarget::MODULE_LIBRARY) &&
           !this->GetPropertyAsBool("NO_SONAME") &&
-          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
+                                                                this)));
 }
 
 //----------------------------------------------------------------------------
@@ -3111,7 +3787,7 @@ std::string cmTarget::GetSOName(const char* config)
   if(this->IsImported())
     {
     // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
       {
       if(info->NoSOName)
         {
@@ -3148,7 +3824,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
 {
   if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
       {
       return info->NoSOName;
       }
@@ -3262,7 +3938,7 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
 std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
 {
   std::string result;
-  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
     {
     result = implib? info->ImportLibrary : info->Location;
     }
@@ -3347,7 +4023,7 @@ void cmTarget::GetFullNameInternal(const char* config,
   const char* suffixVar = this->GetSuffixVariableInternal(implib);
 
   // Check for language-specific default prefix and suffix.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     if(!targetSuffix && suffixVar && *suffixVar)
       {
@@ -3666,10 +4342,15 @@ void cmTarget::SetPropertyDefault(const char* property,
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::HaveBuildTreeRPATH()
+bool cmTarget::HaveBuildTreeRPATH(const char *config)
 {
-  return (!this->GetPropertyAsBool("SKIP_BUILD_RPATH") &&
-          !this->LinkLibraries.empty());
+  if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+    {
+    return false;
+    }
+  std::vector<std::string> libs;
+  this->GetDirectLinkLibraries(config, libs, this);
+  return !libs.empty();
 }
 
 //----------------------------------------------------------------------------
@@ -3718,7 +4399,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
     }
 
   // Check for rpath support on this platform.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
     flagVar += ll;
@@ -3740,7 +4421,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
   // If either a build or install tree rpath is set then the rpath
   // will likely change between the build tree and install tree and
   // this target must be relinked.
-  return this->HaveBuildTreeRPATH() || this->HaveInstallTreeRPATH();
+  return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
 }
 
 //----------------------------------------------------------------------------
@@ -4089,6 +4770,280 @@ const char* cmTarget::GetExportMacro()
 }
 
 //----------------------------------------------------------------------------
+bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
+{
+  return this->LinkImplicitNullProperties.find(p)
+      != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
+                              PropertyType *);
+
+//----------------------------------------------------------------------------
+template<>
+bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
+{
+  return tgt->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
+                                          const char **)
+{
+  return tgt->GetProperty(prop);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+bool consistentProperty(PropertyType lhs, PropertyType rhs);
+
+//----------------------------------------------------------------------------
+template<>
+bool consistentProperty(bool lhs, bool rhs)
+{
+  return lhs == rhs;
+}
+
+//----------------------------------------------------------------------------
+template<>
+bool consistentProperty(const char *lhs, const char *rhs)
+{
+  if (!lhs && !rhs)
+    return true;
+  if (!lhs || !rhs)
+    return false;
+  return strcmp(lhs, rhs) == 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
+                                          const std::string &p,
+                                          const char *config,
+                                          const char *defaultValue,
+                                          PropertyType *)
+{
+  PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
+                                                            0);
+  const bool explicitlySet = tgt->GetProperties()
+                                  .find(p.c_str())
+                                  != tgt->GetProperties().end();
+  const bool impliedByUse =
+          tgt->IsNullImpliedByLinkLibraries(p);
+  assert((impliedByUse ^ explicitlySet)
+      || (!impliedByUse && !explicitlySet));
+
+  cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
+  if(!info)
+    {
+    return propContent;
+    }
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+  bool propInitialized = explicitlySet;
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    // An error should be reported if one dependency
+    // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
+    // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
+    // target itself has a POSITION_INDEPENDENT_CODE which disagrees
+    // with a dependency.
+
+    if (!li->Target)
+      {
+      continue;
+      }
+
+    const bool ifaceIsSet = li->Target->GetProperties()
+                            .find("INTERFACE_" + p)
+                            != li->Target->GetProperties().end();
+    PropertyType ifacePropContent =
+                    getTypedProperty<PropertyType>(li->Target,
+                              ("INTERFACE_" + p).c_str(), 0);
+    if (explicitlySet)
+      {
+      if (ifaceIsSet)
+        {
+        if (!consistentProperty(propContent, ifacePropContent))
+          {
+          cmOStringStream e;
+          e << "Property " << p << " on target \""
+            << tgt->GetName() << "\" does\nnot match the "
+            "INTERFACE_" << p << " property requirement\nof "
+            "dependency \"" << li->Target->GetName() << "\".\n";
+          cmSystemTools::Error(e.str().c_str());
+          break;
+          }
+        else
+          {
+          // Agree
+          continue;
+          }
+        }
+      else
+        {
+        // Explicitly set on target and not set in iface. Can't disagree.
+        continue;
+        }
+      }
+    else if (impliedByUse)
+      {
+      if (ifaceIsSet)
+        {
+        if (!consistentProperty(propContent, ifacePropContent))
+          {
+          cmOStringStream e;
+          e << "Property " << p << " on target \""
+            << tgt->GetName() << "\" is\nimplied to be " << defaultValue
+            << " because it was used to determine the link libraries\n"
+               "already. The INTERFACE_" << p << " property on\ndependency \""
+            << li->Target->GetName() << "\" is in conflict.\n";
+          cmSystemTools::Error(e.str().c_str());
+          break;
+          }
+        else
+          {
+          // Agree
+          continue;
+          }
+        }
+      else
+        {
+        // Implicitly set on target and not set in iface. Can't disagree.
+        continue;
+        }
+      }
+    else
+      {
+      if (ifaceIsSet)
+        {
+        if (propInitialized)
+          {
+          if (!consistentProperty(propContent, ifacePropContent))
+            {
+            cmOStringStream e;
+            e << "The INTERFACE_" << p << " property of \""
+              << li->Target->GetName() << "\" does\nnot agree with the value "
+                "of " << p << " already determined\nfor \""
+              << tgt->GetName() << "\".\n";
+            cmSystemTools::Error(e.str().c_str());
+            break;
+            }
+          else
+            {
+            // Agree.
+            continue;
+            }
+          }
+        else
+          {
+          propContent = ifacePropContent;
+          propInitialized = true;
+          }
+        }
+      else
+        {
+        // Not set. Nothing to agree on.
+        continue;
+        }
+      }
+    }
+  return propContent;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
+                                                     const char *config)
+{
+  return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
+                                                   0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmTarget::GetLinkInterfaceDependentStringProperty(
+                                                      const std::string &p,
+                                                      const char *config)
+{
+  return checkInterfacePropertyCompatibility<const char *>(this,
+                                                           p,
+                                                           config,
+                                                           "empty", 0);
+}
+
+//----------------------------------------------------------------------------
+bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
+                             const char *interfaceProperty,
+                             const char *config)
+{
+  cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
+  if(!info)
+    {
+    return false;
+    }
+
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    if (!li->Target)
+      {
+      continue;
+      }
+    const char *prop = li->Target->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 char *config)
+{
+  if (this->TargetTypeValue == OBJECT_LIBRARY)
+    {
+    return false;
+    }
+  return (p == "POSITION_INDEPENDENT_CODE") ||
+    isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
+                                 config);
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
+                                    const char *config)
+{
+  if (this->TargetTypeValue == OBJECT_LIBRARY)
+    {
+    return false;
+    }
+  return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
+                                 config);
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
 {
   for(std::vector<cmSourceFile*>::const_iterator
@@ -4140,7 +5095,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
 
   // Enable if the rpath flag uses a separator and the target uses ELF
   // binaries.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
     sepVar += ll;
@@ -4164,7 +5119,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
 
 //----------------------------------------------------------------------------
 cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const char* config)
+cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
 {
   // There is no imported information for non-imported targets.
   if(!this->IsImported())
@@ -4183,14 +5138,16 @@ cmTarget::GetImportInfo(const char* config)
     {
     config_upper = "NOCONFIG";
     }
+  TargetConfigPair key(headTarget, config_upper);
   typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
+
   ImportInfoMapType::const_iterator i =
-    this->Internal->ImportInfoMap.find(config_upper);
+    this->Internal->ImportInfoMap.find(key);
   if(i == this->Internal->ImportInfoMap.end())
     {
     ImportInfo info;
-    this->ComputeImportInfo(config_upper, info);
-    ImportInfoMapType::value_type entry(config_upper, info);
+    this->ComputeImportInfo(config_upper, info, headTarget);
+    ImportInfoMapType::value_type entry(key, info);
     i = this->Internal->ImportInfoMap.insert(entry).first;
     }
 
@@ -4205,27 +5162,15 @@ cmTarget::GetImportInfo(const char* config)
   return &i->second;
 }
 
-//----------------------------------------------------------------------------
-void cmTarget::ComputeImportInfo(std::string const& desired_config,
-                                 ImportInfo& info)
+bool cmTarget::GetMappedConfig(std::string const& desired_config,
+                               const char** loc,
+                               const char** imp,
+                               std::string& suffix)
 {
-  // This method finds information about an imported target from its
-  // properties.  The "IMPORTED_" namespace is reserved for properties
-  // defined by the project exporting the target.
-
-  // Initialize members.
-  info.NoSOName = false;
-
   // Track the configuration-specific property suffix.
-  std::string suffix = "_";
+  suffix = "_";
   suffix += desired_config;
 
-  // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
-  // library or an executable with exports.
-  bool allowImp = this->HasImportLibrary();
-
-  // Look for a mapping from the current project's configuration to
-  // the imported project's configuration.
   std::vector<std::string> mappedConfigs;
   {
   std::string mapProp = "MAP_IMPORTED_CONFIG_";
@@ -4236,26 +5181,29 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     }
   }
 
+  // If we needed to find one of the mapped configurations but did not
+  // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
+  // library or an executable with exports.
+  bool allowImp = this->HasImportLibrary();
+
   // If a mapping was found, check its configurations.
-  const char* loc = 0;
-  const char* imp = 0;
   for(std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
-      !loc && !imp && mci != mappedConfigs.end(); ++mci)
+      !*loc && !*imp && mci != mappedConfigs.end(); ++mci)
     {
     // Look for this configuration.
     std::string mcUpper = cmSystemTools::UpperCase(mci->c_str());
     std::string locProp = "IMPORTED_LOCATION_";
     locProp += mcUpper;
-    loc = this->GetProperty(locProp.c_str());
+    *loc = this->GetProperty(locProp.c_str());
     if(allowImp)
       {
       std::string impProp = "IMPORTED_IMPLIB_";
       impProp += mcUpper;
-      imp = this->GetProperty(impProp.c_str());
+      *imp = this->GetProperty(impProp.c_str());
       }
 
     // If it was found, use it for all properties below.
-    if(loc || imp)
+    if(*loc || *imp)
       {
       suffix = "_";
       suffix += mcUpper;
@@ -4265,45 +5213,45 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
   // If we needed to find one of the mapped configurations but did not
   // then the target is not found.  The project does not want any
   // other configuration.
-  if(!mappedConfigs.empty() && !loc && !imp)
+  if(!mappedConfigs.empty() && !*loc && !*imp)
     {
-    return;
+    return false;
     }
 
   // If we have not yet found it then there are no mapped
   // configurations.  Look for an exact-match.
-  if(!loc && !imp)
+  if(!*loc && !*imp)
     {
     std::string locProp = "IMPORTED_LOCATION";
     locProp += suffix;
-    loc = this->GetProperty(locProp.c_str());
+    *loc = this->GetProperty(locProp.c_str());
     if(allowImp)
       {
       std::string impProp = "IMPORTED_IMPLIB";
       impProp += suffix;
-      imp = this->GetProperty(impProp.c_str());
+      *imp = this->GetProperty(impProp.c_str());
       }
     }
 
   // If we have not yet found it then there are no mapped
   // configurations and no exact match.
-  if(!loc && !imp)
+  if(!*loc && !*imp)
     {
     // The suffix computed above is not useful.
     suffix = "";
 
     // Look for a configuration-less location.  This may be set by
     // manually-written code.
-    loc = this->GetProperty("IMPORTED_LOCATION");
+    *loc = this->GetProperty("IMPORTED_LOCATION");
     if(allowImp)
       {
-      imp = this->GetProperty("IMPORTED_IMPLIB");
+      *imp = this->GetProperty("IMPORTED_IMPLIB");
       }
     }
 
   // If we have not yet found it then the project is willing to try
   // any available configuration.
-  if(!loc && !imp)
+  if(!*loc && !*imp)
     {
     std::vector<std::string> availableConfigs;
     if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS"))
@@ -4312,24 +5260,47 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
       }
     for(std::vector<std::string>::const_iterator
           aci = availableConfigs.begin();
-        !loc && !imp && aci != availableConfigs.end(); ++aci)
+        !*loc && !*imp && aci != availableConfigs.end(); ++aci)
       {
       suffix = "_";
       suffix += cmSystemTools::UpperCase(*aci);
       std::string locProp = "IMPORTED_LOCATION";
       locProp += suffix;
-      loc = this->GetProperty(locProp.c_str());
+      *loc = this->GetProperty(locProp.c_str());
       if(allowImp)
         {
         std::string impProp = "IMPORTED_IMPLIB";
         impProp += suffix;
-        imp = this->GetProperty(impProp.c_str());
+        *imp = this->GetProperty(impProp.c_str());
         }
       }
     }
-
   // If we have not yet found it then the target is not available.
-  if(!loc && !imp)
+  if(!*loc && !*imp)
+    {
+    return false;
+    }
+
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ComputeImportInfo(std::string const& desired_config,
+                                 ImportInfo& info,
+                                 cmTarget *headTarget)
+{
+  (void)headTarget;
+  // This method finds information about an imported target from its
+  // properties.  The "IMPORTED_" namespace is reserved for properties
+  // defined by the project exporting the target.
+
+  // Initialize members.
+  info.NoSOName = false;
+
+  const char* loc = 0;
+  const char* imp = 0;
+  std::string suffix;
+  if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
     {
     return;
     }
@@ -4410,16 +5381,30 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
   {
   std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
   linkProp += suffix;
-  if(const char* config_libs = this->GetProperty(linkProp.c_str()))
+
+  const char *propertyLibs = this->GetProperty(linkProp.c_str());
+
+  if(!propertyLibs)
     {
-    cmSystemTools::ExpandListArgument(config_libs,
-                                      info.LinkInterface.Libraries);
+    linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+    propertyLibs = this->GetProperty(linkProp.c_str());
     }
-  else if(const char* libs =
-          this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
+  if(propertyLibs)
     {
-    cmSystemTools::ExpandListArgument(libs,
-                                      info.LinkInterface.Libraries);
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                        this->GetName(),
+                                        linkProp, 0, 0);
+    cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
+                                       ->Evaluate(this->Makefile,
+                                                  desired_config.c_str(),
+                                                  false,
+                                                  headTarget,
+                                                  this,
+                                                  &dagChecker),
+                                    info.LinkInterface.Libraries);
     }
   }
 
@@ -4475,12 +5460,13 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
+cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
+                                                      cmTarget *head)
 {
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
       {
       return &info->LinkInterface;
       }
@@ -4496,14 +5482,15 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
     }
 
   // Lookup any existing link interface for this configuration.
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
   cmTargetInternals::LinkInterfaceMapType::iterator
     i = this->Internal->LinkInterfaceMap.find(key);
   if(i == this->Internal->LinkInterfaceMap.end())
     {
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
-    iface.Exists = this->ComputeLinkInterface(config, iface);
+    iface.Exists = this->ComputeLinkInterface(config, iface, head);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@@ -4514,7 +5501,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
+bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
+                                    cmTarget *headTarget)
 {
   // Construct the property name suffix for this configuration.
   std::string suffix = "_";
@@ -4530,18 +5518,20 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
   // An explicit list of interface libraries may be set for shared
   // libraries and executables that export symbols.
   const char* explicitLibraries = 0;
+  std::string linkIfaceProp;
   if(this->GetType() == cmTarget::SHARED_LIBRARY ||
      this->IsExecutableWithExports())
     {
     // Lookup the per-configuration property.
-    std::string propName = "LINK_INTERFACE_LIBRARIES";
-    propName += suffix;
-    explicitLibraries = this->GetProperty(propName.c_str());
+    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+    linkIfaceProp += suffix;
+    explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
 
     // If not set, try the generic property.
     if(!explicitLibraries)
       {
-      explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+      explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
       }
     }
 
@@ -4559,7 +5549,16 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
   if(explicitLibraries)
     {
     // The interface libraries have been explicitly set.
-    cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+                                               linkIfaceProp, 0, 0);
+    cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
+                                        this->Makefile,
+                                        config,
+                                        false,
+                                        headTarget,
+                                        this, &dagChecker), iface.Libraries);
 
     if(this->GetType() == cmTarget::SHARED_LIBRARY)
       {
@@ -4571,7 +5570,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
         {
         emitted.insert(*li);
         }
-      LinkImplementation const* impl = this->GetLinkImplementation(config);
+      LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                                headTarget);
       for(std::vector<std::string>::const_iterator
             li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
         {
@@ -4599,7 +5599,9 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
   else
     {
     // The link implementation is the default link interface.
-    LinkImplementation const* impl = this->GetLinkImplementation(config);
+    LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                              headTarget);
+    iface.ImplementationIsInterface = true;
     iface.Libraries = impl->Libraries;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -4631,7 +5633,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
 
 //----------------------------------------------------------------------------
 cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const char* config)
+cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
 {
   // There is no link implementation for imported targets.
   if(this->IsImported())
@@ -4640,14 +5642,15 @@ cmTarget::GetLinkImplementation(const char* config)
     }
 
   // Lookup any existing link implementation for this configuration.
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
   cmTargetInternals::LinkImplMapType::iterator
     i = this->Internal->LinkImplMap.find(key);
   if(i == this->Internal->LinkImplMap.end())
     {
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
-    this->ComputeLinkImplementation(config, impl);
+    this->ComputeLinkImplementation(config, impl, head);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -4659,30 +5662,39 @@ cmTarget::GetLinkImplementation(const char* config)
 
 //----------------------------------------------------------------------------
 void cmTarget::ComputeLinkImplementation(const char* config,
-                                         LinkImplementation& impl)
+                                         LinkImplementation& impl,
+                                         cmTarget *head)
 {
   // Compute which library configuration to link.
   cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
 
   // Collect libraries directly linked in this configuration.
-  LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
-  for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
+  std::vector<std::string> llibs;
+  this->GetDirectLinkLibraries(config, llibs, head);
+  for(std::vector<std::string>::const_iterator li = llibs.begin();
       li != llibs.end(); ++li)
     {
     // Skip entries that resolve to the target itself or are empty.
-    std::string item = this->CheckCMP0004(li->first);
+    std::string item = this->CheckCMP0004(*li);
     if(item == this->GetName() || item.empty())
       {
       continue;
       }
+    // The entry is meant for this configuration.
+    impl.Libraries.push_back(item);
+    }
 
-    if(li->second == cmTarget::GENERAL || li->second == linkType)
-      {
-      // The entry is meant for this configuration.
-      impl.Libraries.push_back(item);
-      }
-    else
+  LinkLibraryVectorType const& oldllibs = this->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())
+        {
+        continue;
+        }
       // Support OLD behavior for CMP0003.
       impl.WrongConfigLibraries.push_back(item);
       }
@@ -4771,6 +5783,158 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
   return lib;
 }
 
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
+                                               const std::string prop,
+                                               const char *config,
+                                               PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmTarget *tgt,
+                                         const std::string prop,
+                                         const char *config, bool *)
+{
+  return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
+                                                 const std::string prop,
+                                                 const char *config,
+                                                 const char **)
+{
+  return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
+                              const char *propName,
+                              std::set<cmStdString> &emitted,
+                              const char *config,
+                              PropertyType *)
+{
+  const char *prop = dependee->GetProperty(propName);
+  if (!prop)
+    {
+    return;
+    }
+
+  std::vector<std::string> props;
+  cmSystemTools::ExpandListArgument(prop, props);
+
+  for(std::vector<std::string>::iterator pi = props.begin();
+      pi != props.end(); ++pi)
+    {
+    if (depender->GetMakefile()->GetCMakeInstance()
+                      ->GetIsPropertyDefined(pi->c_str(),
+                                              cmProperty::TARGET))
+      {
+      cmOStringStream e;
+      e << "Target \"" << dependee->GetName() << "\" has property \""
+        << *pi << "\" listed in its " << propName << " property.  "
+          "This is not allowed.  Only user-defined properties may appear "
+          "listed in the " << propName << " property.";
+      depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return;
+      }
+    if(emitted.insert(*pi).second)
+      {
+      getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+                                                      0);
+      if (cmSystemTools::GetErrorOccuredFlag())
+        {
+        return;
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
+                                          const char* config)
+{
+  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+  std::set<cmStdString> emittedBools;
+  std::set<cmStdString> emittedStrings;
+
+  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+      deps.begin();
+      li != deps.end(); ++li)
+    {
+    if (!li->Target)
+      {
+      continue;
+      }
+
+    checkPropertyConsistency<bool>(this, li->Target,
+                                   "COMPATIBLE_INTERFACE_BOOL",
+                                   emittedBools, config, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    checkPropertyConsistency<const char *>(this, li->Target,
+                                           "COMPATIBLE_INTERFACE_STRING",
+                                           emittedStrings, config, 0);
+    if (cmSystemTools::GetErrorOccuredFlag())
+      {
+      return;
+      }
+    }
+
+  for(std::set<cmStdString>::const_iterator li = emittedBools.begin();
+      li != emittedBools.end(); ++li)
+    {
+    const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li);
+    if (si != emittedStrings.end())
+      {
+      cmOStringStream e;
+      e << "Property \"" << *li << "\" appears in both the "
+      "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING "
+      "property in the dependencies of target \"" << this->GetName() <<
+      "\".  This is not allowed. A property may only require compatibility "
+      "in a boolean interpretation or a string interpretation, but not both.";
+      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      break;
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmTarget::GetLinkInformation(const char* config, cmTarget *head)
+{
+  cmTarget *headTarget = head ? head : this;
+  // Lookup any existing information for this configuration.
+  TargetConfigPair key(headTarget,
+                                  cmSystemTools::UpperCase(config?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);
+    if(!info || !info->Compute())
+      {
+      delete info;
+      info = 0;
+      }
+
+    // Store the information for this configuration.
+    cmTargetLinkInformationMap::value_type entry(key, info);
+    i = this->LinkInformation.insert(entry).first;
+
+    if (info)
+      {
+      this->CheckPropertyCompatibility(info, config);
+      }
+    }
+  return i->second;
+}
+
 //----------------------------------------------------------------------------
 std::string cmTarget::GetFrameworkDirectory(const char* config)
 {
@@ -4829,6 +5993,29 @@ std::string cmTarget::GetMacContentDirectory(const char* config,
 }
 
 //----------------------------------------------------------------------------
+cmTargetLinkInformationMap
+::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived()
+{
+  // Ideally cmTarget instances should never be copied.  However until
+  // we can make a sweep to remove that, this copy constructor avoids
+  // allowing the resources (LinkInformation) from getting copied.  In
+  // the worst case this will lead to extra cmComputeLinkInformation
+  // instances.  We also enforce in debug mode that the map be emptied
+  // when copied.
+  static_cast<void>(r);
+  assert(r.empty());
+}
+
+//----------------------------------------------------------------------------
+cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
+{
+  for(derived::iterator i = this->begin(); i != this->end(); ++i)
+    {
+    delete i->second;
+    }
+}
+
+//----------------------------------------------------------------------------
 cmTargetInternalPointer::cmTargetInternalPointer()
 {
   this->Pointer = new cmTargetInternals;
@@ -4847,6 +6034,7 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
+  deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
   delete this->Pointer;
 }
 
index e442d25..9d46796 100644 (file)
@@ -15,6 +15,7 @@
 #include "cmCustomCommand.h"
 #include "cmPropertyMap.h"
 #include "cmPolicies.h"
+#include "cmListFileCache.h"
 
 #include <cmsys/auto_ptr.hxx>
 
@@ -22,7 +23,19 @@ class cmake;
 class cmMakefile;
 class cmSourceFile;
 class cmGlobalGenerator;
+class cmComputeLinkInformation;
 class cmListFileBacktrace;
+class cmTarget;
+
+struct cmTargetLinkInformationMap:
+  public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
+{
+  typedef std::map<std::pair<cmTarget*, std::string>,
+                   cmComputeLinkInformation*> derived;
+  cmTargetLinkInformationMap() {}
+  cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
+  ~cmTargetLinkInformationMap();
+};
 
 class cmTargetInternals;
 class cmTargetInternalPointer
@@ -89,6 +102,10 @@ public:
   cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
     { return this->PolicyStatusCMP0008; }
 
+  /** Get the status of policy CMP0020 when the target was created.  */
+  cmPolicies::PolicyStatus GetPolicyStatusCMP0020() const
+    { return this->PolicyStatusCMP0020; }
+
   /**
    * Get the list of the custom commands for this target
    */
@@ -99,9 +116,6 @@ public:
   std::vector<cmCustomCommand> &GetPostBuildCommands()
     {return this->PostBuildCommands;}
 
-  ///! Return the list of frameworks being linked to this target
-  std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
-
   /**
    * Get the list of the source files used by this target
    */
@@ -158,6 +172,9 @@ public:
   return this->LinkLibraries;}
   const LinkLibraryVectorType &GetOriginalLinkLibraries() const
     {return this->OriginalLinkLibraries;}
+  void GetDirectLinkLibraries(const char *config,
+                              std::vector<std::string> &,
+                              cmTarget *head);
 
   /** Compute the link type to use for the given configuration.  */
   LinkLibraryType ComputeLinkType(const char* config);
@@ -169,7 +186,6 @@ public:
 
   // Check to see if a library is a framework and treat it different on Mac
   bool NameResolvesToFramework(const std::string& libname);
-  bool AddFramework(const std::string& lib, LinkLibraryType llt);
   void AddLinkLibrary(cmMakefile& mf,
                       const char *target, const char* lib,
                       LinkLibraryType llt);
@@ -246,12 +262,15 @@ public:
     // Needed only for OLD behavior of CMP0003.
     std::vector<std::string> WrongConfigLibraries;
 
-    LinkInterface(): Multiplicity(0) {}
+    bool ImplementationIsInterface;
+
+    LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
   };
 
   /** Get the link interface for the given configuration.  Returns 0
       if the target cannot be linked.  */
-  LinkInterface const* GetLinkInterface(const char* config);
+  LinkInterface const* GetLinkInterface(const char* config,
+                                        cmTarget *headTarget);
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */
@@ -267,7 +286,8 @@ public:
     // Needed only for OLD behavior of CMP0003.
     std::vector<std::string> WrongConfigLibraries;
   };
-  LinkImplementation const* GetLinkImplementation(const char* config);
+  LinkImplementation const* GetLinkImplementation(const char* config,
+                                                  cmTarget *head);
 
   /** Link information from the transitive closure of the link
       implementation and the interfaces of its dependencies.  */
@@ -279,7 +299,7 @@ public:
     // Languages whose runtime libraries must be linked.
     std::vector<std::string> Languages;
   };
-  LinkClosure const* GetLinkClosure(const char* config);
+  LinkClosure const* GetLinkClosure(const char* config, cmTarget *head);
 
   /** Strip off leading and trailing whitespace from an item named in
       the link dependencies of this target.  */
@@ -324,7 +344,7 @@ public:
   bool FindSourceFiles();
 
   ///! Return the preferred linker language for this target
-  const char* GetLinkerLanguage(const char* config = 0);
+  const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0);
 
   /** Get the full name of the target according to the settings in its
       makefile.  */
@@ -381,7 +401,7 @@ public:
    */
   bool NeedRelinkBeforeInstall(const char* config);
 
-  bool HaveBuildTreeRPATH();
+  bool HaveBuildTreeRPATH(const char *config);
   bool HaveInstallTreeRPATH();
 
   /** Return true if builtin chrpath will work for this target */
@@ -392,9 +412,17 @@ public:
   std::string GetInstallNameDirForInstallTree(const char* config,
                                               bool for_xcode = false);
 
+  cmComputeLinkInformation* GetLinkInformation(const char* config,
+                                               cmTarget *head = 0);
+
   // Get the properties
   cmPropertyMap &GetProperties() { return this->Properties; };
 
+  bool GetMappedConfig(std::string const& desired_config,
+                       const char** loc,
+                       const char** imp,
+                       std::string& suffix);
+
   // Define the properties
   static void DefineProperties(cmake *cm);
 
@@ -402,6 +430,8 @@ public:
       If no macro should be defined null is returned.  */
   const char* GetExportMacro();
 
+  std::string GetCompileDefinitions(const char *config);
+
   // Compute the set of languages compiled by the target.  This is
   // computed every time it is called because the languages can change
   // when source file properties are changed and we do not have enough
@@ -462,6 +492,26 @@ public:
   /** @return the Mac framework directory without the base. */
   std::string GetFrameworkDirectory(const char* config = 0);
 
+  std::vector<std::string> GetIncludeDirectories(const char *config);
+  void InsertInclude(const cmValueWithOrigin &entry,
+                     bool before = false);
+
+  void AppendBuildInterfaceIncludes();
+
+  bool IsNullImpliedByLinkLibraries(const std::string &p);
+  bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+                                            const char *config);
+  bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+                                              const char *config);
+
+  bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
+                                             const char *config);
+
+  const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+                                                      const char *config);
+
+  std::string GetDebugGeneratorExpressions(const std::string &value,
+                                  cmTarget::LinkLibraryType llt);
 private:
   /**
    * A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -557,7 +607,6 @@ private:
   LinkLibraryVectorType LinkLibraries;
   LinkLibraryVectorType PrevLinkedLibraries;
   bool LinkLibrariesAnalyzed;
-  std::vector<std::string> Frameworks;
   std::vector<std::string> LinkDirectories;
   std::set<cmStdString> LinkDirectoriesEmmitted;
   bool HaveInstallRule;
@@ -572,6 +621,9 @@ private:
   bool DLLPlatform;
   bool IsApple;
   bool IsImportedTarget;
+  bool DebugIncludesDone;
+  mutable std::set<std::string> LinkImplicitNullProperties;
+  bool BuildInterfaceIncludesAppended;
 
   // Cache target output paths for each configuration.
   struct OutputInfo;
@@ -581,14 +633,21 @@ private:
 
   // Cache import information from properties for each configuration.
   struct ImportInfo;
-  ImportInfo const* GetImportInfo(const char* config);
-  void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
+  ImportInfo const* GetImportInfo(const char* config,
+                                        cmTarget *workingTarget);
+  void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
+                                        cmTarget *head);
+
+  cmTargetLinkInformationMap LinkInformation;
+  void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+                                  const char* config);
 
-  bool ComputeLinkInterface(const char* config, LinkInterface& iface);
+  bool ComputeLinkInterface(const char* config, LinkInterface& iface,
+                                        cmTarget *head);
 
   void ComputeLinkImplementation(const char* config,
-                                 LinkImplementation& impl);
-  void ComputeLinkClosure(const char* config, LinkClosure& lc);
+                                 LinkImplementation& impl, cmTarget *head);
+  void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
 
   void ClearLinkMaps();
 
@@ -604,6 +663,7 @@ private:
   cmPolicies::PolicyStatus PolicyStatusCMP0003;
   cmPolicies::PolicyStatus PolicyStatusCMP0004;
   cmPolicies::PolicyStatus PolicyStatusCMP0008;
+  cmPolicies::PolicyStatus PolicyStatusCMP0020;
 
   // Internal representation details.
   friend class cmTargetInternals;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
new file mode 100644 (file)
index 0000000..ba0ad59
--- /dev/null
@@ -0,0 +1,66 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 "cmTargetCompileDefinitionsCommand.h"
+
+bool cmTargetCompileDefinitionsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+  return this->HandleArguments(args, "COMPILE_DEFINITIONS");
+}
+
+void cmTargetCompileDefinitionsCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+  cmOStringStream e;
+  e << "Cannot specify compile definitions for imported target \""
+    << tgt << "\".";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+void cmTargetCompileDefinitionsCommand
+::HandleMissingTarget(const std::string &name)
+{
+  cmOStringStream e;
+  e << "Cannot specify compile definitions for target \"" << name << "\" "
+       "which is not built by this project.";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetCompileDefinitionsCommand
+::Join(const std::vector<std::string> &content)
+{
+  std::string defs;
+  std::string sep;
+  for(std::vector<std::string>::const_iterator it = content.begin();
+    it != content.end(); ++it)
+    {
+    if (strncmp(it->c_str(), "-D", 2) == 0)
+      {
+      defs += sep + it->substr(2);
+      }
+    else
+      {
+      defs += sep + *it;
+      }
+    sep = ";";
+    }
+  return defs;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetCompileDefinitionsCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+                                   bool)
+{
+  tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
new file mode 100644 (file)
index 0000000..ec9b071
--- /dev/null
@@ -0,0 +1,88 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 cmTargetCompileDefinitionsCommand_h
+#define cmTargetCompileDefinitionsCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+class cmTargetCompileDefinitionsCommand : public cmTargetPropCommandBase
+{
+public:
+  /**
+   * This is a virtual constructor for the command.
+   */
+  virtual cmCommand* Clone()
+    {
+    return new cmTargetCompileDefinitionsCommand;
+    }
+
+  /**
+   * This is called when the command is first encountered in
+   * the CMakeLists.txt file.
+   */
+  virtual bool InitialPass(std::vector<std::string> const& args,
+                           cmExecutionStatus &status);
+
+  /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual const char* GetName() const { return "target_compile_definitions";}
+
+  /**
+   * Succinct documentation.
+   */
+  virtual const char* GetTerseDocumentation() const
+    {
+    return
+      "Add compile definitions to a target.";
+    }
+
+  /**
+   * More documentation.
+   */
+  virtual const char* GetFullDocumentation() const
+    {
+    return
+      "  target_compile_definitions(<target> "
+      "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
+      "    [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
+      "Specify compile definitions to use when compiling a given target.  "
+      "The named <target> must have been created by a command such as "
+      "add_executable or add_library and must not be an IMPORTED target.  "
+      "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
+      "the scope of the following arguments.  PRIVATE and PUBLIC items will "
+      "populate the COMPILE_DEFINITIONS property of <target>.  PUBLIC and "
+      "INTERFACE items will populate the INTERFACE_COMPILE_DEFINITIONS "
+      "property of <target>.   "
+      "The following arguments specify compile definitions.  "
+      "Repeated calls for the same <target> append items in the order called."
+      "\n"
+      "Arguments to target_compile_definitions may use \"generator "
+      "expressions\" with the syntax \"$<...>\".  "
+      CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
+      ;
+    }
+
+  cmTypeMacro(cmTargetCompileDefinitionsCommand, cmTargetPropCommandBase);
+
+private:
+  virtual void HandleImportedTarget(const std::string &tgt);
+  virtual void HandleMissingTarget(const std::string &name);
+
+  virtual void HandleDirectContent(cmTarget *tgt,
+                                   const std::vector<std::string> &content,
+                                   bool prepend);
+  virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
new file mode 100644 (file)
index 0000000..12d0a51
--- /dev/null
@@ -0,0 +1,74 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 "cmTargetIncludeDirectoriesCommand.h"
+
+//----------------------------------------------------------------------------
+bool cmTargetIncludeDirectoriesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+  return this->HandleArguments(args, "INCLUDE_DIRECTORIES", PROCESS_BEFORE);
+}
+
+//----------------------------------------------------------------------------
+void cmTargetIncludeDirectoriesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+  cmOStringStream e;
+  e << "Cannot specify include directories for imported target \""
+    << tgt << "\".";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetIncludeDirectoriesCommand
+::HandleMissingTarget(const std::string &name)
+{
+  cmOStringStream e;
+  e << "Cannot specify include directories for target \"" << name << "\" "
+       "which is not built by this project.";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetIncludeDirectoriesCommand
+::Join(const std::vector<std::string> &content)
+{
+  std::string dirs;
+  std::string sep;
+  std::string prefix = this->Makefile->GetStartDirectory() + std::string("/");
+  for(std::vector<std::string>::const_iterator it = content.begin();
+    it != content.end(); ++it)
+    {
+    if (cmSystemTools::FileIsFullPath(it->c_str())
+        || cmGeneratorExpression::Find(*it) != std::string::npos)
+      {
+      dirs += sep + *it;
+      }
+    else
+      {
+      dirs += sep + prefix + *it;
+      }
+    sep = ";";
+    }
+  return dirs;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetIncludeDirectoriesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+                      bool prepend)
+{
+  cmListFileBacktrace lfbt;
+  this->Makefile->GetBacktrace(lfbt);
+  cmValueWithOrigin entry(this->Join(content), lfbt);
+  tgt->InsertInclude(entry, prepend);
+}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
new file mode 100644 (file)
index 0000000..e4bc9cf
--- /dev/null
@@ -0,0 +1,93 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 cmTargetIncludeDirectoriesCommand_h
+#define cmTargetIncludeDirectoriesCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+//----------------------------------------------------------------------------
+class cmTargetIncludeDirectoriesCommand : public cmTargetPropCommandBase
+{
+public:
+  /**
+   * This is a virtual constructor for the command.
+   */
+  virtual cmCommand* Clone()
+    {
+    return new cmTargetIncludeDirectoriesCommand;
+    }
+
+  /**
+   * This is called when the command is first encountered in
+   * the CMakeLists.txt file.
+   */
+  virtual bool InitialPass(std::vector<std::string> const& args,
+                           cmExecutionStatus &status);
+
+  /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual const char* GetName() const { return "target_include_directories";}
+
+  /**
+   * Succinct documentation.
+   */
+  virtual const char* GetTerseDocumentation() const
+    {
+    return
+      "Add include directories to a target.";
+    }
+
+  /**
+   * More documentation.
+   */
+  virtual const char* GetFullDocumentation() const
+    {
+    return
+      "  target_include_directories(<target> [BEFORE] "
+      "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
+      "    [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
+      "Specify include directories or targets to use when compiling a given "
+      "target.  "
+      "The named <target> must have been created by a command such as "
+      "add_executable or add_library and must not be an IMPORTED target.\n"
+      "If BEFORE is specified, the content will be prepended to the property "
+      "instead of being appended.\n"
+      "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
+      "the scope of the following arguments.  PRIVATE and PUBLIC items will "
+      "populate the INCLUDE_DIRECTORIES property of <target>.  PUBLIC and "
+      "INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES "
+      "property of <target>.   "
+      "The following arguments specify include directories.  Specified "
+      "include directories may be absolute paths or relative paths.  "
+      "Repeated calls for the same <target> append items in the order called."
+      "\n"
+      "Arguments to target_include_directories may use \"generator "
+      "expressions\" with the syntax \"$<...>\".  "
+      CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
+      ;
+    }
+
+  cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmTargetPropCommandBase);
+
+private:
+  virtual void HandleImportedTarget(const std::string &tgt);
+  virtual void HandleMissingTarget(const std::string &name);
+
+  virtual void HandleDirectContent(cmTarget *tgt,
+                                   const std::vector<std::string> &content,
+                                   bool prepend);
+  virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif
index f42b0f6..b7b7691 100644 (file)
@@ -11,6 +11,8 @@
 ============================================================================*/
 #include "cmTargetLinkLibrariesCommand.h"
 
+#include "cmGeneratorExpression.h"
+
 const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
 {
   "general",
index 63114d2..c683016 100644 (file)
@@ -13,6 +13,7 @@
 #define cmTargetLinkLibrariesCommand_h
 
 #include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
 
 /** \class cmTargetLinkLibrariesCommand
  * \brief Specify a list of libraries to link into executables.
@@ -92,7 +93,21 @@ public:
       "linked to this target will appear on the link line for the other "
       "target too.  "
       "See the LINK_INTERFACE_LIBRARIES target property to override the "
-      "set of transitive link dependencies for a target."
+      "set of transitive link dependencies for a target.  "
+      "Calls to other signatures of this command may set the property "
+      "making any libraries linked exclusively by this signature private."
+      "\n"
+      "CMake will also propagate \"usage requirements\" from linked library "
+      "targets.  "
+      "Usage requirements affect compilation of sources in the <target>.  "
+      "They are specified by properties defined on linked targets.  "
+      "During generation of the build system, CMake integrates "
+      "usage requirement property values with the corresponding "
+      "build properties for <target>:\n"
+      " INTERFACE_COMPILE_DEFINITONS: Appends to COMPILE_DEFINITONS\n"
+      " INTERFACE_INCLUDE_DIRECTORIES: Appends to INCLUDE_DIRECTORIES\n"
+      " INTERFACE_POSITION_INDEPENDENT_CODE: Sets POSITION_INDEPENDENT_CODE\n"
+      "   or checked for consistency with existing value\n"
       "\n"
       "  target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
       "                        [[debug|optimized|general] <lib>] ...)\n"
@@ -100,11 +115,11 @@ public:
       "to the LINK_INTERFACE_LIBRARIES and its per-configuration equivalent "
       "target properties instead of using them for linking.  "
       "Libraries specified as \"debug\" are appended to the "
-      "the LINK_INTERFACE_LIBRARIES_DEBUG property (or to the properties "
+      "LINK_INTERFACE_LIBRARIES_DEBUG property (or to the properties "
       "corresponding to configurations listed in the DEBUG_CONFIGURATIONS "
       "global property if it is set).  "
       "Libraries specified as \"optimized\" are appended to the "
-      "the LINK_INTERFACE_LIBRARIES property.  "
+      "LINK_INTERFACE_LIBRARIES property.  "
       "Libraries specified as \"general\" (or without any keyword) are "
       "treated as if specified for both \"debug\" and \"optimized\"."
       "\n"
@@ -141,6 +156,12 @@ public:
       "However, if two archives are really so interdependent they should "
       "probably be combined into a single archive."
       ")"
+      "\n"
+      "Arguments to target_link_libraries may use \"generator expressions\" "
+      "with the syntax \"$<...>\".  Note however, that generator expressions "
+      "will not be used in OLD handling of CMP0003 or CMP0004."
+      "\n"
+      CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
       ;
     }
 
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
new file mode 100644 (file)
index 0000000..771097c
--- /dev/null
@@ -0,0 +1,144 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 "cmTargetPropCommandBase.h"
+
+#include "cmGlobalGenerator.h"
+
+//----------------------------------------------------------------------------
+bool cmTargetPropCommandBase
+::HandleArguments(std::vector<std::string> const& args, const char *prop,
+                 ArgumentFlags flags)
+{
+  if(args.size() < 3)
+    {
+    this->SetError("called with incorrect number of arguments");
+    return false;
+    }
+
+  // Lookup the target for which libraries are specified.
+  this->Target =
+    this->Makefile->GetCMakeInstance()
+    ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+  if(!this->Target)
+    {
+    this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
+    }
+  if(!this->Target)
+    {
+    this->HandleMissingTarget(args[0]);
+    return false;
+    }
+  if ((this->Target->GetType() != cmTarget::SHARED_LIBRARY)
+    && (this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+    && (this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
+    && (this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+    && (this->Target->GetType() != cmTarget::EXECUTABLE))
+    {
+    this->SetError("called with non-compilable target type");
+    return false;
+    }
+
+  unsigned int argIndex = 1;
+
+  bool prepend = false;
+  if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE")
+    {
+    if (args.size() < 4)
+      {
+      this->SetError("called with incorrect number of arguments");
+      return false;
+      }
+    prepend = true;
+    ++argIndex;
+    }
+
+  this->Property = prop;
+
+  while (argIndex < args.size())
+    {
+    if (!this->ProcessContentArgs(args, argIndex, prepend))
+      {
+      return false;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetPropCommandBase
+::ProcessContentArgs(std::vector<std::string> const& args,
+                     unsigned int &argIndex, bool prepend)
+{
+  const std::string scope = args[argIndex];
+
+  if(scope != "PUBLIC"
+      && scope != "PRIVATE"
+      && scope != "INTERFACE" )
+    {
+    this->SetError("called with invalid arguments");
+    return false;
+    }
+
+  if(this->Target->IsImported())
+    {
+    this->HandleImportedTarget(args[0]);
+    return false;
+    }
+
+  ++argIndex;
+
+  std::vector<std::string> content;
+
+  for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex)
+    {
+    if(args[i] == "PUBLIC"
+        || args[i] == "PRIVATE"
+        || args[i] == "INTERFACE" )
+      {
+      this->PopulateTargetProperies(scope, content, prepend);
+      return true;
+      }
+    content.push_back(args[i]);
+    }
+  this->PopulateTargetProperies(scope, content, prepend);
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetPropCommandBase
+::PopulateTargetProperies(const std::string &scope,
+                          const std::vector<std::string> &content,
+                          bool prepend)
+{
+  if (scope == "PRIVATE" || scope == "PUBLIC")
+    {
+    this->HandleDirectContent(this->Target, content, prepend);
+    }
+  if (scope == "INTERFACE" || scope == "PUBLIC")
+    {
+    if (prepend)
+      {
+      const std::string propName = std::string("INTERFACE_") + this->Property;
+      const char *propValue = this->Target->GetProperty(propName.c_str());
+      const std::string totalContent = this->Join(content) + (propValue
+                                                ? std::string(";") + propValue
+                                                : std::string());
+      this->Target->SetProperty(propName.c_str(), totalContent.c_str());
+      }
+    else
+      {
+      this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(),
+                                   this->Join(content).c_str());
+      }
+    }
+}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
new file mode 100644 (file)
index 0000000..8047a48
--- /dev/null
@@ -0,0 +1,55 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+  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 cmTargetPropCommandBase_h
+#define cmTargetPropCommandBase_h
+
+#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
+
+class cmTarget;
+
+//----------------------------------------------------------------------------
+class cmTargetPropCommandBase : public cmCommand
+{
+public:
+
+  enum ArgumentFlags {
+    NO_FLAGS = 0,
+    PROCESS_BEFORE = 1
+  };
+
+  bool HandleArguments(std::vector<std::string> const& args,
+                           const char *prop, ArgumentFlags flags = NO_FLAGS);
+
+  cmTypeMacro(cmTargetPropCommandBase, cmCommand);
+protected:
+  std::string Property;
+  cmTarget *Target;
+
+private:
+  virtual void HandleImportedTarget(const std::string &tgt) = 0;
+  virtual void HandleMissingTarget(const std::string &name) = 0;
+
+  virtual void HandleDirectContent(cmTarget *tgt,
+                                   const std::vector<std::string> &content,
+                                   bool prepend) = 0;
+  virtual std::string Join(const std::vector<std::string> &content) = 0;
+
+  bool ProcessContentArgs(std::vector<std::string> const& args,
+                          unsigned int &argIndex, bool prepend);
+  void PopulateTargetProperies(const std::string &scope,
+                               const std::vector<std::string> &content,
+                               bool prepend);
+};
+
+#endif
index 2f650e7..42f511e 100644 (file)
@@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
   else
     {
     // Use the command name given.
-    exe = ge.Parse(exe.c_str()).Evaluate(mf, config);
+    exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
     cmSystemTools::ConvertToUnixSlashes(exe);
     }
 
@@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
   for(std::vector<std::string>::const_iterator ci = command.begin()+1;
       ci != command.end(); ++ci)
     {
-    os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config));
+    os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
     }
 
   // Finish the test command.
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
new file mode 100644 (file)
index 0000000..ac26503
--- /dev/null
@@ -0,0 +1,134 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 "cmTimestamp.h"
+
+#include <cstring>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+//----------------------------------------------------------------------------
+std::string cmTimestamp::CurrentTime(
+  const std::string& formatString, bool utcFlag)
+{
+  time_t currentTimeT = time(0);
+  if(currentTimeT == time_t(-1))
+    {
+    return std::string();
+    }
+
+  return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag);
+}
+
+//----------------------------------------------------------------------------
+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)
+    {
+    return std::string();
+    }
+
+  return CreateTimestampFromTimeT(info.st_mtime, formatString, utcFlag);
+}
+
+//----------------------------------------------------------------------------
+std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
+    std::string formatString, bool utcFlag)
+{
+  if(formatString.empty())
+    {
+    formatString = "%Y-%m-%dT%H:%M:%S";
+    if(utcFlag)
+      {
+      formatString += "Z";
+      }
+    }
+
+  struct tm timeStruct;
+  memset(&timeStruct, 0, sizeof(timeStruct));
+
+  struct tm* ptr = (struct tm*) 0;
+  if(utcFlag)
+    {
+    ptr = gmtime(&timeT);
+    }
+  else
+    {
+    ptr = localtime(&timeT);
+    }
+
+  if(ptr == 0)
+    {
+    return std::string();
+    }
+
+  timeStruct = *ptr;
+
+  std::string result;
+  for(std::string::size_type i = 0; i < formatString.size(); ++i)
+    {
+    char c1 = formatString[i];
+    char c2 = (i+1 < formatString.size()) ?
+      formatString[i+1] : static_cast<char>(0);
+
+    if(c1 == '%' && c2 != 0)
+      {
+      result += AddTimestampComponent(c2, timeStruct);
+      ++i;
+      }
+    else
+      {
+      result += c1;
+      }
+    }
+
+  return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTimestamp::AddTimestampComponent(
+  char flag, struct tm& timeStruct)
+{
+  std::string formatString = "%";
+  formatString += flag;
+
+  switch(flag)
+    {
+    case 'd':
+    case 'H':
+    case 'I':
+    case 'j':
+    case 'm':
+    case 'M':
+    case 'S':
+    case 'U':
+    case 'w':
+    case 'y':
+    case 'Y':
+      break;
+    default:
+      {
+      return formatString;
+      }
+    }
+
+  char buffer[16];
+
+  size_t size = strftime(buffer, sizeof(buffer),
+    formatString.c_str(), &timeStruct);
+
+  return std::string(buffer, size);
+}
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
new file mode 100644 (file)
index 0000000..24c1869
--- /dev/null
@@ -0,0 +1,40 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 cmTimestamp_h
+#define cmTimestamp_h
+
+#include <string>
+#include <time.h>
+
+/** \class cmTimestamp
+ * \brief Utility class to generate sting representation of a timestamp
+ *
+ */
+class cmTimestamp
+{
+public:
+  cmTimestamp() {}
+
+  std::string CurrentTime(const std::string& formatString, bool utcFlag);
+
+  std::string FileModificationTime(const char* path,
+    const std::string& formatString, bool utcFlag);
+
+private:
+  std::string CreateTimestampFromTimeT(time_t timeT,
+      std::string formatString, bool utcFlag);
+
+  std::string AddTimestampComponent(char flag, struct tm& timeStruct);
+};
+
+
+#endif
index 68ec666..6caa130 100644 (file)
@@ -67,6 +67,7 @@ public:
       "  try_compile(RESULT_VAR <bindir> <srcfile>\n"
       "              [CMAKE_FLAGS flags...]\n"
       "              [COMPILE_DEFINITIONS flags...]\n"
+      "              [LINK_LIBRARIES libs...]\n"
       "              [OUTPUT_VARIABLE <var>]\n"
       "              [COPY_FILE <fileName>])\n"
       "Try building a source file into an executable.  "
@@ -90,7 +91,12 @@ public:
       "Some extra flags that can be included are,  "
       "INCLUDE_DIRECTORIES, LINK_DIRECTORIES, and LINK_LIBRARIES.  "
       "COMPILE_DEFINITIONS are -Ddefinition that will be passed to the "
-      "compile line.  "
+      "compile line.\n"
+      "The srcfile signature also accepts a LINK_LIBRARIES argument which "
+      "may contain a list of libraries or IMPORTED targets which will be "
+      "linked to in the generated project.  If LINK_LIBRARIES is specified "
+      "as a parameter to try_compile, then any LINK_LIBRARIES passed as "
+      "CMAKE_FLAGS will be ignored.\n"
       "try_compile creates a CMakeList.txt "
       "file on the fly that looks like this:\n"
       "  add_definitions( <expanded COMPILE_DEFINITIONS from calling "
index 7878729..13b9973 100644 (file)
@@ -81,7 +81,7 @@ public:
       "the executable, but it will not try to run the executable. Instead it "
       "will create cache variables which must be filled by the user or by "
       "presetting them in some CMake script file to the values the "
-      "executable would have produced if it would have been run on its actual "
+      "executable would have produced if it had been run on its actual "
       "target platform. These variables are RUN_RESULT_VAR (explanation see "
       "above) and if RUN_OUTPUT_VARIABLE (or OUTPUT_VARIABLE) was used, an "
       "additional cache variable "
index c60e8eb..64febbb 100644 (file)
@@ -182,8 +182,8 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] =
   {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0},
   {"SupportNobindOfDelayLoadedDLL", "DELAY:NOBIND", "", "true", 0},
   {"Profile", "PROFILE", "", "true", 0},
-  {"DelaySign", "DELAYSIGN:NO", "", "false", 0},
-  {"DelaySign", "DELAYSIGN", "", "true", 0},
+  {"LinkDelaySign", "DELAYSIGN:NO", "", "false", 0},
+  {"LinkDelaySign", "DELAYSIGN", "", "true", 0},
   {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
   {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
   {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0},
@@ -294,7 +294,7 @@ static cmVS7FlagTable cmVS10LinkFlagTable[] =
   {"MergeSections", "MERGE:",
    "Merge Sections",
    "", cmVS7FlagTable::UserValue},
-  {"KeyFile", "KEYFILE:",
+  {"LinkKeyFile", "KEYFILE:",
    "Key File",
    "", cmVS7FlagTable::UserValue},
   {"KeyContainer", "KEYCONTAINER:",
diff --git a/Source/cmVS12CLFlagTable.h b/Source/cmVS12CLFlagTable.h
new file mode 100644 (file)
index 0000000..8f51319
--- /dev/null
@@ -0,0 +1,297 @@
+static cmVS7FlagTable cmVS12CLFlagTable[] =
+{
+
+  //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: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},
+  {"PREfastAdditionalOptions", "analyze:",
+   "Additional Code Analysis Native options",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"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.
+  {"PREfastLog", "analyze:log ",
+   "Code Analysis Log",
+   "", cmVS7FlagTable::UserValue},
+  // Skip [AdditionalOptions] - no command line Switch.
+  {0,0,0,0,0}
+};
diff --git a/Source/cmVS12LibFlagTable.h b/Source/cmVS12LibFlagTable.h
new file mode 100644 (file)
index 0000000..10bb805
--- /dev/null
@@ -0,0 +1,102 @@
+static cmVS7FlagTable cmVS12LibFlagTable[] =
+{
+
+  //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/cmVS12LinkFlagTable.h b/Source/cmVS12LinkFlagTable.h
new file mode 100644 (file)
index 0000000..ce32e38
--- /dev/null
@@ -0,0 +1,343 @@
+static cmVS7FlagTable cmVS12LinkFlagTable[] =
+{
+
+  //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",
+   cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+  {"EnableUAC", "MANIFESTUAC:NO", "Enable User Account Control (UAC)", "",
+   cmVS7FlagTable::UserValueRequired},
+  {"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}
+};
index 1e37ca5..9cfb370 100644 (file)
 #include "cmVS11CLFlagTable.h"
 #include "cmVS11LinkFlagTable.h"
 #include "cmVS11LibFlagTable.h"
+#include "cmVS12CLFlagTable.h"
+#include "cmVS12LinkFlagTable.h"
+#include "cmVS12LibFlagTable.h"
 
 #include <cmsys/auto_ptr.hxx>
 
 static cmVS7FlagTable const*
 cmVSGetCLFlagTable(cmLocalVisualStudioGenerator* lg)
 {
-  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11)
+  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
+    { return cmVS12CLFlagTable; }
+  else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
     { return cmVS11CLFlagTable; }
-  return cmVS10CLFlagTable;
+  else
+    { return cmVS10CLFlagTable; }
 }
 
 static cmVS7FlagTable const*
 cmVSGetLibFlagTable(cmLocalVisualStudioGenerator* lg)
 {
-  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11)
+  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
+    { return cmVS12LibFlagTable; }
+  else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
     { return cmVS11LibFlagTable; }
-  return cmVS10LibFlagTable;
+  else
+    { return cmVS10LibFlagTable; }
 }
 
 static cmVS7FlagTable const*
 cmVSGetLinkFlagTable(cmLocalVisualStudioGenerator* lg)
 {
-  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS11)
+  if(lg->GetVersion() >= cmLocalVisualStudioGenerator::VS12)
+    { return cmVS12LinkFlagTable; }
+  else if(lg->GetVersion() == cmLocalVisualStudioGenerator::VS11)
     { return cmVS11LinkFlagTable; }
-  return cmVS10LinkFlagTable;
+  else
+    { return cmVS10LinkFlagTable; }
 }
 
 static std::string cmVS10EscapeXML(std::string arg)
@@ -109,6 +121,11 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
     {
     delete i->second;
     }
+  for(OptionsMap::iterator i = this->LinkOptions.begin();
+      i != this->LinkOptions.end(); ++i)
+    {
+    delete i->second;
+    }
   if(!this->BuildFileStream)
     {
     return;
@@ -181,6 +198,10 @@ void cmVisualStudio10TargetGenerator::Generate()
       {
       return;
       }
+    if(!this->ComputeLinkOptions())
+      {
+      return;
+      }
     }
   cmMakefile* mf = this->Target->GetMakefile();
   std::string path =  mf->GetStartOutputDirectory();
@@ -395,6 +416,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
       case cmTarget::UTILITY:
         configType += "Utility";
         break;
+      case cmTarget::GLOBAL_TARGET:
+      case cmTarget::UNKNOWN_LIBRARY:
+        break;
       }
     configType += "</ConfigurationType>\n";
     this->WriteString(configType.c_str(), 2);
@@ -416,8 +440,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
     mfcLine += useOfMfcValue + "</UseOfMfc>\n";
     this->WriteString(mfcLine.c_str(), 2);
 
-    if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
-       this->ClOptions[*i]->UsingUnicode() ||
+    if((this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
+       this->ClOptions[*i]->UsingUnicode()) ||
        this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
       {
       this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2);
@@ -560,6 +584,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
       sep = ";";
       }
     (*this->BuildFileStream ) << "</Outputs>\n";
+    if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
+      {
+      // VS >= 11 let us turn off linking of custom command outputs.
+      this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3);
+      (*this->BuildFileStream ) << "false</LinkObjects>\n";
+      }
     }
   this->WriteString("</CustomBuild>\n", 2);
 }
@@ -867,14 +897,23 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
       }
     }
 
-  for(std::vector<cmSourceFile*>::const_iterator
-        si = this->GeneratorTarget->ExternalObjects.begin();
-      si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+  if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
+    {
+    // For VS >= 11 we use LinkObjects to avoid linking custom command
+    // outputs.  Use Object for all external objects, generated or not.
+    this->WriteSources("Object", this->GeneratorTarget->ExternalObjects);
+    }
+  else
     {
     // If an object file is generated in this target, then vs10 will use
     // it in the build, and we have to list it as None instead of Object.
-    std::vector<cmSourceFile*> const* d = this->Target->GetSourceDepends(*si);
-    this->WriteSource((d && !d->empty())? "None":"Object", *si);
+    for(std::vector<cmSourceFile*>::const_iterator
+          si = this->GeneratorTarget->ExternalObjects.begin();
+        si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+      {
+      std::vector<cmSourceFile*> const* d=this->Target->GetSourceDepends(*si);
+      this->WriteSource((d && !d->empty())? "None":"Object", *si);
+      }
     }
 
   this->WriteSources("None", this->GeneratorTarget->ExtraSources);
@@ -898,7 +937,6 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
   cmSourceFile* source)
 {
   cmSourceFile& sf = *source;
-  cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
 
   std::string objectName;
   if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
@@ -1077,7 +1115,6 @@ void
 cmVisualStudio10TargetGenerator::
 OutputLinkIncremental(std::string const& configName)
 {
-  std::string CONFIG = cmSystemTools::UpperCase(configName);
   // static libraries and things greater than modules do not need
   // to set this option
   if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
@@ -1085,72 +1122,36 @@ OutputLinkIncremental(std::string const& configName)
     {
     return;
     }
-  const char* linkType = "SHARED";
-  if(this->Target->GetType() == cmTarget::EXECUTABLE)
-    {
-    linkType = "EXE";
-    }
+  Options& linkOptions = *(this->LinkOptions[configName]);
 
-  // assume incremental linking
-  const char* incremental = "true";
-  const char* linkLanguage =
-    this->Target->GetLinkerLanguage(configName.c_str());
-  if(!linkLanguage)
-    {
-    cmSystemTools::Error
-      ("CMake can not determine linker language for target:",
-       this->Name.c_str());
-    return;
-    }
-  std::string linkFlagVarBase = "CMAKE_";
-  linkFlagVarBase += linkType;
-  linkFlagVarBase += "_LINKER_FLAGS";
-  std::string flags = this->
-    Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
-  std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
-  flags += this->
-    Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
-  if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
-     || strcmp(linkLanguage, "Fortran") == 0)
-    {
-    std::string baseFlagVar = "CMAKE_";
-    baseFlagVar += linkLanguage;
-    baseFlagVar += "_FLAGS";
-    flags += this->
-      Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
-    std::string flagVar = baseFlagVar + std::string("_") + CONFIG;
-    flags +=
-      Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
-    }
-  const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
-  if(targetLinkFlags)
-    {
-    flags += " ";
-    flags += targetLinkFlags;
-    }
-  std::string flagsProp = "LINK_FLAGS_";
-  flagsProp += CONFIG;
-  if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
-    {
-    flags += " ";
-    flags += flagsConfig;
-    }
-  if(flags.find("INCREMENTAL:NO") != flags.npos)
-    {
-    incremental = "false";
-    }
+  const char* incremental = linkOptions.GetFlag("LinkIncremental");
   this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3);
-  *this->BuildFileStream << incremental
+  *this->BuildFileStream << (incremental?incremental:"true")
                          << "</LinkIncremental>\n";
+  linkOptions.RemoveFlag("LinkIncremental");
 
-  const char* manifest = "true";
-  if(flags.find("MANIFEST:NO") != flags.npos)
-    {
-    manifest = "false";
-    }
+  const char* manifest = linkOptions.GetFlag("GenerateManifest");
   this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3);
-  *this->BuildFileStream << manifest
+  *this->BuildFileStream << (manifest?manifest:"true")
                          << "</GenerateManifest>\n";
+  linkOptions.RemoveFlag("GenerateManifest");
+
+  // Some link options belong here.  Use them now and remove them so that
+  // WriteLinkOptions does not use them.
+  const char* flags[] = {
+    "LinkDelaySign",
+    "LinkKeyFile",
+    0};
+  for(const char** f = flags; *f; ++f)
+    {
+    const char* flag = *f;
+    if(const char* value = linkOptions.GetFlag(flag))
+      {
+      this->WritePlatformConfigTag(flag, configName.c_str(), 3);
+      *this->BuildFileStream << value << "</" << flag << ">\n";
+      linkOptions.RemoveFlag(flag);
+      }
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -1231,9 +1232,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   clOptions.AddFlag("PrecompiledHeader", "NotUsing");
   clOptions.Parse(flags.c_str());
   clOptions.Parse(defineFlags.c_str());
-  clOptions.AddDefines(
-                     this->GeneratorTarget->GetCompileDefinitions().c_str());
-  clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions(
+  clOptions.AddDefines(this->Target->GetCompileDefinitions(
                                                 configName.c_str()).c_str());
   clOptions.SetVerboseMakefile(
     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -1343,18 +1342,36 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
     }
 }
 
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeLinkOptions()
+{
+  if(this->Target->GetType() == cmTarget::EXECUTABLE ||
+     this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+     this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    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->ComputeLinkOptions(*i))
+        {
+        return false;
+        }
+      }
+    }
+  return true;
+}
 
-void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
-                                                       config)
+//----------------------------------------------------------------------------
+bool
+cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
 {
+  cmsys::auto_ptr<Options> pOptions(
+    new Options(this->LocalGenerator, Options::Linker,
+                cmVSGetLinkFlagTable(this->LocalGenerator), 0, this));
+  Options& linkOptions = *pOptions;
 
-  // static libraries and things greater than modules do not need
-  // to set this option
-  if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
-     || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
-    {
-    return;
-    }
   const char* linkLanguage =
     this->Target->GetLinkerLanguage(config.c_str());
   if(!linkLanguage)
@@ -1362,10 +1379,9 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
     cmSystemTools::Error
       ("CMake can not determine linker language for target:",
        this->Name.c_str());
-    return;
+    return false;
     }
 
-  this->WriteString("<Link>\n", 2);
   std::string CONFIG = cmSystemTools::UpperCase(config);
 
   const char* linkType = "SHARED";
@@ -1384,10 +1400,9 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
   std::string flags;
   if(stackVal)
     {
-    flags += " ";
+    flags += " /STACK:";
     flags += stackVal;
     }
-  // assume incremental linking
   std::string linkFlagVarBase = "CMAKE_";
   linkFlagVarBase += linkType;
   linkFlagVarBase += "_LINKER_FLAGS";
@@ -1411,10 +1426,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
     flags += " ";
     flags += flagsConfig;
     }
-  cmVisualStudioGeneratorOptions
-    linkOptions(this->LocalGenerator,
-                cmVisualStudioGeneratorOptions::Linker,
-                cmVSGetLinkFlagTable(this->LocalGenerator), 0, this);
   if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
     {
     flags += " /SUBSYSTEM:WINDOWS";
@@ -1423,8 +1434,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
     {
     flags += " /SUBSYSTEM:CONSOLE";
     }
-  cmSystemTools::ReplaceString(flags, "/INCREMENTAL:YES", "");
-  cmSystemTools::ReplaceString(flags, "/INCREMENTAL:NO", "");
   std::string standardLibsVar = "CMAKE_";
   standardLibsVar += linkLanguage;
   standardLibsVar += "_STANDARD_LIBRARIES";
@@ -1446,13 +1455,13 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
   // Replace spaces in libs with ;
   cmSystemTools::ReplaceString(libs, " ", ";");
   cmComputeLinkInformation* pcli =
-    this->GeneratorTarget->GetLinkInformation(config.c_str());
+    this->Target->GetLinkInformation(config.c_str());
   if(!pcli)
     {
     cmSystemTools::Error
       ("CMake can not compute cmComputeLinkInformation for target:",
        this->Name.c_str());
-    return;
+    return false;
     }
   // add the libraries for the target to libs string
   cmComputeLinkInformation& cli = *pcli;
@@ -1521,7 +1530,22 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
                         this->GeneratorTarget->ModuleDefinitionFile.c_str());
     }
 
-  linkOptions.RemoveFlag("GenerateManifest");
+  this->LinkOptions[config] = pOptions.release();
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
+{
+  if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
+     || this->Target->GetType() > cmTarget::MODULE_LIBRARY)
+    {
+    return;
+    }
+  Options& linkOptions = *(this->LinkOptions[config]);
+  this->WriteString("<Link>\n", 2);
+
   linkOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
   linkOptions.OutputFlagMap(*this->BuildFileStream, "      ");
 
index 308b9bd..55a850a 100644 (file)
@@ -68,6 +68,8 @@ private:
                       std::vector<std::string> const & includes);
   void WriteRCOptions(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);
@@ -95,6 +97,7 @@ private:
   typedef cmVisualStudioGeneratorOptions Options;
   typedef std::map<cmStdString, Options*> OptionsMap;
   OptionsMap ClOptions;
+  OptionsMap LinkOptions;
   std::string PathToVcxproj;
   cmTarget* Target;
   cmGeneratorTarget* GeneratorTarget;
index 1df0d9e..01950e1 100644 (file)
@@ -66,6 +66,7 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
       break;
     case cmLocalVisualStudioGenerator::VS10:
     case cmLocalVisualStudioGenerator::VS11:
+    case cmLocalVisualStudioGenerator::VS12:
       // 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
diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx
new file mode 100644 (file)
index 0000000..b302246
--- /dev/null
@@ -0,0 +1,175 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 "cmVisualStudioWCEPlatformParser.h"
+#include "cmGlobalVisualStudioGenerator.h"
+#include "cmXMLParser.h"
+
+int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version)
+{
+  const std::string registryBase =
+    cmGlobalVisualStudioGenerator::GetRegistryBase(version);
+  const std::string vckey = registryBase + "\\Setup\\VC;ProductDir";
+  const std::string vskey = registryBase + "\\Setup\\VS;ProductDir";
+
+  if(!cmSystemTools::ReadRegistryValue(vckey.c_str(), this->VcInstallDir) ||
+     !cmSystemTools::ReadRegistryValue(vskey.c_str(), this->VsInstallDir))
+    {
+    return 0;
+    }
+  cmSystemTools::ConvertToUnixSlashes(this->VcInstallDir);
+  cmSystemTools::ConvertToUnixSlashes(this->VsInstallDir);
+  this->VcInstallDir.append("/");
+  this->VsInstallDir.append("/");
+
+  const std::string configFilename =
+    this->VcInstallDir + "vcpackages/WCE.VCPlatform.config";
+
+  return this->ParseFile(configFilename.c_str());
+}
+
+std::string cmVisualStudioWCEPlatformParser::GetOSVersion() const
+{
+  if (this->OSMinorVersion.empty())
+    {
+    return OSMajorVersion;
+    }
+
+  return OSMajorVersion + "." + OSMinorVersion;
+}
+
+const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
+{
+  std::map<std::string, std::string>::const_iterator it =
+    this->Macros.find("ARCHFAM");
+  if (it != this->Macros.end())
+    {
+    return it->second.c_str();
+    }
+
+  return 0;
+}
+
+void cmVisualStudioWCEPlatformParser::StartElement(const char* name,
+                                                   const char** attributes)
+{
+  if(this->FoundRequiredName)
+    {
+    return;
+    }
+
+  this->CharacterData = "";
+
+  if(strcmp(name, "PlatformData") == 0)
+    {
+    this->PlatformName = "";
+    this->OSMajorVersion = "";
+    this->OSMinorVersion = "";
+    this->Macros.clear();
+    }
+
+  if(strcmp(name, "Macro") == 0)
+    {
+    std::string macroName;
+    std::string macroValue;
+
+    for(const char** attr = attributes; *attr; attr += 2)
+      {
+      if(strcmp(attr[0], "Name") == 0)
+        {
+        macroName = attr[1];
+        }
+      else if(strcmp(attr[0], "Value") == 0)
+        {
+        macroValue = attr[1];
+        }
+      }
+
+    if(!macroName.empty())
+      {
+      this->Macros[macroName] = macroValue;
+      }
+    }
+  else if(strcmp(name, "Directories") == 0)
+    {
+    for(const char** attr = attributes; *attr; attr += 2)
+      {
+      if(strcmp(attr[0], "Include") == 0)
+        {
+        this->Include = attr[1];
+        }
+      else if(strcmp(attr[0], "Library") == 0)
+        {
+        this->Library = attr[1];
+        }
+      else if(strcmp(attr[0], "Path") == 0)
+        {
+        this->Path = attr[1];
+        }
+      }
+    }
+}
+
+void cmVisualStudioWCEPlatformParser::EndElement(const char* name)
+{
+  if(!this->RequiredName)
+    {
+    if(strcmp(name, "PlatformName") == 0)
+      {
+      this->AvailablePlatforms.push_back(this->CharacterData);
+      }
+    return;
+    }
+
+  if(this->FoundRequiredName)
+    {
+    return;
+    }
+
+  if(strcmp(name, "PlatformName") == 0)
+    {
+    this->PlatformName = this->CharacterData;
+    }
+  else if(strcmp(name, "OSMajorVersion") == 0)
+    {
+    this->OSMajorVersion = this->CharacterData;
+    }
+  else if(strcmp(name, "OSMinorVersion") == 0)
+   {
+   this->OSMinorVersion = this->CharacterData;
+   }
+  else if(strcmp(name, "Platform") == 0)
+    {
+    if(this->PlatformName == this->RequiredName)
+      {
+      this->FoundRequiredName = true;
+      }
+    }
+}
+
+void cmVisualStudioWCEPlatformParser::CharacterDataHandler(const char* data,
+                                                           int length)
+{
+  this->CharacterData.append(data, length);
+}
+
+std::string cmVisualStudioWCEPlatformParser::FixPaths(
+    const std::string& paths) const
+{
+  std::string ret = paths;
+  cmSystemTools::ReplaceString(ret, "$(PATH)", "%PATH%");
+  cmSystemTools::ReplaceString(ret, "$(VCInstallDir)", VcInstallDir.c_str());
+  cmSystemTools::ReplaceString(ret, "$(VSInstallDir)", VsInstallDir.c_str());
+  cmSystemTools::ReplaceString(ret, "\\", "/");
+  cmSystemTools::ReplaceString(ret, "//", "/");
+  cmSystemTools::ReplaceString(ret, "/", "\\");
+  return ret;
+}
diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h
new file mode 100644 (file)
index 0000000..466e1dd
--- /dev/null
@@ -0,0 +1,68 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmVisualStudioWCEPlatformParser_h
+#define cmVisualStudioWCEPlatformParser_h
+#include "cmStandardIncludes.h"
+
+#include "cmXMLParser.h"
+
+// This class is used to parse XML with configuration
+// of installed SDKs in system
+class cmVisualStudioWCEPlatformParser : public cmXMLParser
+{
+public:
+  cmVisualStudioWCEPlatformParser(const char* name = NULL)
+      : RequiredName(name)
+      , FoundRequiredName(false)
+    {
+    }
+
+  int ParseVersion(const char* version);
+
+  bool Found() const {return this->FoundRequiredName;}
+  const char* GetArchitectureFamily() const;
+  std::string GetOSVersion() const;
+  std::string GetIncludeDirectories() const {
+    return this->FixPaths(this->Include); }
+  std::string GetLibraryDirectories() const {
+    return this->FixPaths(this->Library); }
+  std::string GetPathDirectories() const {
+    return this->FixPaths(this->Path); }
+  const std::vector<std::string>& GetAvailablePlatforms() const {
+    return this->AvailablePlatforms; }
+
+protected:
+  virtual void StartElement(const char* name, const char** attributes);
+  void EndElement(const char* name);
+  void CharacterDataHandler(const char* data, int length);
+
+private:
+  std::string FixPaths(const std::string& paths) const;
+
+  std::string CharacterData;
+
+  std::string Include;
+  std::string Library;
+  std::string Path;
+  std::string PlatformName;
+  std::string OSMajorVersion;
+  std::string OSMinorVersion;
+  std::map<std::string, std::string> Macros;
+  std::vector<std::string> AvailablePlatforms;
+
+  const char* RequiredName;
+  bool FoundRequiredName;
+  std::string VcInstallDir;
+  std::string VsInstallDir;
+};
+
+#endif
index 9a536c1..5752ab6 100644 (file)
@@ -271,13 +271,6 @@ bool cmWin32ProcessExecution::Wait(int timeout)
   return this->PrivateClose(timeout);
 }
 
-/*
- * Internal dictionary mapping popen* file pointers to process handles,
- * for use when retrieving the process exit code.  See _PyPclose() below
- * for more information on this dictionary's use.
- */
-static void *_PyPopenProcs = NULL;
-
 static BOOL RealPopenCreateProcess(const char *cmdstring,
                                    const char *path,
                                    const char *szConsoleSpawn,
@@ -679,18 +672,6 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
       }
     }
 
-  /*
-   * Insert the files we've created into the process dictionary
-   * all referencing the list with the process handle and the
-   * initial number of files (see description below in _PyPclose).
-   * Since if _PyPclose later tried to wait on a process when all
-   * handles weren't closed, it could create a deadlock with the
-   * child, we spend some energy here to try to ensure that we
-   * either insert all file handles into the dictionary or none
-   * at all.  It's a little clumsy with the various popen modes
-   * and variable number of files involved.
-   */
-
   /* Child is launched. Close the parents copy of those pipe
    * handles that only the child should have open.  You need to
    * make sure that no handles to the write end of the output pipe
@@ -761,43 +742,6 @@ cmWin32ProcessExecution::~cmWin32ProcessExecution()
   this->CloseHandles();
 }
 
-/*
- * Wrapper for fclose() to use for popen* files, so we can retrieve the
- * exit code for the child process and return as a result of the close.
- *
- * This function uses the _PyPopenProcs dictionary in order to map the
- * input file pointer to information about the process that was
- * originally created by the popen* call that created the file pointer.
- * The dictionary uses the file pointer as a key (with one entry
- * inserted for each file returned by the original popen* call) and a
- * single list object as the value for all files from a single call.
- * The list object contains the Win32 process handle at [0], and a file
- * count at [1], which is initialized to the total number of file
- * handles using that list.
- *
- * This function closes whichever handle it is passed, and decrements
- * the file count in the dictionary for the process handle pointed to
- * by this file.  On the last close (when the file count reaches zero),
- * this function will wait for the child process and then return its
- * exit code as the result of the close() operation.  This permits the
- * files to be closed in any order - it is always the close() of the
- * final handle that will return the exit code.
- */
-
- /* RED_FLAG 31-Aug-2000 Tim
-  * This is always called (today!) between a pair of
-  * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
-  * macros.  So the thread running this has no valid thread state, as
-  * far as Python is concerned.  However, this calls some Python API
-  * functions that cannot be called safely without a valid thread
-  * state, in particular PyDict_GetItem.
-  * As a temporary hack (although it may last for years ...), we
-  * *rely* on not having a valid thread state in this function, in
-  * order to create our own "from scratch".
-  * This will deadlock if _PyPclose is ever called by a thread
-  * holding the global lock.
-  */
-
 bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
 {
   HANDLE hProcess = this->ProcessHandle;
index de150ee..6abf6bf 100644 (file)
@@ -38,7 +38,6 @@ cmXCodeObject::~cmXCodeObject()
 cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
 {
   this->Version = 15;
-  this->PBXTargetDependencyValue = 0;
   this->Target = 0;
   this->Object =0;
 
index bb2d5b2..b89f78c 100644 (file)
@@ -120,14 +120,6 @@ public:
       return 0;
     }
 
-  cmXCodeObject* GetPBXTargetDependency()
-    {
-      return this->PBXTargetDependencyValue;
-    }
-  void SetPBXTargetDependency(cmXCodeObject* d)
-    {
-      this->PBXTargetDependencyValue = d;
-    }
   void CopyAttributes(cmXCodeObject* );
 
   void AddDependLibrary(const char* configName,
@@ -170,7 +162,6 @@ protected:
   cmStdString Comment;
   cmStdString String;
   cmXCodeObject* Object;
-  cmXCodeObject* PBXTargetDependencyValue;
   std::vector<cmXCodeObject*> List;
   std::map<cmStdString, StringVec> DependLibraries;
   std::map<cmStdString, StringVec> DependTargets;
index 0123427..376758e 100644 (file)
 #    include "cmGlobalVisualStudio71Generator.h"
 #    include "cmGlobalVisualStudio8Generator.h"
 #    include "cmGlobalVisualStudio9Generator.h"
-#    include "cmGlobalVisualStudio9IA64Generator.h"
-#    include "cmGlobalVisualStudio9Win64Generator.h"
 #    include "cmGlobalVisualStudio10Generator.h"
-#    include "cmGlobalVisualStudio10IA64Generator.h"
-#    include "cmGlobalVisualStudio10Win64Generator.h"
 #    include "cmGlobalVisualStudio11Generator.h"
-#    include "cmGlobalVisualStudio11Win64Generator.h"
-#    include "cmGlobalVisualStudio11ARMGenerator.h"
-#    include "cmGlobalVisualStudio8Win64Generator.h"
+#    include "cmGlobalVisualStudio12Generator.h"
 #    include "cmGlobalBorlandMakefileGenerator.h"
 #    include "cmGlobalNMakeMakefileGenerator.h"
 #    include "cmGlobalJOMMakefileGenerator.h"
 
 #if defined(CMAKE_HAVE_VS_GENERATORS)
 #include "cmCallVisualStudioMacro.h"
+#include "cmVisualStudioWCEPlatformParser.h"
 #endif
 
 #if !defined(CMAKE_BOOT_MINGW)
 # include "cmExtraCodeBlocksGenerator.h"
 #endif
+#include "cmExtraSublimeTextGenerator.h"
 
 #ifdef CMAKE_USE_KDEVELOP
 # include "cmGlobalKdevelopGenerator.h"
 
 #include <sys/stat.h> // struct stat
 
-#include <memory> // auto_ptr
-
 static bool cmakeCheckStampFile(const char* stampName);
 static bool cmakeCheckStampList(const char* stampName);
 
@@ -222,6 +216,11 @@ cmake::~cmake()
     {
     delete (*j).second;
     }
+  for(RegisteredGeneratorsVector::iterator j = this->Generators.begin();
+      j != this->Generators.end(); ++j)
+    {
+    delete *j;
+    }
 #ifdef CMAKE_BUILD_WITH_CMAKE
   delete this->VariableWatch;
 #endif
@@ -521,7 +520,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
   // read in the list file to fill the cache
   if(path)
     {
-    std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
+    cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
     lg->GetMakefile()->SetHomeOutputDirectory
       (cmSystemTools::GetCurrentWorkingDirectory().c_str());
     lg->GetMakefile()->SetStartOutputDirectory
@@ -560,7 +559,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
   this->SetGlobalGenerator(gg);
 
   // read in the list file to fill the cache
-  std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
   cmMakefile* mf = lg->GetMakefile();
   mf->SetHomeOutputDirectory
     (cmSystemTools::GetCurrentWorkingDirectory().c_str());
@@ -662,6 +661,7 @@ void cmake::SetArgs(const std::vector<std::string>& args,
                     bool directoriesSetBefore)
 {
   bool directoriesSet = directoriesSetBefore;
+  bool haveToolset = false;
   for(unsigned int i=1; i < args.size(); ++i)
     {
     std::string arg = args[i];
@@ -790,6 +790,27 @@ void cmake::SetArgs(const std::vector<std::string>& args,
                    "uninitialized variables.\n";
       this->SetCheckSystemVars(true);
       }
+    else if(arg.find("-T",0) == 0)
+      {
+      std::string value = arg.substr(2);
+      if(value.size() == 0)
+        {
+        ++i;
+        if(i >= args.size())
+          {
+          cmSystemTools::Error("No toolset specified for -T");
+          return;
+          }
+        value = args[i];
+        }
+      if(haveToolset)
+        {
+        cmSystemTools::Error("Multiple -T options not allowed");
+        return;
+        }
+      this->GeneratorToolset = value;
+      haveToolset = true;
+      }
     else if(arg.find("-G",0) == 0)
       {
       std::string value = arg.substr(2);
@@ -956,7 +977,7 @@ int cmake::AddCMakePaths()
   cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str());
   cMakeSelf += "/cmake";
   cMakeSelf += cmSystemTools::GetExecutableExtension();
-#if __APPLE__
+#ifdef __APPLE__
   // on the apple this might be the gui bundle
   if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
     {
@@ -1147,6 +1168,10 @@ void CMakeCommandUsage(const char* program)
     << "Available on Windows only:\n"
     << "  comspec                   - on windows 9x use this for RunCommand\n"
     << "  delete_regv key           - delete registry value\n"
+    << "  env_vs8_wince sdkname     - displays a batch file which sets the "
+       "environment for the provided Windows CE SDK installed in VS2005\n"
+    << "  env_vs9_wince sdkname     - displays a batch file which sets the "
+       "environment for the provided Windows CE SDK installed in VS2008\n"
     << "  write_regv key value      - write registry value\n"
 #else
     << "Available on UNIX only:\n"
@@ -1656,7 +1681,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
       if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str()))
         {
         cm.SetGlobalGenerator(ggd);
-        std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
+        cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
         lgd->GetMakefile()->SetStartDirectory(startDir.c_str());
         lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str());
         lgd->GetMakefile()->MakeStartDirectoriesCurrent();
@@ -1812,6 +1837,14 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
         }
       return cmWin32ProcessExecution::Windows9xHack(command.c_str());
       }
+    else if (args[1] == "env_vs8_wince" && args.size() == 3)
+      {
+      return cmake::WindowsCEEnvironment("8.0", args[2]);
+      }
+    else if (args[1] == "env_vs9_wince" && args.size() == 3)
+      {
+      return cmake::WindowsCEEnvironment("9.0", args[2]);
+      }
 #endif
     }
 
@@ -1847,6 +1880,8 @@ void cmake::AddDefaultExtraGenerators()
 
   this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(),
                           &cmExtraCodeBlocksGenerator::New);
+  this->AddExtraGenerator(cmExtraSublimeTextGenerator::GetActualName(),
+                          &cmExtraSublimeTextGenerator::New);
 
 #ifdef CMAKE_USE_ECLIPSE
   this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(),
@@ -1869,10 +1904,10 @@ void cmake::AddDefaultExtraGenerators()
 //----------------------------------------------------------------------------
 void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
 {
-  for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
+  for(RegisteredGeneratorsVector::const_iterator i = this->Generators.begin();
       i != this->Generators.end(); ++i)
     {
-    names.push_back(i->first);
+    (*i)->GetGenerators(names);
     }
   for(RegisteredExtraGeneratorsMap::const_iterator
       i = this->ExtraGenerators.begin();
@@ -1884,29 +1919,36 @@ void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
 
 cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
 {
-  cmGlobalGenerator* generator = 0;
   cmExternalMakefileProjectGenerator* extraGenerator = 0;
-  RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name);
-  if(genIt == this->Generators.end())
+  RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
+                                            this->ExtraGenerators.find(name);
+  if (extraGenIt != this->ExtraGenerators.end())
     {
-    RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
-                                              this->ExtraGenerators.find(name);
-    if (extraGenIt == this->ExtraGenerators.end())
-      {
-      return 0;
-      }
     extraGenerator = (extraGenIt->second)();
-    genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name));
-    if(genIt == this->Generators.end())
+    name = extraGenerator->GetGlobalGeneratorName(name);
+    }
+
+  cmGlobalGenerator* generator = 0;
+  for (RegisteredGeneratorsVector::const_iterator i =
+    this->Generators.begin(); i != this->Generators.end(); ++i)
+    {
+    generator = (*i)->CreateGlobalGenerator(name);
+    if (generator)
       {
-      delete extraGenerator;
-      return 0;
+      break;
       }
-  }
+    }
+
+  if (generator)
+    {
+    generator->SetCMakeInstance(this);
+    generator->SetExternalMakefileProjectGenerator(extraGenerator);
+    }
+  else
+    {
+    delete extraGenerator;
+    }
 
-  generator = (genIt->second)();
-  generator->SetCMakeInstance(this);
-  generator->SetExternalMakefileProjectGenerator(extraGenerator);
   return generator;
 }
 
@@ -2046,7 +2088,7 @@ struct SaveCacheEntry
 int cmake::HandleDeleteCacheVariables(const char* var)
 {
   std::vector<std::string> argsSplit;
-  cmSystemTools::ExpandListArgument(std::string(var), argsSplit);
+  cmSystemTools::ExpandListArgument(std::string(var), argsSplit, true);
   // erase the property to avoid infinite recursion
   this->SetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
   if(this->GetIsInTryCompile())
@@ -2203,6 +2245,7 @@ int cmake::ActualConfigure()
         {"9.0", "Visual Studio 9 2008"},
         {"10.0", "Visual Studio 10"},
         {"11.0", "Visual Studio 11"},
+        {"12.0", "Visual Studio 12"},
         {0, 0}};
       for(int i=0; version[i].MSVersion != 0; i++)
         {
@@ -2266,6 +2309,39 @@ int cmake::ActualConfigure()
                                 cmCacheManager::INTERNAL);
     }
 
+  if(const char* tsName =
+     this->CacheManager->GetCacheValue("CMAKE_GENERATOR_TOOLSET"))
+    {
+    if(this->GeneratorToolset.empty())
+      {
+      this->GeneratorToolset = tsName;
+      }
+    else if(this->GeneratorToolset != tsName)
+      {
+      std::string message = "Error: generator toolset: ";
+      message += this->GeneratorToolset;
+      message += "\nDoes not match the toolset used previously: ";
+      message += tsName;
+      message +=
+        "\nEither remove the CMakeCache.txt file or choose a different"
+        " binary directory.";
+      cmSystemTools::Error(message.c_str());
+      return -2;
+      }
+    }
+  else
+    {
+    this->CacheManager->AddCacheEntry("CMAKE_GENERATOR_TOOLSET",
+                                      this->GeneratorToolset.c_str(),
+                                      "Name of generator toolset.",
+                                      cmCacheManager::INTERNAL);
+    }
+  if(!this->GeneratorToolset.empty() &&
+     !this->GlobalGenerator->SetGeneratorToolset(this->GeneratorToolset))
+    {
+    return -2;
+    }
+
   // reset any system configuration information, except for when we are
   // InTryCompile. With TryCompile the system info is taken from the parent's
   // info to save time
@@ -2570,55 +2646,43 @@ void cmake::AddDefaultGenerators()
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 # if !defined(CMAKE_BOOT_MINGW)
-  this->Generators[cmGlobalVisualStudio6Generator::GetActualName()] =
-    &cmGlobalVisualStudio6Generator::New;
-  this->Generators[cmGlobalVisualStudio7Generator::GetActualName()] =
-    &cmGlobalVisualStudio7Generator::New;
-  this->Generators[cmGlobalVisualStudio10Generator::GetActualName()] =
-    &cmGlobalVisualStudio10Generator::New;
-  this->Generators[cmGlobalVisualStudio10IA64Generator::GetActualName()] =
-    &cmGlobalVisualStudio10IA64Generator::New;
-  this->Generators[cmGlobalVisualStudio10Win64Generator::GetActualName()] =
-    &cmGlobalVisualStudio10Win64Generator::New;
-  this->Generators[cmGlobalVisualStudio11Generator::GetActualName()] =
-    &cmGlobalVisualStudio11Generator::New;
-  this->Generators[cmGlobalVisualStudio11Win64Generator::GetActualName()] =
-    &cmGlobalVisualStudio11Win64Generator::New;
-  this->Generators[cmGlobalVisualStudio11ARMGenerator::GetActualName()] =
-    &cmGlobalVisualStudio11ARMGenerator::New;
-  this->Generators[cmGlobalVisualStudio71Generator::GetActualName()] =
-    &cmGlobalVisualStudio71Generator::New;
-  this->Generators[cmGlobalVisualStudio8Generator::GetActualName()] =
-    &cmGlobalVisualStudio8Generator::New;
-  this->Generators[cmGlobalVisualStudio9Generator::GetActualName()] =
-    &cmGlobalVisualStudio9Generator::New;
-  this->Generators[cmGlobalVisualStudio9IA64Generator::GetActualName()] =
-    &cmGlobalVisualStudio9IA64Generator::New;
-  this->Generators[cmGlobalVisualStudio9Win64Generator::GetActualName()] =
-    &cmGlobalVisualStudio9Win64Generator::New;
-  this->Generators[cmGlobalVisualStudio8Win64Generator::GetActualName()] =
-    &cmGlobalVisualStudio8Win64Generator::New;
-  this->Generators[cmGlobalBorlandMakefileGenerator::GetActualName()] =
-    &cmGlobalBorlandMakefileGenerator::New;
-  this->Generators[cmGlobalNMakeMakefileGenerator::GetActualName()] =
-    &cmGlobalNMakeMakefileGenerator::New;
-  this->Generators[cmGlobalJOMMakefileGenerator::GetActualName()] =
-    &cmGlobalJOMMakefileGenerator::New;
-  this->Generators[cmGlobalWatcomWMakeGenerator::GetActualName()] =
-    &cmGlobalWatcomWMakeGenerator::New;
+  this->Generators.push_back(
+    cmGlobalVisualStudio6Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio7Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio10Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio11Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio12Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio71Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio8Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalVisualStudio9Generator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalBorlandMakefileGenerator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalNMakeMakefileGenerator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalJOMMakefileGenerator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalWatcomWMakeGenerator::NewFactory());
 # endif
-  this->Generators[cmGlobalMSYSMakefileGenerator::GetActualName()] =
-    &cmGlobalMSYSMakefileGenerator::New;
-  this->Generators[cmGlobalMinGWMakefileGenerator::GetActualName()] =
-    &cmGlobalMinGWMakefileGenerator::New;
+  this->Generators.push_back(
+    cmGlobalMSYSMakefileGenerator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalMinGWMakefileGenerator::NewFactory());
 #endif
-  this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] =
-    &cmGlobalUnixMakefileGenerator3::New;
-  this->Generators[cmGlobalNinjaGenerator::GetActualName()] =
-    &cmGlobalNinjaGenerator::New;
+  this->Generators.push_back(
+    cmGlobalUnixMakefileGenerator3::NewFactory());
+  this->Generators.push_back(
+    cmGlobalNinjaGenerator::NewFactory());
 #ifdef CMAKE_USE_XCODE
-  this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
-    &cmGlobalXCodeGenerator::New;
+  this->Generators.push_back(
+    cmGlobalXCodeGenerator::NewFactory());
 #endif
 }
 
@@ -2712,17 +2776,15 @@ void cmake::GetPropertiesDocumentation(std::map<std::string,
 
 void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
 {
-  for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
-      i != this->Generators.end(); ++i)
+  for(RegisteredGeneratorsVector::const_iterator i =
+      this->Generators.begin(); i != this->Generators.end(); ++i)
     {
     cmDocumentationEntry e;
-    cmGlobalGenerator* generator = (i->second)();
-    generator->GetDocumentation(e);
-    delete generator;
+    (*i)->GetDocumentation(e);
     v.push_back(e);
     }
-  for(RegisteredExtraGeneratorsMap::const_iterator
-      i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
+  for(RegisteredExtraGeneratorsMap::const_iterator i =
+      this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
     {
     cmDocumentationEntry e;
     cmExternalMakefileProjectGenerator* generator = (i->second)();
@@ -2805,7 +2867,7 @@ int cmake::CheckBuildSystem()
   cmake cm;
   cmGlobalGenerator gg;
   gg.SetCMakeInstance(&cm);
-  std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+  cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
   cmMakefile* mf = lg->GetMakefile();
   if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) ||
      cmSystemTools::GetErrorOccuredFlag())
@@ -2831,11 +2893,11 @@ int cmake::CheckBuildSystem()
       }
 
     // Create the generator and use it to clear the dependencies.
-    std::auto_ptr<cmGlobalGenerator>
+    cmsys::auto_ptr<cmGlobalGenerator>
       ggd(this->CreateGlobalGenerator(genName));
     if(ggd.get())
       {
-      std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
+      cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
       lgd->ClearDependencies(mf, verbose);
       }
     }
@@ -3078,7 +3140,7 @@ void cmake::MarkCliAsUsed(const std::string& variable)
 void cmake::GenerateGraphViz(const char* fileName) const
 {
 #ifdef CMAKE_BUILD_WITH_CMAKE
-  std::auto_ptr<cmGraphVizWriter> gvWriter(
+  cmsys::auto_ptr<cmGraphVizWriter> gvWriter(
        new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators()));
 
   std::string settingsFile = this->GetHomeOutputDirectory();
@@ -3299,6 +3361,12 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
   int result = 0;
   while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
     {
+    // Skip empty command lines.
+    if(command.find_first_not_of(" \t") == command.npos)
+      {
+      continue;
+      }
+
     // Setup this command line.
     const char* cmd[2] = {command.c_str(), 0};
     cmsysProcess_SetCommand(cp, cmd);
@@ -3552,6 +3620,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
                                                   chained);
 }
 
+bool cmake::GetIsPropertyDefined(const char *name,
+                                 cmProperty::ScopeType scope)
+{
+  return this->PropertyDefinitions[scope].find(name) !=
+                                      this->PropertyDefinitions[scope].end();
+}
+
 cmPropertyDefinition *cmake
 ::GetPropertyDefinition(const char *name,
                         cmProperty::ScopeType scope)
@@ -3965,10 +4040,18 @@ static bool cmakeCheckStampFile(const char* stampName)
     }
 
   // The build system is up to date.  The stamp file has been removed
-  // by the VS IDE due to a "rebuild" request.  Just restore it.
-  std::ofstream stamp(stampName);
+  // by the VS IDE due to a "rebuild" request.  Restore it atomically.
+  cmOStringStream stampTempStream;
+  stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed();
+  std::string stampTempString = stampTempStream.str();
+  const char* stampTemp = stampTempString.c_str();
+  {
+  // TODO: Teach cmGeneratedFileStream to use a random temp file (with
+  // multiple tries in unlikely case of conflict) and use that here.
+  std::ofstream stamp(stampTemp);
   stamp << "# CMake generation timestamp file this directory.\n";
-  if(stamp)
+  }
+  if(cmSystemTools::RenameFile(stampTemp, stampName))
     {
     // Notify the user why CMake is not re-running.  It is safe to
     // just print to stdout here because this code is only reachable
@@ -3979,6 +4062,7 @@ static bool cmakeCheckStampFile(const char* stampName)
     }
   else
     {
+    cmSystemTools::RemoveFile(stampTemp);
     cmSystemTools::Error("Cannot restore timestamp ", stampName);
     return false;
     }
@@ -4014,6 +4098,29 @@ static bool cmakeCheckStampList(const char* stampList)
   return true;
 }
 
+//----------------------------------------------------------------------------
+int cmake::WindowsCEEnvironment(const char* version, const std::string& name)
+{
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+  cmVisualStudioWCEPlatformParser parser(name.c_str());
+  parser.ParseVersion(version);
+  if (parser.Found())
+    {
+    std::cout << "@echo off" << std::endl;
+    std::cout << "echo Environment Selection: " << name << std::endl;
+    std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
+    std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() <<std::endl;
+    std::cout << "set LIB=" << parser.GetLibraryDirectories() <<std::endl;
+    return 0;
+    }
+#else
+  (void)version;
+#endif
+
+  std::cerr << "Could not find " << name;
+  return -1;
+}
+
 // For visual studio 2005 and newer manifest files need to be embeded into
 // exe and dll's.  This code does that in such a way that incremental linking
 // still works.
@@ -4358,6 +4465,10 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
     isError = true;
     msg << "CMake Internal Error (please report a bug)";
     }
+  else if(t == cmake::LOG)
+    {
+    msg << "CMake Debug Log";
+    }
   else
     {
     msg << "CMake Warning";
@@ -4477,7 +4588,7 @@ int cmake::Build(const std::string& dir,
     std::cerr << "Error: could find generator in Cache\n";
     return 1;
     }
-  std::auto_ptr<cmGlobalGenerator> gen(
+  cmsys::auto_ptr<cmGlobalGenerator> gen(
     this->CreateGlobalGenerator(it.GetValue()));
   std::string output;
   std::string projName;
index 94c6f12..63065a1 100644 (file)
@@ -17,6 +17,7 @@
 #include "cmPropertyDefinitionMap.h"
 #include "cmPropertyMap.h"
 
+class cmGlobalGeneratorFactory;
 class cmGlobalGenerator;
 class cmLocalGenerator;
 class cmCacheManager;
@@ -186,6 +187,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 toolset.
+  void SetGeneratorToolset(std::string const& ts)
+    { this->GeneratorToolset = ts; }
+
+  ///! Get the name of the selected generator-specific toolset.
+  std::string const& GetGeneratorToolset() const
+    { return this->GeneratorToolset; }
+
   ///! get the cmCachemManager used by this invocation of cmake
   cmCacheManager *GetCacheManager() { return this->CacheManager; }
 
@@ -340,6 +349,8 @@ class cmake
                       bool chain = false,
                       const char *variableGroup = 0);
 
+  bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
+
   // get property definition
   cmPropertyDefinition *GetPropertyDefinition
   (const char *name, cmProperty::ScopeType scope);
@@ -396,12 +407,9 @@ protected:
      cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
   typedef std::map<cmStdString,
                 CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
-
-  typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
-  typedef std::map<cmStdString,
-                   CreateGeneratorFunctionType> RegisteredGeneratorsMap;
+  typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector;
   RegisteredCommandsMap Commands;
-  RegisteredGeneratorsMap Generators;
+  RegisteredGeneratorsVector Generators;
   RegisteredExtraGeneratorsMap ExtraGenerators;
   void AddDefaultCommands();
   void AddDefaultGenerators();
@@ -418,6 +426,7 @@ protected:
   std::string StartOutputDirectory;
   bool SuppressDevWarnings;
   bool DoSuppressDevWarnings;
+  std::string GeneratorToolset;
 
   ///! read in a cmake list file to initialize the cache
   void ReadListFile(const std::vector<std::string>& args, const char *path);
@@ -447,6 +456,8 @@ protected:
                               std::string const& link);
   static int ExecuteEchoColor(std::vector<std::string>& args);
   static int ExecuteLinkScript(std::vector<std::string>& args);
+  static int WindowsCEEnvironment(const char* version,
+                                  const std::string& name);
   static int VisualStudioLink(std::vector<std::string>& args, int type);
   static int VisualStudioLinkIncremental(std::vector<std::string>& args,
                                          int type,
@@ -526,6 +537,13 @@ private:
    "A makefile generator is responsible for generating a particular build " \
    "system.  Possible generator names are specified in the Generators " \
    "section."},\
+  {"-T <toolset-name>", "Specify toolset name if supported by generator.", \
+   "Some CMake generators support a toolset name to be given to the " \
+   "native build system to choose a compiler.  " \
+   "This is supported only on specific generators:\n" \
+   "  Visual Studio >= 10\n" \
+   "  Xcode >= 3.0\n" \
+   "See native build system documentation for allowed toolset names."}, \
   {"-Wno-dev", "Suppress developer warnings.",\
    "Suppress warnings that are meant for the author"\
    " of the CMakeLists.txt files."},\
index 11a4267..4267841 100644 (file)
@@ -344,19 +344,17 @@ int main(int ac, char** av)
 
 int do_cmake(int ac, char** av)
 {
-  int nocwd = 0;
-
   if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
     {
     std::cerr << "Current working directory cannot be established."
               << std::endl;
-    nocwd = 1;
+    return 1;
     }
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
   cmDocumentation doc;
   doc.addCMakeStandardDocSections();
-  if(doc.CheckOptions(ac, av, "-E") || nocwd)
+  if(doc.CheckOptions(ac, av, "-E"))
     {
     // Construct and print requested documentation.
     cmake hcm;
@@ -424,7 +422,7 @@ int do_cmake(int ac, char** av)
     return result;
     }
 #else
-  if ( nocwd || ac == 1 )
+  if ( ac == 1 )
     {
     std::cout <<
       "Bootstrap CMake should not be used outside CMake build process."
index 34350bf..04dab59 100644 (file)
@@ -237,12 +237,14 @@ int main() {
 
   // needed to suppress filename output of msvc tools
   std::string srcfilename;
+  {
   std::string::size_type pos = srcfile.rfind("\\");
   if (pos == std::string::npos) {
     srcfilename = srcfile;
   } else {
     srcfilename = srcfile.substr(pos + 1);
   }
+  }
 
   std::string nol = " /nologo ";
   std::string show = " /showIncludes ";
@@ -266,10 +268,12 @@ int main() {
 
     // call cl in object dir so the .i is generated there
     std::string objdir;
+    {
     std::string::size_type pos = objfile.rfind("\\");
     if (pos != std::string::npos) {
       objdir = objfile.substr(0, pos);
     }
+    }
 
     // extract dependencies with cl.exe
     int exit_code = process(srcfilename, dfile, objfile,
index 35b55ca..d1b61ef 100755 (executable)
@@ -9,6 +9,9 @@
 #  "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/cl.xml"
 #  "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/lib.xml"
 #  "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/V110/1033/link.xml"
+#  "${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"
 #
 #  BoolProperty  <Name>true|false</Name>
 #   simple example:
index e6014b3..ab238d5 100644 (file)
@@ -31,14 +31,14 @@ int main (int argc, char *argv[])
   int cc;
   for ( cc = 2; cc < argc; cc ++ )
     {
-    std::string arg = argv[cc];
-    if ( (arg.find_first_of(" ") != arg.npos) &&
-         (arg.find_first_of("\"") == arg.npos) )
+    std::string nextArg = argv[cc];
+    if ( (nextArg.find_first_of(" ") != nextArg.npos) &&
+         (nextArg.find_first_of("\"") == nextArg.npos) )
       {
-      arg = "\"" + arg + "\"";
+      nextArg = "\"" + nextArg + "\"";
       }
     command += " ";
-    command += arg;
+    command += nextArg;
     }
 
   return cmWin32ProcessExecution::Windows9xHack(command.c_str());
index d650777..3e63183 100644 (file)
@@ -187,6 +187,7 @@ static const char * cmDocumentationOptions[][3] =
   {"--build-two-config", "Run CMake twice", "" },
   {"--build-exe-dir", "Specify the directory for the executable.", "" },
   {"--build-generator", "Specify the generator to use.", "" },
+  {"--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.", "" },
   {"--build-noclean", "Skip the make clean step.", "" },
@@ -273,14 +274,13 @@ int main (int argc, char *argv[])
     return cmCTestLaunch::Main(argc, argv);
     }
 
-  int nocwd = 0;
   cmCTest inst;
 
   if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
     {
     cmCTestLog(&inst, ERROR_MESSAGE,
       "Current working directory cannot be established." << std::endl);
-    nocwd = 1;
+    return 1;
     }
 
   // If there is a testing input file, check for documentation options
@@ -298,7 +298,7 @@ int main (int argc, char *argv[])
       }
     cmDocumentation doc;
     doc.addCTestStandardDocSections();
-    if(doc.CheckOptions(argc, argv) || nocwd)
+    if(doc.CheckOptions(argc, argv))
       {
       // Construct and print requested documentation.
       std::vector<cmDocumentationEntry> commands;
index a132357..124b8ac 100644 (file)
@@ -116,7 +116,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
   SET(KWSYS_USE_MD5 1)
   SET(KWSYS_USE_Process 1)
   SET(KWSYS_USE_RegularExpression 1)
-  SET(KWSYS_USE_Registry 1)
   SET(KWSYS_USE_System 1)
   SET(KWSYS_USE_SystemTools 1)
   SET(KWSYS_USE_CommandLineArguments 1)
@@ -509,19 +508,28 @@ ENDIF(KWSYS_USE_FundamentalType)
 
 IF(KWSYS_USE_IOStream)
   # Determine whether iostreams support long long.
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
+    -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
+    -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
   IF(KWSYS_CXX_HAS_LONG_LONG)
-    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
-      -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI}
-      -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD})
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
       "Checking if istream supports long long" DIRECT)
     KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
       "Checking if ostream supports long long" DIRECT)
-    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
   ELSE()
     SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
     SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
   ENDIF()
+  IF(KWSYS_CXX_HAS___INT64)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
+      "Checking if istream supports __int64" DIRECT)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
+      "Checking if ostream supports __int64" DIRECT)
+  ELSE()
+    SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
+    SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
+  ENDIF()
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
 ENDIF(KWSYS_USE_IOStream)
 
 IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
@@ -566,9 +574,106 @@ IF(KWSYS_USE_SystemTools)
 ENDIF()
 
 IF(KWSYS_USE_SystemInformation)
-  SET_PROPERTY(SOURCE SystemInformation.cxx PROPERTY
-    COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=${KWSYS_USE_LONG_LONG}
-                        KWSYS_USE___INT64=${KWSYS_USE___INT64})
+  SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
+  IF(NOT CYGWIN)
+    INCLUDE(CheckIncludeFiles)
+    CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
+    IF(KWSYS_SYS_HAS_IFADDRS_H)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1)
+    ENDIF()
+  ENDIF()
+  IF(WIN32)
+    INCLUDE(CheckSymbolExists)
+    SET(CMAKE_REQUIRED_LIBRARIES Psapi)
+    CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI)
+    UNSET(CMAKE_REQUIRED_LIBRARIES)
+    IF(KWSYS_SYS_HAS_PSAPI)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1)
+      IF(MSVC70 OR MSVC71)
+        # Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF
+        SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
+      ENDIF()
+    ENDIF()
+  ENDIF()
+  IF(CMAKE_SYSTEM MATCHES "HP-UX")
+    CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
+    IF(KWSYS_SYS_HAS_MPCTL_H)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
+    ENDIF()
+  ENDIF()
+  IF(CMAKE_SYSTEM MATCHES "BSD")
+    CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
+    IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
+    ENDIF()
+  ENDIF()
+  IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
+    SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
+    "Checking whether CXX compiler has rlimit64" DIRECT)
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+  IF(KWSYS_CXX_HAS_RLIMIT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
+    "Checking whether CXX compiler has atol" DIRECT)
+  IF(KWSYS_CXX_HAS_ATOL)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
+    "Checking whether CXX compiler has atoll" DIRECT)
+  IF(KWSYS_CXX_HAS_ATOLL)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
+  ENDIF()
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
+    "Checking whether CXX compiler has _atoi64" DIRECT)
+  IF(KWSYS_CXX_HAS__ATOI64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
+  ENDIF()
+  IF(BORLAND)
+    KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
+      "Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
+    IF(KWSYS_CXX_HAS_BORLAND_ASM)
+      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
+      KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
+        "Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
+      IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+        SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+          COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
+      ENDIF()
+    ENDIF()
+  ENDIF()
+  IF(KWSYS_USE___INT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
+  ENDIF()
+  IF(KWSYS_USE_LONG_LONG)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
+  ENDIF()
+  IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
+  ENDIF()
+  IF(KWSYS_IOS_HAS_OSTREAM___INT64)
+    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
+  ENDIF()
+  IF(KWSYS_BUILD_SHARED)
+    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
+  ENDIF()
 ENDIF()
 
 #-----------------------------------------------------------------------------
@@ -686,7 +791,7 @@ SET(KWSYS_HXX_FILES Configure String
 # Add selected C++ classes.
 SET(cppclasses
   Directory DynamicLoader Glob RegularExpression SystemTools
-  CommandLineArguments Registry IOStream SystemInformation
+  CommandLineArguments IOStream SystemInformation
   )
 FOREACH(cpp ${cppclasses})
   IF(KWSYS_USE_${cpp})
@@ -724,12 +829,8 @@ SET(KWSYS_CXX_SRCS)
 # Add the proper sources for this platform's Process implementation.
 IF(KWSYS_USE_Process)
   IF(NOT UNIX)
-    # Use the Windows implementation.  We need the encoded forwarding executable.
-    SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c
-      ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c)
-    SET_SOURCE_FILES_PROPERTIES(
-      ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
-      PROPERTIES GENERATED 1)
+    # Use the Windows implementation.
+    SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
   ELSE(NOT UNIX)
     # Use the UNIX implementation.
     SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
@@ -802,9 +903,12 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
       TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
     ENDIF(UNIX)
   ENDIF(KWSYS_USE_DynamicLoader)
-  
+
   IF(KWSYS_USE_SystemInformation AND WIN32)
     TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ws2_32)
+    IF(KWSYS_SYS_HAS_PSAPI)
+      TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} Psapi)
+    ENDIF()
   ENDIF(KWSYS_USE_SystemInformation AND WIN32)
 
   # Apply user-defined target properties to the library.
@@ -842,6 +946,16 @@ ENDIF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
 # line to configure the namespace in the C and C++ source files.
 ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
 
+# Disable deprecation warnings for standard C functions.
+IF(MSVC OR (WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$"))
+  ADD_DEFINITIONS(
+    -D_CRT_NONSTDC_NO_DEPRECATE
+    -D_CRT_SECURE_NO_DEPRECATE
+    -D_CRT_SECURE_NO_WARNINGS
+    -D_SCL_SECURE_NO_DEPRECATE
+    )
+ENDIF()
+
 IF(KWSYS_USE_String)
   # Activate code in "String.c".  See the comment in the source.
   SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
@@ -849,43 +963,6 @@ IF(KWSYS_USE_String)
 ENDIF(KWSYS_USE_String)
 
 #-----------------------------------------------------------------------------
-# Process execution on windows needs to build a forwarding executable
-# that works around a Win9x bug.  We encode the executable into a C
-# file and build it into the library.  Win9x platforms reproduce the
-# executable into a temporary directory when it is needed.
-IF(KWSYS_USE_Process)
-  IF(NOT UNIX)
-    # Build the forwarding executable itself and a program that will
-    # encode it into a C file.
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}ProcessFwd9x ProcessFwd9x.c)
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}EncodeExecutable EncodeExecutable.c)
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE})
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE})
-
-    SET(CFG_INTDIR "/${CMAKE_CFG_INTDIR}")
-    IF(CMAKE_BUILD_TOOL MATCHES "make")
-      SET(CFG_INTDIR "")
-    ENDIF(CMAKE_BUILD_TOOL MATCHES "make")
-
-    # Take advantage of a better custom command syntax if possible.
-    SET(CMD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}EncodeExecutable.exe)
-    SET(FWD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}ProcessFwd9x.exe)
-    ADD_CUSTOM_COMMAND(
-      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
-      COMMAND ${CMD}
-      ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
-           ${KWSYS_NAMESPACE} ProcessFwd9x
-      DEPENDS ${CMD} ${FWD})
-
-    # Make sure build occurs in proper order.
-    ADD_DEPENDENCIES(${KWSYS_NAMESPACE} ${KWSYS_NAMESPACE}ProcessFwd9x
-                     ${KWSYS_NAMESPACE}EncodeExecutable)
-  ENDIF(NOT UNIX)
-ENDIF(KWSYS_USE_Process)
-
-#-----------------------------------------------------------------------------
 # Setup testing if not being built as part of another project.
 IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
   IF(BUILD_TESTING)
@@ -923,7 +1000,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
         )
     ENDIF(NOT WATCOM)
     SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
-      testRegistry
       testIOS
       testSystemTools
       testCommandLineArguments
@@ -1027,8 +1103,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
       # We expect test to fail
       SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
       GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
-      SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR_NOT_VALGRIND;FAIL;Test failed")
-      SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES PASS_REGULAR_EXPRESSION "Test passed")
       SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
       MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
     ENDIF()
index ecd29d1..2e1a584 100644 (file)
 #elif defined(__SYSC_ZARCH__)
 # define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
 
+/* Aarch64 */
+#elif defined(__aarch64__)
+# if !defined(__AARCH64EB__)
+#  define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
+# else
+#  define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
+# endif
+
 /* Unknown CPU */
 #else
 # define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID 0
index 9ab6ed8..d977b47 100644 (file)
@@ -1,6 +1,6 @@
 #=============================================================================
 # KWSys - Kitware System Library
-# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+# Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
 #
 # Distributed under the OSI-approved BSD License (the "License");
 # see accompanying file Copyright.txt for details.
@@ -9,10 +9,9 @@
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 # See the License for more information.
 #=============================================================================
-set (CTEST_PROJECT_NAME "kwsys")
-set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-set (CTEST_DART_SERVER_VERSION "2")
+set(CTEST_PROJECT_NAME "KWSys")
+set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
 set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
 set(CTEST_DROP_SITE_CDASH TRUE)
index 15986cf..70cf844 100644 (file)
 /* Whether kwsys namespace is "kwsys".  */
 #define @KWSYS_NAMESPACE@_NAME_IS_KWSYS @KWSYS_NAME_IS_KWSYS@
 
-/* If we are building a kwsys .c or .cxx file, suppress the Microsoft
-   deprecation warnings.  */
-#if defined(KWSYS_NAMESPACE)
-# ifndef _CRT_NONSTDC_NO_DEPRECATE
-#  define _CRT_NONSTDC_NO_DEPRECATE
-# endif
-# ifndef _CRT_SECURE_NO_DEPRECATE
-#  define _CRT_SECURE_NO_DEPRECATE
-# endif
-# ifndef _SCL_SECURE_NO_DEPRECATE
-#  define _SCL_SECURE_NO_DEPRECATE
-# endif
-#endif
-
 /* Whether Large File Support is requested.  */
 #define @KWSYS_NAMESPACE@_LFS_REQUESTED @KWSYS_LFS_REQUESTED@
 
index c4ee095..fd83752 100644 (file)
@@ -428,6 +428,58 @@ const char* DynamicLoader::LastError()
 } // namespace KWSYS_NAMESPACE
 #endif
 
+#ifdef __MINT__
+#define DYNAMICLOADER_DEFINED 1
+#define _GNU_SOURCE /* for program_invocation_name */
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dld.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+  char *name = (char *)calloc(1, strlen(libname) + 1);
+  dld_init(program_invocation_name);
+  strncpy(name, libname, strlen(libname));
+  dld_link(libname);
+  return (void *)name;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+  dld_unlink_by_file((char *)lib, 0);
+  free(lib);
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+  DynamicLoader::LibraryHandle lib, const char* sym)
+{
+  // Hack to cast pointer-to-data to pointer-to-function.
+  union
+  {
+    void* pvoid;
+    DynamicLoader::SymbolPointer psym;
+  } result;
+  result.pvoid = dld_get_symbol(sym);
+  return result.psym;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+  return dld_strerror(dld_errno);
+}
+
+} // namespace KWSYS_NAMESPACE
+#endif
+
 // ---------------------------------------------------------------
 // 6. Implementation for default UNIX machines.
 // if nothing has been defined then use this
diff --git a/Source/kwsys/EncodeExecutable.c b/Source/kwsys/EncodeExecutable.c
deleted file mode 100644 (file)
index bc30568..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  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 <stdio.h>
-#ifdef __WATCOMC__
-#define _unlink unlink
-#endif
-int main(int argc, char* argv[])
-{
-  FILE* ifp;
-  FILE* ofp;
-  int i;
-  int n;
-  int count = 0;
-  unsigned char buffer[1024];
-  
-  /* Check arguments.  */
-  if(argc != 5)
-    {
-    fprintf(stderr, "Usage: %s <input> <output> <kwsys-name> <array>\n",
-            argv[0]);
-    return 1;
-    }
-  
-  /* Open the input file.  */
-  ifp = fopen(argv[1], "rb");
-  if(!ifp)
-    {
-    fprintf(stderr, "Cannot open input file: \"%s\"\n", argv[1]);
-    return 2;
-    }
-  ofp = fopen(argv[2], "w");
-  if(!ofp)
-    {
-    fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]);
-    fclose(ifp);
-    return 2;
-    }
-  
-  /* Prepend header comment.  */
-  fprintf(ofp, "/*\n * DO NOT EDIT\n * This file is generated by:\n");
-  fprintf(ofp, " * %s\n */\n\n", argv[0]);
-  fprintf(ofp, "#include \"kwsysPrivate.h\"\n");
-  fprintf(ofp, "#include KWSYS_HEADER(Configure.h)\n\n");
-  fprintf(ofp, "#include <stdio.h>\n\n");
-  fprintf(ofp, "#if defined(_WIN32)\n");
-  fprintf(ofp, "# include <io.h>\n");
-  fprintf(ofp, "#else\n");
-  fprintf(ofp, "# include <unistd.h>\n");
-  fprintf(ofp, "#endif\n");
-  fprintf(ofp, "\n");
-  fprintf(ofp, "static void kwsys_unlink(const char* fname)\n");
-  fprintf(ofp, "{\n");
-  fprintf(ofp, "#if defined(__WATCOMC__)\n");
-  fprintf(ofp, "  unlink(fname);\n");
-  fprintf(ofp, "#else\n");
-  fprintf(ofp, "  _unlink(fname);\n");
-  fprintf(ofp, "#endif\n");
-  fprintf(ofp, "}\n");
-  fprintf(ofp, "\n");
-  
-  /* Split file up in 1024-byte chunks.  */
-  while((n = (int)fread(buffer, 1, 1024, ifp)) > 0)
-    {
-    fprintf(ofp, "static unsigned char kwsysEncodedArray%s_%d[%d] = {\n", 
-            argv[4], count++, n);
-    for(i=0; i < n-1; ++i)
-      {
-      fprintf(ofp, "0x%02X", buffer[i]);
-      if(i%10 == 9)
-        {
-        fprintf(ofp, ",\n");
-        }
-      else
-        {
-        fprintf(ofp, ", ");
-        }
-      }
-    fprintf(ofp, "0x%02X};\n\n", buffer[n-1]);
-    }
-  fclose(ifp);
-  
-  /* Provide a function to write the data to a file.  */
-  fprintf(ofp, "extern %s_EXPORT int %sEncodedWriteArray%s(const char* fname)\n",
-          argv[3], argv[3], argv[4]);
-  fprintf(ofp, "{\n");
-  fprintf(ofp, "  FILE* ofp = fopen(fname, \"wb\");\n");
-  fprintf(ofp, "  if(!ofp) { return 0; }\n");
-  for(i=0; i < count; ++i)
-    {
-    fprintf(ofp, "  if(fwrite(kwsysEncodedArray%s_%d, 1,\n"
-                 "            sizeof(kwsysEncodedArray%s_%d), ofp) !=\n"
-                 "       sizeof(kwsysEncodedArray%s_%d))\n",
-            argv[4], i, argv[4], i, argv[4], i);
-    fprintf(ofp, "    {\n");
-    fprintf(ofp, "    fclose(ofp);\n");
-    fprintf(ofp, "    kwsys_unlink(fname);\n");
-    fprintf(ofp, "    return 0;\n");
-    fprintf(ofp, "    }\n");
-    }
-  fprintf(ofp, "  fclose(ofp);\n");
-  fprintf(ofp, "  return 1;\n");
-  fprintf(ofp, "}\n");
-  fclose(ofp);
-  return 0;
-}
index 513eb64..46a7e4f 100644 (file)
@@ -399,7 +399,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
   if ( last_slash > 0 )
     {
     //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
-    //<< kwsys_ios::endl;
+    // << kwsys_ios::endl;
     skip = last_slash;
     }
   if ( skip == 0 )
index 57b696e..a31f8c8 100644 (file)
@@ -272,6 +272,7 @@ namespace KWSYS_NAMESPACE
 
 // Create one public symbol in this object file to avoid warnings from
 // archivers.
+void IOStreamSymbolToAvoidWarning();
 void IOStreamSymbolToAvoidWarning()
 {
 }
index 9eb99e0..2eeedf2 100644 (file)
 /* Whether ostream supports long long.  */
 #define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
 
-/* Size of type long long and 0 if not available.  */
-#define @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG @KWSYS_SIZEOF_LONG_LONG@
-
 /* Determine whether we need to define the streaming operators for
    long long or __int64.  */
-#if @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
+#if @KWSYS_USE_LONG_LONG@
 # if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
      !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
 # define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
@@ -136,7 +133,6 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
 /* If building a C++ file in kwsys itself, give the source file
    access to the macros without a configured namespace.  */
 #if defined(KWSYS_NAMESPACE)
-# define KWSYS_IOS_SIZEOF_LONG_LONG      @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
 # define KWSYS_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
 # define KWSYS_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
 # define KWSYS_IOS_NEED_OPERATORS_LL     @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
diff --git a/Source/kwsys/ProcessFwd9x.c b/Source/kwsys/ProcessFwd9x.c
deleted file mode 100644 (file)
index 536c54b..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  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.
-============================================================================*/
-
-/*
-  On Windows9x platforms, this executable is spawned between a parent
-  process and the child it is invoking to work around a bug.  See the
-  Win32 implementation file for details.
-
-  Future Work: This executable must be linked statically against the C
-  runtime library before being encoded into the library.  Building it
-  in this way may be hard because CMake has limited abilities to build
-  different targets with different configurations in the same
-  directory.  We may just have to create and encode the executable
-  once instead of generating it during the build.  This would be an
-  acceptable solution because the forwarding executable should not
-  change very often and is pretty simple.
-*/
-
-#ifdef _MSC_VER
-#pragma warning (push, 1)
-#endif
-#include <windows.h>
-#include <stdio.h>
-
-void ReportLastError(HANDLE errorPipe);
-
-int main()
-{
-  /* Process startup information for the real child.  */
-  STARTUPINFO si;
-  PROCESS_INFORMATION pi;
-
-  /* The result of waiting for the child to exit.  */
-  DWORD waitResult;
-
-  /* The child's process return code.  */
-  DWORD retVal;
-
-  /* The command line used to invoke this process.  */
-  LPSTR commandLine = GetCommandLine();
-
-  /* Pointer that will be advanced to the beginning of the command
-     line of the real child process.  */
-  LPSTR cmdLine = commandLine;
-
-  /* Handle to the error reporting pipe provided by the parent.  This
-     is parsed off the command line.  */
-  HANDLE errorPipe = 0;
-  HANDLE errorPipeOrig = 0;
-
-  /* Handle to the event the parent uses to tell us to resume the child.
-     This is parsed off the command line.  */
-  HANDLE resumeEvent = 0;
-
-  /* Handle to the event the parent uses to tell us to kill the child.
-     This is parsed off the command line.  */
-  HANDLE killEvent = 0;
-
-  /* Flag for whether to hide window of child process.  */
-  int hideWindow = 0;
-
-  /* An array of the handles on which we wait when the child is
-     running.  */
-  HANDLE waitHandles[2] = {0, 0};
-
-  /* Move the pointer past the name of this executable.  */
-  if(*cmdLine == '"')
-    {
-    ++cmdLine;
-    while(*cmdLine && *cmdLine != '"') { ++cmdLine; }
-    if(*cmdLine) { ++cmdLine; }
-    }
-  else
-    {
-    while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
-    }
-
-  /* Parse the error pipe handle.  */
-  while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
-  sscanf(cmdLine, "%p", &errorPipeOrig);
-
-  /* Parse the resume event handle.  */
-  while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
-  while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
-  sscanf(cmdLine, "%p", &resumeEvent);
-
-  /* Parse the kill event handle.  */
-  while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
-  while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
-  sscanf(cmdLine, "%p", &killEvent);
-
-  /* Parse the hide window flag.  */
-  while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
-  while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
-  sscanf(cmdLine, "%d", &hideWindow);
-
-  /* Skip to the beginning of the command line of the real child.  */
-  while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
-  while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
-
-  /* Create a non-inherited copy of the error pipe.  We do not want
-     the child to get it.  */
-  if(DuplicateHandle(GetCurrentProcess(), errorPipeOrig,
-                     GetCurrentProcess(), &errorPipe,
-                     0, FALSE, DUPLICATE_SAME_ACCESS))
-    {
-    /* Have a non-inherited duplicate.  Close the inherited one.  */
-    CloseHandle(errorPipeOrig);
-    }
-  else
-    {
-    /* Could not duplicate handle.  Report the error.  */
-    ReportLastError(errorPipeOrig);
-    return 1;
-    }
-
-  /* Create the subprocess.  */
-  ZeroMemory(&si, sizeof(si));
-  ZeroMemory(&pi, sizeof(pi));
-  si.cb = sizeof(si);
-  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
-  si.wShowWindow = hideWindow?SW_HIDE:SW_SHOWDEFAULT;
-  si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-  if(CreateProcess(0, cmdLine, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi))
-    {
-    /* Process created successfully.  Close the error reporting pipe
-       to notify the parent of success.  */
-    CloseHandle(errorPipe);
-    }
-  else
-    {
-    /* Error creating the process.  Report the error to the parent
-       process through the special error reporting pipe.  */
-    ReportLastError(errorPipe);
-    return 1;
-    }
-
-  /* Wait for resume or kill event from parent.  */
-  waitHandles[0] = killEvent;
-  waitHandles[1] = resumeEvent;
-  waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
-
-  /* Check what happened.  */
-  if(waitResult == WAIT_OBJECT_0)
-    {
-    /* We were asked to kill the child.  */
-    TerminateProcess(pi.hProcess, 255);
-    WaitForSingleObject(pi.hProcess, INFINITE);
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
-    return 1;
-    }
-  else
-    {
-    /* We were asked to resume the child.  */
-    ResumeThread(pi.hThread);
-    CloseHandle(pi.hThread);
-    }
-
-  /* Wait for subprocess to exit or for kill event from parent.  */
-  waitHandles[0] = killEvent;
-  waitHandles[1] = pi.hProcess;
-  waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
-
-  /* Check what happened.  */
-  if(waitResult == WAIT_OBJECT_0)
-    {
-    /* We were asked to kill the child.  */
-    TerminateProcess(pi.hProcess, 255);
-    WaitForSingleObject(pi.hProcess, INFINITE);
-    CloseHandle(pi.hProcess);
-    return 1;
-    }
-  else
-    {
-    /* The child exited.  Get the return code.  */
-    GetExitCodeProcess(pi.hProcess, &retVal);
-    CloseHandle(pi.hProcess);
-    return retVal;
-    }
-}
-
-void ReportLastError(HANDLE errorPipe)
-{
-  LPVOID lpMsgBuf;
-  DWORD n;
-  FormatMessage(
-    FORMAT_MESSAGE_ALLOCATE_BUFFER |
-    FORMAT_MESSAGE_FROM_SYSTEM |
-    FORMAT_MESSAGE_IGNORE_INSERTS,
-    NULL,
-    GetLastError(),
-    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-    (LPTSTR) &lpMsgBuf,
-    0,
-    NULL
-    );
-  WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0);
-  LocalFree( lpMsgBuf );
-}
index 9c66a44..b9af2f1 100644 (file)
@@ -47,6 +47,12 @@ do.
 
 */
 
+#if defined(__CYGWIN__)
+/* Increase the file descriptor limit for select() before including
+   related system headers. (Default: 64) */
+# define FD_SETSIZE 16384
+#endif
+
 #include <stddef.h>    /* ptrdiff_t */
 #include <stdio.h>     /* snprintf */
 #include <stdlib.h>    /* malloc, free */
@@ -63,10 +69,6 @@ do.
 #include <dirent.h>    /* DIR, dirent */
 #include <ctype.h>     /* isspace */
 
-#ifdef __HAIKU__
-#undef __BEOS__
-#endif
-
 #if defined(__VMS)
 # define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
 #else
@@ -106,7 +108,7 @@ static inline void kwsysProcess_usleep(unsigned int msec)
  * pipes' file handles to be non-blocking and just poll them directly
  * without select().
  */
-#if !defined(__BEOS__) && !defined(__VMS)
+#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__)
 # define KWSYSPE_USE_SELECT 1
 #endif
 
@@ -422,9 +424,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
        parse it.  */
     newCommands[cp->NumberOfCommands] =
       kwsysSystem_Parse_CommandForUnix(*command, 0);
-    if(!newCommands[cp->NumberOfCommands])
+    if(!newCommands[cp->NumberOfCommands] ||
+       !newCommands[cp->NumberOfCommands][0])
       {
-      /* Out of memory.  */
+      /* Out of memory or no command parsed.  */
       free(newCommands);
       return 0;
       }
@@ -2732,6 +2735,7 @@ static void kwsysProcessesSignalHandler(int signum
     kwsysProcess* cp = kwsysProcesses.Processes[i];
     kwsysProcess_ssize_t status=
       read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
+    (void)status;
     status=write(cp->SignalPipe, &buf, 1);
     (void)status;
     }
index 5aa4d8b..c836f9b 100644 (file)
@@ -28,14 +28,6 @@ On windows, a thread is created to wait for data on each pipe.  The
 threads are synchronized with the main thread to simulate the use of
 a UNIX-style select system call.
 
-On Windows9x platforms, a small WIN32 console application is spawned
-in-between the calling process and the actual child to be executed.
-This is to work-around a problem with connecting pipes from WIN16
-console applications to WIN32 applications.
-
-For more information, please check Microsoft Knowledge Base Articles
-Q190351 and Q150956.
-
 */
 
 #ifdef _MSC_VER
@@ -91,18 +83,12 @@ Q190351 and Q150956.
 # define KWSYSPE_DEBUG(x) (void)1
 #endif
 
-#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x)
-
 typedef LARGE_INTEGER kwsysProcessTime;
 
 typedef struct kwsysProcessCreateInformation_s
 {
   /* Windows child startup control data.  */
   STARTUPINFO StartupInfo;
-
-  /* Special error reporting pipe for Win9x forwarding executable.  */
-  HANDLE ErrorPipeRead;
-  HANDLE ErrorPipeWrite;
 } kwsysProcessCreateInformation;
 
 /*--------------------------------------------------------------------------*/
@@ -146,7 +132,6 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
 static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
 static void kwsysProcessKillTree(int pid);
 static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
-extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
 
 /*--------------------------------------------------------------------------*/
 /* A structure containing synchronization data for each thread.  */
@@ -233,15 +218,6 @@ struct kwsysProcess_s
   /* Whether to treat command lines as verbatim.  */
   int Verbatim;
 
-  /* On Win9x platforms, the path to the forwarding executable.  */
-  char* Win9x;
-
-  /* On Win9x platforms, the resume event for the forwarding executable.  */
-  HANDLE Win9xResumeEvent;
-
-  /* On Win9x platforms, the kill event for the forwarding executable.  */
-  HANDLE Win9xKillEvent;
-
   /* Mutex to protect the shared index used by threads to report data.  */
   HANDLE SharedIndexMutex;
 
@@ -269,9 +245,6 @@ struct kwsysProcess_s
   HANDLE PipeNativeSTDOUT[2];
   HANDLE PipeNativeSTDERR[2];
 
-  /* Handle to automatically delete the Win9x forwarding executable.  */
-  HANDLE Win9xHandle;
-
   /* ------------- Data managed per call to Execute ------------- */
 
   /* The exceptional behavior that terminated the process, if any.  */
@@ -311,7 +284,7 @@ struct kwsysProcess_s
      for pipes to close after process termination.  */
   int PipesLeft;
 
-  /* Buffer for error messages (possibly from Win9x child).  */
+  /* Buffer for error messages.  */
   char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
 
   /* Description for the ExitException.  */
@@ -337,9 +310,6 @@ kwsysProcess* kwsysProcess_New(void)
   /* Process control structure.  */
   kwsysProcess* cp;
 
-  /* Path to Win9x forwarding executable.  */
-  char* win9x = 0;
-
   /* Windows version number data.  */
   OSVERSIONINFO osv;
 
@@ -365,73 +335,11 @@ kwsysProcess* kwsysProcess_New(void)
   GetVersionEx(&osv);
   if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
     {
-    /* This is Win9x.  We need the console forwarding executable to
-       work-around a Windows 9x bug.  */
-    char fwdName[_MAX_FNAME+1] = "";
-    char tempDir[_MAX_PATH+1] = "";
-
-    /* We will try putting the executable in the system temp
-       directory.  Note that the returned path already has a trailing
-       slash.  */
-    DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
-
-    /* Construct the executable name from the process id and kwsysProcess
-       instance.  This should be unique.  */
-    sprintf(fwdName, KWSYS_NAMESPACE_STRING "pew9xfwd_%ld_%p.exe",
-            GetCurrentProcessId(), cp);
-
-    /* If we have a temp directory, use it.  */
-    if(length > 0 && length <= _MAX_PATH)
-      {
-      /* Allocate a buffer to hold the forwarding executable path.  */
-      size_t tdlen = strlen(tempDir);
-      win9x = (char*)malloc(tdlen + strlen(fwdName) + 2);
-      if(!win9x)
-        {
-        kwsysProcess_Delete(cp);
-        return 0;
-        }
-
-      /* Construct the full path to the forwarding executable.  */
-      sprintf(win9x, "%s%s", tempDir, fwdName);
-      }
-
-    /* If we found a place to put the forwarding executable, try to
-       write it. */
-    if(win9x)
-      {
-      if(!kwsysEncodedWriteArrayProcessFwd9x(win9x))
-        {
-        /* Failed to create forwarding executable.  Give up.  */
-        free(win9x);
-        kwsysProcess_Delete(cp);
-        return 0;
-        }
-
-      /* Get a handle to the file that will delete it when closed.  */
-      cp->Win9xHandle = CreateFile(win9x, GENERIC_READ, FILE_SHARE_READ, 0,
-                                   OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
-      if(cp->Win9xHandle == INVALID_HANDLE_VALUE)
-        {
-        /* We were not able to get a read handle for the forwarding
-           executable.  It will not be deleted properly.  Give up.  */
-        _unlink(win9x);
-        free(win9x);
-        kwsysProcess_Delete(cp);
-        return 0;
-        }
-      }
-    else
-      {
-      /* Failed to find a place to put forwarding executable.  */
-      kwsysProcess_Delete(cp);
-      return 0;
-      }
+    /* Win9x no longer supported.  */
+    kwsysProcess_Delete(cp);
+    return 0;
     }
 
-  /* Save the path to the forwarding executable.  */
-  cp->Win9x = win9x;
-
   /* Initially no thread owns the mutex.  Initialize semaphore to 1.  */
   if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
     {
@@ -446,30 +354,6 @@ kwsysProcess* kwsysProcess_New(void)
     return 0;
     }
 
-  if(cp->Win9x)
-    {
-    SECURITY_ATTRIBUTES sa;
-    ZeroMemory(&sa, sizeof(sa));
-    sa.nLength = sizeof(sa);
-    sa.bInheritHandle = TRUE;
-
-    /* Create an event to tell the forwarding executable to resume the
-       child.  */
-    if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0)))
-      {
-      kwsysProcess_Delete(cp);
-      return 0;
-      }
-
-    /* Create an event to tell the forwarding executable to kill the
-       child.  */
-    if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0)))
-      {
-      kwsysProcess_Delete(cp);
-      return 0;
-      }
-    }
-
   /* Create the thread to read each pipe.  */
   for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
     {
@@ -620,13 +504,6 @@ void kwsysProcess_Delete(kwsysProcess* cp)
   kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
   kwsysProcessCleanupHandle(&cp->Full);
 
-  /* Close the Win9x resume and kill event handles.  */
-  if(cp->Win9x)
-    {
-    kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
-    kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
-    }
-
   /* Free memory.  */
   kwsysProcess_SetCommand(cp, 0);
   kwsysProcess_SetWorkingDirectory(cp, 0);
@@ -637,12 +514,6 @@ void kwsysProcess_Delete(kwsysProcess* cp)
     {
     free(cp->CommandExitCodes);
     }
-  if(cp->Win9x)
-    {
-    /* Close our handle to the forwarding executable file.  This will
-       cause it to be deleted.  */
-    kwsysProcessCleanupHandle(&cp->Win9xHandle);
-    }
   free(cp);
 }
 
@@ -1017,21 +888,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
     SetCurrentDirectory(cp->WorkingDirectory);
     }
 
-  /* Reset the Win9x resume and kill events.  */
-  if(cp->Win9x)
-    {
-    if(!ResetEvent(cp->Win9xResumeEvent))
-      {
-      kwsysProcessCleanup(cp, 1);
-      return;
-      }
-    if(!ResetEvent(cp->Win9xKillEvent))
-      {
-      kwsysProcessCleanup(cp, 1);
-      return;
-      }
-    }
-
   /* Initialize startup info data.  */
   ZeroMemory(&si, sizeof(si));
   si.StartupInfo.cb = sizeof(si.StartupInfo);
@@ -1130,8 +986,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
                                     STD_OUTPUT_HANDLE);
       kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
                                     STD_ERROR_HANDLE);
-      kwsysProcessCleanupHandle(&si.ErrorPipeRead);
-      kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
       return;
       }
     }
@@ -1160,16 +1014,9 @@ void kwsysProcess_Execute(kwsysProcess* cp)
 
   /* All processes in the pipeline have been started in suspended
      mode.  Resume them all now.  */
-  if(cp->Win9x)
-    {
-    SetEvent(cp->Win9xResumeEvent);
-    }
-  else
+  for(i=0; i < cp->NumberOfCommands; ++i)
     {
-    for(i=0; i < cp->NumberOfCommands; ++i)
-      {
-      ResumeThread(cp->ProcessInformation[i].hThread);
-      }
+    ResumeThread(cp->ProcessInformation[i].hThread);
     }
 
   /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
@@ -1480,21 +1327,12 @@ void kwsysProcess_Kill(kwsysProcess* cp)
 
   /* Kill the children.  */
   cp->Killed = 1;
-  if(cp->Win9x)
-    {
-    /* Windows 9x.  Tell the forwarding executable to kill the child.  */
-    SetEvent(cp->Win9xKillEvent);
-    }
-  else
+  for(i=0; i < cp->NumberOfCommands; ++i)
     {
-    /* Not Windows 9x.  Just terminate the children.  */
-    for(i=0; i < cp->NumberOfCommands; ++i)
-      {
-      kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId); 
-      // close the handle if we kill it
-      kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
-      kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
-      }
+    kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
+    // close the handle if we kill it
+    kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
+    kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
     }
 
   /* We are killing the children and ignoring all data.  Do not wait
@@ -1815,97 +1653,13 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
       }
     }
 
-  /* Create the child process.  */
-  {
-  BOOL r;
-  char* realCommand;
-  if(cp->Win9x)
-    {
-    /* Create an error reporting pipe for the forwarding executable.
-       Neither end is directly inherited.  */
-    if(!CreatePipe(&si->ErrorPipeRead, &si->ErrorPipeWrite, 0, 0))
-      {
-      return 0;
-      }
-
-    /* Create an inherited duplicate of the write end.  This also closes
-       the non-inherited version. */
-    if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite,
-                        GetCurrentProcess(), &si->ErrorPipeWrite,
-                        0, TRUE, (DUPLICATE_CLOSE_SOURCE |
-                                  DUPLICATE_SAME_ACCESS)))
-      {
-      return 0;
-      }
-
-    /* The forwarding executable is given a handle to the error pipe
-       and resume and kill events.  */
-    realCommand = (char*)malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100);
-    if(!realCommand)
-      {
-      return 0;
-      }
-    sprintf(realCommand, "%s %p %p %p %d %s", cp->Win9x,
-            si->ErrorPipeWrite, cp->Win9xResumeEvent, cp->Win9xKillEvent,
-            cp->HideWindow, cp->Commands[index]);
-    }
-  else
-    {
-    realCommand = cp->Commands[index];
-    }
-
   /* Create the child in a suspended state so we can wait until all
      children have been created before running any one.  */
-  r = CreateProcess(0, realCommand, 0, 0, TRUE,
-                    cp->Win9x? 0 : CREATE_SUSPENDED, 0, 0,
-                    &si->StartupInfo, &cp->ProcessInformation[index]);
-  if(cp->Win9x)
-    {
-    /* Free memory.  */
-    free(realCommand);
-
-    /* Close the error pipe write end so we can detect when the
-       forwarding executable closes it.  */
-    kwsysProcessCleanupHandle(&si->ErrorPipeWrite);
-    if(r)
-      {
-      /* Wait for the forwarding executable to report an error or
-         close the error pipe to report success.  */
-      DWORD total = 0;
-      DWORD n = 1;
-      while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
-        {
-        if(ReadFile(si->ErrorPipeRead, cp->ErrorMessage+total,
-                    KWSYSPE_PIPE_BUFFER_SIZE-total, &n, 0))
-          {
-          total += n;
-          }
-        else
-          {
-          n = 0;
-          }
-        }
-      if(total > 0 || GetLastError() != ERROR_BROKEN_PIPE)
-        {
-        /* The forwarding executable could not run the process, or
-           there was an error reading from its error pipe.  Preserve
-           the last error while cleaning up the forwarding executable
-           so the cleanup our caller does reports the proper error.  */
-        DWORD error = GetLastError();
-        kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
-        kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
-        SetLastError(error);
-        return 0;
-        }
-      }
-    kwsysProcessCleanupHandle(&si->ErrorPipeRead);
-    }
-
-  if(!r)
+  if(!CreateProcess(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
+                    0, &si->StartupInfo, &cp->ProcessInformation[index]))
     {
     return 0;
     }
-  }
 
   /* Successfully created this child process.  Close the current
      process's copies of the inherited stdout and stdin handles.  The
@@ -2152,19 +1906,12 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
     /* Cleanup any processes already started in a suspended state.  */
     if(cp->ProcessInformation)
       {
-      if(cp->Win9x)
-        {
-        SetEvent(cp->Win9xKillEvent);
-        }
-      else
+      for(i=0; i < cp->NumberOfCommands; ++i)
         {
-        for(i=0; i < cp->NumberOfCommands; ++i)
+        if(cp->ProcessInformation[i].hProcess)
           {
-          if(cp->ProcessInformation[i].hProcess)
-            {
-            TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
-            WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
-            }
+          TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
+          WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
           }
         }
       for(i=0; i < cp->NumberOfCommands; ++i)
diff --git a/Source/kwsys/Registry.cxx b/Source/kwsys/Registry.cxx
deleted file mode 100644 (file)
index cd521c9..0000000
+++ /dev/null
@@ -1,818 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  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 "kwsysPrivate.h"
-#include KWSYS_HEADER(Registry.hxx)
-
-#include KWSYS_HEADER(Configure.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(stl/string)
-#include KWSYS_HEADER(stl/map)
-#include KWSYS_HEADER(ios/iostream)
-#include KWSYS_HEADER(ios/fstream)
-#include KWSYS_HEADER(ios/sstream)
-// Work-around CMake dependency scanning limitation.  This must
-// duplicate the above list of headers.
-#if 0
-# include "Registry.hxx.in"
-# include "Configure.hxx.in"
-# include "kwsys_stl.hxx.in"
-# include "kwsys_stl_string.hxx.in"
-# include "kwsys_stl_map.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-# include "kwsys_ios_fstream.h.in"
-# include "kwsys_ios_sstream.h.in"
-#endif
-
-#include <ctype.h> // for isspace
-#include <stdio.h>
-#include <string.h> /* strlen, strncpy */
-#include <stdlib.h> /* getenv */
-
-#ifdef _WIN32
-# include <windows.h>
-#endif
-
-
-namespace KWSYS_NAMESPACE
-{
-class RegistryHelper {
-public:
-  RegistryHelper(Registry::RegistryType registryType);
-  virtual ~RegistryHelper();
-
-  // Read a value from the registry.
-  virtual bool ReadValue(const char *key, const char **value);
-
-  // Delete a key from the registry.
-  virtual bool DeleteKey(const char *key);
-
-  // Delete a value from a given key.
-  virtual bool DeleteValue(const char *key);
-
-  // Set value in a given key.
-  virtual bool SetValue(const char *key, const char *value);
-
-  // Open the registry at toplevel/subkey.
-  virtual bool Open(const char *toplevel, const char *subkey,
-    int readonly);
-
-  // Close the registry.
-  virtual bool Close();
-
-  // Set the value of changed
-  void SetChanged(bool b) { m_Changed = b; }
-  void SetTopLevel(const char* tl);
-  const char* GetTopLevel() { return m_TopLevel.c_str(); }
-
-  //! Read from local or global scope. On Windows this mean from local machine
-  // or local user. On unix this will read from $HOME/.Projectrc or
-  // /etc/Project
-  void SetGlobalScope(bool b);
-  bool GetGlobalScope();
-
-  kwsys_stl::string EncodeKey(const char* str);
-  kwsys_stl::string EncodeValue(const char* str);
-  kwsys_stl::string DecodeValue(const char* str);
-
-protected:
-  bool m_Changed;
-  kwsys_stl::string m_TopLevel;
-  bool m_GlobalScope;
-
-#ifdef _WIN32
-  HKEY HKey;
-#endif
-  // Strip trailing and ending spaces.
-  char *Strip(char *str);
-  void SetSubKey(const char* sk);
-  kwsys_stl::string CreateKey(const char *key);
-
-  typedef kwsys_stl::map<kwsys_stl::string, kwsys_stl::string> StringToStringMap;
-  StringToStringMap EntriesMap;
-  kwsys_stl::string m_SubKey;
-  bool m_Empty;
-  bool m_SubKeySpecified;
-  kwsys_stl::string m_HomeDirectory;
-
-  Registry::RegistryType m_RegistryType;
-};
-
-//----------------------------------------------------------------------------
-#define Registry_BUFFER_SIZE 8192
-
-//----------------------------------------------------------------------------
-Registry::Registry(Registry::RegistryType registryType)
-{
-  m_Opened      = false;
-  m_Locked      = false;
-  this->Helper = 0;
-  this->Helper = new RegistryHelper(registryType);
-}
-
-//----------------------------------------------------------------------------
-Registry::~Registry()
-{
-  if ( m_Opened )
-    {
-    kwsys_ios::cerr << "Registry::Close should be "
-                  "called here. The registry is not closed."
-                  << kwsys_ios::endl;
-    }
-  delete this->Helper;
-}
-
-//----------------------------------------------------------------------------
-void Registry::SetGlobalScope(bool b)
-{
-  this->Helper->SetGlobalScope(b);
-}
-
-//----------------------------------------------------------------------------
-bool Registry::GetGlobalScope()
-{
-  return this->Helper->GetGlobalScope();
-}
-
-//----------------------------------------------------------------------------
-bool Registry::Open(const char *toplevel,
-  const char *subkey, int readonly)
-{
-  bool res = false;
-  if ( m_Locked )
-    {
-    return res;
-    }
-  if ( m_Opened )
-    {
-    if ( !this->Close() )
-      {
-      return res;
-      }
-    }
-  if ( !toplevel || !*toplevel )
-    {
-    kwsys_ios::cerr << "Registry::Opened() Toplevel not defined"
-      << kwsys_ios::endl;
-    return res;
-    }
-
-  if ( isspace(toplevel[0]) ||
-       isspace(toplevel[strlen(toplevel)-1]) )
-    {
-    kwsys_ios::cerr << "Toplevel has to start with letter or number and end"
-      " with one" << kwsys_ios::endl;
-    return res;
-    }
-
-  res = this->Helper->Open(toplevel, subkey, readonly);
-  if ( readonly != Registry::READONLY )
-    {
-    m_Locked = true;
-    }
-
-  if ( res )
-    {
-    m_Opened = true;
-    this->Helper->SetTopLevel(toplevel);
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-bool Registry::Close()
-{
-  bool res = false;
-  if ( m_Opened )
-    {
-    res = this->Helper->Close();
-    }
-
-  if ( res )
-    {
-    m_Opened = false;
-    m_Locked = false;
-    this->Helper->SetChanged(false);
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-bool Registry::ReadValue(const char *subkey,
-  const char *key,
-  const char **value)
-{
-  bool res = false;
-  bool open = false;
-  if ( ! value )
-    {
-    return res;
-    }
-  *value = 0;
-  if ( !m_Opened )
-    {
-    if ( !this->Open(this->GetTopLevel(), subkey,
-        Registry::READONLY) )
-      {
-      return res;
-      }
-    open = true;
-    }
-  res = this->Helper->ReadValue(key, value);
-
-  if ( open )
-    {
-    if ( !this->Close() )
-      {
-      res = false;
-      }
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-bool Registry::DeleteKey(const char *subkey, const char *key)
-{
-  bool res = false;
-  bool open = false;
-  if ( !m_Opened )
-    {
-    if ( !this->Open(this->GetTopLevel(), subkey,
-        Registry::READWRITE) )
-      {
-      return res;
-      }
-    open = true;
-    }
-
-  res = this->Helper->DeleteKey(key);
-  if ( res )
-    {
-    this->Helper->SetChanged(true);
-    }
-
-  if ( open )
-    {
-    if ( !this->Close() )
-      {
-      res = false;
-      }
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-bool Registry::DeleteValue(const char *subkey, const char *key)
-{
-  bool res = false;
-  bool open = false;
-  if ( !m_Opened )
-    {
-    if ( !this->Open(this->GetTopLevel(), subkey,
-        Registry::READWRITE) )
-      {
-      return res;
-      }
-    open = true;
-    }
-
-  res = this->Helper->DeleteValue(key);
-  if ( res )
-    {
-    this->Helper->SetChanged(true);
-    }
-
-  if ( open )
-    {
-    if ( !this->Close() )
-      {
-      res = false;
-      }
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-bool Registry::SetValue(const char *subkey, const char *key,
-  const char *value)
-{
-  bool res = false;
-  bool open = false;
-  if ( !m_Opened )
-    {
-    if ( !this->Open(this->GetTopLevel(), subkey,
-        Registry::READWRITE) )
-      {
-      return res;
-      }
-    open = true;
-    }
-
-  res = this->Helper->SetValue( key, value );
-  if ( res )
-    {
-    this->Helper->SetChanged(true);
-    }
-
-  if ( open )
-    {
-    if ( !this->Close() )
-      {
-      res = false;
-      }
-    }
-  return res;
-}
-
-//----------------------------------------------------------------------------
-const char* Registry::GetTopLevel()
-{
-  return this->Helper->GetTopLevel();
-}
-
-//----------------------------------------------------------------------------
-void Registry::SetTopLevel(const char* tl)
-{
-  this->Helper->SetTopLevel(tl);
-}
-
-//----------------------------------------------------------------------------
-void RegistryHelper::SetTopLevel(const char* tl)
-{
-  if ( tl )
-    {
-    m_TopLevel = tl;
-    }
-  else
-    {
-    m_TopLevel = "";
-    }
-}
-
-//----------------------------------------------------------------------------
-RegistryHelper::RegistryHelper(Registry::RegistryType registryType)
-{
-  m_Changed = false;
-  m_TopLevel    = "";
-  m_SubKey  = "";
-  m_SubKeySpecified = false;
-  m_Empty       = true;
-  m_GlobalScope = false;
-  m_RegistryType = registryType;
-}
-
-//----------------------------------------------------------------------------
-RegistryHelper::~RegistryHelper()
-{
-}
-
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::Open(const char *toplevel, const char *subkey,
-  int readonly)
-{
-  this->EntriesMap.clear();
-  m_Empty = 1;
-
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    HKEY scope = HKEY_CURRENT_USER;
-    if ( this->GetGlobalScope() )
-      {
-      scope = HKEY_LOCAL_MACHINE;
-      }
-    int res = 0;
-    kwsys_ios::ostringstream str;
-    DWORD dwDummy;
-    str << "Software\\Kitware\\" << toplevel << "\\" << subkey;
-    if ( readonly == Registry::READONLY )
-      {
-      res = ( RegOpenKeyEx(scope, str.str().c_str(),
-          0, KEY_READ, &this->HKey) == ERROR_SUCCESS );
-      }
-    else
-      {
-      char lpClass[] = "";
-      res = ( RegCreateKeyEx(scope, str.str().c_str(),
-          0, lpClass, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
-          NULL, &this->HKey, &dwDummy) == ERROR_SUCCESS );
-      }
-    if ( res != 0 )
-      {
-      this->SetSubKey( subkey );
-      }
-    return (res != 0);
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    bool res = false;
-    int cc;
-    kwsys_ios::ostringstream str;
-    const char* homeDirectory;
-    if ( (homeDirectory = getenv("HOME")) == 0 )
-      {
-      if ( (homeDirectory = getenv("USERPROFILE")) == 0 )
-        {
-        return false;
-        }
-      }
-    m_HomeDirectory = homeDirectory;
-    str << m_HomeDirectory.c_str() << "/." << toplevel << "rc";
-    if ( readonly == Registry::READWRITE )
-      {
-      kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app );
-      if ( ofs.fail() )
-        {
-        return false;
-        }
-      ofs.close();
-      }
-
-    kwsys_ios::ifstream *ifs = new kwsys_ios::ifstream(str.str().c_str(), kwsys_ios::ios::in
-#ifndef KWSYS_IOS_USE_ANSI
-      | kwsys_ios::ios::nocreate
-#endif
-      );
-    if ( !ifs )
-      {
-      return false;
-      }
-    if ( ifs->fail())
-      {
-      delete ifs;
-      return false;
-      }
-
-    res = true;
-    char buffer[Registry_BUFFER_SIZE];
-    while( !ifs->fail() )
-      {
-      ifs->getline(buffer, Registry_BUFFER_SIZE);
-      if ( ifs->fail() || ifs->eof() )
-        {
-        break;
-        }
-      char *line = this->Strip(buffer);
-      if ( *line == '#'  || *line == 0 )
-        {
-        // Comment
-        continue;
-        }
-      int linelen = static_cast<int>(strlen(line));
-      for ( cc = 0; cc < linelen; cc++ )
-        {
-        if ( line[cc] == '=' )
-          {
-          char *key = new char[ cc+1 ];
-          strncpy( key, line, cc );
-          key[cc] = 0;
-          char *value = line + cc + 1;
-          char *nkey = this->Strip(key);
-          char *nvalue = this->Strip(value);
-          this->EntriesMap[nkey] = this->DecodeValue(nvalue);
-          m_Empty = 0;
-          delete [] key;
-          break;
-          }
-        }
-      }
-    ifs->close();
-    this->SetSubKey( subkey );
-    delete ifs;
-    return res;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::Close()
-{
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    int res;
-    res = ( RegCloseKey(this->HKey) == ERROR_SUCCESS );
-    return (res != 0);
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    if ( !m_Changed )
-      {
-      this->SetSubKey(0);
-      return true;
-      }
-
-    kwsys_ios::ostringstream str;
-    str << m_HomeDirectory.c_str() << "/." << this->GetTopLevel() << "rc";
-    kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out);
-    if ( !ofs )
-      {
-      return false;
-      }
-    if ( ofs->fail())
-      {
-      delete ofs;
-      return false;
-      }
-    *ofs << "# This file is automatically generated by the application" << kwsys_ios::endl
-      << "# If you change any lines or add new lines, note that all" << kwsys_ios::endl
-      << "# comments and empty lines will be deleted. Every line has" << kwsys_ios::endl
-      << "# to be in format: " << kwsys_ios::endl
-      << "# key = value" << kwsys_ios::endl
-      << "#" << kwsys_ios::endl;
-
-    if ( !this->EntriesMap.empty() )
-      {
-      RegistryHelper::StringToStringMap::iterator it;
-      for ( it = this->EntriesMap.begin();
-        it != this->EntriesMap.end();
-        ++ it )
-        {
-        *ofs << it->first.c_str() << " = " << this->EncodeValue(it->second.c_str()).c_str() << kwsys_ios::endl;
-        }
-      }
-    this->EntriesMap.clear();
-    ofs->close();
-    delete ofs;
-    this->SetSubKey(0);
-    m_Empty = 1;
-    return true;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::ReadValue(const char *skey, const char **value)
-
-{
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    kwsys_stl::string key = this->CreateKey( skey );
-    if ( key.empty() )
-      {
-      return false;
-      }
-    DWORD dwType, dwSize;
-    dwType = REG_SZ;
-    char buffer[1024]; // Replace with RegQueryInfoKey
-    dwSize = sizeof(buffer);
-    int res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType,
-        (BYTE *)buffer, &dwSize) == ERROR_SUCCESS );
-    if ( !res )
-      {
-      return false;
-      }
-    this->EntriesMap[key] = buffer;
-    RegistryHelper::StringToStringMap::iterator it
-      = this->EntriesMap.find(key);
-    *value = it->second.c_str();
-    return true;
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    bool res = false;
-    kwsys_stl::string key = this->CreateKey( skey );
-    if ( key.empty() )
-      {
-      return false;
-      }
-
-    RegistryHelper::StringToStringMap::iterator it
-      = this->EntriesMap.find(key);
-    if ( it != this->EntriesMap.end() )
-      {
-      *value = it->second.c_str();
-      res = true;
-      }
-    return res;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::DeleteKey(const char* skey)
-{
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    int res = ( RegDeleteKey( this->HKey, skey ) == ERROR_SUCCESS );
-    return (res != 0);
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    kwsys_stl::string key = this->CreateKey( skey );
-    if ( key.empty() )
-      {
-      return false;
-      }
-    this->EntriesMap.erase(key);
-    return true;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::DeleteValue(const char *skey)
-{
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    int res = ( RegDeleteValue( this->HKey, skey ) == ERROR_SUCCESS );
-    return (res != 0);
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    kwsys_stl::string key = this->CreateKey( skey );
-    if ( key.empty() )
-      {
-      return false;
-      }
-    this->EntriesMap.erase(key);
-    return true;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::SetValue(const char *skey, const char *value)
-{
-#ifdef _WIN32
-  if ( m_RegistryType == Registry::WIN32_REGISTRY)
-    {
-    DWORD len = (DWORD)(value ? strlen(value) : 0);
-    int res = ( RegSetValueEx(this->HKey, skey, 0, REG_SZ,
-        (CONST BYTE *)(const char *)value,
-        len+1) == ERROR_SUCCESS );
-    return (res != 0);
-    }
-#endif
-  if ( m_RegistryType == Registry::FILE_REGISTRY )
-    {
-    kwsys_stl::string key = this->CreateKey( skey );
-    if ( key.empty() )
-      {
-      return 0;
-      }
-    this->EntriesMap[key] = value;
-    return 1;
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-kwsys_stl::string RegistryHelper::CreateKey( const char *key )
-{
-  if ( !m_SubKeySpecified || m_SubKey.empty() || !key )
-    {
-    return "";
-    }
-  kwsys_ios::ostringstream ostr;
-  ostr << this->EncodeKey(this->m_SubKey.c_str()).c_str()
-       << "\\" << this->EncodeKey(key).c_str();
-  return ostr.str();
-}
-
-//----------------------------------------------------------------------------
-void RegistryHelper::SetSubKey(const char* sk)
-{
-  if ( !sk )
-    {
-    m_SubKey = "";
-    m_SubKeySpecified = false;
-    }
-  else
-    {
-    m_SubKey = sk;
-    m_SubKeySpecified = true;
-    }
-}
-
-//----------------------------------------------------------------------------
-char *RegistryHelper::Strip(char *str)
-{
-  int cc;
-  size_t len;
-  char *nstr;
-  if ( !str )
-    {
-    return NULL;
-    }
-  len = strlen(str);
-  nstr = str;
-  for( cc=0; cc < static_cast<int>(len); cc++ )
-    {
-    if ( !isspace( *nstr ) )
-      {
-      break;
-      }
-    nstr ++;
-    }
-  for( cc= static_cast<int>(strlen(nstr))-1; cc>=0; cc-- )
-    {
-    if ( !isspace( nstr[cc] ) )
-      {
-      nstr[cc+1] = 0;
-      break;
-      }
-    }
-  return nstr;
-}
-
-//----------------------------------------------------------------------------
-void RegistryHelper::SetGlobalScope(bool b)
-{
-  m_GlobalScope = b;
-}
-
-//----------------------------------------------------------------------------
-bool RegistryHelper::GetGlobalScope()
-{
-  return m_GlobalScope;
-}
-
-//----------------------------------------------------------------------------
-kwsys_stl::string RegistryHelper::EncodeKey(const char* str)
-{
-  kwsys_ios::ostringstream ostr;
-  while ( *str )
-    {
-    switch ( *str )
-      {
-    case '%': case '=': case '\n': case '\r': case '\t':
-      char buffer[4];
-      sprintf(buffer, "%%%02X", *str);
-      ostr << buffer;
-      break;
-    default:
-      ostr << *str;
-      }
-    str ++;
-    }
-  return ostr.str();
-}
-
-//----------------------------------------------------------------------------
-kwsys_stl::string RegistryHelper::EncodeValue(const char* str)
-{
-  kwsys_ios::ostringstream ostr;
-  while ( *str )
-    {
-    switch ( *str )
-      {
-    case '%': case '=': case '\n': case '\r': case '\t':
-      char buffer[4];
-      sprintf(buffer, "%%%02X", *str);
-      ostr << buffer;
-      break;
-    default:
-      ostr << *str;
-      }
-    str ++;
-    }
-  return ostr.str();
-}
-
-//----------------------------------------------------------------------------
-kwsys_stl::string RegistryHelper::DecodeValue(const char* str)
-{
-  kwsys_ios::ostringstream ostr;
-  while ( *str )
-    {
-    unsigned int val;
-    switch ( *str )
-      {
-    case '%':
-      if ( *(str+1) && *(str+2) && sscanf(str+1, "%x", &val) == 1 )
-        {
-        ostr << static_cast<char>(val);
-        str += 2;
-        }
-      else
-        {
-        ostr << *str;
-        }
-      break;
-    default:
-      ostr << *str;
-      }
-    str ++;
-    }
-  return ostr.str();
-}
-
-} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Registry.hxx.in b/Source/kwsys/Registry.hxx.in
deleted file mode 100644 (file)
index ed9b010..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  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 @KWSYS_NAMESPACE@_Registry_hxx
-#define @KWSYS_NAMESPACE@_Registry_hxx
-
-#include <@KWSYS_NAMESPACE@/Configure.h>
-
-#include <@KWSYS_NAMESPACE@/stl/string>
-
-namespace @KWSYS_NAMESPACE@
-{
-
-class RegistryHelper;
-
-/** \class Registry
- * \brief Portable registry class
- *
- * This class abstracts the storing of data that can be restored
- * when the program executes again. On Win32 platform it is
- * implemented using the registry and on unix as a file in
- * the user's home directory.
- */
-class @KWSYS_NAMESPACE@_EXPORT Registry
-{
-public:
-  enum RegistryType
-    {
-#ifdef _WIN32
-    WIN32_REGISTRY,
-#endif
-    FILE_REGISTRY
-    };
-
-#ifdef _WIN32
-  Registry(RegistryType registryType = WIN32_REGISTRY);
-#else
-  Registry(RegistryType registryType = FILE_REGISTRY);
-#endif
-
-  virtual ~Registry();
-
-  //! Read a value from the registry.
-  bool ReadValue(const char *subkey, const char *key, const char **value);
-
-  //! Delete a key from the registry.
-  bool DeleteKey(const char *subkey, const char *key);
-
-  //! Delete a value from a given key.
-  bool DeleteValue(const char *subkey, const char *key);
-
-  //! Set value in a given key.
-  bool SetValue(const char *subkey, const char *key,
-               const char *value);
-
-  //! Open the registry at toplevel/subkey.
-  bool Open(const char *toplevel, const char *subkey,
-           int readonly);
-
-  //! Close the registry.
-  bool Close();
-
-  //! Read from local or global scope. On Windows this mean from local machine
-  // or local user. On unix this will read from $HOME/.Projectrc or
-  // /etc/Project
-  void GlobalScopeOn() { this->SetGlobalScope(1); }
-  void GlobalScopeOff() { this->SetGlobalScope(0); }
-  void SetGlobalScope(bool b);
-  bool GetGlobalScope();
-
-  // Set or get the toplevel registry key.
-  void SetTopLevel(const char* tl);
-  const char* GetTopLevel();
-
-  // Return true if registry opened
-  bool GetOpened() { return m_Opened; }
-
-  // Should the registry be locked?
-  bool GetLocked() { return m_Locked; }
-
-  enum {
-    READONLY,
-    READWRITE
-  };
-
-  // Return true if the character is space.
-  int IsSpace(char c);
-
-private:
-  RegistryHelper* Helper;
-
-  bool m_Opened;
-
-  bool m_Locked;
-}; // End Class: Registry
-
-} // namespace @KWSYS_NAMESPACE@
-
-#endif
index e1ee873..9e2a93d 100644 (file)
@@ -9,7 +9,12 @@
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the License for more information.
 ============================================================================*/
-#ifdef _WIN32
+
+#if defined(_WIN32)
+# define NOMINMAX // use our min,max
+# if !defined(_WIN32_WINNT) && !(defined(_MSC_VER) && _MSC_VER < 1300)
+#  define _WIN32_WINNT 0x0501
+# endif
 # include <winsock.h> // WSADATA, include before sys/types.h
 #endif
 
@@ -33,6 +38,7 @@
 #include KWSYS_HEADER(Process.h)
 #include KWSYS_HEADER(ios/iostream)
 #include KWSYS_HEADER(ios/sstream)
+#include KWSYS_HEADER(ios/fstream)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 # include "kwsys_stl_iosfwd.in"
 # include "kwsys_ios_sstream.h.in"
 # include "kwsys_ios_iostream.h.in"
+# include "kwsys_ios_fstream.h.in"
 #endif
 
-#ifndef WIN32
+#if defined(_WIN32)
+# include <windows.h>
+# include <errno.h>
+# if defined(KWSYS_SYS_HAS_PSAPI)
+#  include <psapi.h>
+# endif
+# if !defined(siginfo_t)
+typedef int siginfo_t;
+# endif
+#else
+# include <sys/types.h>
+# include <sys/time.h>
 # include <sys/utsname.h> // int uname(struct utsname *buf);
+# include <sys/resource.h> // getrlimit
+# include <unistd.h>
+# include <signal.h>
+# include <fcntl.h>
+# include <errno.h> // extern int errno;
 #endif
 
-#ifdef _WIN32
-# include <windows.h>
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+# include <fenv.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# if defined(KWSYS_SYS_HAS_IFADDRS_H)
+#  include <ifaddrs.h>
+#  define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
+# endif
+#endif
+
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif
+
+#if defined(KWSYS_SYS_HAS_MACHINE_CPU_H)
+# include <machine/cpu.h>
+#endif
+
+#if defined(__DragonFly__)
+# include <sys/sysctl.h>
 #endif
 
 #ifdef __APPLE__
-#include <sys/sysctl.h>
-#include <mach/vm_statistics.h>
-#include <mach/host_info.h>
-#include <mach/mach.h>
-#include <mach/mach_types.h>
+# include <sys/sysctl.h>
+# include <mach/vm_statistics.h>
+# include <mach/host_info.h>
+# include <mach/mach.h>
+# include <mach/mach_types.h>
+# include <fenv.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# if defined(KWSYS_SYS_HAS_IFADDRS_H)
+#  include <ifaddrs.h>
+#  define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
+# endif
+# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050
+#  include <execinfo.h>
+#  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
+# endif
 #endif
 
 #ifdef __linux
-# include <sys/types.h>
-# include <unistd.h>
-# include <fcntl.h>
-# include <ctype.h> // int isdigit(int c);
-# include <errno.h> // extern int errno;
-# include <sys/time.h>
+# include <fenv.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# if defined(KWSYS_SYS_HAS_IFADDRS_H)
+#  include <ifaddrs.h>
+#  if !defined(__LSB_VERSION__) /* LSB has no getifaddrs */
+#   define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
+#  endif
+# endif
+# if defined(__GNUC__)
+#  include <execinfo.h>
+#  if !(defined(__LSB_VERSION__) && __LSB_VERSION__ < 41)
+#   define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
+#  endif
+# endif
+# if defined(KWSYS_CXX_HAS_RLIMIT64)
+typedef struct rlimit64 ResourceLimitType;
+#  define GetResourceLimit getrlimit64
+# else
+typedef struct rlimit ResourceLimitType;
+#  define GetResourceLimit getrlimit
+# endif
 #elif defined( __hpux )
 # include <sys/param.h>
 # include <sys/pstat.h>
+# if defined(KWSYS_SYS_HAS_MPCTL_H)
+#  include <sys/mpctl.h>
+# endif
 #endif
 
 #ifdef __HAIKU__
-#include <OS.h>
+# include <OS.h>
 #endif
 
 #include <memory.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h> // int isdigit(int c);
+
+#if defined(KWSYS_USE_LONG_LONG)
+# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#elif defined(KWSYS_USE___INT64)
+# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#else
+# error "No Long Long"
+#endif
 
+#if defined(KWSYS_CXX_HAS_ATOLL)
+# define atoLongLong atoll
+#else
+# if defined(KWSYS_CXX_HAS__ATOI64)
+#  define atoLongLong _atoi64
+# elif defined(KWSYS_CXX_HAS_ATOL)
+#  define atoLongLong atol
+# else
+#  define atoLongLong atoi
+# endif
+#endif
 
-namespace KWSYS_NAMESPACE
-{
+#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64)
+#define USE_ASM_INSTRUCTIONS 1
+#else
+#define USE_ASM_INSTRUCTIONS 0
+#endif
 
-// Create longlong
-#if KWSYS_USE_LONG_LONG
-  typedef long long LongLong;
-#elif KWSYS_USE___INT64
-  typedef __int64 LongLong;
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#include <intrin.h>
+#define USE_CPUID_INTRINSICS 1
 #else
-# error "No Long Long"
+#define USE_CPUID_INTRINSICS 0
+#endif
+
+#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS || defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+# define USE_CPUID 1
+#else
+# define USE_CPUID 0
+#endif
+
+#if USE_CPUID
+
+#define CPUID_AWARE_COMPILER
+
+/**
+ * call CPUID instruction
+ *
+ * Will return false if the instruction failed.
+ */
+static bool call_cpuid(int select, int result[4])
+{
+#if USE_CPUID_INTRINSICS
+  __cpuid(result, select);
+  return true;
+#else
+  int tmp[4];
+#if defined(_MSC_VER)
+  // Use SEH to determine CPUID presence
+  __try {
+    _asm {
+#ifdef CPUID_AWARE_COMPILER
+      ; we must push/pop the registers <<CPUID>> writes to, as the
+      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
+      ; these registers to change.
+      push eax
+      push ebx
+      push ecx
+      push edx
+#endif
+      ; <<CPUID>>
+      mov eax, select
+#ifdef CPUID_AWARE_COMPILER
+      cpuid
+#else
+      _asm _emit 0x0f
+      _asm _emit 0xa2
+#endif
+      mov tmp[0 * TYPE int], eax
+      mov tmp[1 * TYPE int], ebx
+      mov tmp[2 * TYPE int], ecx
+      mov tmp[3 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+      pop edx
+      pop ecx
+      pop ebx
+      pop eax
+#endif
+      }
+    }
+  __except(1)
+    {
+    return false;
+    }
+
+    memcpy(result, tmp, sizeof(tmp));
+#elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+  unsigned int a, b, c, d;
+  __asm {
+    mov EAX, select;
+    cpuid
+    mov a, EAX;
+    mov b, EBX;
+    mov c, ECX;
+    mov d, EDX;
+  }
+
+  result[0] = a;
+  result[1] = b;
+  result[2] = c;
+  result[3] = d;
+#endif
+
+  // The cpuid instruction succeeded.
+  return true;
+#endif
+}
 #endif
 
 
+namespace KWSYS_NAMESPACE
+{
+template<typename T>
+T min(T a, T b){ return a<b ? a : b; }
+
+extern "C" { typedef void (*SigAction)(int,siginfo_t*,void*); }
+
 //  Define SystemInformationImplementation class
 typedef  void (*DELAY_FUNC)(unsigned int uiMS);
 
-
 class SystemInformationImplementation
 {
 public:
+  typedef SystemInformation::LongLong LongLong;
   SystemInformationImplementation ();
   ~SystemInformationImplementation ();
 
@@ -113,6 +310,7 @@ public:
   kwsys_stl::string GetTypeID();
   kwsys_stl::string GetFamilyID();
   kwsys_stl::string GetModelID();
+  kwsys_stl::string GetModelName();
   kwsys_stl::string GetSteppingCode();
   const char * GetExtendedProcessorName();
   const char * GetProcessorSerialNumber();
@@ -122,9 +320,10 @@ public:
   int GetProcessorAPICID();
   int GetProcessorCacheXSize(long int);
   bool DoesCPUSupportFeature(long int);
-  
+
   const char * GetOSName();
   const char * GetHostname();
+  int GetFullyQualifiedDomainName(kwsys_stl::string &fqdn);
   const char * GetOSRelease();
   const char * GetOSVersion();
   const char * GetOSPlatform();
@@ -140,7 +339,23 @@ public:
   size_t GetTotalVirtualMemory();
   size_t GetAvailableVirtualMemory();
   size_t GetTotalPhysicalMemory();
-  size_t GetAvailablePhysicalMemory();  
+  size_t GetAvailablePhysicalMemory();
+
+  LongLong GetProcessId();
+
+  // Retrieve memory information in kib
+  LongLong GetHostMemoryTotal();
+  LongLong GetHostMemoryAvailable(const char *envVarName);
+  LongLong GetHostMemoryUsed();
+
+  LongLong GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName);
+  LongLong GetProcMemoryUsed();
+
+  // enable/disable stack trace signal handler.
+  static
+  void SetStackTraceOnError(int enable);
 
   /** Run the different checks */
   void RunCPUCheck();
@@ -159,6 +374,7 @@ public:
     kwsys_stl::string ProcessorName;
     kwsys_stl::string Vendor;
     kwsys_stl::string SerialNumber;
+    kwsys_stl::string ModelName;
     } ID;
 
   typedef struct tagCPUPowerManagement
@@ -206,7 +422,7 @@ public:
   enum Manufacturer
     {
     AMD, Intel, NSC, UMC, Cyrix, NexGen, IDT, Rise, Transmeta, Sun, IBM,
-    Motorola, UnknownManufacturer
+    Motorola, HP, UnknownManufacturer
     };
 
 protected:
@@ -234,28 +450,32 @@ protected:
   int CPUCount();
   unsigned char LogicalCPUPerPhysicalCPU();
   unsigned char GetAPICId();
-  unsigned int IsHyperThreadingSupported();
-  LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
+  bool IsHyperThreadingSupported();
+  static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
 
   // For Linux and Cygwin, /proc/cpuinfo formats are slightly different
-  int RetreiveInformationFromCpuInfoFile();
+  bool RetreiveInformationFromCpuInfoFile();
   kwsys_stl::string ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,
                                           const char* word, size_t init=0);
 
+  bool QueryLinuxMemory();
+  bool QueryCygwinMemory();
+
   static void Delay (unsigned int);
   static void DelayOverhead (unsigned int);
 
-  void FindManufacturer();
+  void FindManufacturer(const kwsys_stl::string &family = "");
 
   // For Mac
   bool ParseSysCtl();
-  void CallSwVers();
+  int CallSwVers(const char *arg, kwsys_stl::string &ver);
   void TrimNewline(kwsys_stl::string&);
   kwsys_stl::string ExtractValueFromSysCtl(const char* word);
   kwsys_stl::string SysCtlBuffer;
 
   // For Solaris
-  bool QuerySolarisInfo();
+  bool QuerySolarisMemory();
+  bool QuerySolarisProcessor();
   kwsys_stl::string ParseValueFromKStat(const char* arguments);
   kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
 
@@ -266,8 +486,26 @@ protected:
   bool QueryQNXMemory();
   bool QueryQNXProcessor();
 
+  //For OpenBSD, FreeBSD, NetBSD, DragonFly
+  bool QueryBSDMemory();
+  bool QueryBSDProcessor();
+
+  //For HP-UX
+  bool QueryHPUXMemory();
+  bool QueryHPUXProcessor();
+
+  //For Microsoft Windows
+  bool QueryWindowsMemory();
+
+  //For AIX
+  bool QueryAIXMemory();
+
+  bool QueryProcessorBySysconf();
+  bool QueryProcessor();
+
   // Evaluate the memory information.
-  int QueryMemory();
+  bool QueryMemoryBySysconf();
+  bool QueryMemory();
   size_t TotalVirtualMemory;
   size_t AvailableVirtualMemory;
   size_t TotalPhysicalMemory;
@@ -281,7 +519,7 @@ protected:
   kwsys_stl::string Hostname;
   kwsys_stl::string OSRelease;
   kwsys_stl::string OSVersion;
-  kwsys_stl::string OSPlatform; 
+  kwsys_stl::string OSPlatform;
 };
 
 
@@ -320,6 +558,11 @@ kwsys_stl::string SystemInformation::GetModelID()
   return this->Implementation->GetModelID();
 }
 
+kwsys_stl::string SystemInformation::GetModelName()
+{
+  return this->Implementation->GetModelName();
+}
+
 kwsys_stl::string SystemInformation::GetSteppingCode()
 {
   return this->Implementation->GetSteppingCode();
@@ -365,6 +608,37 @@ bool SystemInformation::DoesCPUSupportFeature(long int i)
   return this->Implementation->DoesCPUSupportFeature(i);
 }
 
+kwsys_stl::string SystemInformation::GetCPUDescription()
+{
+  kwsys_ios::ostringstream oss;
+  oss
+    << this->GetNumberOfPhysicalCPU()
+    << " core ";
+  if (this->GetModelName().empty())
+    {
+    oss
+      << this->GetProcessorClockFrequency()
+      << " MHz "
+      << this->GetVendorString()
+      << " "
+      << this->GetExtendedProcessorName();
+    }
+  else
+    {
+    oss << this->GetModelName();
+    }
+
+  // remove extra spaces
+  kwsys_stl::string tmp=oss.str();
+  size_t pos;
+  while( (pos=tmp.find("  "))!=kwsys_stl::string::npos)
+    {
+    tmp.replace(pos,2," ");
+    }
+
+  return tmp;
+}
+
 const char * SystemInformation::GetOSName()
 {
   return this->Implementation->GetOSName();
@@ -375,6 +649,13 @@ const char * SystemInformation::GetHostname()
   return this->Implementation->GetHostname();
 }
 
+kwsys_stl::string SystemInformation::GetFullyQualifiedDomainName()
+{
+  kwsys_stl::string fqdn;
+  this->Implementation->GetFullyQualifiedDomainName(fqdn);
+  return fqdn;
+}
+
 const char * SystemInformation::GetOSRelease()
 {
   return this->Implementation->GetOSRelease();
@@ -390,6 +671,46 @@ const char * SystemInformation::GetOSPlatform()
   return this->Implementation->GetOSPlatform();
 }
 
+int SystemInformation::GetOSIsWindows()
+{
+#if defined(_WIN32)
+  return 1;
+#else
+  return 0;
+#endif
+}
+
+int SystemInformation::GetOSIsLinux()
+{
+#if defined(__linux)
+  return 1;
+#else
+  return 0;
+#endif
+}
+
+int SystemInformation::GetOSIsApple()
+{
+#if defined(__APPLE__)
+  return 1;
+#else
+  return 0;
+#endif
+}
+
+kwsys_stl::string SystemInformation::GetOSDescription()
+{
+  kwsys_ios::ostringstream oss;
+  oss
+    << this->GetOSName()
+    << " "
+    << this->GetOSRelease()
+    << " "
+    << this->GetOSVersion();
+
+  return oss.str();
+}
+
 bool SystemInformation::Is64Bits()
 {
   return this->Implementation->Is64Bits();
@@ -431,6 +752,66 @@ size_t SystemInformation::GetAvailablePhysicalMemory()
   return this->Implementation->GetAvailablePhysicalMemory();
 }
 
+kwsys_stl::string SystemInformation::GetMemoryDescription(
+      const char *hostLimitEnvVarName,
+      const char *procLimitEnvVarName)
+{
+  kwsys_ios::ostringstream oss;
+  oss
+    << "Host Total: "
+    << iostreamLongLong(this->GetHostMemoryTotal())
+    << " KiB, Host Available: "
+    << iostreamLongLong(this->GetHostMemoryAvailable(hostLimitEnvVarName))
+    << " KiB, Process Available: "
+    << iostreamLongLong(
+         this->GetProcMemoryAvailable(hostLimitEnvVarName,procLimitEnvVarName))
+    << " KiB";
+  return oss.str();
+}
+
+// host memory info in units of KiB.
+SystemInformation::LongLong SystemInformation::GetHostMemoryTotal()
+{
+  return this->Implementation->GetHostMemoryTotal();
+}
+
+SystemInformation::LongLong
+SystemInformation::GetHostMemoryAvailable(const char *hostLimitEnvVarName)
+{
+  return this->Implementation->GetHostMemoryAvailable(hostLimitEnvVarName);
+}
+
+SystemInformation::LongLong SystemInformation::GetHostMemoryUsed()
+{
+  return this->Implementation->GetHostMemoryUsed();
+}
+
+// process memory info in units of KiB.
+SystemInformation::LongLong
+SystemInformation::GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName)
+{
+  return this->Implementation->GetProcMemoryAvailable(
+          hostLimitEnvVarName,
+          procLimitEnvVarName);
+}
+
+SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
+{
+  return this->Implementation->GetProcMemoryUsed();
+}
+
+SystemInformation::LongLong SystemInformation::GetProcessId()
+{
+  return this->Implementation->GetProcessId();
+}
+
+void SystemInformation::SetStackTraceOnError(int enable)
+{
+  SystemInformationImplementation::SetStackTraceOnError(enable);
+}
+
 /** Run the different checks */
 void SystemInformation::RunCPUCheck()
 {
@@ -451,24 +832,11 @@ void SystemInformation::RunMemoryCheck()
 // --------------------------------------------------------------
 // SystemInformationImplementation starts here
 
-#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64)
-#define USE_ASM_INSTRUCTIONS 1
-#else
-#define USE_ASM_INSTRUCTIONS 0
-#endif
-
 #define STORE_TLBCACHE_INFO(x,y)  x = (x < y) ? y : x
 #define TLBCACHE_INFO_UNITS      (15)
 #define CLASSICAL_CPU_FREQ_LOOP    10000000
 #define RDTSC_INSTRUCTION      _asm _emit 0x0f _asm _emit 0x31
 
-#define CPUID_AWARE_COMPILER
-#ifdef CPUID_AWARE_COMPILER
-  #define CPUID_INSTRUCTION    cpuid
-#else
-  #define CPUID_INSTRUCTION    _asm _emit 0x0f _asm _emit 0xa2
-#endif
-
 #define MMX_FEATURE            0x00000001
 #define MMX_PLUS_FEATURE       0x00000002
 #define SSE_FEATURE            0x00000004
@@ -501,94 +869,438 @@ void SystemInformation::RunMemoryCheck()
 #define HT_CANNOT_DETECT         4
 
 // EDX[28]  Bit 28 is set if HT is supported
-#define HT_BIT             0x10000000   
+#define HT_BIT             0x10000000
 
 // EAX[11:8] Bit 8-11 contains family processor ID.
 #define FAMILY_ID          0x0F00
-#define PENTIUM4_ID        0x0F00         
+#define PENTIUM4_ID        0x0F00
 // EAX[23:20] Bit 20-23 contains extended family processor ID
-#define EXT_FAMILY_ID      0x0F00000 
+#define EXT_FAMILY_ID      0x0F00000
 // EBX[23:16] Bit 16-23 in ebx contains the number of logical
-#define NUM_LOGICAL_BITS   0x00FF0000  
-// processors per physical processor when execute cpuid with 
+#define NUM_LOGICAL_BITS   0x00FF0000
+// processors per physical processor when execute cpuid with
 // eax set to 1
-// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique 
-#define INITIAL_APIC_ID_BITS  0xFF000000  
+// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique
+#define INITIAL_APIC_ID_BITS  0xFF000000
 // initial APIC ID for the processor this code is running on.
 // Default value = 0xff if HT is not supported
 
-
-SystemInformationImplementation::SystemInformationImplementation()
+// Hide implementation details in an anonymous namespace.
+namespace {
+// *****************************************************************************
+#if defined(__linux) || defined(__APPLE__)
+int LoadLines(
+      FILE *file,
+      kwsys_stl::vector<kwsys_stl::string> &lines)
 {
-  this->TotalVirtualMemory = 0;
-  this->AvailableVirtualMemory = 0;
-  this->TotalPhysicalMemory = 0;
-  this->AvailablePhysicalMemory = 0;
-  this->CurrentPositionInFile = 0;
-  this->ChipManufacturer = UnknownManufacturer;
-  memset(&this->Features, 0, sizeof(CPUFeatures));
-  this->ChipID.Type = 0;
-  this->ChipID.Family = 0;
-  this->ChipID.Model = 0;
-  this->ChipID.Revision = 0;
-  this->ChipID.ExtendedFamily = 0;
-  this->ChipID.ExtendedModel = 0;
-  this->CPUSpeedInMHz = 0;
-  this->NumberOfLogicalCPU = 0;
-  this->NumberOfPhysicalCPU = 0;
-  this->OSName = "";
-  this->Hostname = "";
-  this->OSRelease = "";
-  this->OSVersion = "";
-  this->OSPlatform = "";
+  // Load each line in the given file into a the vector.
+  int nRead=0;
+  const int bufSize=1024;
+  char buf[bufSize]={'\0'};
+  while (!feof(file) && !ferror(file))
+    {
+    errno=0;
+    if (fgets(buf,bufSize,file) == 0)
+      {
+      if (ferror(file) && (errno==EINTR))
+        {
+        clearerr(file);
+        }
+      continue;
+      }
+    lines.push_back(buf);
+    ++nRead;
+    }
+  if (ferror(file))
+    {
+    return 0;
+    }
+  return nRead;
 }
 
-SystemInformationImplementation::~SystemInformationImplementation()
+# if defined(__linux)
+// *****************************************************************************
+int LoadLines(
+      const char *fileName,
+      kwsys_stl::vector<kwsys_stl::string> &lines)
 {
+  FILE *file=fopen(fileName,"r");
+  if (file==0)
+    {
+    return 0;
+    }
+  int nRead=LoadLines(file,lines);
+  fclose(file);
+  return nRead;
 }
+# endif
 
-void SystemInformationImplementation::RunCPUCheck()
+// ****************************************************************************
+template<typename T>
+int NameValue(
+      kwsys_stl::vector<kwsys_stl::string> &lines,
+      kwsys_stl::string name, T &value)
 {
-#ifdef WIN32
-  // Check to see if this processor supports CPUID.
-  bool supportsCPUID = DoesCPUSupportCPUID();
-
-  if (supportsCPUID)
+  size_t nLines=lines.size();
+  for (size_t i=0; i<nLines; ++i)
     {
-    // Retrieve the CPU details.
-    RetrieveCPUIdentity();
-    RetrieveCPUFeatures();
+    size_t at=lines[i].find(name);
+    if (at==kwsys_stl::string::npos)
+      {
+      continue;
+      }
+    kwsys_ios::istringstream is(lines[i].substr(at+name.size()));
+    is >> value;
+    return 0;
     }
+  return -1;
+}
+#endif
 
-  // These two may be called without support for the CPUID instruction.
-  // (But if the instruction is there, they should be called *after*
-  // the above call to RetrieveCPUIdentity... that's why the two if
-  // blocks exist with the same "if (supportsCPUID)" logic...
-  //
-  if (!RetrieveCPUClockSpeed())
+#if defined(__linux)
+// ****************************************************************************
+template<typename T>
+int GetFieldsFromFile(
+      const char *fileName,
+      const char **fieldNames,
+      T *values)
+{
+  kwsys_stl::vector<kwsys_stl::string> fields;
+  if (!LoadLines(fileName,fields))
     {
-    RetrieveClassicalCPUClockSpeed();
+    return -1;
     }
-
-  if (supportsCPUID)
+  int i=0;
+  while (fieldNames[i]!=NULL)
     {
-    // Retrieve cache information.
-    if (!RetrieveCPUCacheDetails()) 
-      {
-      RetrieveClassicalCPUCacheDetails();
-      }
-
-    // Retrieve the extended CPU details.
-    if (!RetrieveExtendedCPUIdentity()) 
+    int ierr=NameValue(fields,fieldNames[i],values[i]);
+    if (ierr)
       {
-      RetrieveClassicalCPUIdentity();
+      return -(i+2);
       }
-
-    RetrieveExtendedCPUFeatures();
-    RetrieveCPUPowerManagement();
-
-    // Now attempt to retrieve the serial number (if possible).
-    RetrieveProcessorSerialNumber();
+    i+=1;
+    }
+  return 0;
+}
+
+// ****************************************************************************
+template<typename T>
+int GetFieldFromFile(
+      const char *fileName,
+      const char *fieldName,
+      T &value)
+{
+  const char *fieldNames[2]={fieldName,NULL};
+  T values[1]={T(0)};
+  int ierr=GetFieldsFromFile(fileName,fieldNames,values);
+  if (ierr)
+    {
+    return ierr;
+    }
+  value=values[0];
+  return 0;
+}
+#endif
+
+// ****************************************************************************
+#if defined(__APPLE__)
+template<typename T>
+int GetFieldsFromCommand(
+      const char *command,
+      const char **fieldNames,
+      T *values)
+{
+  FILE *file=popen(command,"r");
+  if (file==0)
+    {
+    return -1;
+    }
+  kwsys_stl::vector<kwsys_stl::string> fields;
+  int nl=LoadLines(file,fields);
+  pclose(file);
+  if (nl==0)
+    {
+    return -1;
+    }
+  int i=0;
+  while (fieldNames[i]!=NULL)
+    {
+    int ierr=NameValue(fields,fieldNames[i],values[i]);
+    if (ierr)
+      {
+      return -(i+2);
+      }
+    i+=1;
+    }
+  return 0;
+}
+#endif
+
+// ****************************************************************************
+#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+void StacktraceSignalHandler(
+      int sigNo,
+      siginfo_t *sigInfo,
+      void * /*sigContext*/)
+{
+#if defined(__linux) || defined(__APPLE__)
+  kwsys_ios::ostringstream oss;
+  oss
+     << "=========================================================" << kwsys_ios::endl
+     << "Process id " << getpid() << " ";
+  switch (sigNo)
+    {
+    case SIGFPE:
+      oss << "Caught SIGFPE ";
+      switch (sigInfo->si_code)
+        {
+# if defined(FPE_INTDIV)
+        case FPE_INTDIV:
+          oss << "integer division by zero";
+          break;
+# endif
+
+# if defined(FPE_INTOVF)
+        case FPE_INTOVF:
+          oss << "integer overflow";
+          break;
+# endif
+
+        case FPE_FLTDIV:
+          oss << "floating point divide by zero";
+          break;
+
+        case FPE_FLTOVF:
+          oss << "floating point overflow";
+          break;
+
+        case FPE_FLTUND:
+          oss << "floating point underflow";
+          break;
+
+        case FPE_FLTRES:
+          oss << "floating point inexact result";
+          break;
+
+        case FPE_FLTINV:
+          oss << "floating point invalid operation";
+          break;
+
+#if defined(FPE_FLTSUB)
+        case FPE_FLTSUB:
+          oss << "floating point subscript out of range";
+          break;
+#endif
+
+        default:
+          oss << "code " << sigInfo->si_code;
+          break;
+        }
+      break;
+
+    case SIGSEGV:
+      oss << "Caught SIGSEGV ";
+      switch (sigInfo->si_code)
+        {
+        case SEGV_MAPERR:
+          oss << "address not mapped to object";
+          break;
+
+        case SEGV_ACCERR:
+          oss << "invalid permission for mapped object";
+          break;
+
+        default:
+          oss << "code " << sigInfo->si_code;
+          break;
+        }
+      break;
+
+    case SIGINT:
+      oss << "Caught SIGTERM";
+      break;
+
+    case SIGTERM:
+      oss << "Caught SIGTERM";
+      break;
+
+    case SIGBUS:
+      oss << "Caught SIGBUS type ";
+      switch (sigInfo->si_code)
+        {
+        case BUS_ADRALN:
+          oss << "invalid address alignment";
+          break;
+
+# if defined(BUS_ADRERR)
+        case BUS_ADRERR:
+          oss << "non-exestent physical address";
+          break;
+# endif
+
+# if defined(BUS_OBJERR)
+        case BUS_OBJERR:
+          oss << "object specific hardware error";
+          break;
+# endif
+
+        default:
+          oss << "code " << sigInfo->si_code;
+          break;
+        }
+      break;
+
+    case SIGILL:
+      oss << "Caught SIGILL ";
+      switch (sigInfo->si_code)
+        {
+        case ILL_ILLOPC:
+          oss << "illegal opcode";
+          break;
+
+# if defined(ILL_ILLOPN)
+        case ILL_ILLOPN:
+          oss << "illegal operand";
+          break;
+# endif
+
+# if defined(ILL_ILLADR)
+        case ILL_ILLADR:
+          oss << "illegal addressing mode.";
+          break;
+# endif
+
+        case ILL_ILLTRP:
+          oss << "illegal trap";
+
+        case ILL_PRVOPC:
+          oss << "privileged opcode";
+          break;
+
+# if defined(ILL_PRVREG)
+        case ILL_PRVREG:
+          oss << "privileged register";
+          break;
+# endif
+
+# if defined(ILL_COPROC)
+        case ILL_COPROC:
+          oss << "co-processor error";
+          break;
+# endif
+
+# if defined(ILL_BADSTK)
+        case ILL_BADSTK:
+          oss << "internal stack error";
+          break;
+# endif
+
+        default:
+          oss << "code " << sigInfo->si_code;
+          break;
+        }
+      break;
+
+    default:
+      oss << "Caught " << sigNo << " code " << sigInfo->si_code;
+      break;
+    }
+  oss << kwsys_ios::endl;
+#if defined(KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE)
+  oss << "Program Stack:" << kwsys_ios::endl;
+  void *stackSymbols[128];
+  int n=backtrace(stackSymbols,128);
+  char **stackText=backtrace_symbols(stackSymbols,n);
+  for (int i=0; i<n; ++i)
+    {
+    oss << "  " << stackText[i] << kwsys_ios::endl;
+    }
+#endif
+  oss
+     << "=========================================================" << kwsys_ios::endl;
+  kwsys_ios::cerr << oss.str() << kwsys_ios::endl;
+  abort();
+#else
+  // avoid warning C4100
+  (void)sigNo;
+  (void)sigInfo;
+#endif
+}
+#endif
+} // anonymous namespace
+
+SystemInformationImplementation::SystemInformationImplementation()
+{
+  this->TotalVirtualMemory = 0;
+  this->AvailableVirtualMemory = 0;
+  this->TotalPhysicalMemory = 0;
+  this->AvailablePhysicalMemory = 0;
+  this->CurrentPositionInFile = 0;
+  this->ChipManufacturer = UnknownManufacturer;
+  memset(&this->Features, 0, sizeof(CPUFeatures));
+  this->ChipID.Type = 0;
+  this->ChipID.Family = 0;
+  this->ChipID.Model = 0;
+  this->ChipID.Revision = 0;
+  this->ChipID.ExtendedFamily = 0;
+  this->ChipID.ExtendedModel = 0;
+  this->CPUSpeedInMHz = 0;
+  this->NumberOfLogicalCPU = 0;
+  this->NumberOfPhysicalCPU = 0;
+  this->OSName = "";
+  this->Hostname = "";
+  this->OSRelease = "";
+  this->OSVersion = "";
+  this->OSPlatform = "";
+}
+
+SystemInformationImplementation::~SystemInformationImplementation()
+{
+}
+
+void SystemInformationImplementation::RunCPUCheck()
+{
+#ifdef WIN32
+  // Check to see if this processor supports CPUID.
+  bool supportsCPUID = DoesCPUSupportCPUID();
+
+  if (supportsCPUID)
+    {
+    // Retrieve the CPU details.
+    RetrieveCPUIdentity();
+    this->FindManufacturer();
+    RetrieveCPUFeatures();
+    }
+
+  // These two may be called without support for the CPUID instruction.
+  // (But if the instruction is there, they should be called *after*
+  // the above call to RetrieveCPUIdentity... that's why the two if
+  // blocks exist with the same "if (supportsCPUID)" logic...
+  //
+  if (!RetrieveCPUClockSpeed())
+    {
+    RetrieveClassicalCPUClockSpeed();
+    }
+
+  if (supportsCPUID)
+    {
+    // Retrieve cache information.
+    if (!RetrieveCPUCacheDetails())
+      {
+      RetrieveClassicalCPUCacheDetails();
+      }
+
+    // Retrieve the extended CPU details.
+    if (!RetrieveExtendedCPUIdentity())
+      {
+      RetrieveClassicalCPUIdentity();
+      }
+
+    RetrieveExtendedCPUFeatures();
+    RetrieveCPUPowerManagement();
+
+    // Now attempt to retrieve the serial number (if possible).
+    RetrieveProcessorSerialNumber();
     }
 
   this->CPUCount();
@@ -596,13 +1308,19 @@ void SystemInformationImplementation::RunCPUCheck()
 #elif defined(__APPLE__)
   this->ParseSysCtl();
 #elif defined (__SVR4) && defined (__sun)
-  this->QuerySolarisInfo();
+  this->QuerySolarisProcessor();
 #elif defined(__HAIKU__)
   this->QueryHaikuInfo();
 #elif defined(__QNX__)
   this->QueryQNXProcessor();
-#else
+#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  this->QueryBSDProcessor();
+#elif defined(__hpux)
+  this->QueryHPUXProcessor();
+#elif defined(__linux) || defined(__CYGWIN__)
   this->RetreiveInformationFromCpuInfoFile();
+#else
+  this->QueryProcessor();
 #endif
 }
 
@@ -616,11 +1334,23 @@ void SystemInformationImplementation::RunMemoryCheck()
 #if defined(__APPLE__)
   this->ParseSysCtl();
 #elif defined (__SVR4) && defined (__sun)
-  this->QuerySolarisInfo();
+  this->QuerySolarisMemory();
 #elif defined(__HAIKU__)
   this->QueryHaikuInfo();
 #elif defined(__QNX__)
   this->QueryQNXMemory();
+#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  this->QueryBSDMemory();
+#elif defined(__CYGWIN__)
+  this->QueryCygwinMemory();
+#elif defined(_WIN32)
+  this->QueryWindowsMemory();
+#elif defined(__hpux)
+  this->QueryHPUXMemory();
+#elif defined(__linux)
+  this->QueryLinuxMemory();
+#elif defined(_AIX)
+  this->QueryAIXMemory();
 #else
   this->QueryMemory();
 #endif
@@ -641,9 +1371,145 @@ const char * SystemInformationImplementation::GetOSName()
 /** Get the hostname */
 const char* SystemInformationImplementation::GetHostname()
 {
+  if (this->Hostname.empty())
+    {
+    this->Hostname="localhost";
+#if defined(_WIN32)
+    WORD wVersionRequested;
+    WSADATA wsaData;
+    char name[255];
+    wVersionRequested = MAKEWORD(2,0);
+    if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
+      {
+      gethostname(name,sizeof(name));
+      WSACleanup( );
+      }
+    this->Hostname = name;
+#else
+    struct utsname unameInfo;
+    int errorFlag = uname(&unameInfo);
+    if(errorFlag == 0)
+      {
+      this->Hostname = unameInfo.nodename;
+      }
+#endif
+    }
   return this->Hostname.c_str();
 }
 
+/** Get the FQDN */
+int SystemInformationImplementation::GetFullyQualifiedDomainName(
+      kwsys_stl::string &fqdn)
+{
+  // in the event of absolute failure return localhost.
+  fqdn="localhost";
+
+#if defined(_WIN32)
+  int ierr;
+  // TODO - a more robust implementation for windows, see comments
+  // in unix implementation.
+  WSADATA wsaData;
+  WORD ver=MAKEWORD(2,0);
+  ierr=WSAStartup(ver,&wsaData);
+  if (ierr)
+    {
+    return -1;
+    }
+
+  char base[256]={'\0'};
+  ierr=gethostname(base,256);
+  if (ierr)
+    {
+    WSACleanup();
+    return -2;
+    }
+  fqdn=base;
+
+  HOSTENT *hent=gethostbyname(base);
+  if (hent)
+    {
+    fqdn=hent->h_name;
+    }
+
+  WSACleanup();
+  return 0;
+
+#elif defined(KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN)
+  // gethostname typical returns an alias for loopback interface
+  // we want the fully qualified domain name. Because there are
+  // any number of interfaces on this system we look for the
+  // first of these that contains the name returned by gethostname
+  // and is longer. failing that we return gethostname and indicate
+  // with a failure code. Return of a failure code is not necessarilly
+  // an indication of an error. for instance gethostname may return
+  // the fully qualified domain name, or there may not be one if the
+  // system lives on a private network such as in the case of a cluster
+  // node.
+
+  int ierr=0;
+  char base[NI_MAXHOST];
+  ierr=gethostname(base,NI_MAXHOST);
+  if (ierr)
+    {
+    return -1;
+    }
+  size_t baseSize=strlen(base);
+  fqdn=base;
+
+  struct ifaddrs *ifas;
+  struct ifaddrs *ifa;
+  ierr=getifaddrs(&ifas);
+  if (ierr)
+    {
+    return -2;
+    }
+
+  for (ifa=ifas; ifa!=NULL; ifa=ifa->ifa_next)
+    {
+    int fam = ifa->ifa_addr? ifa->ifa_addr->sa_family : -1;
+    if ((fam==AF_INET) || (fam==AF_INET6))
+      {
+      char host[NI_MAXHOST]={'\0'};
+
+      int addrlen
+        = (fam==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6));
+
+      ierr=getnameinfo(
+            ifa->ifa_addr,
+            addrlen,
+            host,
+            NI_MAXHOST,
+            NULL,
+            0,
+            NI_NAMEREQD);
+      if (ierr)
+        {
+        // don't report the failure now since we may succeed on another
+        // interface. If all attempts fail then return the failure code.
+        ierr=-3;
+        continue;
+        }
+
+      kwsys_stl::string candidate=host;
+      if ((candidate.find(base)!=kwsys_stl::string::npos) && baseSize<candidate.size())
+        {
+        // success, stop now.
+        ierr=0;
+        fqdn=candidate;
+        break;
+        }
+      }
+    }
+  freeifaddrs(ifas);
+
+  return ierr;
+#else
+  /* TODO: Implement on more platforms.  */
+  fqdn=this->GetHostname();
+  return -1;
+#endif
+}
+
 /** Get the OS release */
 const char* SystemInformationImplementation::GetOSRelease()
 {
@@ -692,6 +1558,8 @@ const char * SystemInformationImplementation::GetVendorID()
       return "IBM";
     case Motorola:
       return "Motorola";
+    case HP:
+      return "Hewlett-Packard";
     default:
       return "Unknown Manufacturer";
     }
@@ -721,9 +1589,15 @@ kwsys_stl::string SystemInformationImplementation::GetModelID()
   return str.str();
 }
 
+// Return the model name of CPU present */
+kwsys_stl::string SystemInformationImplementation::GetModelName()
+{
+  return this->ChipID.ModelName;
+}
+
 /** Return the stepping code of the CPU present. */
 kwsys_stl::string SystemInformationImplementation::GetSteppingCode()
-{ 
+{
   kwsys_ios::ostringstream str;
   str << this->ChipID.Revision;
   return str.str();
@@ -734,8 +1608,8 @@ const char * SystemInformationImplementation::GetExtendedProcessorName()
 {
   return this->ChipID.ProcessorName.c_str();
 }
-  
-/** Return the serial number of the processor 
+
+/** Return the serial number of the processor
  *  in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */
 const char * SystemInformationImplementation::GetProcessorSerialNumber()
 {
@@ -870,7 +1744,7 @@ void SystemInformationImplementation::Delay(unsigned int uiMS)
   QueryPerformanceCounter (&StartCounter);
 
   do {
-    // Get the ending position of the counter.  
+    // Get the ending position of the counter.
     QueryPerformanceCounter (&EndCounter);
     } while (EndCounter.QuadPart - StartCounter.QuadPart < x);
 #endif
@@ -880,140 +1754,89 @@ void SystemInformationImplementation::Delay(unsigned int uiMS)
 
 bool SystemInformationImplementation::DoesCPUSupportCPUID()
 {
+#if USE_CPUID
+  int dummy[4] = { 0, 0, 0, 0 };
+
 #if USE_ASM_INSTRUCTIONS
-  // Use SEH to determine CPUID presence
-    __try {
-        _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
+  return call_cpuid(0, dummy);
+#else
+  call_cpuid(0, dummy);
+  return dummy[0] || dummy[1] || dummy[2] || dummy[3];
 #endif
-      ; <<CPUID>> 
-            mov eax, 0
-      CPUID_INSTRUCTION
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-        }
-    }
-  __except(1) 
-    {
-    // Stop the class from trying to use CPUID again!
-    return false;
-    }
-
-  // The cpuid instruction succeeded.
-  return true;
-
-#else
-  // Assume no cpuid instruction.
-  return false;
+#else
+  // Assume no cpuid instruction.
+  return false;
 #endif
 }
 
 
 bool SystemInformationImplementation::RetrieveCPUFeatures()
 {
-#if USE_ASM_INSTRUCTIONS
-  int localCPUFeatures = 0;
-  int localCPUAdvanced = 0;
-
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>> 
-      ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;        ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;        edx: CPU feature flags
-      mov eax,1
-      CPUID_INSTRUCTION
-      mov localCPUFeatures, edx
-      mov localCPUAdvanced, ebx
+#if USE_CPUID
+  int cpuinfo[4] = { 0, 0, 0, 0 };
 
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1) 
+  if (!call_cpuid(1, cpuinfo))
     {
     return false;
     }
 
   // Retrieve the features of CPU present.
-  this->Features.HasFPU =     ((localCPUFeatures & 0x00000001) != 0);    // FPU Present --> Bit 0
-  this->Features.HasTSC =     ((localCPUFeatures & 0x00000010) != 0);    // TSC Present --> Bit 4
-  this->Features.HasAPIC =    ((localCPUFeatures & 0x00000200) != 0);    // APIC Present --> Bit 9
-  this->Features.HasMTRR =    ((localCPUFeatures & 0x00001000) != 0);    // MTRR Present --> Bit 12
-  this->Features.HasCMOV =    ((localCPUFeatures & 0x00008000) != 0);    // CMOV Present --> Bit 15
-  this->Features.HasSerial =  ((localCPUFeatures & 0x00040000) != 0);    // Serial Present --> Bit 18
-  this->Features.HasACPI =    ((localCPUFeatures & 0x00400000) != 0);    // ACPI Capable --> Bit 22
-  this->Features.HasMMX =     ((localCPUFeatures & 0x00800000) != 0);    // MMX Present --> Bit 23
-  this->Features.HasSSE =     ((localCPUFeatures & 0x02000000) != 0);    // SSE Present --> Bit 25
-  this->Features.HasSSE2 =    ((localCPUFeatures & 0x04000000) != 0);    // SSE2 Present --> Bit 26
-  this->Features.HasThermal = ((localCPUFeatures & 0x20000000) != 0);    // Thermal Monitor Present --> Bit 29
-  this->Features.HasIA64 =    ((localCPUFeatures & 0x40000000) != 0);    // IA64 Present --> Bit 30
+  this->Features.HasFPU =     ((cpuinfo[3] & 0x00000001) != 0);    // FPU Present --> Bit 0
+  this->Features.HasTSC =     ((cpuinfo[3] & 0x00000010) != 0);    // TSC Present --> Bit 4
+  this->Features.HasAPIC =    ((cpuinfo[3] & 0x00000200) != 0);    // APIC Present --> Bit 9
+  this->Features.HasMTRR =    ((cpuinfo[3] & 0x00001000) != 0);    // MTRR Present --> Bit 12
+  this->Features.HasCMOV =    ((cpuinfo[3] & 0x00008000) != 0);    // CMOV Present --> Bit 15
+  this->Features.HasSerial =  ((cpuinfo[3] & 0x00040000) != 0);    // Serial Present --> Bit 18
+  this->Features.HasACPI =    ((cpuinfo[3] & 0x00400000) != 0);    // ACPI Capable --> Bit 22
+  this->Features.HasMMX =     ((cpuinfo[3] & 0x00800000) != 0);    // MMX Present --> Bit 23
+  this->Features.HasSSE =     ((cpuinfo[3] & 0x02000000) != 0);    // SSE Present --> Bit 25
+  this->Features.HasSSE2 =    ((cpuinfo[3] & 0x04000000) != 0);    // SSE2 Present --> Bit 26
+  this->Features.HasThermal = ((cpuinfo[3] & 0x20000000) != 0);    // Thermal Monitor Present --> Bit 29
+  this->Features.HasIA64 =    ((cpuinfo[3] & 0x40000000) != 0);    // IA64 Present --> Bit 30
 
+#if USE_ASM_INSTRUCTIONS
   // Retrieve extended SSE capabilities if SSE is available.
   if (this->Features.HasSSE) {
-    
+
     // Attempt to __try some SSE FP instructions.
-    __try 
+    __try
       {
       // Perform: orps xmm0, xmm0
-      _asm 
+      _asm
         {
         _emit 0x0f
         _emit 0x56
-        _emit 0xc0  
+        _emit 0xc0
         }
 
       // SSE FP capable processor.
       this->Features.HasSSEFP = true;
-      }   
-    __except(1) 
+      }
+    __except(1)
       {
       // bad instruction - processor or OS cannot handle SSE FP.
       this->Features.HasSSEFP = false;
       }
-    } 
-  else 
+    }
+  else
     {
     // Set the advanced SSE capabilities to not available.
     this->Features.HasSSEFP = false;
     }
+#else
+  this->Features.HasSSEFP = false;
+#endif
 
   // Retrieve Intel specific extended features.
-  if (this->ChipManufacturer == Intel) 
+  if (this->ChipManufacturer == Intel)
     {
-    this->Features.ExtendedFeatures.SupportsHyperthreading =  ((localCPUFeatures &  0x10000000) != 0);  // Intel specific: Hyperthreading --> Bit 28
-    this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((localCPUAdvanced & 0x00FF0000) >> 16) : 1;
-    
+    this->Features.ExtendedFeatures.SupportsHyperthreading =  ((cpuinfo[3] &  0x10000000) != 0);  // Intel specific: Hyperthreading --> Bit 28
+    this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((cpuinfo[1] & 0x00FF0000) >> 16) : 1;
+
     if ((this->Features.ExtendedFeatures.SupportsHyperthreading) && (this->Features.HasAPIC))
       {
       // Retrieve APIC information if there is one present.
-      this->Features.ExtendedFeatures.APIC_ID = ((localCPUAdvanced & 0xFF000000) >> 24);
+      this->Features.ExtendedFeatures.APIC_ID = ((cpuinfo[1] & 0xFF000000) >> 24);
       }
     }
 
@@ -1026,7 +1849,7 @@ bool SystemInformationImplementation::RetrieveCPUFeatures()
 
 
 /** Find the manufacturer given the vendor id */
-void SystemInformationImplementation::FindManufacturer()
+void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& family)
 {
   if (this->ChipID.Vendor == "GenuineIntel")       this->ChipManufacturer = Intel;        // Intel Corp.
   else if (this->ChipID.Vendor == "UMC UMC UMC ")  this->ChipManufacturer = UMC;          // United Microelectronics Corp.
@@ -1041,7 +1864,9 @@ void SystemInformationImplementation::FindManufacturer()
   else if (this->ChipID.Vendor == "Geode By NSC")  this->ChipManufacturer = NSC;          // National Semiconductor
   else if (this->ChipID.Vendor == "Sun")           this->ChipManufacturer = Sun;          // Sun Microelectronics
   else if (this->ChipID.Vendor == "IBM")           this->ChipManufacturer = IBM;          // IBM Microelectronics
+  else if (this->ChipID.Vendor == "Hewlett-Packard") this->ChipManufacturer = HP;         // Hewlett-Packard
   else if (this->ChipID.Vendor == "Motorola")      this->ChipManufacturer = Motorola;          // Motorola Microelectronics
+  else if (family.substr(0, 7) == "PA-RISC")       this->ChipManufacturer = HP;           // Hewlett-Packard
   else                                             this->ChipManufacturer = UnknownManufacturer;  // Unknown manufacturer
 }
 
@@ -1049,73 +1874,41 @@ void SystemInformationImplementation::FindManufacturer()
 /** */
 bool SystemInformationImplementation::RetrieveCPUIdentity()
 {
-#if USE_ASM_INSTRUCTIONS
-  int localCPUVendor[3];
-  int localCPUSignature;
+#if USE_CPUID
+  int localCPUVendor[4];
+  int localCPUSignature[4];
 
-  // Use assembly to detect CPUID information...
-  __try 
+  if (!call_cpuid(0, localCPUVendor))
     {
-    _asm 
-      {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 0 --> eax: maximum value of CPUID instruction.
-      ;        ebx: part 1 of 3; CPU signature.
-      ;        edx: part 2 of 3; CPU signature.
-      ;        ecx: part 3 of 3; CPU signature.
-      mov eax, 0
-      CPUID_INSTRUCTION
-      mov localCPUVendor[0 * TYPE int], ebx
-      mov localCPUVendor[1 * TYPE int], edx
-      mov localCPUVendor[2 * TYPE int], ecx
-
-      ; <<CPUID>> 
-      ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;        ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;        edx: CPU feature flags
-      mov eax,1
-      CPUID_INSTRUCTION
-      mov localCPUSignature, eax
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
+    return false;
     }
-  }
-  __except(1) 
+  if (!call_cpuid(1, localCPUSignature))
     {
     return false;
     }
 
   // Process the returned information.
+  //    ; eax = 0 --> eax: maximum value of CPUID instruction.
+  //    ;        ebx: part 1 of 3; CPU signature.
+  //    ;        edx: part 2 of 3; CPU signature.
+  //    ;        ecx: part 3 of 3; CPU signature.
   char vbuf[13];
-  memcpy (&(vbuf[0]), &(localCPUVendor[0]), sizeof (int));
-  memcpy (&(vbuf[4]), &(localCPUVendor[1]), sizeof (int));
+  memcpy (&(vbuf[0]), &(localCPUVendor[1]), sizeof (int));
+  memcpy (&(vbuf[4]), &(localCPUVendor[3]), sizeof (int));
   memcpy (&(vbuf[8]), &(localCPUVendor[2]), sizeof (int));
   vbuf[12] = '\0';
   this->ChipID.Vendor = vbuf;
 
-  this->FindManufacturer();
-
   // Retrieve the family of CPU present.
-  this->ChipID.ExtendedFamily =    ((localCPUSignature & 0x0FF00000) >> 20);  // Bits 27..20 Used
-  this->ChipID.ExtendedModel =    ((localCPUSignature & 0x000F0000) >> 16);  // Bits 19..16 Used
-  this->ChipID.Type =        ((localCPUSignature & 0x0000F000) >> 12);  // Bits 15..12 Used
-  this->ChipID.Family =        ((localCPUSignature & 0x00000F00) >> 8);    // Bits 11..8 Used
-  this->ChipID.Model =        ((localCPUSignature & 0x000000F0) >> 4);    // Bits 7..4 Used
-  this->ChipID.Revision =      ((localCPUSignature & 0x0000000F) >> 0);    // Bits 3..0 Used
+  //    ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
+  //    ;        ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
+  //    ;        edx: CPU feature flags
+  this->ChipID.ExtendedFamily = ((localCPUSignature[0] & 0x0FF00000) >> 20);  // Bits 27..20 Used
+  this->ChipID.ExtendedModel =  ((localCPUSignature[0] & 0x000F0000) >> 16);  // Bits 19..16 Used
+  this->ChipID.Type =           ((localCPUSignature[0] & 0x0000F000) >> 12);  // Bits 15..12 Used
+  this->ChipID.Family =         ((localCPUSignature[0] & 0x00000F00) >> 8);    // Bits 11..8 Used
+  this->ChipID.Model =          ((localCPUSignature[0] & 0x000000F0) >> 4);    // Bits 7..4 Used
+  this->ChipID.Revision =       ((localCPUSignature[0] & 0x0000000F) >> 0);    // Bits 3..0 Used
 
   return true;
 
@@ -1128,111 +1921,43 @@ bool SystemInformationImplementation::RetrieveCPUIdentity()
 /** */
 bool SystemInformationImplementation::RetrieveCPUCacheDetails()
 {
-#if USE_ASM_INSTRUCTIONS
+#if USE_CPUID
   int L1Cache[4] = { 0, 0, 0, 0 };
   int L2Cache[4] = { 0, 0, 0, 0 };
 
   // Check to see if what we are about to do is supported...
-  if (RetrieveCPUExtendedLevelSupport (0x80000005)) 
+  if (RetrieveCPUExtendedLevelSupport (0x80000005))
     {
-    // Use assembly to retrieve the L1 cache information ...
-    __try 
-      {
-      _asm 
-        {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 0x80000005 --> eax: L1 cache information - Part 1 of 4.
-        ;             ebx: L1 cache information - Part 2 of 4.
-        ;             edx: L1 cache information - Part 3 of 4.
-        ;              ecx: L1 cache information - Part 4 of 4.
-        mov eax, 0x80000005
-        CPUID_INSTRUCTION
-        mov L1Cache[0 * TYPE int], eax
-        mov L1Cache[1 * TYPE int], ebx
-        mov L1Cache[2 * TYPE int], ecx
-        mov L1Cache[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1) 
+    if (!call_cpuid(0x80000005, L1Cache))
       {
       return false;
       }
     // Save the L1 data cache size (in KB) from ecx: bits 31..24 as well as data cache size from edx: bits 31..24.
     this->Features.L1CacheSize = ((L1Cache[2] & 0xFF000000) >> 24);
     this->Features.L1CacheSize += ((L1Cache[3] & 0xFF000000) >> 24);
-    } 
-  else 
+    }
+  else
     {
     // Store -1 to indicate the cache could not be queried.
     this->Features.L1CacheSize = -1;
     }
 
   // Check to see if what we are about to do is supported...
-  if (RetrieveCPUExtendedLevelSupport (0x80000006)) 
+  if (RetrieveCPUExtendedLevelSupport (0x80000006))
     {
-    // Use assembly to retrieve the L2 cache information ...
-    __try 
-      {
-      _asm 
-        {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 0x80000006 --> eax: L2 cache information - Part 1 of 4.
-        ;             ebx: L2 cache information - Part 2 of 4.
-        ;             edx: L2 cache information - Part 3 of 4.
-        ;              ecx: L2 cache information - Part 4 of 4.
-        mov eax, 0x80000006
-        CPUID_INSTRUCTION
-        mov L2Cache[0 * TYPE int], eax
-        mov L2Cache[1 * TYPE int], ebx
-        mov L2Cache[2 * TYPE int], ecx
-        mov L2Cache[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1) 
+    if (!call_cpuid(0x80000006, L2Cache))
       {
       return false;
       }
     // Save the L2 unified cache size (in KB) from ecx: bits 31..16.
     this->Features.L2CacheSize = ((L2Cache[2] & 0xFFFF0000) >> 16);
-    } 
+    }
   else
     {
     // Store -1 to indicate the cache could not be queried.
     this->Features.L2CacheSize = -1;
     }
-  
+
   // Define L3 as being not present as we cannot test for it.
   this->Features.L3CacheSize = -1;
 
@@ -1246,7 +1971,7 @@ bool SystemInformationImplementation::RetrieveCPUCacheDetails()
 /** */
 bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
 {
-#if USE_ASM_INSTRUCTIONS
+#if USE_CPUID
   int TLBCode = -1, TLBData = -1, L1Code = -1, L1Data = -1, L1Trace = -1, L2Unified = -1, L3Unified = -1;
   int TLBCacheData[4] = { 0, 0, 0, 0 };
   int TLBPassCounter = 0;
@@ -1254,39 +1979,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
 
 
   do {
-    // Use assembly to retrieve the L2 cache information ...
-    __try {
-      _asm {
-#ifdef CPUID_AWARE_COMPILER
-         ; we must push/pop the registers <<CPUID>> writes to, as the
-        ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-        ; these registers to change.
-        push eax
-        push ebx
-        push ecx
-        push edx
-#endif
-        ; <<CPUID>>
-        ; eax = 2 --> eax: TLB and cache information - Part 1 of 4.
-        ;        ebx: TLB and cache information - Part 2 of 4.
-        ;        ecx: TLB and cache information - Part 3 of 4.
-        ;        edx: TLB and cache information - Part 4 of 4.
-        mov eax, 2
-        CPUID_INSTRUCTION
-        mov TLBCacheData[0 * TYPE int], eax
-        mov TLBCacheData[1 * TYPE int], ebx
-        mov TLBCacheData[2 * TYPE int], ecx
-        mov TLBCacheData[3 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-        pop edx
-        pop ecx
-        pop ebx
-        pop eax
-#endif
-        }
-      }
-    __except(1)
+    if (!call_cpuid(2, TLBCacheData))
       {
       return false;
       }
@@ -1294,10 +1987,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
     int bob = ((TLBCacheData[0] & 0x00FF0000) >> 16);
     (void)bob;
     // Process the returned TLB and cache information.
-    for (int nCounter = 0; nCounter < TLBCACHE_INFO_UNITS; nCounter ++) 
+    for (int nCounter = 0; nCounter < TLBCACHE_INFO_UNITS; nCounter ++)
       {
       // First of all - decide which unit we are dealing with.
-      switch (nCounter) 
+      switch (nCounter)
         {
         // eax: bits 8..15 : bits 16..23 : bits 24..31
         case 0: TLBCacheUnit = ((TLBCacheData[0] & 0x0000FF00) >> 8); break;
@@ -1327,7 +2020,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
         }
 
       // Now process the resulting unit to see what it means....
-      switch (TLBCacheUnit) 
+      switch (TLBCacheUnit)
         {
         case 0x00: break;
         case 0x01: STORE_TLBCACHE_INFO (TLBCode, 4); break;
@@ -1383,7 +2076,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
         case 0x90: STORE_TLBCACHE_INFO (TLBCode, 262144); break;  // <-- FIXME: IA-64 Only
         case 0x96: STORE_TLBCACHE_INFO (TLBCode, 262144); break;  // <-- FIXME: IA-64 Only
         case 0x9b: STORE_TLBCACHE_INFO (TLBCode, 262144); break;  // <-- FIXME: IA-64 Only
-        
+
         // Default case - an error has occured.
         default: return false;
         }
@@ -1394,47 +2087,47 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
     } while ((TLBCacheData[0] & 0x000000FF) > TLBPassCounter);
 
   // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
-  if ((L1Code == -1) && (L1Data == -1) && (L1Trace == -1)) 
+  if ((L1Code == -1) && (L1Data == -1) && (L1Trace == -1))
     {
     this->Features.L1CacheSize = -1;
     }
-  else if ((L1Code == -1) && (L1Data == -1) && (L1Trace != -1)) 
+  else if ((L1Code == -1) && (L1Data == -1) && (L1Trace != -1))
     {
     this->Features.L1CacheSize = L1Trace;
     }
-  else if ((L1Code != -1) && (L1Data == -1)) 
+  else if ((L1Code != -1) && (L1Data == -1))
     {
     this->Features.L1CacheSize = L1Code;
     }
-  else if ((L1Code == -1) && (L1Data != -1)) 
+  else if ((L1Code == -1) && (L1Data != -1))
     {
     this->Features.L1CacheSize = L1Data;
     }
-  else if ((L1Code != -1) && (L1Data != -1)) 
+  else if ((L1Code != -1) && (L1Data != -1))
     {
     this->Features.L1CacheSize = L1Code + L1Data;
     }
-  else 
+  else
     {
     this->Features.L1CacheSize = -1;
     }
 
   // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
-  if (L2Unified == -1) 
+  if (L2Unified == -1)
     {
     this->Features.L2CacheSize = -1;
     }
-  else 
+  else
     {
     this->Features.L2CacheSize = L2Unified;
     }
 
   // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
-  if (L3Unified == -1) 
+  if (L3Unified == -1)
     {
     this->Features.L3CacheSize = -1;
     }
-  else 
+  else
     {
     this->Features.L3CacheSize = L3Unified;
     }
@@ -1453,11 +2146,40 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
   bool retrieved = false;
 
 #if defined(_WIN32)
-  // First of all we check to see if the RDTSC (0x0F, 0x31) instruction is
-  // supported. If not, we fallback to trying to read this value from the
-  // registry:
-  //
-  if (!this->Features.HasTSC)
+  unsigned int uiRepetitions = 1;
+  unsigned int uiMSecPerRepetition = 50;
+  __int64  i64Total = 0;
+  __int64 i64Overhead = 0;
+
+  // Check if the TSC implementation works at all
+  if (this->Features.HasTSC &&
+      GetCyclesDifference(SystemInformationImplementation::Delay,
+                          uiMSecPerRepetition) > 0)
+    {
+    for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++)
+      {
+      i64Total += GetCyclesDifference (SystemInformationImplementation::Delay,
+                                       uiMSecPerRepetition);
+      i64Overhead +=
+        GetCyclesDifference (SystemInformationImplementation::DelayOverhead,
+                             uiMSecPerRepetition);
+      }
+
+    // Calculate the MHz speed.
+    i64Total -= i64Overhead;
+    i64Total /= uiRepetitions;
+    i64Total /= uiMSecPerRepetition;
+    i64Total /= 1000;
+
+    // Save the CPU speed.
+    this->CPUSpeedInMHz = (float) i64Total;
+
+    retrieved = true;
+    }
+
+  // If RDTSC is not supported, we fallback to trying to read this value
+  // from the registry:
+  if (!retrieved)
     {
     HKEY hKey = NULL;
     LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
@@ -1482,34 +2204,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed()
       RegCloseKey(hKey);
       hKey = NULL;
       }
-
-    return retrieved;
     }
-
-  unsigned int uiRepetitions = 1;
-  unsigned int uiMSecPerRepetition = 50;
-  __int64  i64Total = 0;
-  __int64 i64Overhead = 0;
-
-  for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++)
-    {
-    i64Total += GetCyclesDifference (SystemInformationImplementation::Delay,
-                                     uiMSecPerRepetition);
-    i64Overhead +=
-      GetCyclesDifference (SystemInformationImplementation::DelayOverhead,
-                           uiMSecPerRepetition);
-    }
-
-  // Calculate the MHz speed.
-  i64Total -= i64Overhead;
-  i64Total /= uiRepetitions;
-  i64Total /= uiMSecPerRepetition;
-  i64Total /= 1000;
-
-  // Save the CPU speed.
-  this->CPUSpeedInMHz = (float) i64Total;
-
-  retrieved = true;
 #endif
 
   return retrieved;
@@ -1526,19 +2221,19 @@ bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed()
   // Attempt to get a starting tick count.
   QueryPerformanceCounter (&liStart);
 
-  __try 
+  __try
     {
-    _asm 
+    _asm
       {
       mov eax, 0x80000000
       mov ebx, CLASSICAL_CPU_FREQ_LOOP
-      Timer_Loop: 
+      Timer_Loop:
       bsf ecx,eax
       dec ebx
       jnz Timer_Loop
-      }  
+      }
     }
-  __except(1) 
+  __except(1)
     {
     return false;
     }
@@ -1551,22 +2246,22 @@ bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed()
   dDifference = (((double) liEnd.QuadPart - (double) liStart.QuadPart) / (double) liCountsPerSecond.QuadPart);
 
   // Calculate the clock speed.
-  if (this->ChipID.Family == 3) 
+  if (this->ChipID.Family == 3)
     {
     // 80386 processors....  Loop time is 115 cycles!
     dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 115) / dDifference) / 1000000);
-    } 
-  else if (this->ChipID.Family == 4) 
+    }
+  else if (this->ChipID.Family == 4)
     {
     // 80486 processors....  Loop time is 47 cycles!
     dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 47) / dDifference) / 1000000);
-    } 
-  else if (this->ChipID.Family == 5) 
+    }
+  else if (this->ChipID.Family == 5)
     {
     // Pentium processors....  Loop time is 43 cycles!
     dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 43) / dDifference) / 1000000);
     }
-  
+
   // Save the clock speed.
   this->Features.CPUSpeed = (int) dFrequency;
 
@@ -1581,9 +2276,9 @@ bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed()
 /** */
 bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULevelToCheck)
 {
-  int MaxCPUExtendedLevel = 0;
+  int cpuinfo[4] = { 0, 0, 0, 0 };
 
-  // The extended CPUID is supported by various vendors starting with the following CPU models: 
+  // The extended CPUID is supported by various vendors starting with the following CPU models:
   //
   //    Manufacturer & Chip Name      |    Family     Model    Revision
   //
@@ -1596,27 +2291,27 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev
   //
 
   // We check to see if a supported processor is present...
-  if (this->ChipManufacturer == AMD) 
+  if (this->ChipManufacturer == AMD)
     {
     if (this->ChipID.Family < 5) return false;
     if ((this->ChipID.Family == 5) && (this->ChipID.Model < 6)) return false;
-    } 
-  else if (this->ChipManufacturer == Cyrix) 
+    }
+  else if (this->ChipManufacturer == Cyrix)
     {
     if (this->ChipID.Family < 5) return false;
     if ((this->ChipID.Family == 5) && (this->ChipID.Model < 4)) return false;
     if ((this->ChipID.Family == 6) && (this->ChipID.Model < 5)) return false;
-    } 
-  else if (this->ChipManufacturer == IDT) 
+    }
+  else if (this->ChipManufacturer == IDT)
     {
     if (this->ChipID.Family < 5) return false;
     if ((this->ChipID.Family == 5) && (this->ChipID.Model < 8)) return false;
-    } 
-  else if (this->ChipManufacturer == Transmeta) 
+    }
+  else if (this->ChipManufacturer == Transmeta)
     {
     if (this->ChipID.Family < 5) return false;
-    } 
-  else if (this->ChipManufacturer == Intel) 
+    }
+  else if (this->ChipManufacturer == Intel)
     {
     if (this->ChipID.Family < 0xf)
       {
@@ -1624,35 +2319,8 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev
       }
     }
 
-#if USE_ASM_INSTRUCTIONS
-
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>> 
-      ; eax = 0x80000000 --> eax: maximum supported extended level
-      mov eax,0x80000000
-      CPUID_INSTRUCTION
-      mov MaxCPUExtendedLevel, eax
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1) 
+#if USE_CPUID
+  if (!call_cpuid(0x80000000, cpuinfo))
     {
     return false;
     }
@@ -1660,7 +2328,7 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev
 
   // Now we have to check the level wanted vs level returned...
   int nLevelWanted = (CPULevelToCheck & 0x7FFFFFFF);
-  int nLevelReturn = (MaxCPUExtendedLevel & 0x7FFFFFFF);
+  int nLevelReturn = (cpuinfo[0] & 0x7FFFFFFF);
 
   // Check to see if the level provided is supported...
   if (nLevelWanted > nLevelReturn)
@@ -1677,7 +2345,7 @@ bool SystemInformationImplementation::RetrieveExtendedCPUFeatures()
 {
 
   // Check that we are not using an Intel processor as it does not support this.
-  if (this->ChipManufacturer == Intel) 
+  if (this->ChipManufacturer == Intel)
     {
     return false;
     }
@@ -1688,60 +2356,30 @@ bool SystemInformationImplementation::RetrieveExtendedCPUFeatures()
     return false;
     }
 
-#if USE_ASM_INSTRUCTIONS
-  int localCPUExtendedFeatures = 0;
-
-  // Use assembly to detect CPUID information...
-  __try 
-    {
-    _asm 
-      {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>> 
-      ; eax = 0x80000001 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
-      ;             ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
-      ;             edx: CPU feature flags
-      mov eax,0x80000001
-      CPUID_INSTRUCTION
-      mov localCPUExtendedFeatures, edx
+#if USE_CPUID
+  int localCPUExtendedFeatures[4] = { 0, 0, 0, 0 };
 
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-      }
-    }
-  __except(1) 
+  if (!call_cpuid(0x80000001, localCPUExtendedFeatures))
     {
     return false;
     }
 
   // Retrieve the extended features of CPU present.
-  this->Features.ExtendedFeatures.Has3DNow = ((localCPUExtendedFeatures & 0x80000000) != 0);  // 3DNow Present --> Bit 31.
-  this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures & 0x40000000) != 0);  // 3DNow+ Present -- > Bit 30.
-  this->Features.ExtendedFeatures.HasSSEMMX = ((localCPUExtendedFeatures & 0x00400000) != 0);  // SSE MMX Present --> Bit 22.
-  this->Features.ExtendedFeatures.SupportsMP = ((localCPUExtendedFeatures & 0x00080000) != 0);  // MP Capable -- > Bit 19.
-  
+  this->Features.ExtendedFeatures.Has3DNow =     ((localCPUExtendedFeatures[3] & 0x80000000) != 0);  // 3DNow Present --> Bit 31.
+  this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures[3] & 0x40000000) != 0);  // 3DNow+ Present -- > Bit 30.
+  this->Features.ExtendedFeatures.HasSSEMMX =    ((localCPUExtendedFeatures[3] & 0x00400000) != 0);  // SSE MMX Present --> Bit 22.
+  this->Features.ExtendedFeatures.SupportsMP =   ((localCPUExtendedFeatures[3] & 0x00080000) != 0);  // MP Capable -- > Bit 19.
+
   // Retrieve AMD specific extended features.
-  if (this->ChipManufacturer == AMD) 
+  if (this->ChipManufacturer == AMD)
     {
-    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures &  0x00400000) != 0);  // AMD specific: MMX-SSE --> Bit 22
+    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x00400000) != 0);  // AMD specific: MMX-SSE --> Bit 22
     }
 
   // Retrieve Cyrix specific extended features.
-  if (this->ChipManufacturer == Cyrix) 
+  if (this->ChipManufacturer == Cyrix)
     {
-    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures &  0x01000000) != 0);  // Cyrix specific: Extended MMX --> Bit 24
+    this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x01000000) != 0);  // Cyrix specific: Extended MMX --> Bit 24
     }
 
   return true;
@@ -1761,51 +2399,20 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber()
     return false;
     }
 
-#if USE_ASM_INSTRUCTIONS
-  int SerialNumber[3];
-
-    // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>>
-      ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!?
-      ;        ecx: middle 32 bits are the processor signature bits
-      ;        edx: bottom 32 bits are the processor signature bits
-      mov eax, 3
-      CPUID_INSTRUCTION
-      mov SerialNumber[0 * TYPE int], ebx
-      mov SerialNumber[1 * TYPE int], ecx
-      mov SerialNumber[2 * TYPE int], edx
+#if USE_CPUID
+  int SerialNumber[4];
 
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1) 
+  if (!call_cpuid(3, SerialNumber))
     {
     return false;
     }
 
   // Process the returned information.
+  //    ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!?
+  //    ;        ecx: middle 32 bits are the processor signature bits
+  //    ;        edx: bottom 32 bits are the processor signature bits
   char sn[128];
   sprintf (sn, "%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x",
-       ((SerialNumber[0] & 0xff000000) >> 24),
-       ((SerialNumber[0] & 0x00ff0000) >> 16),
-       ((SerialNumber[0] & 0x0000ff00) >> 8),
-       ((SerialNumber[0] & 0x000000ff) >> 0),
        ((SerialNumber[1] & 0xff000000) >> 24),
        ((SerialNumber[1] & 0x00ff0000) >> 16),
        ((SerialNumber[1] & 0x0000ff00) >> 8),
@@ -1813,7 +2420,11 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber()
        ((SerialNumber[2] & 0xff000000) >> 24),
        ((SerialNumber[2] & 0x00ff0000) >> 16),
        ((SerialNumber[2] & 0x0000ff00) >> 8),
-       ((SerialNumber[2] & 0x000000ff) >> 0));
+       ((SerialNumber[2] & 0x000000ff) >> 0),
+       ((SerialNumber[3] & 0xff000000) >> 24),
+       ((SerialNumber[3] & 0x00ff0000) >> 16),
+       ((SerialNumber[3] & 0x0000ff00) >> 8),
+       ((SerialNumber[3] & 0x000000ff) >> 0));
   this->ChipID.SerialNumber = sn;
   return true;
 
@@ -1835,45 +2446,18 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
     return false;
     }
 
-#if USE_ASM_INSTRUCTIONS
-  int localCPUPowerManagement = 0;
-
+#if USE_CPUID
+  int localCPUPowerManagement[4] = { 0, 0, 0, 0 };
 
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>> 
-      ; eax = 0x80000007 --> edx: get processor power management
-      mov eax,0x80000007
-      CPUID_INSTRUCTION
-      mov localCPUPowerManagement, edx
-      
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
-    }
-  }
-  __except(1) 
+  if (!call_cpuid(0x80000007, localCPUPowerManagement))
     {
     return false;
     }
 
   // Check for the power management capabilities of the CPU.
-  this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode =  ((localCPUPowerManagement & 0x00000001) != 0);
-  this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID =    ((localCPUPowerManagement & 0x00000002) != 0);
-  this->Features.ExtendedFeatures.PowerManagement.HasVoltageID =    ((localCPUPowerManagement & 0x00000004) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode =  ((localCPUPowerManagement[3] & 0x00000001) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID =     ((localCPUPowerManagement[3] & 0x00000002) != 0);
+  this->Features.ExtendedFeatures.PowerManagement.HasVoltageID =       ((localCPUPowerManagement[3] & 0x00000004) != 0);
 
   return true;
 
@@ -1882,7 +2466,9 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
 #endif
 }
 
-void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
+#if USE_CPUID
+// Used only in USE_CPUID implementation below.
+static void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
 {
   // Because some manufacturers have leading white space - we have to post-process the name.
   kwsys_stl::string::size_type pos = str.find_first_not_of(" ");
@@ -1891,6 +2477,7 @@ void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
     str = str.substr(pos);
     }
 }
+#endif
 
 /** */
 bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
@@ -1903,57 +2490,18 @@ bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
   if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000004)))
     return false;
 
-#if USE_ASM_INSTRUCTIONS
+#if USE_CPUID
   int CPUExtendedIdentity[12];
 
-  // Use assembly to detect CPUID information...
-  __try {
-    _asm {
-#ifdef CPUID_AWARE_COMPILER
-       ; we must push/pop the registers <<CPUID>> writes to, as the
-      ; optimiser doesn't know about <<CPUID>>, and so doesn't expect
-      ; these registers to change.
-      push eax
-      push ebx
-      push ecx
-      push edx
-#endif
-      ; <<CPUID>> 
-      ; eax = 0x80000002 --> eax, ebx, ecx, edx: get processor name string (part 1)
-      mov eax,0x80000002
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[0 * TYPE int], eax
-      mov CPUExtendedIdentity[1 * TYPE int], ebx
-      mov CPUExtendedIdentity[2 * TYPE int], ecx
-      mov CPUExtendedIdentity[3 * TYPE int], edx
-
-      ; <<CPUID>> 
-      ; eax = 0x80000003 --> eax, ebx, ecx, edx: get processor name string (part 2)
-      mov eax,0x80000003
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[4 * TYPE int], eax
-      mov CPUExtendedIdentity[5 * TYPE int], ebx
-      mov CPUExtendedIdentity[6 * TYPE int], ecx
-      mov CPUExtendedIdentity[7 * TYPE int], edx
-
-      ; <<CPUID>> 
-      ; eax = 0x80000004 --> eax, ebx, ecx, edx: get processor name string (part 3)
-      mov eax,0x80000004
-      CPUID_INSTRUCTION
-      mov CPUExtendedIdentity[8 * TYPE int], eax
-      mov CPUExtendedIdentity[9 * TYPE int], ebx
-      mov CPUExtendedIdentity[10 * TYPE int], ecx
-      mov CPUExtendedIdentity[11 * TYPE int], edx
-
-#ifdef CPUID_AWARE_COMPILER
-      pop edx
-      pop ecx
-      pop ebx
-      pop eax
-#endif
+  if (!call_cpuid(0x80000002, CPUExtendedIdentity))
+    {
+    return false;
     }
-  }
-  __except(1) 
+  if (!call_cpuid(0x80000003, CPUExtendedIdentity + 4))
+    {
+    return false;
+    }
+  if (!call_cpuid(0x80000004, CPUExtendedIdentity + 8))
     {
     return false;
     }
@@ -1974,6 +2522,7 @@ bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
   memcpy (&(nbuf[44]), &(CPUExtendedIdentity[11]), sizeof (int));
   nbuf[48] = '\0';
   this->ChipID.ProcessorName = nbuf;
+  this->ChipID.ModelName = nbuf;
 
   // Because some manufacturers have leading white space - we have to post-process the name.
   SystemInformationStripLeadingSpace(this->ChipID.ProcessorName);
@@ -1988,13 +2537,13 @@ bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
 bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
 {
   // Start by decided which manufacturer we are using....
-  switch (this->ChipManufacturer) 
+  switch (this->ChipManufacturer)
     {
     case Intel:
       // Check the family / model / revision to determine the CPU ID.
       switch (this->ChipID.Family) {
         case 3:
-          this->ChipID.ProcessorName =  "Newer i80386 family"; 
+          this->ChipID.ProcessorName =  "Newer i80386 family";
           break;
         case 4:
           switch (this->ChipID.Model) {
@@ -2011,7 +2560,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "P5 A-Step"; break;
             case 1: this->ChipID.ProcessorName = "P5"; break;
@@ -2024,7 +2573,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 6:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "P6 A-Step"; break;
             case 1: this->ChipID.ProcessorName = "P6"; break;
@@ -2044,10 +2593,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
           break;
         case 0xf:
           // Check the extended family bits...
-          switch (this->ChipID.ExtendedFamily) 
+          switch (this->ChipID.ExtendedFamily)
             {
             case 0:
-              switch (this->ChipID.Model) 
+              switch (this->ChipID.Model)
                 {
                 case 0: this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; break;
                 case 1: this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; break;
@@ -2070,10 +2619,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
 
     case AMD:
       // Check the family / model / revision to determine the CPU ID.
-      switch (this->ChipID.Family) 
+      switch (this->ChipID.Family)
         {
         case 4:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 3: this->ChipID.ProcessorName = "80486DX2"; break;
             case 7: this->ChipID.ProcessorName = "80486DX2 WriteBack"; break;
@@ -2085,7 +2634,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "SSA5 (PR75, PR90 =  PR100)"; break;
             case 1: this->ChipID.ProcessorName = "5k86 (PR120 =  PR133)"; break;
@@ -2100,7 +2649,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 6:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 1: this->ChipID.ProcessorName = "Athlon- (0.25 micron)"; break;
             case 2: this->ChipID.ProcessorName = "Athlon- (0.18 micron)"; break;
@@ -2108,9 +2657,9 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             case 4: this->ChipID.ProcessorName = "Athlon- (Thunderbird core)"; break;
             case 6: this->ChipID.ProcessorName = "Athlon- (Palomino core)"; break;
             case 7: this->ChipID.ProcessorName = "Duron- (Morgan core)"; break;
-            case 8: 
+            case 8:
               if (this->Features.ExtendedFeatures.SupportsMP)
-                this->ChipID.ProcessorName = "Athlon - MP (Thoroughbred core)"; 
+                this->ChipID.ProcessorName = "Athlon - MP (Thoroughbred core)";
               else this->ChipID.ProcessorName = "Athlon - XP (Thoroughbred core)";
               break;
             default: this->ChipID.ProcessorName = "Unknown K7 family"; return false;
@@ -2123,10 +2672,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case Transmeta:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 4: this->ChipID.ProcessorName = "Crusoe TM3x00 and TM5x00"; break;
             default: this->ChipID.ProcessorName = "Unknown Crusoe family"; return false;
@@ -2139,10 +2688,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case Rise:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "mP6 (0.25 micron)"; break;
             case 2: this->ChipID.ProcessorName = "mP6 (0.18 micron)"; break;
@@ -2156,10 +2705,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case UMC:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 4:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 1: this->ChipID.ProcessorName = "U5D"; break;
             case 2: this->ChipID.ProcessorName = "U5S"; break;
@@ -2173,10 +2722,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case IDT:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 4: this->ChipID.ProcessorName = "C6"; break;
             case 8: this->ChipID.ProcessorName = "C2"; break;
@@ -2185,7 +2734,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 6:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 6: this->ChipID.ProcessorName = "VIA Cyrix III - Samuel"; break;
             default: this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; return false;
@@ -2198,10 +2747,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case Cyrix:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 4:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 4: this->ChipID.ProcessorName = "MediaGX GX =  GXm"; break;
             case 9: this->ChipID.ProcessorName = "5x86"; break;
@@ -2209,7 +2758,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 2: this->ChipID.ProcessorName = "Cx6x86"; break;
             case 4: this->ChipID.ProcessorName = "MediaGX GXm"; break;
@@ -2217,7 +2766,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
             }
           break;
         case 6:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "6x86MX"; break;
             case 5: this->ChipID.ProcessorName = "Cyrix M2 Core"; break;
@@ -2234,10 +2783,10 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
       break;
 
     case NexGen:
-      switch (this->ChipID.Family) 
-        {  
+      switch (this->ChipID.Family)
+        {
         case 5:
-          switch (this->ChipID.Model) 
+          switch (this->ChipID.Model)
             {
             case 0: this->ChipID.ProcessorName = "Nx586 or Nx586FPU"; break;
             default: this->ChipID.ProcessorName = "Unknown NexGen family"; return false;
@@ -2272,6 +2821,16 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(k
     size_t pos2 = buffer.find("\n",pos);
     if(pos!=buffer.npos && pos2!=buffer.npos)
       {
+      // It may happen that the beginning matches, but this is still not the requested key.
+      // An example is looking for "cpu" when "cpu family" comes first. So we check that
+      // we have only spaces from here to pos, otherwise we search again.
+      for(size_t i=this->CurrentPositionInFile+strlen(word); i < pos; ++i)
+        {
+        if(buffer[i] != ' ' && buffer[i] != '\t')
+          {
+          return this->ExtractValueFromCpuInfoFile(buffer, word, pos2);
+          }
+        }
       return buffer.substr(pos+2,pos2-pos-2);
       }
     }
@@ -2280,19 +2839,19 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(k
 }
 
 /** Query for the cpu status */
-int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
+bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 {
   this->NumberOfLogicalCPU = 0;
   this->NumberOfPhysicalCPU = 0;
   kwsys_stl::string buffer;
 
   FILE *fd = fopen("/proc/cpuinfo", "r" );
-  if ( !fd ) 
+  if ( !fd )
     {
     kwsys_ios::cout << "Problem opening /proc/cpuinfo" << kwsys_ios::endl;
-    return 0;
+    return false;
     }
-  
+
   size_t fileSize = 0;
   while(!feof(fd))
     {
@@ -2336,14 +2895,14 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
 
 #else // __CYGWIN__
   // does not have "physical id" entries, neither "cpu cores"
-  // this has to be fixed for hyper-threading.  
+  // this has to be fixed for hyper-threading.
   kwsys_stl::string cpucount =
     this->ExtractValueFromCpuInfoFile(buffer,"cpu count");
   this->NumberOfPhysicalCPU=
     this->NumberOfLogicalCPU = atoi(cpucount.c_str());
 #endif
-  // gotta have one, and if this is 0 then we get a / by 0n 
-  // beter to have a bad answer than a crash
+  // gotta have one, and if this is 0 then we get a / by 0n
+  // better to have a bad answer than a crash
   if(this->NumberOfPhysicalCPU <= 0)
     {
     this->NumberOfPhysicalCPU = 1;
@@ -2352,49 +2911,500 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
   this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical=
       this->NumberOfLogicalCPU/this->NumberOfPhysicalCPU;
 
-  // CPU speed (checking only the first proc
+  // CPU speed (checking only the first processor)
   kwsys_stl::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
   this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str()));
 
   // Chip family
-  this->ChipID.Family = atoi(this->ExtractValueFromCpuInfoFile(buffer,"cpu family").c_str());
+  kwsys_stl::string familyStr =
+    this->ExtractValueFromCpuInfoFile(buffer,"cpu family");
+  if(familyStr.empty())
+    {
+    familyStr = this->ExtractValueFromCpuInfoFile(buffer,"CPU architecture");
+    }
+  this->ChipID.Family = atoi(familyStr.c_str());
+
   // Chip Vendor
   this->ChipID.Vendor = this->ExtractValueFromCpuInfoFile(buffer,"vendor_id");
-  this->FindManufacturer();
-  
+  this->FindManufacturer(familyStr);
+
+  // second try for setting family
+  if (this->ChipID.Family == 0 && this->ChipManufacturer == HP)
+    {
+    if (familyStr == "PA-RISC 1.1a")
+      this->ChipID.Family = 0x11a;
+    else if (familyStr == "PA-RISC 2.0")
+      this->ChipID.Family = 0x200;
+    // If you really get CMake to work on a machine not belonging to
+    // any of those families I owe you a dinner if you get it to
+    // contribute nightly builds regularly.
+    }
+
   // Chip Model
   this->ChipID.Model = atoi(this->ExtractValueFromCpuInfoFile(buffer,"model").c_str());
-  this->RetrieveClassicalCPUIdentity();
+  if(!this->RetrieveClassicalCPUIdentity())
+    {
+    // Some platforms (e.g. PA-RISC) tell us their CPU name here.
+    // Note: x86 does not.
+    kwsys_stl::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu");
+    if(!cpuname.empty())
+      {
+      this->ChipID.ProcessorName = cpuname;
+      }
+    }
+
+  // Chip revision
+  kwsys_stl::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping");
+  if(cpurev.empty())
+    {
+    cpurev = this->ExtractValueFromCpuInfoFile(buffer,"CPU revision");
+    }
+  this->ChipID.Revision = atoi(cpurev.c_str());
+
+  // Chip Model Name
+  this->ChipID.ModelName = this->ExtractValueFromCpuInfoFile(buffer,"model name").c_str();
 
   // L1 Cache size
-  kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,"cache size");
-  pos = cacheSize.find(" KB");
-  if(pos!=cacheSize.npos)
+  // Different architectures may show different names for the caches.
+  // Sum up everything we find.
+  kwsys_stl::vector<const char*> cachename;
+  cachename.clear();
+
+  cachename.push_back("cache size"); // e.g. x86
+  cachename.push_back("I-cache"); // e.g. PA-RISC
+  cachename.push_back("D-cache"); // e.g. PA-RISC
+
+  this->Features.L1CacheSize = 0;
+  for (size_t index = 0; index < cachename.size(); index ++)
     {
-    cacheSize = cacheSize.substr(0,pos);
+    kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]);
+    if (!cacheSize.empty())
+      {
+      pos = cacheSize.find(" KB");
+      if(pos!=cacheSize.npos)
+        {
+        cacheSize = cacheSize.substr(0,pos);
+        }
+      this->Features.L1CacheSize += atoi(cacheSize.c_str());
+      }
     }
-  this->Features.L1CacheSize = atoi(cacheSize.c_str());
-  return 1;
+
+  // processor feature flags (probably x86 specific)
+  kwsys_stl::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags");
+  if(!cpurev.empty())
+    {
+    // now we can match every flags as space + flag + space
+    cpuflags = " " + cpuflags + " ";
+    if ((cpuflags.find(" fpu ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasFPU = true;
+      }
+    if ((cpuflags.find(" tsc ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasTSC = true;
+      }
+    if ((cpuflags.find(" mmx ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasMMX = true;
+      }
+    if ((cpuflags.find(" sse ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasSSE = true;
+      }
+    if ((cpuflags.find(" sse2 ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasSSE2 = true;
+      }
+    if ((cpuflags.find(" apic ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasAPIC = true;
+      }
+    if ((cpuflags.find(" cmov ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasCMOV = true;
+      }
+    if ((cpuflags.find(" mtrr ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasMTRR = true;
+      }
+    if ((cpuflags.find(" acpi ")!=kwsys_stl::string::npos))
+      {
+      this->Features.HasACPI = true;
+      }
+    if ((cpuflags.find(" 3dnow ")!=kwsys_stl::string::npos))
+      {
+      this->Features.ExtendedFeatures.Has3DNow = true;
+      }
+    }
+
+  return true;
 }
 
-/** Query for the memory status */
-int SystemInformationImplementation::QueryMemory()
+bool SystemInformationImplementation::QueryProcessorBySysconf()
 {
-  this->TotalVirtualMemory = 0;
-  this->TotalPhysicalMemory = 0;
-  this->AvailableVirtualMemory = 0;
-  this->AvailablePhysicalMemory = 0;
-#ifdef __CYGWIN__
+#if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN)
+// IRIX names this slightly different
+# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN
+#endif
+
+#ifdef _SC_NPROCESSORS_ONLN
+  long c = sysconf(_SC_NPROCESSORS_ONLN);
+  if (c <= 0)
+    {
+    return false;
+    }
+
+  this->NumberOfPhysicalCPU = static_cast<unsigned int>(c);
+  this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryProcessor()
+{
+  return this->QueryProcessorBySysconf();
+}
+
+/**
+Get total system RAM in units of KiB.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetHostMemoryTotal()
+{
+#if defined(_WIN32)
+# if defined(_MSC_VER) && _MSC_VER < 1300
+  MEMORYSTATUS stat;
+  stat.dwLength = sizeof(stat);
+  GlobalMemoryStatus(&stat);
+  return stat.dwTotalPhys/1024;
+# else
+  MEMORYSTATUSEX statex;
+  statex.dwLength=sizeof(statex);
+  GlobalMemoryStatusEx(&statex);
+  return statex.ullTotalPhys/1024;
+# endif
+#elif defined(__linux)
+  SystemInformation::LongLong memTotal=0;
+  int ierr=GetFieldFromFile("/proc/meminfo","MemTotal:",memTotal);
+  if (ierr)
+    {
+    return -1;
+    }
+  return memTotal;
+#elif defined(__APPLE__)
+  uint64_t mem;
+  size_t len = sizeof(mem);
+  int ierr=sysctlbyname("hw.memsize", &mem, &len, NULL, 0);
+  if (ierr)
+    {
+    return -1;
+    }
+  return mem/1024;
+#else
   return 0;
-#elif defined(_WIN32)
-#if  _MSC_VER < 1300
+#endif
+}
+
+/**
+Get total system RAM in units of KiB. This may differ from the
+host total if a host-wide resource limit is applied.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetHostMemoryAvailable(const char *hostLimitEnvVarName)
+{
+  SystemInformation::LongLong memTotal=this->GetHostMemoryTotal();
+
+  // the following mechanism is provided for systems that
+  // apply resource limits across groups of processes.
+  // this is of use on certain SMP systems (eg. SGI UV)
+  // where the host has a large amount of ram but a given user's
+  // access to it is severly restricted. The system will
+  // apply a limit across a set of processes. Units are in KiB.
+  if (hostLimitEnvVarName)
+    {
+    const char *hostLimitEnvVarValue=getenv(hostLimitEnvVarName);
+    if (hostLimitEnvVarValue)
+      {
+      SystemInformation::LongLong hostLimit=atoLongLong(hostLimitEnvVarValue);
+      if (hostLimit>0)
+        {
+        memTotal=min(hostLimit,memTotal);
+        }
+      }
+    }
+
+  return memTotal;
+}
+
+/**
+Get total system RAM in units of KiB. This may differ from the
+host total if a per-process resource limit is applied.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName,
+        const char *procLimitEnvVarName)
+{
+  SystemInformation::LongLong memAvail
+    = this->GetHostMemoryAvailable(hostLimitEnvVarName);
+
+  // the following mechanism is provide for systems where rlimits
+  // are not employed. Units are in KiB.
+  if (procLimitEnvVarName)
+    {
+    const char *procLimitEnvVarValue=getenv(procLimitEnvVarName);
+    if (procLimitEnvVarValue)
+      {
+      SystemInformation::LongLong procLimit=atoLongLong(procLimitEnvVarValue);
+      if (procLimit>0)
+        {
+        memAvail=min(procLimit,memAvail);
+        }
+      }
+    }
+
+#if defined(__linux)
+  int ierr;
+  ResourceLimitType rlim;
+  ierr=GetResourceLimit(RLIMIT_DATA,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+
+  ierr=GetResourceLimit(RLIMIT_AS,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+#elif defined(__APPLE__)
+  struct rlimit rlim;
+  int ierr;
+  ierr=getrlimit(RLIMIT_DATA,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+
+  ierr=getrlimit(RLIMIT_RSS,&rlim);
+  if ((ierr==0) && (rlim.rlim_cur != RLIM_INFINITY))
+    {
+    memAvail=min((SystemInformation::LongLong)rlim.rlim_cur/1024,memAvail);
+    }
+#endif
+
+  return memAvail;
+}
+
+/**
+Get RAM used by all processes in the host, in units of KiB.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetHostMemoryUsed()
+{
+#if defined(_WIN32)
+# if defined(_MSC_VER) && _MSC_VER < 1300
+  MEMORYSTATUS stat;
+  stat.dwLength = sizeof(stat);
+  GlobalMemoryStatus(&stat);
+  return (stat.dwTotalPhys - stat.dwAvailPhys)/1024;
+# else
+  MEMORYSTATUSEX statex;
+  statex.dwLength=sizeof(statex);
+  GlobalMemoryStatusEx(&statex);
+  return (statex.ullTotalPhys - statex.ullAvailPhys)/1024;
+# endif
+#elif defined(__linux)
+  const char *names[3]={"MemTotal:","MemFree:",NULL};
+  SystemInformation::LongLong values[2]={SystemInformation::LongLong(0)};
+  int ierr=GetFieldsFromFile("/proc/meminfo",names,values);
+  if (ierr)
+    {
+    return ierr;
+    }
+  SystemInformation::LongLong &memTotal=values[0];
+  SystemInformation::LongLong &memFree=values[1];
+  return memTotal - memFree;
+#elif defined(__APPLE__)
+  SystemInformation::LongLong psz=getpagesize();
+  if (psz<1)
+    {
+    return -1;
+    }
+  const char *names[4]={"Pages active:","Pages inactive:","Pages wired down:",NULL};
+  SystemInformation::LongLong values[3]={SystemInformation::LongLong(0)};
+  int ierr=GetFieldsFromCommand("vm_stat", names, values);
+  if (ierr)
+    {
+    return -1;
+    }
+  SystemInformation::LongLong &vmActive=values[0];
+  SystemInformation::LongLong &vmInactive=values[1];
+  SystemInformation::LongLong &vmWired=values[2];
+  return ((vmActive+vmInactive+vmWired)*psz)/1024;
+#else
+  return 0;
+#endif
+}
+
+/**
+Get system RAM used by the process associated with the given
+process id in units of KiB.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetProcMemoryUsed()
+{
+#if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI)
+  long pid=GetCurrentProcessId();
+  HANDLE hProc;
+  hProc=OpenProcess(
+      PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
+      false,
+      pid);
+  if (hProc==0)
+    {
+    return -1;
+    }
+  PROCESS_MEMORY_COUNTERS pmc;
+  int ok=GetProcessMemoryInfo(hProc,&pmc,sizeof(pmc));
+  CloseHandle(hProc);
+  if (!ok)
+    {
+    return -2;
+    }
+  return pmc.WorkingSetSize/1024;
+#elif defined(__linux)
+  SystemInformation::LongLong memUsed=0;
+  int ierr=GetFieldFromFile("/proc/self/status","VmRSS:",memUsed);
+  if (ierr)
+    {
+    return -1;
+    }
+  return memUsed;
+#elif defined(__APPLE__)
+  SystemInformation::LongLong memUsed=0;
+  pid_t pid=getpid();
+  kwsys_ios::ostringstream oss;
+  oss << "ps -o rss= -p " << pid;
+  FILE *file=popen(oss.str().c_str(),"r");
+  if (file==0)
+    {
+    return -1;
+    }
+  oss.str("");
+  while (!feof(file) && !ferror(file))
+    {
+    char buf[256]={'\0'};
+    errno=0;
+    size_t nRead=fread(buf,1,256,file);
+    if (ferror(file) && (errno==EINTR))
+      {
+      clearerr(file);
+      }
+    if (nRead) oss << buf;
+    }
+  int ierr=ferror(file);
+  pclose(file);
+  if (ierr)
+    {
+    return -2;
+    }
+  kwsys_ios::istringstream iss(oss.str());
+  iss >> memUsed;
+  return memUsed;
+#else
+  return 0;
+#endif
+}
+
+/**
+Get the process id of the running process.
+*/
+SystemInformation::LongLong
+SystemInformationImplementation::GetProcessId()
+{
+#if defined(_WIN32)
+  return GetCurrentProcessId();
+#elif defined(__linux) || defined(__APPLE__)
+  return getpid();
+#else
+  return -1;
+#endif
+}
+
+/**
+when set print stack trace in response to common signals.
+*/
+void SystemInformationImplementation::SetStackTraceOnError(int enable)
+{
+#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+  static int saOrigValid=0;
+  static struct sigaction saSEGVOrig;
+  static struct sigaction saTERMOrig;
+  static struct sigaction saINTOrig;
+  static struct sigaction saILLOrig;
+  static struct sigaction saBUSOrig;
+  static struct sigaction saFPEOrig;
+
+  if (enable && !saOrigValid)
+    {
+    // save the current actions
+    sigaction(SIGSEGV,0,&saSEGVOrig);
+    sigaction(SIGTERM,0,&saTERMOrig);
+    sigaction(SIGINT,0,&saINTOrig);
+    sigaction(SIGILL,0,&saILLOrig);
+    sigaction(SIGBUS,0,&saBUSOrig);
+    sigaction(SIGFPE,0,&saFPEOrig);
+
+    // enable read, disable write
+    saOrigValid=1;
+
+    // install ours
+    struct sigaction sa;
+    sa.sa_sigaction=(SigAction)StacktraceSignalHandler;
+    sa.sa_flags=SA_SIGINFO|SA_RESTART;
+    sigemptyset(&sa.sa_mask);
+
+    sigaction(SIGSEGV,&sa,0);
+    sigaction(SIGTERM,&sa,0);
+    sigaction(SIGINT,&sa,0);
+    sigaction(SIGILL,&sa,0);
+    sigaction(SIGBUS,&sa,0);
+    sigaction(SIGFPE,&sa,0);
+    }
+  else
+  if (!enable && saOrigValid)
+    {
+    // restore previous actions
+    sigaction(SIGSEGV,&saSEGVOrig,0);
+    sigaction(SIGTERM,&saTERMOrig,0);
+    sigaction(SIGINT,&saINTOrig,0);
+    sigaction(SIGILL,&saILLOrig,0);
+    sigaction(SIGBUS,&saBUSOrig,0);
+    sigaction(SIGFPE,&saFPEOrig,0);
+
+    // enable write, disable read
+    saOrigValid=0;
+    }
+#else
+  // avoid warning C4100
+  (void)enable;
+#endif
+}
+
+bool SystemInformationImplementation::QueryWindowsMemory()
+{
+#if defined(_WIN32)
+# if defined(_MSC_VER) && _MSC_VER < 1300
   MEMORYSTATUS ms;
   unsigned long tv, tp, av, ap;
   ms.dwLength = sizeof(ms);
   GlobalMemoryStatus(&ms);
-  #define MEM_VAL(value) dw##value
-#else
+#  define MEM_VAL(value) dw##value
+# else
   MEMORYSTATUSEX ms;
   DWORDLONG tv, tp, av, ap;
   ms.dwLength = sizeof(ms);
@@ -2402,8 +3412,8 @@ int SystemInformationImplementation::QueryMemory()
   {
     return 0;
   }
-#define MEM_VAL(value) ull##value
-#endif
+#  define MEM_VAL(value) ull##value
+# endif
   tv = ms.MEM_VAL(TotalVirtual);
   tp = ms.MEM_VAL(TotalPhys);
   av = ms.MEM_VAL(AvailVirtual);
@@ -2412,51 +3422,58 @@ int SystemInformationImplementation::QueryMemory()
   this->TotalPhysicalMemory = tp>>10>>10;
   this->AvailableVirtualMemory = av>>10>>10;
   this->AvailablePhysicalMemory = ap>>10>>10;
-  return 1;
-#elif defined(__linux)
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryLinuxMemory()
+{
+#if defined(__linux)
   unsigned long tv=0;
   unsigned long tp=0;
   unsigned long av=0;
   unsigned long ap=0;
-  
+
   char buffer[1024]; // for reading lines
-  
+
   int linuxMajor = 0;
   int linuxMinor = 0;
-  
+
   // Find the Linux kernel version first
   struct utsname unameInfo;
   int errorFlag = uname(&unameInfo);
   if( errorFlag!=0 )
     {
     kwsys_ios::cout << "Problem calling uname(): " << strerror(errno) << kwsys_ios::endl;
-    return 0;
+    return false;
     }
+
   if( unameInfo.release!=0 && strlen(unameInfo.release)>=3 )
     {
     // release looks like "2.6.3-15mdk-i686-up-4GB"
     char majorChar=unameInfo.release[0];
     char minorChar=unameInfo.release[2];
-    
+
     if( isdigit(majorChar) )
       {
       linuxMajor=majorChar-'0';
       }
-    
+
     if( isdigit(minorChar) )
       {
       linuxMinor=minorChar-'0';
       }
     }
-  
+
   FILE *fd = fopen("/proc/meminfo", "r" );
-  if ( !fd ) 
+  if ( !fd )
     {
     kwsys_ios::cout << "Problem opening /proc/meminfo" << kwsys_ios::endl;
-    return 0;
+    return false;
     }
-  
+
   if( linuxMajor>=3 || ( (linuxMajor>=2) && (linuxMinor>=6) ) )
     {
     // new /proc/meminfo format since kernel 2.6.x
@@ -2493,13 +3510,13 @@ int SystemInformationImplementation::QueryMemory()
       {
       kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
       fclose(fd);
-      return 0;
+      return false;
       }
     }
   else
     {
     // /proc/meminfo format for kernel older than 2.6.x
-    
+
     unsigned long temp;
     unsigned long cachedMem;
     unsigned long buffersMem;
@@ -2525,72 +3542,132 @@ int SystemInformationImplementation::QueryMemory()
       {
       kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
       fclose(fd);
-      return 0;
+      return false;
       }
     }
   fclose( fd );
-  return 1;
-#elif defined(__hpux)
-  unsigned long tv=0;
-  unsigned long tp=0;
-  unsigned long av=0;
-  unsigned long ap=0;
-  struct pst_static pst;
-  struct pst_dynamic pdy;
-     
-  unsigned long ps = 0;
-  if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) != -1)
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryCygwinMemory()
+{
+#ifdef __CYGWIN__
+  // _SC_PAGE_SIZE does return the mmap() granularity on Cygwin,
+  // see http://cygwin.com/ml/cygwin/2006-06/msg00350.html
+  // Therefore just use 4096 as the page size of Windows.
+  long m = sysconf(_SC_PHYS_PAGES);
+  if (m < 0)
     {
-    ps = pst.page_size;
-    tp =  pst.physical_memory *ps;
-    tv = (pst.physical_memory + pst.pst_maxmem) * ps;
-    if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t) 1, 0) != -1)
-      {
-      ap = tp - pdy.psd_rm * ps;
-      av = tv - pdy.psd_vm;
-      this->TotalVirtualMemory = tv>>10>>10;
-      this->TotalPhysicalMemory = tp>>10>>10;
-      this->AvailableVirtualMemory = av>>10>>10;
-      this->AvailablePhysicalMemory = ap>>10>>10;
-      return 1;
-      }
+    return false;
     }
-  return 0;
+  this->TotalPhysicalMemory = m >> 8;
+  return true;
 #else
-  return 0;
+  return false;
 #endif
+}
 
+bool SystemInformationImplementation::QueryAIXMemory()
+{
+#if defined(_AIX)
+  long c = sysconf(_SC_AIX_REALMEM);
+  if (c <= 0)
+    {
+    return false;
+    }
 
+  this->TotalPhysicalMemory = c / 1024;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryMemoryBySysconf()
+{
+#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
+  // Assume the mmap() granularity as returned by _SC_PAGESIZE is also
+  // the system page size. The only known system where this isn't true
+  // is Cygwin.
+  long p = sysconf(_SC_PHYS_PAGES);
+  long m = sysconf(_SC_PAGESIZE);
+
+  if (p < 0 || m < 0)
+    {
+    return false;
+    }
+
+  // assume pagesize is a power of 2 and smaller 1 MiB
+  size_t pagediv = (1024 * 1024 / m);
+
+  this->TotalPhysicalMemory = p;
+  this->TotalPhysicalMemory /= pagediv;
+
+#if defined(_SC_AVPHYS_PAGES)
+  p = sysconf(_SC_AVPHYS_PAGES);
+  if (p < 0)
+    {
+    return false;
+    }
+
+  this->AvailablePhysicalMemory = p;
+  this->AvailablePhysicalMemory /= pagediv;
+#endif
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+/** Query for the memory status */
+bool SystemInformationImplementation::QueryMemory()
+{
+  return this->QueryMemoryBySysconf();
 }
 
 /** */
-size_t SystemInformationImplementation::GetTotalVirtualMemory() 
-{ 
-  return this->TotalVirtualMemory; 
+size_t SystemInformationImplementation::GetTotalVirtualMemory()
+{
+  return this->TotalVirtualMemory;
 }
 
 /** */
-size_t SystemInformationImplementation::GetAvailableVirtualMemory() 
-{ 
-  return this->AvailableVirtualMemory; 
+size_t SystemInformationImplementation::GetAvailableVirtualMemory()
+{
+  return this->AvailableVirtualMemory;
 }
 
-size_t SystemInformationImplementation::GetTotalPhysicalMemory() 
-{ 
-  return this->TotalPhysicalMemory; 
+size_t SystemInformationImplementation::GetTotalPhysicalMemory()
+{
+  return this->TotalPhysicalMemory;
 }
 
 /** */
-size_t SystemInformationImplementation::GetAvailablePhysicalMemory() 
-{ 
-  return this->AvailablePhysicalMemory; 
+size_t SystemInformationImplementation::GetAvailablePhysicalMemory()
+{
+  return this->AvailablePhysicalMemory;
 }
 
 /** Get Cycle differences */
-LongLong SystemInformationImplementation::GetCyclesDifference (DELAY_FUNC DelayFunction,
+SystemInformation::LongLong
+SystemInformationImplementation::GetCyclesDifference (DELAY_FUNC DelayFunction,
                                                   unsigned int uiParameter)
 {
-#if USE_ASM_INSTRUCTIONS
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+  unsigned __int64 stamp1, stamp2;
+
+  stamp1 = __rdtsc();
+  DelayFunction(uiParameter);
+  stamp2 = __rdtsc();
+
+  return stamp2 - stamp1;
+#elif USE_ASM_INSTRUCTIONS
 
   unsigned int edx1, eax1;
   unsigned int edx2, eax2;
@@ -2619,7 +3696,7 @@ LongLong SystemInformationImplementation::GetCyclesDifference (DELAY_FUNC DelayF
       mov eax1, esi      ; eax2 = esi
     }
   }
-  __except(1) 
+  __except(1)
     {
     return -1;
     }
@@ -2642,7 +3719,7 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
   __int64 x;
 
   // Get the frequency of the high performance counter.
-  if(!QueryPerformanceFrequency (&Frequency)) 
+  if(!QueryPerformanceFrequency (&Frequency))
     {
     return;
     }
@@ -2650,9 +3727,9 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
 
   // Get the starting position of the counter.
   QueryPerformanceCounter (&StartCounter);
-  
+
   do {
-    // Get the ending position of the counter.  
+    // Get the ending position of the counter.
     QueryPerformanceCounter (&EndCounter);
   } while (EndCounter.QuadPart - StartCounter.QuadPart == x);
 #endif
@@ -2672,61 +3749,53 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
     }
   return static_cast<unsigned char>(cores_per_package);
 #else
-  unsigned int Regebx = 0;
-#if USE_ASM_INSTRUCTIONS
+  int Regs[4] = { 0, 0, 0, 0 };
+#if USE_CPUID
   if (!this->IsHyperThreadingSupported())
     {
-    return static_cast<unsigned char>(1);  // HT not supported
-    }
-  __asm
-    {
-    mov eax, 1
-    cpuid
-    mov Regebx, ebx
+    return static_cast<unsigned char>(1);  // HT not supported
     }
+  call_cpuid(1, Regs);
 #endif
-  return static_cast<unsigned char> ((Regebx & NUM_LOGICAL_BITS) >> 16);
+  return static_cast<unsigned char> ((Regs[1] & NUM_LOGICAL_BITS) >> 16);
 #endif
 }
 
 
 /** Works only for windows */
-unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
+bool SystemInformationImplementation::IsHyperThreadingSupported()
 {
-#if USE_ASM_INSTRUCTIONS
-  unsigned int Regedx    = 0,
-             Regeax      = 0,
-             VendorId[3] = {0, 0, 0};
-  __try    // Verify cpuid instruction is supported
+  if (this->Features.ExtendedFeatures.SupportsHyperthreading)
     {
-      __asm
-      {
-        xor eax, eax          // call cpuid with eax = 0
-            cpuid                 // Get vendor id string
-        mov VendorId, ebx
-        mov VendorId + 4, edx
-        mov VendorId + 8, ecx
-        
-        mov eax, 1            // call cpuid with eax = 1
-        cpuid
-        mov Regeax, eax      // eax contains family processor type
-        mov Regedx, edx      // edx has info about the availability of hyper-Threading
-      }
+    return true;
+    }
+
+#if USE_CPUID
+  int Regs[4] = { 0, 0, 0, 0 },
+             VendorId[4] = { 0, 0, 0, 0 };
+  // Get vendor id string
+  if (!call_cpuid(0, VendorId))
+    {
+    return false;
     }
-  __except (EXCEPTION_EXECUTE_HANDLER)
+  // eax contains family processor type
+  // edx has info about the availability of hyper-Threading
+  if (!call_cpuid(1, Regs))
     {
-    return(0);                   // cpuid is unavailable
+    return false;
     }
 
-  if (((Regeax & FAMILY_ID) == PENTIUM4_ID) || (Regeax & EXT_FAMILY_ID))
+  if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID))
     {
-    if (VendorId[0] == 'uneG')
+    if (VendorId[1] == 0x756e6547) // 'uneG'
       {
-      if (VendorId[1] == 'Ieni')
+      if (VendorId[3] == 0x49656e69) // 'Ieni'
         {
-        if (VendorId[2] == 'letn')
+        if (VendorId[2] == 0x6c65746e) // 'letn'
           {
-          return(Regedx & HT_BIT);    // Genuine Intel with hyper-Threading technology
+          // Genuine Intel with hyper-Threading technology
+          this->Features.ExtendedFeatures.SupportsHyperthreading = ((Regs[3] & HT_BIT) != 0);
+          return this->Features.ExtendedFeatures.SupportsHyperthreading;
           }
         }
       }
@@ -2740,22 +3809,17 @@ unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
 /** Return the APIC Id. Works only for windows. */
 unsigned char SystemInformationImplementation::GetAPICId()
 {
-  unsigned int Regebx = 0;
+  int Regs[4] = { 0, 0, 0, 0 };
 
-#if USE_ASM_INSTRUCTIONS
-  if (!this->IsHyperThreadingSupported()) 
+#if USE_CPUID
+  if (!this->IsHyperThreadingSupported())
     {
     return static_cast<unsigned char>(-1);  // HT not supported
     } // Logical processor = 1
-  __asm
-    {
-    mov eax, 1
-    cpuid
-    mov Regebx, ebx
-    }
+  call_cpuid(1, Regs);
 #endif
 
-  return static_cast<unsigned char>((Regebx & INITIAL_APIC_ID_BITS) >> 24);
+  return static_cast<unsigned char>((Regs[1] & INITIAL_APIC_ID_BITS) >> 24);
 }
 
 
@@ -2773,7 +3837,7 @@ int SystemInformationImplementation::CPUCount()
 
   // Number of physical processors in a non-Intel system
   // or in a 32-bit Intel system with Hyper-Threading technology disabled
-  this->NumberOfPhysicalCPU = (unsigned char) info.dwNumberOfProcessors;  
+  this->NumberOfPhysicalCPU = (unsigned char) info.dwNumberOfProcessors;
 
   if (this->IsHyperThreadingSupported())
     {
@@ -2789,7 +3853,7 @@ int SystemInformationImplementation::CPUCount()
       DWORD_PTR  dwSystemAffinity;
       DWORD  dwAffinityMask;
 
-      // Calculate the appropriate  shifts and mask based on the 
+      // Calculate the appropriate  shifts and mask based on the
       // number of logical processors.
       unsigned int i = 1;
       unsigned char PHY_ID_MASK  = 0xFF;
@@ -2801,7 +3865,7 @@ int SystemInformationImplementation::CPUCount()
          PHY_ID_MASK  <<= 1;
          // PHY_ID_SHIFT++;
         }
-      
+
       hCurrentProcessHandle = GetCurrentProcess();
       GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity,
                                                   &dwSystemAffinity);
@@ -2829,8 +3893,8 @@ int SystemInformationImplementation::CPUCount()
 
             APIC_ID = GetAPICId();
             LOG_ID  = APIC_ID & ~PHY_ID_MASK;
-            if (LOG_ID != 0) 
+
+            if (LOG_ID != 0)
               {
               HT_Enabled = 1;
               }
@@ -2840,7 +3904,7 @@ int SystemInformationImplementation::CPUCount()
         }
       // Reset the processor affinity
       SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity);
-            
+
       if (this->NumberOfLogicalCPU == 1)  // Normal P4 : HT is disabled in hardware
         {
         StatusFlag = HT_DISABLED;
@@ -2853,7 +3917,7 @@ int SystemInformationImplementation::CPUCount()
           this->NumberOfPhysicalCPU /= (this->NumberOfLogicalCPU);
           StatusFlag = HT_ENABLED;
           }
-        else 
+        else
           {
           StatusFlag = HT_SUPPORTED_NOT_ENABLED;
           }
@@ -2891,6 +3955,7 @@ unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU()
 bool SystemInformationImplementation::ParseSysCtl()
 {
 #if defined(__APPLE__)
+  char retBuf[128];
   int err = 0;
   uint64_t value = 0;
   size_t len = sizeof(value);
@@ -2901,9 +3966,10 @@ bool SystemInformationImplementation::ParseSysCtl()
   this->AvailablePhysicalMemory = 0;
   vm_statistics_data_t  vmstat;
   mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
-  if ( host_statistics(mach_host_self(), HOST_VM_INFO, 
+  if ( host_statistics(mach_host_self(), HOST_VM_INFO,
                        (host_info_t) &vmstat, &count) == KERN_SUCCESS )
     {
+    len = sizeof(value);
     err = sysctlbyname("hw.pagesize", &value, &len, NULL, 0);
     int64_t available_memory = vmstat.free_count * value;
     this->AvailablePhysicalMemory = static_cast< size_t >( available_memory / 1048576 );
@@ -2914,7 +3980,7 @@ bool SystemInformationImplementation::ParseSysCtl()
   int mib[2] = { CTL_VM, VM_SWAPUSAGE };
   size_t miblen = sizeof(mib) / sizeof(mib[0]);
   struct xsw_usage swap;
-  len = sizeof(struct xsw_usage);
+  len = sizeof(swap);
   err = sysctl(mib, miblen, &swap, &len, NULL, 0);
   if (err == 0)
     {
@@ -2929,8 +3995,9 @@ bool SystemInformationImplementation::ParseSysCtl()
 // CPU Info
   len = sizeof(this->NumberOfPhysicalCPU);
   sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, NULL, 0);
+  len = sizeof(this->NumberOfLogicalCPU);
   sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, NULL, 0);
-  this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = 
+  this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
     this->LogicalCPUPerPhysicalCPU();
 
   len = sizeof(value);
@@ -2947,16 +4014,16 @@ bool SystemInformationImplementation::ParseSysCtl()
   if (err != 0) // Go back to names we know but are less descriptive
     {
     this->ChipID.Family = 0;
-    char retBuf[32];
-    ::memset(retBuf, 0, 32);
+    ::memset(retBuf, 0, 128);
     len = 32;
-    err = sysctlbyname("hw.machine", &retBuf, &len, NULL, 0); 
+    err = sysctlbyname("hw.machine", &retBuf, &len, NULL, 0);
     kwsys_stl::string machineBuf(retBuf);
     if (machineBuf.find_first_of("Power") != kwsys_stl::string::npos)
       {
       this->ChipID.Vendor = "IBM";
-      len = 4;
+      len = sizeof(this->ChipID.Family);
       err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, NULL, 0);
+      len = sizeof(this->ChipID.Model);
       err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, NULL, 0);
       this->FindManufacturer();
       }
@@ -2964,35 +4031,115 @@ bool SystemInformationImplementation::ParseSysCtl()
   else  // Should be an Intel Chip.
     {
     len = sizeof(this->ChipID.Family);
-    err = 
+    err =
       sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, NULL, 0);
-    
-    char retBuf[128];
+
     ::memset(retBuf, 0, 128);
     len = 128;
     err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, NULL, 0);
     // Chip Vendor
     this->ChipID.Vendor = retBuf;
     this->FindManufacturer();
-    
-    ::memset(retBuf, 0, 128);
-    err = 
-      sysctlbyname("machdep.cpu.brand_string", 
-                   retBuf, &len, NULL, 0);
-    this->ChipID.ProcessorName = retBuf;
 
     // Chip Model
     len = sizeof(value);
     err = sysctlbyname("machdep.cpu.model", &value, &len, NULL, 0);
     this->ChipID.Model = static_cast< int >( value );
+
+    // Chip Stepping
+    len = sizeof(value);
+    value = 0;
+    err = sysctlbyname("machdep.cpu.stepping", &value, &len, NULL, 0);
+    if (!err)
+      {
+      this->ChipID.Revision = static_cast< int >( value );
+      }
+
+    // feature string
+    char *buf = 0;
+    size_t allocSize = 128;
+
+    err = 0;
+    len = 0;
+
+    // sysctlbyname() will return with err==0 && len==0 if the buffer is too small
+    while (err == 0 && len == 0)
+      {
+      delete[] buf;
+      allocSize *= 2;
+      buf = new char[allocSize];
+      if (!buf)
+        {
+        break;
+        }
+      buf[0] = ' ';
+      len = allocSize - 2; // keep space for leading and trailing space
+      err = sysctlbyname("machdep.cpu.features", buf + 1, &len, NULL, 0);
+      }
+    if (!err && buf && len)
+      {
+      // now we can match every flags as space + flag + space
+      buf[len + 1] = ' ';
+      kwsys_stl::string cpuflags(buf, len + 2);
+
+      if ((cpuflags.find(" FPU ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasFPU = true;
+        }
+      if ((cpuflags.find(" TSC ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasTSC = true;
+        }
+      if ((cpuflags.find(" MMX ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasMMX = true;
+        }
+      if ((cpuflags.find(" SSE ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasSSE = true;
+        }
+      if ((cpuflags.find(" SSE2 ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasSSE2 = true;
+        }
+      if ((cpuflags.find(" APIC ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasAPIC = true;
+        }
+      if ((cpuflags.find(" CMOV ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasCMOV = true;
+        }
+      if ((cpuflags.find(" MTRR ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasMTRR = true;
+        }
+      if ((cpuflags.find(" ACPI ")!=kwsys_stl::string::npos))
+        {
+        this->Features.HasACPI = true;
+        }
+      }
+    delete[] buf;
     }
+
+  // brand string
+  ::memset(retBuf, 0, sizeof(retBuf));
+  len = sizeof(retBuf);
+  err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, NULL, 0);
+  if (!err)
+    {
+    this->ChipID.ProcessorName = retBuf;
+    this->ChipID.ModelName = retBuf;
+    }
+
   // Cache size
   len = sizeof(value);
   err = sysctlbyname("hw.l1icachesize", &value, &len, NULL, 0);
   this->Features.L1CacheSize = static_cast< int >( value );
+  len = sizeof(value);
   err = sysctlbyname("hw.l2cachesize", &value, &len, NULL, 0);
   this->Features.L2CacheSize = static_cast< int >( value );
-  
+
   return true;
 #else
   return false;
@@ -3019,7 +4166,7 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const
 
 /** Run a given process */
 kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<const char*> args)
-{ 
+{
   kwsys_stl::string buffer = "";
 
   // Run the application
@@ -3032,13 +4179,12 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
   char* data = NULL;
   int length;
   double timeout = 255;
+  int pipe; // pipe id as returned by kwsysProcess_WaitForData()
 
-  while(kwsysProcess_WaitForData(gp,&data,&length,&timeout)) // wait for 1s
+  while( ( pipe = kwsysProcess_WaitForData(gp,&data,&length,&timeout),
+           (pipe == kwsysProcess_Pipe_STDOUT || pipe == kwsysProcess_Pipe_STDERR) ) ) // wait for 1s
     {
-    for(int i=0;i<length;i++)
-      {
-      buffer += data[i];
-      }
+      buffer.append(data, length);
     }
   kwsysProcess_WaitForExit(gp, 0);
 
@@ -3085,7 +4231,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
   args.clear();
   args.push_back("kstat");
   args.push_back("-p");
-  
+
   kwsys_stl::string command = arguments;
   size_t start = command.npos;
   size_t pos = command.find(' ',0);
@@ -3105,7 +4251,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
       b0 = command.find('"',b1+1);
       b1 = command.find('"',b0+1);
       }
-    
+
     if(!inQuotes)
       {
       kwsys_stl::string arg = command.substr(start+1,pos-start-1);
@@ -3117,7 +4263,7 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
         arg.erase(quotes,1);
         quotes = arg.find('"');
         }
-      args.push_back(arg.c_str());  
+      args.push_back(arg.c_str());
       start = pos;
       }
     pos = command.find(' ',pos+1);
@@ -3146,48 +4292,55 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
   return value;
 }
 
-
 /** Querying for system information from Solaris */
-bool SystemInformationImplementation::QuerySolarisInfo()
+bool SystemInformationImplementation::QuerySolarisMemory()
 {
-  // Parse values
-  this->NumberOfPhysicalCPU = static_cast<unsigned int>(
-    atoi(this->ParseValueFromKStat("-n syste_misc -s ncpus").c_str()));
-  this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
-  
-  if(this->NumberOfPhysicalCPU!=0)
+#if defined (__SVR4) && defined (__sun)
+  // Solaris allows querying this value by sysconf, but if this is
+  // a 32 bit process on a 64 bit host the returned memory will be
+  // limited to 4GiB. So if this is a 32 bit process or if the sysconf
+  // method fails use the kstat interface.
+#if SIZEOF_VOID_P == 8
+  if (this->QueryMemoryBySysconf())
+    {
+    return true;
+    }
+#endif
+
+  char* tail;
+  unsigned long totalMemory =
+       strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
+  this->TotalPhysicalMemory = totalMemory/128;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QuerySolarisProcessor()
+{
+  if (!this->QueryProcessorBySysconf())
     {
-    this->NumberOfLogicalCPU /= this->NumberOfPhysicalCPU;
+    return false;
     }
 
+  // Parse values
   this->CPUSpeedInMHz = static_cast<float>(atoi(this->ParseValueFromKStat("-s clock_MHz").c_str()));
 
   // Chip family
-  this->ChipID.Family = 0; 
-  // Chip Vendor
-  this->ChipID.Vendor = "Sun";
-  this->FindManufacturer();
-  
+  this->ChipID.Family = 0;
+
   // Chip Model
   this->ChipID.ProcessorName = this->ParseValueFromKStat("-s cpu_type");
   this->ChipID.Model = 0;
 
-  // Cache size
-  this->Features.L1CacheSize = 0; 
-  this->Features.L2CacheSize = 0;  
-
-  char* tail;
-  unsigned long totalMemory =
-       strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
-  this->TotalPhysicalMemory = totalMemory/1024;
-  this->TotalPhysicalMemory *= 8192;
-  this->TotalPhysicalMemory /= 1024;
-
-  // Undefined values (for now at least)
-  this->TotalVirtualMemory = 0;
-  this->AvailablePhysicalMemory = 0;
-  this->AvailableVirtualMemory = 0;
+  // Chip Vendor
+  if (this->ChipID.ProcessorName != "i386")
+    {
+    this->ChipID.Vendor = "Sun";
+    this->FindManufacturer();
+    }
 
   return true;
 }
@@ -3200,16 +4353,16 @@ bool SystemInformationImplementation::QueryHaikuInfo()
 
   system_info info;
   get_system_info(&info);
-  
+
   this->NumberOfPhysicalCPU = info.cpu_count;
   this->CPUSpeedInMHz = info.cpu_clock_speed / 1000000.0F;
 
   // Physical Memory
   this->TotalPhysicalMemory = (info.max_pages * B_PAGE_SIZE) / (1024 * 1024) ;
-  this->AvailablePhysicalMemory = this->TotalPhysicalMemory - 
+  this->AvailablePhysicalMemory = this->TotalPhysicalMemory -
     ((info.used_pages * B_PAGE_SIZE) / (1024 * 1024));
 
-  
+
   // NOTE: get_system_info_etc is currently a private call so just set to 0
   // until it becomes public
   this->TotalVirtualMemory = 0;
@@ -3237,8 +4390,8 @@ bool SystemInformationImplementation::QueryHaikuInfo()
   this->ChipID.Type = cpu_info.eax_1.type;
 
   // Chip family
-  this->ChipID.Family = cpu_info.eax_1.family; 
-  
+  this->ChipID.Family = cpu_info.eax_1.family;
+
   // Chip Model
   this->ChipID.Model = cpu_info.eax_1.model;
 
@@ -3296,6 +4449,31 @@ bool SystemInformationImplementation::QueryQNXMemory()
   return false;
 }
 
+bool SystemInformationImplementation::QueryBSDMemory()
+{
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  int ctrl[2] = { CTL_HW, HW_PHYSMEM };
+#if defined(HW_PHYSMEM64)
+  int64_t k;
+  ctrl[1] = HW_PHYSMEM64;
+#else
+  int k;
+#endif
+  size_t sz = sizeof(k);
+
+  if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->TotalPhysicalMemory = k>>10>>10;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
 bool SystemInformationImplementation::QueryQNXProcessor()
 {
 #if defined(__QNX__)
@@ -3349,6 +4527,163 @@ bool SystemInformationImplementation::QueryQNXProcessor()
 #endif
 }
 
+bool SystemInformationImplementation::QueryBSDProcessor()
+{
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  int k;
+  size_t sz = sizeof(k);
+  int ctrl[2] = { CTL_HW, HW_NCPU };
+
+  if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->NumberOfPhysicalCPU = k;
+  this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
+
+#if defined(HW_CPUSPEED)
+  ctrl[1] = HW_CPUSPEED;
+
+  if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->CPUSpeedInMHz = (float) k;
+#endif
+
+#if defined(CPU_SSE)
+  ctrl[0] = CTL_MACHDEP;
+  ctrl[1] = CPU_SSE;
+
+  if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->Features.HasSSE = (k > 0);
+#endif
+
+#if defined(CPU_SSE2)
+  ctrl[0] = CTL_MACHDEP;
+  ctrl[1] = CPU_SSE2;
+
+  if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->Features.HasSSE2 = (k > 0);
+#endif
+
+#if defined(CPU_CPUVENDOR)
+  ctrl[0] = CTL_MACHDEP;
+  ctrl[1] = CPU_CPUVENDOR;
+  char vbuf[25];
+  ::memset(vbuf, 0, sizeof(vbuf));
+  sz = sizeof(vbuf) - 1;
+  if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0)
+    {
+    return false;
+    }
+
+  this->ChipID.Vendor = vbuf;
+  this->FindManufacturer();
+#endif
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryHPUXMemory()
+{
+#if defined(__hpux)
+  unsigned long tv=0;
+  unsigned long tp=0;
+  unsigned long av=0;
+  unsigned long ap=0;
+  struct pst_static pst;
+  struct pst_dynamic pdy;
+
+  unsigned long ps = 0;
+  if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) == -1)
+    {
+    return false;
+    }
+
+  ps = pst.page_size;
+  tp =  pst.physical_memory *ps;
+  tv = (pst.physical_memory + pst.pst_maxmem) * ps;
+  if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t) 1, 0) == -1)
+    {
+    return false;
+    }
+
+  ap = tp - pdy.psd_rm * ps;
+  av = tv - pdy.psd_vm;
+  this->TotalVirtualMemory = tv>>10>>10;
+  this->TotalPhysicalMemory = tp>>10>>10;
+  this->AvailableVirtualMemory = av>>10>>10;
+  this->AvailablePhysicalMemory = ap>>10>>10;
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryHPUXProcessor()
+{
+#if defined(__hpux)
+# if defined(KWSYS_SYS_HAS_MPCTL_H)
+  int c = mpctl(MPC_GETNUMSPUS_SYS, 0, 0);
+  if (c <= 0)
+    {
+    return false;
+    }
+
+  this->NumberOfPhysicalCPU = c;
+  this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
+
+  long t = sysconf(_SC_CPU_VERSION);
+
+  if (t == -1)
+    {
+    return false;
+    }
+
+  switch (t)
+    {
+    case CPU_PA_RISC1_0:
+      this->ChipID.Vendor = "Hewlett-Packard";
+      this->ChipID.Family = 0x100;
+    case CPU_PA_RISC1_1:
+      this->ChipID.Vendor = "Hewlett-Packard";
+      this->ChipID.Family = 0x110;
+    case CPU_PA_RISC2_0:
+      this->ChipID.Vendor = "Hewlett-Packard";
+      this->ChipID.Family = 0x200;
+    case CPU_IA64_ARCHREV_0:
+      this->ChipID.Vendor = "GenuineIntel";
+      this->Features.HasIA64 = true;
+      break;
+    default:
+      return false;
+    }
+
+  this->FindManufacturer();
+
+  return true;
+# else
+  return false;
+# endif
+#else
+  return false;
+#endif
+}
+
 /** Query the operating system information */
 bool SystemInformationImplementation::QueryOSInformation()
 {
@@ -3365,16 +4700,16 @@ bool SystemInformationImplementation::QueryOSInformation()
   ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
   bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);
-  if (!bOsVersionInfoEx) 
+  if (!bOsVersionInfoEx)
     {
     osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-    if (!GetVersionEx ((OSVERSIONINFO *) &osvi)) 
+    if (!GetVersionEx ((OSVERSIONINFO *) &osvi))
       {
       return false;
       }
     }
 
-  switch (osvi.dwPlatformId) 
+  switch (osvi.dwPlatformId)
     {
     case VER_PLATFORM_WIN32_NT:
       // Test for the product.
@@ -3417,40 +4752,40 @@ bool SystemInformationImplementation::QueryOSInformation()
               {
               this->OSRelease += " Personal";
               }
-            else 
+            else
               {
               this->OSRelease += " Professional";
               }
             }
 #endif
-          } 
+          }
         else if (osvi.wProductType == VER_NT_SERVER)
           {
           // Check for .NET Server instead of Windows XP.
-          if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) 
+          if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
             {
             this->OSRelease = ".NET";
             }
 
           // Continue with the type detection.
-          if (osvi.wSuiteMask & VER_SUITE_DATACENTER) 
+          if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
             {
             this->OSRelease += " DataCenter Server";
             }
-          else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) 
+          else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
             {
             this->OSRelease += " Advanced Server";
             }
-          else 
+          else
             {
             this->OSRelease += " Server";
             }
           }
 
         sprintf (operatingSystem, "%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
-        this->OSVersion = operatingSystem; 
+        this->OSVersion = operatingSystem;
         }
-      else 
+      else
 #endif        // VER_NT_WORKSTATION
         {
         HKEY hKey;
@@ -3473,7 +4808,7 @@ bool SystemInformationImplementation::QueryOSInformation()
             {
             this->OSRelease += " Standard Server";
             }
-          else 
+          else
             {
             this->OSRelease += " Server";
             }
@@ -3485,7 +4820,7 @@ bool SystemInformationImplementation::QueryOSInformation()
             {
             this->OSRelease += " Enterprise Server";
             }
-          else 
+          else
             {
             this->OSRelease += " Advanced Server";
             }
@@ -3493,7 +4828,7 @@ bool SystemInformationImplementation::QueryOSInformation()
          }
 
       // Display version, service pack (if any), and build number.
-      if (osvi.dwMajorVersion <= 4) 
+      if (osvi.dwMajorVersion <= 4)
         {
         // NB: NT 4.0 and earlier.
         sprintf (operatingSystem, "version %ld.%ld %s (Build %ld)",
@@ -3502,30 +4837,30 @@ bool SystemInformationImplementation::QueryOSInformation()
                  osvi.szCSDVersion,
                  osvi.dwBuildNumber & 0xFFFF);
         this->OSVersion = operatingSystem;
-        } 
-      else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) 
+        }
+      else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
         {
         // Windows XP and .NET server.
         typedef BOOL (CALLBACK* LPFNPROC) (HANDLE, BOOL *);
-        HINSTANCE hKernelDLL; 
+        HINSTANCE hKernelDLL;
         LPFNPROC DLLProc;
-        
+
         // Load the Kernel32 DLL.
         hKernelDLL = LoadLibrary ("kernel32");
-        if (hKernelDLL != NULL)  { 
+        if (hKernelDLL != NULL)  {
           // Only XP and .NET Server support IsWOW64Process so... Load dynamically!
-          DLLProc = (LPFNPROC) GetProcAddress (hKernelDLL, "IsWow64Process"); 
-         
+          DLLProc = (LPFNPROC) GetProcAddress (hKernelDLL, "IsWow64Process");
+
           // If the function address is valid, call the function.
           if (DLLProc != NULL) (DLLProc) (GetCurrentProcess (), &bIsWindows64Bit);
           else bIsWindows64Bit = false;
-         
+
           // Free the DLL module.
-          FreeLibrary (hKernelDLL); 
-          } 
-        } 
-      else 
-        { 
+          FreeLibrary (hKernelDLL);
+          }
+        }
+      else
+        {
         // Windows 2000 and everything else.
         sprintf (operatingSystem,"%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
         this->OSVersion = operatingSystem;
@@ -3534,32 +4869,32 @@ bool SystemInformationImplementation::QueryOSInformation()
 
     case VER_PLATFORM_WIN32_WINDOWS:
       // Test for the product.
-      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) 
+      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
         {
         this->OSRelease = "95";
-        if(osvi.szCSDVersion[1] == 'C') 
+        if(osvi.szCSDVersion[1] == 'C')
           {
           this->OSRelease += "OSR 2.5";
           }
-        else if(osvi.szCSDVersion[1] == 'B') 
+        else if(osvi.szCSDVersion[1] == 'B')
           {
           this->OSRelease += "OSR 2";
           }
-      } 
+      }
 
-      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) 
+      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
         {
         this->OSRelease = "98";
-        if (osvi.szCSDVersion[1] == 'A' ) 
+        if (osvi.szCSDVersion[1] == 'A' )
           {
           this->OSRelease += "SE";
           }
-        } 
+        }
 
-      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) 
+      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
         {
         this->OSRelease = "Me";
-        } 
+        }
       break;
 
     case VER_PLATFORM_WIN32s:
@@ -3583,7 +4918,7 @@ bool SystemInformationImplementation::QueryOSInformation()
     WSACleanup( );
     }
   this->Hostname = name;
-  
+
   const char* arch = getenv("PROCESSOR_ARCHITECTURE");
   if(arch)
     {
@@ -3604,51 +4939,41 @@ bool SystemInformationImplementation::QueryOSInformation()
     }
 
 #ifdef __APPLE__
-  this->CallSwVers();
+  this->OSName="Unknown Apple OS";
+  this->OSRelease="Unknown product version";
+  this->OSVersion="Unknown build version";
+
+  this->CallSwVers("-productName",this->OSName);
+  this->CallSwVers("-productVersion",this->OSRelease);
+  this->CallSwVers("-buildVersion",this->OSVersion);
 #endif
 
 #endif
 
   return true;
-
 }
 
-
-void SystemInformationImplementation::CallSwVers()
+int SystemInformationImplementation::CallSwVers(
+      const char *arg,
+      kwsys_stl::string &ver)
 {
 #ifdef __APPLE__
-  kwsys_stl::string output;
   kwsys_stl::vector<const char*> args;
-  args.clear();
-  
-  args.push_back("sw_vers");
-  args.push_back("-productName");
-  args.push_back(0);
-  output = this->RunProcess(args);
-  this->TrimNewline(output);
-  this->OSName = output;
-  args.clear();
-
   args.push_back("sw_vers");
-  args.push_back("-productVersion");
+  args.push_back(arg);
   args.push_back(0);
-  output = this->RunProcess(args);
-  this->TrimNewline(output);
-  this->OSRelease = output;
-  args.clear();
-
-  args.push_back("sw_vers");
-  args.push_back("-buildVersion");
-  args.push_back(0);
-  output = this->RunProcess(args);
-  this->TrimNewline(output);
-  this->OSVersion = output;
+  ver = this->RunProcess(args);
+  this->TrimNewline(ver);
+#else
+  // avoid C4100
+  (void)arg;
+  (void)ver;
 #endif
+  return 0;
 }
 
-
 void SystemInformationImplementation::TrimNewline(kwsys_stl::string& output)
-{  
+{
   // remove \r
   kwsys_stl::string::size_type pos=0;
   while((pos = output.find("\r", pos)) != kwsys_stl::string::npos)
index b6ebe6a..8f4cb4e 100644 (file)
 namespace @KWSYS_NAMESPACE@
 {
 
-
-// forward declare the implementation class  
+// forward declare the implementation class
 class SystemInformationImplementation;
-  
-class @KWSYS_NAMESPACE@_EXPORT SystemInformation 
-{
 
+class @KWSYS_NAMESPACE@_EXPORT SystemInformation
+{
+#if @KWSYS_USE_LONG_LONG@
+  typedef long long LongLong;
+#elif @KWSYS_USE___INT64@
+  typedef __int64 LongLong;
+#else
+# error "No Long Long"
+#endif
+  friend class SystemInformationImplementation;
+  SystemInformationImplementation* Implementation;
 public:
+
   SystemInformation ();
   ~SystemInformation ();
 
@@ -40,6 +48,7 @@ public:
   kwsys_stl::string GetTypeID();
   kwsys_stl::string GetFamilyID();
   kwsys_stl::string GetModelID();
+  kwsys_stl::string GetModelName();
   kwsys_stl::string GetSteppingCode();
   const char * GetExtendedProcessorName();
   const char * GetProcessorSerialNumber();
@@ -49,13 +58,27 @@ public:
   int GetProcessorAPICID();
   int GetProcessorCacheXSize(long int);
   bool DoesCPUSupportFeature(long int);
-  
-  const char * GetOSName();
+
+  // returns an informative general description of the cpu
+  // on this system.
+  kwsys_stl::string GetCPUDescription();
+
   const char * GetHostname();
+  kwsys_stl::string GetFullyQualifiedDomainName();
+
+  const char * GetOSName();
   const char * GetOSRelease();
   const char * GetOSVersion();
   const char * GetOSPlatform();
 
+  int GetOSIsWindows();
+  int GetOSIsLinux();
+  int GetOSIsApple();
+
+  // returns an informative general description of the os
+  // on this system.
+  kwsys_stl::string GetOSDescription();
+
   bool Is64Bits();
 
   unsigned int GetNumberOfLogicalCPU(); // per physical cpu
@@ -63,20 +86,62 @@ public:
 
   bool DoesCPUSupportCPUID();
 
+  // Retrieve id of the current running process
+  LongLong GetProcessId();
+
   // Retrieve memory information in megabyte.
   size_t GetTotalVirtualMemory();
   size_t GetAvailableVirtualMemory();
   size_t GetTotalPhysicalMemory();
-  size_t GetAvailablePhysicalMemory();  
+  size_t GetAvailablePhysicalMemory();
+
+  // returns an informative general description if the installed and
+  // available ram on this system. See the  GetHostMmeoryTotal, and
+  // Get{Host,Proc}MemoryAvailable methods for more information.
+  kwsys_stl::string GetMemoryDescription(
+        const char *hostLimitEnvVarName=NULL,
+        const char *procLimitEnvVarName=NULL);
+
+  // Retrieve amount of physical memory installed on the system in KiB
+  // units.
+  LongLong GetHostMemoryTotal();
+
+  // Get total system RAM in units of KiB available colectivley to all
+  // processes in a process group. An example of a process group
+  // are the processes comprising an mpi program which is running in
+  // parallel. The amount of memory reported may differ from the host
+  // total if a host wide resource limit is applied. Such reource limits
+  // are reported to us via an applicaiton specified environment variable.
+  LongLong GetHostMemoryAvailable(const char *hostLimitEnvVarName=NULL);
+
+  // Get total system RAM in units of KiB available to this process.
+  // This may differ from the host available if a per-process resource
+  // limit is applied. per-process memory limits are applied on unix
+  // system via rlimit api. Resource limits that are not imposed via
+  // rlimit api may be reported to us via an application specified
+  // environment variable.
+  LongLong GetProcMemoryAvailable(
+        const char *hostLimitEnvVarName=NULL,
+        const char *procLimitEnvVarName=NULL);
+
+  // Get the system RAM used by all processes on the host, in units of KiB.
+  LongLong GetHostMemoryUsed();
+
+  // Get system RAM used by this process id in units of KiB.
+  LongLong GetProcMemoryUsed();
+
+  // enable/disable stack trace signal handler. In order to
+  // produce an informative stack trace the application should
+  // be dynamically linked and compiled with debug symbols.
+  static
+  void SetStackTraceOnError(int enable);
 
   /** Run the different checks */
   void RunCPUCheck();
   void RunOSCheck();
   void RunMemoryCheck();
-private:
-  SystemInformationImplementation* Implementation;
-
 };
+
 } // namespace @KWSYS_NAMESPACE@
 
 /* Undefine temporary macros.  */
index 66850e9..8b25d60 100644 (file)
@@ -157,7 +157,7 @@ public:
 #include <os/storage/Path.h>
 #endif
 
-#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__)
+#if defined(__BEOS__) && !defined(__ZETA__)
 #include <be/kernel/OS.h>
 #include <be/storage/Path.h>
 
@@ -196,18 +196,16 @@ inline int Rmdir(const char* dir)
 }
 inline const char* Getcwd(char* buf, unsigned int len)
 {
-  const char* ret = _getcwd(buf, len);
-  if(!ret)
+  if(const char* ret = _getcwd(buf, len))
     {
-    fprintf(stderr, "No current working directory.\n");
-    abort();
-    }
-  // make sure the drive letter is capital
-  if(strlen(buf) > 1 && buf[1] == ':')
-    {
-    buf[0] = toupper(buf[0]);
+    // make sure the drive letter is capital
+    if(strlen(buf) > 1 && buf[1] == ':')
+      {
+      buf[0] = toupper(buf[0]);
+      }
+    return ret;
     }
-  return ret;
+  return 0;
 }
 inline int Chdir(const char* dir)
 {
@@ -245,13 +243,7 @@ inline int Rmdir(const char* dir)
 }
 inline const char* Getcwd(char* buf, unsigned int len)
 {
-  const char* ret = getcwd(buf, len);
-  if(!ret)
-    {
-    fprintf(stderr, "No current working directory\n");
-    abort();
-    }
-  return ret;
+  return getcwd(buf, len);
 }
 
 inline int Chdir(const char* dir)
@@ -622,11 +614,7 @@ bool SystemTools::MakeDirectory(const char* path)
     }
   SystemTools::ConvertToUnixSlashes(dir);
 
-  kwsys_stl::string::size_type pos = dir.find(':');
-  if(pos == kwsys_stl::string::npos)
-    {
-    pos = 0;
-    }
+  kwsys_stl::string::size_type pos = 0;
   kwsys_stl::string topdir;
   while((pos = dir.find('/', pos)) != kwsys_stl::string::npos)
     {
@@ -634,14 +622,7 @@ bool SystemTools::MakeDirectory(const char* path)
     Mkdir(topdir.c_str());
     pos++;
     }
-  if(dir[dir.size()-1] == '/')
-    {
-    topdir = dir.substr(0, dir.size());
-    }
-  else
-    {
-    topdir = dir;
-    }
+  topdir = dir;
   if(Mkdir(topdir.c_str()) != 0)
     {
     // There is a bug in the Borland Run time library which makes MKDIR
@@ -1665,7 +1646,7 @@ kwsys_stl::string SystemTools::EscapeChars(
   kwsys_stl::string n;
   if (str)
     {
-    if (!chars_to_escape | !*chars_to_escape)
+    if (!chars_to_escape || !*chars_to_escape)
       {
       n.append(str);
       }
@@ -2754,15 +2735,30 @@ kwsys_stl::string SystemTools::GetRealPath(const char* path)
 
 bool SystemTools::FileIsDirectory(const char* name)
 {
+  size_t length = strlen(name);
+  if (length == 0)
+    {
+    return false;
+    }
+
   // Remove any trailing slash from the name.
-  char buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
-  size_t last = strlen(name)-1;
+  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)
     {
-    memcpy(buffer, name, last);
-    buffer[last] = 0;
-    name = buffer;
+    if(last < sizeof(local_buffer))
+      {
+      memcpy(local_buffer, name, last);
+      local_buffer[last] = 0;
+      name = local_buffer;
+      }
+    else
+      {
+      string_buffer.append(name, last);
+      name = string_buffer.c_str();
+      }
     }
 
   // Now check the file node type.
@@ -3042,7 +3038,7 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
   path.erase(path.end()-1, path.end());
 }
 
-void
+static void
 SystemToolsAppendComponents(
   kwsys_stl::vector<kwsys_stl::string>& out_components,
   kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
@@ -3094,7 +3090,7 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
         }
       else
         {
-        // ??
+        base_components.push_back("");
         }
       }
 
@@ -4048,7 +4044,7 @@ kwsys_stl::string SystemTools::GetCurrentDateTime(const char* format)
   return kwsys_stl::string(buf);
 }
 
-kwsys_stl::string SystemTools::MakeCindentifier(const char* s)
+kwsys_stl::string SystemTools::MakeCidentifier(const char* s)
 {
   kwsys_stl::string str(s);
   if (str.find_first_of("0123456789") == 0)
@@ -4709,7 +4705,7 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
 // ----------------------------------------------------------------------
 // These must NOT be initialized.  Default initialization to zero is
 // necessary.
-unsigned int SystemToolsManagerCount;
+static unsigned int SystemToolsManagerCount;
 SystemToolsTranslationMap *SystemTools::TranslationMap;
 SystemToolsTranslationMap *SystemTools::LongPathMap;
 #ifdef __CYGWIN__
index 5171125..9c56e96 100644 (file)
@@ -91,8 +91,13 @@ public:
    * then an underscore is prepended.  Note that this can produce
    * identifiers that the standard reserves (_[A-Z].* and __.*).
    */
-  static kwsys_stl::string MakeCindentifier(const char* s);
-  
+  static kwsys_stl::string MakeCidentifier(const char* s);
+
+  static kwsys_stl::string MakeCindentifier(const char* s)
+  {
+    return MakeCidentifier(s);
+  }
+
   /**
    * Replace replace all occurences of the string in the source string.
    */
index 7b73d06..48976c4 100644 (file)
@@ -358,6 +358,30 @@ int main()
 }
 #endif
 
+#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
+int test_istream(kwsys_ios::istream& is, __int64& x)
+{
+  return (is >> x)? 1:0;
+}
+int main()
+{
+  __int64 x = 0;
+  return test_istream(kwsys_ios::cin, x);
+}
+#endif
+
+#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
+int test_ostream(kwsys_ios::ostream& os, __int64 x)
+{
+  return (os << x)? 1:0;
+}
+int main()
+{
+  __int64 x = 0;
+  return test_ostream(kwsys_ios::cout, x);
+}
+#endif
+
 #ifdef TEST_KWSYS_CHAR_IS_SIGNED
 /* Return 0 for char signed and 1 for char unsigned.  */
 int main()
@@ -428,6 +452,48 @@ int main()
 }
 #endif
 
+#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
+# if defined(KWSYS_HAS_LFS)
+#  define _LARGEFILE_SOURCE
+#  define _LARGEFILE64_SOURCE
+#  define _LARGE_FILES
+#  define _FILE_OFFSET_BITS 64
+# endif
+# include <sys/resource.h>
+int main()
+{
+  struct rlimit64 rlim;
+  return getrlimit64(0,&rlim);
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_ATOLL
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(atoll(str));
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_ATOL
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(atol(str));
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS__ATOI64
+#include <stdlib.h>
+int main()
+{
+  const char *str="1024";
+  return static_cast<int>(_atoi64(str));
+}
+#endif
+
 #ifdef TEST_KWSYS_CXX_TYPE_INFO
 /* Collect fundamental type information and save it to a CMake script.  */
 
@@ -514,3 +580,30 @@ int main()
     }
 }
 #endif
+
+#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
+int main()
+{
+  int a = 1;
+  __asm {
+    xor EBX, EBX;
+    mov a, EBX;
+  }
+
+  return a;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
+int main()
+{
+  int a = 0;
+  __asm {
+    xor EAX, EAX;
+    cpuid;
+    mov a, EAX;
+  }
+
+  return a;
+}
+#endif
index e75a87e..72e6544 100644 (file)
@@ -24,9 +24,9 @@
 #include <stddef.h> /* size_t */
 #include <string.h> /* strcmp */
 
-void* random_ptr = reinterpret_cast<void*>(0x123);
+static void* random_ptr = reinterpret_cast<void*>(0x123);
 
-int argument(const char* arg, const char* value, void* call_data)
+static int argument(const char* arg, const char* value, void* call_data)
 {
   kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
   if ( call_data != random_ptr )
@@ -37,7 +37,7 @@ int argument(const char* arg, const char* value, void* call_data)
   return 1;
 }
 
-int unknown_argument(const char* argument, void* call_data)
+static int unknown_argument(const char* argument, void* call_data)
 {
   kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
   if ( call_data != random_ptr )
@@ -48,12 +48,12 @@ int unknown_argument(const char* argument, void* call_data)
   return 1;
 }
 
-bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(const char* i1,
+static bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(const char* i1,
   const char* i2) { return strcmp(i1, i2) == 0; }
-bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
+static bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
   const kwsys_stl::string& i2) { return i1 == i2; }
 
 int testCommandLineArguments(int argc, char* argv[])
index a7adbca..61c1572 100644 (file)
@@ -15,7 +15,7 @@
 #include KWSYS_HEADER(ios/iostream)
 #include KWSYS_HEADER(stl/string)
 
-#if defined(__BEOS__) && !defined(__HAIKU__)
+#if defined(__BEOS__)
 #include <be/kernel/OS.h>  /* disable_debugger() API. */
 #endif
 
@@ -35,7 +35,7 @@
 // left on disk.
 #include <testSystemTools.h>
 
-kwsys_stl::string GetLibName(const char* lname)
+static kwsys_stl::string GetLibName(const char* lname)
 {
   // Construct proper name of lib
   kwsys_stl::string slname;
index 877002a..6d5eb71 100644 (file)
@@ -32,7 +32,7 @@
 # pragma warn -8060 /* possibly incorrect assignment */
 #endif
 
-#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__)
+#if defined(__BEOS__) && !defined(__ZETA__)
 /* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */
 # include <be/kernel/OS.h>
 static inline void testProcess_usleep(unsigned int msec)
@@ -47,7 +47,7 @@ int runChild(const char* cmd[], int state, int exception, int value,
              int share, int output, int delay, double timeout, int poll,
              int repeat, int disown);
 
-int test1(int argc, const char* argv[])
+static int test1(int argc, const char* argv[])
 {
   (void)argc; (void)argv;
   fprintf(stdout, "Output on stdout from test returning 0.\n");
@@ -55,7 +55,7 @@ int test1(int argc, const char* argv[])
   return 0;
 }
 
-int test2(int argc, const char* argv[])
+static int test2(int argc, const char* argv[])
 {
   (void)argc; (void)argv;
   fprintf(stdout, "Output on stdout from test returning 123.\n");
@@ -63,7 +63,7 @@ int test2(int argc, const char* argv[])
   return 123;
 }
 
-int test3(int argc, const char* argv[])
+static int test3(int argc, const char* argv[])
 {
   (void)argc; (void)argv;
   fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
@@ -80,8 +80,16 @@ int test3(int argc, const char* argv[])
   return 0;
 }
 
-int test4(int argc, const char* argv[])
+static int test4(int argc, const char* argv[])
 {
+  /* Prepare a pointer to an invalid address.  Don't use null, because
+  dereferencing null is undefined behaviour and compilers are free to
+  do whatever they want. ex: Clang will warn at compile time, or even
+  optimize away the write. We hope to 'outsmart' them by using
+  'volatile' and a slightly larger address, based on a runtime value. */
+  volatile int* invalidAddress = 0;
+  invalidAddress += argc?1:2;
+
 #if defined(_WIN32)
   /* Avoid error diagnostic popups since we are crashing on purpose.  */
   SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
@@ -94,17 +102,14 @@ int test4(int argc, const char* argv[])
   fprintf(stderr, "Output before crash on stderr from crash test.\n");  
   fflush(stdout);
   fflush(stderr);
-#if defined(__clang__)
-  *(int*)1 = 0; /* Clang warns about 0-ptr; undefined behavior.  */
-#else
-  *(int*)0 = 0;
-#endif
+  /* Provoke deliberate crash by writing to the invalid address. */
+  *invalidAddress = 0;
   fprintf(stdout, "Output after crash on stdout from crash test.\n");
   fprintf(stderr, "Output after crash on stderr from crash test.\n");
   return 0;
 }
 
-int test5(int argc, const char* argv[])
+static int test5(int argc, const char* argv[])
 {
   int r;
   const char* cmd[4];
@@ -127,7 +132,7 @@ int test5(int argc, const char* argv[])
 }
 
 #define TEST6_SIZE (4096*2)
-void test6(int argc, const char* argv[])
+static void test6(int argc, const char* argv[])
 {
   int i;
   char runaway[TEST6_SIZE+1];
@@ -151,7 +156,7 @@ void test6(int argc, const char* argv[])
    delaying 1/10th of a second should ever have to poll.  */
 #define MINPOLL 5
 #define MAXPOLL 20
-int test7(int argc, const char* argv[])
+static int test7(int argc, const char* argv[])
 {
   (void)argc; (void)argv;
   fprintf(stdout, "Output on stdout before sleep.\n");
@@ -171,7 +176,7 @@ int test7(int argc, const char* argv[])
   return 0;
 }
 
-int test8(int argc, const char* argv[])
+static int test8(int argc, const char* argv[])
 {
   /* Create a disowned grandchild to test handling of processes
      that exit before their children.  */
@@ -195,7 +200,7 @@ int test8(int argc, const char* argv[])
   return r;
 }
 
-int test8_grandchild(int argc, const char* argv[])
+static int test8_grandchild(int argc, const char* argv[])
 {
   (void)argc; (void)argv;
   fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
@@ -216,7 +221,7 @@ int test8_grandchild(int argc, const char* argv[])
   return 0;
 }
 
-int runChild2(kwsysProcess* kp,
+static int runChild2(kwsysProcess* kp,
               const char* cmd[], int state, int exception, int value,
               int share, int output, int delay, double timeout,
               int poll, int disown)
@@ -500,7 +505,7 @@ int main(int argc, const char* argv[])
     fprintf(stderr, "Output on stderr after test %d.\n", n);
     fflush(stdout);
     fflush(stderr);
-#if _WIN32
+#if defined(_WIN32)
     if(argv0) { free(argv0); }
 #endif
     return r;
diff --git a/Source/kwsys/testRegistry.cxx b/Source/kwsys/testRegistry.cxx
deleted file mode 100644 (file)
index 7e9b0d4..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*============================================================================
-  KWSys - Kitware System Library
-  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 "kwsysPrivate.h"
-
-#include KWSYS_HEADER(Registry.hxx)
-#include KWSYS_HEADER(ios/iostream)
-#include <string.h>
-
-// Work-around CMake dependency scanning limitation.  This must
-// duplicate the above list of headers.
-#if 0
-# include "Registry.hxx.in"
-# include "kwsys_ios_iostream.h.in"
-#endif
-
-#define IFT(x,res) if ( !x )                    \
-  {                                             \
-  res = 1;                                      \
-  kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl;           \
-  }
-#define IFNT(x,res) if ( x )                    \
-  {                                             \
-  res = 1;                                      \
-  kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl;           \
-  }
-
-#define CHE(x,y,res) if ( x && strcmp(x,y) )                 \
-  {                                                     \
-  res = 1;                                              \
-  kwsys_ios::cout << "Error, " << x << " != " << y << kwsys_ios::endl;        \
-  }
-
-int testRegistry(int, char*[])
-{
-  int res = 0;
-  
-  kwsys::Registry reg;
-  reg.SetTopLevel("TestRegistry");
-  
-  IFT(reg.SetValue("TestSubkey",  "TestKey1", "Test Value 1"), res);
-  IFT(reg.SetValue("TestSubkey1", "TestKey2", "Test Value 2"), res);
-  IFT(reg.SetValue("TestSubkey",  "TestKey3", "Test Value 3"), res);
-  IFT(reg.SetValue("TestSubkey2", "TestKey4", "Test Value 4"), res);
-
-  const char *buffer;
-  IFT(reg.ReadValue("TestSubkey",  "TestKey1", &buffer), res);
-  CHE(buffer, "Test Value 1", res);
-  IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
-  CHE(buffer, "Test Value 2", res);
-  IFT(reg.ReadValue("TestSubkey",  "TestKey3", &buffer), res);
-  CHE(buffer, "Test Value 3", res);
-  IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
-  CHE(buffer, "Test Value 4", res);
-  IFT(reg.SetValue("TestSubkey",  "TestKey1", "New Test Value 1"), res);
-  IFT(reg.SetValue("TestSubkey1", "TestKey2", "New Test Value 2"), res);
-  IFT(reg.SetValue("TestSubkey",  "TestKey3", "New Test Value 3"), res);
-  IFT(reg.SetValue("TestSubkey2", "TestKey4", "New Test Value 4"), res);
-
-  IFT(reg.ReadValue("TestSubkey",  "TestKey1", &buffer), res);
-  CHE(buffer, "New Test Value 1", res);
-  IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
-  CHE(buffer, "New Test Value 2", res);
-  IFT(reg.ReadValue("TestSubkey",  "TestKey3", &buffer), res);
-  CHE(buffer, "New Test Value 3", res);
-  IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
-  CHE(buffer, "New Test Value 4", res);
-
-  IFT( reg.DeleteValue("TestSubkey",  "TestKey1"), res);
-  IFNT(reg.ReadValue(  "TestSubkey",  "TestKey1", &buffer), res);
-  IFT( reg.DeleteValue("TestSubkey1", "TestKey2"), res);
-  IFNT(reg.ReadValue(  "TestSubkey1", "TestKey2", &buffer), res);
-  IFT( reg.DeleteValue("TestSubkey",  "TestKey3"), res);
-  IFNT(reg.ReadValue(  "TestSubkey",  "TestKey3", &buffer), res);
-  IFT( reg.DeleteValue("TestSubkey2", "TestKey4"), res);
-  IFNT(reg.ReadValue(  "TestSubkey2", "TestKey5", &buffer), res);  
-
-  const char* longStringWithNewLines = "Value with embedded CR and LF characters CR='\015' LF='\012' CRLF='\015\012'";
-  IFT(reg.SetValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName",  "TestKey1", longStringWithNewLines), res);
-  IFT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res);
-  CHE(buffer, longStringWithNewLines, res);
-  IFT(reg.DeleteValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName",  "TestKey1"), res);
-  IFNT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res);
-
-  IFT(reg.SetValue("TestSubkeyWith = EqualSignChar",  "TestKey = 1", "Some value"), res);
-  IFT(reg.ReadValue("TestSubkeyWith = EqualSignChar",  "TestKey = 1", &buffer), res);
-  CHE(buffer, "Some value", res);
-  IFT(reg.DeleteValue("TestSubkeyWith = EqualSignChar",  "TestKey = 1"), res);
-  IFNT(reg.ReadValue("TestSubkeyWith = EqualSignChar",  "TestKey = 1", &buffer), res);
-
-  if ( res )
-    {
-    kwsys_ios::cout << "Test failed" << kwsys_ios::endl;
-    }
-  else
-    {
-    kwsys_ios::cout << "Test passed" << kwsys_ios::endl;
-    }
-  return res;
-}
index b3afc9d..49a686c 100644 (file)
@@ -13,8 +13,6 @@
 #include KWSYS_HEADER(SystemInformation.hxx)
 #include KWSYS_HEADER(ios/iostream)
 
-
-
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 # include "kwsys_ios_iostream.h.in"
 #endif
 
-#define printMethod(inof, m) kwsys_ios::cout << #m << ": " \
+#if defined(KWSYS_USE_LONG_LONG)
+# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#elif defined(KWSYS_USE___INT64)
+# if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
+#  define iostreamLongLong(x) (x)
+# else
+#  define iostreamLongLong(x) ((long)x)
+# endif
+#else
+# error "No Long Long"
+#endif
+
+#define printMethod(info, m) kwsys_ios::cout << #m << ": " \
 << info.m() << "\n"
 
-#define printMethod2(inof, m, unit) kwsys_ios::cout << #m << ": " \
+#define printMethod2(info, m, unit) kwsys_ios::cout << #m << ": " \
 << info.m() << " " << unit << "\n"
 
+#define printMethod3(info, m, unit) kwsys_ios::cout << #m << ": " \
+<< iostreamLongLong(info.m) << " " << unit << "\n"
+
 int testSystemInformation(int, char*[])
 {
+  kwsys_ios::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation
+
   kwsys::SystemInformation info;
   info.RunCPUCheck();
   info.RunOSCheck();
   info.RunMemoryCheck();
   printMethod(info, GetOSName);
+  printMethod(info, GetOSIsLinux);
+  printMethod(info, GetOSIsApple);
+  printMethod(info, GetOSIsWindows);
   printMethod(info, GetHostname);
+  printMethod(info, GetFullyQualifiedDomainName);
   printMethod(info, GetOSRelease);
   printMethod(info, GetOSVersion);
   printMethod(info, GetOSPlatform);
@@ -45,6 +68,7 @@ int testSystemInformation(int, char*[])
   printMethod(info, GetFamilyID);
   printMethod(info, GetModelID);
   printMethod(info, GetExtendedProcessorName);
+  printMethod(info, GetSteppingCode);
   printMethod(info, GetProcessorSerialNumber);
   printMethod2(info, GetProcessorCacheSize, "KB");
   printMethod(info, GetLogicalProcessorsPerPhysical);
@@ -58,7 +82,19 @@ int testSystemInformation(int, char*[])
   printMethod2(info, GetAvailableVirtualMemory, "MB");
   printMethod2(info, GetTotalPhysicalMemory, "MB");
   printMethod2(info, GetAvailablePhysicalMemory, "MB");
+  printMethod3(info, GetHostMemoryTotal(), "KiB");
+  printMethod3(info, GetHostMemoryAvailable("KWSHL"), "KiB");
+  printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
+  printMethod3(info, GetHostMemoryUsed(), "KiB");
+  printMethod3(info, GetProcMemoryUsed(), "KiB");
 
+  for (int i = 0; i <= 31; i++)
+    {
+    if (info.DoesCPUSupportFeature(1 << i))
+      {
+      kwsys_ios::cout << "CPU feature " << i << "\n";
+      }
+    }
   //int GetProcessorCacheXSize(long int);
 //  bool DoesCPUSupportFeature(long int);
   return 0;
index 3ac0cb3..1690fd5 100644 (file)
@@ -32,7 +32,7 @@
 #include <string.h> /* strcmp */
 
 //----------------------------------------------------------------------------
-const char* toUnixPaths[][2] =
+static const char* toUnixPaths[][2] =
 {
     { "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
     { "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
@@ -52,8 +52,8 @@ const char* toUnixPaths[][2] =
     {0, 0}
 };
 
-bool CheckConvertToUnixSlashes(kwsys_stl::string input,
-                               kwsys_stl::string output)
+static bool CheckConvertToUnixSlashes(kwsys_stl::string input,
+                                      kwsys_stl::string output)
 {
   kwsys_stl::string result = input;
   kwsys::SystemTools::ConvertToUnixSlashes(result);
@@ -69,17 +69,17 @@ bool CheckConvertToUnixSlashes(kwsys_stl::string input,
 }
 
 //----------------------------------------------------------------------------
-const char* checkEscapeChars[][4] =
+static const char* checkEscapeChars[][4] =
 {
   { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2"},
   { " {} ", "{}", "#", " #{#} "},
   {0, 0, 0, 0}
 };
 
-bool CheckEscapeChars(kwsys_stl::string input,
-                      const char *chars_to_escape,
-                      char escape_char,
-                      kwsys_stl::string output)
+static bool CheckEscapeChars(kwsys_stl::string input,
+                             const char *chars_to_escape,
+                             char escape_char,
+                             kwsys_stl::string output)
 {
   kwsys_stl::string result = kwsys::SystemTools::EscapeChars(
     input.c_str(), chars_to_escape, escape_char);
@@ -95,7 +95,7 @@ bool CheckEscapeChars(kwsys_stl::string input,
 }
 
 //----------------------------------------------------------------------------
-bool CheckFileOperations()
+static bool CheckFileOperations()
 {
   bool res = true;
 
@@ -129,7 +129,7 @@ bool CheckFileOperations()
 }
 
 //----------------------------------------------------------------------------
-bool CheckStringOperations()
+static bool CheckStringOperations()
 {
   bool res = true;
 
@@ -329,7 +329,7 @@ bool CheckStringOperations()
 
 //----------------------------------------------------------------------------
 
-bool CheckPutEnv(const char* env, const char* name, const char* value)
+static bool CheckPutEnv(const char* env, const char* name, const char* value)
 {
   if(!kwsys::SystemTools::PutEnv(env))
     {
@@ -348,7 +348,7 @@ bool CheckPutEnv(const char* env, const char* name, const char* value)
   return true;
 }
 
-bool CheckUnPutEnv(const char* env, const char* name)
+static bool CheckUnPutEnv(const char* env, const char* name)
 {
   if(!kwsys::SystemTools::UnPutEnv(env))
     {
@@ -365,7 +365,7 @@ bool CheckUnPutEnv(const char* env, const char* name)
   return true;
 }
 
-bool CheckEnvironmentOperations()
+static bool CheckEnvironmentOperations()
 {
   bool res = true;
   res &= CheckPutEnv("A=B", "A", "B");
index 2a70b6e..2792751 100644 (file)
@@ -60,6 +60,12 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
   "static const char* zot_macro_tgt = \"zot_macro_tgt\";\n")
 
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_lib.h
+  "#define link_depends_no_shared_lib_value 1\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_exe.h
+  "#define link_depends_no_shared_exe_value 0\n")
+set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_check.txt)
+
 help_xcode_depends()
 
 message("Building project first time")
@@ -125,6 +131,19 @@ else()
   message(SEND_ERROR "Project did not initially build properly: ${out}")
 endif()
 
+if(EXISTS "${link_depends_no_shared_check_txt}")
+  file(STRINGS "${link_depends_no_shared_check_txt}" link_depends_no_shared_check LIMIT_COUNT 1)
+  if("${link_depends_no_shared_check}" STREQUAL "1")
+    message(STATUS "link_depends_no_shared_exe is newer than link_depends_no_shared_lib as expected.")
+  else()
+    message(SEND_ERROR "Project did not initially build properly: "
+      "link_depends_no_shared_exe is older than link_depends_no_shared_lib.")
+  endif()
+else()
+  message(SEND_ERROR "Project did not initially build properly: "
+    "Targets link_depends_no_shared_lib and link_depends_no_shared_exe not both built.")
+endif()
+
 message("Waiting 3 seconds...")
 # any additional argument will cause ${bar} to wait forever
 execute_process(COMMAND ${bar} -infinite TIMEOUT 3 OUTPUT_VARIABLE out)
@@ -141,6 +160,9 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
   "static const char* zot_macro_tgt = \"zot_macro_tgt changed\";\n")
 
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_lib.h
+  "#define link_depends_no_shared_lib_value 0\n")
+
 if(TEST_LINK_DEPENDS)
   file(WRITE ${TEST_LINK_DEPENDS} "2")
 endif()
@@ -219,3 +241,15 @@ is not newer than dependency
 ")
   endif()
 endif()
+
+if(EXISTS "${link_depends_no_shared_check_txt}")
+  file(STRINGS "${link_depends_no_shared_check_txt}" link_depends_no_shared_check LIMIT_COUNT 1)
+  if("${link_depends_no_shared_check}" STREQUAL "0")
+    message(STATUS "link_depends_no_shared_exe is older than link_depends_no_shared_lib as expected.")
+  else()
+    message(SEND_ERROR "Project did not rebuild properly: link_depends_no_shared_exe is newer than link_depends_no_shared_lib.")
+  endif()
+else()
+  message(SEND_ERROR "Project did not rebuild properly.  "
+    "Targets link_depends_no_shared_lib and link_depends_no_shared_exe not both built.")
+endif()
index 01f5f62..f8a3d15 100644 (file)
@@ -64,7 +64,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Make")
   # Test the IMPLICIT_DEPENDS feature.
   set(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
   set(ZOT_CUSTOM_DEP
-    IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx)
+    IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx
+                     CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom2.cxx )
 else()
   # No IMPLICIT_DEPENDS...just depend directly.
   set(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
@@ -107,3 +108,18 @@ if(TEST_LINK_DEPENDS)
   add_executable(linkdep linkdep.cxx)
   set_property(TARGET linkdep PROPERTY LINK_DEPENDS ${TEST_LINK_DEPENDS})
 endif()
+
+add_library(link_depends_no_shared_lib SHARED link_depends_no_shared_lib.c
+  ${CMAKE_CURRENT_BINARY_DIR}/link_depends_no_shared_lib.h)
+add_executable(link_depends_no_shared_exe link_depends_no_shared_exe.c
+  ${CMAKE_CURRENT_BINARY_DIR}/link_depends_no_shared_exe.h)
+target_link_libraries(link_depends_no_shared_exe link_depends_no_shared_lib)
+set_property(TARGET link_depends_no_shared_exe PROPERTY LINK_DEPENDS_NO_SHARED 1)
+add_custom_target(link_depends_no_shared_check ALL
+  COMMAND ${CMAKE_COMMAND}
+   -Dlib=$<TARGET_FILE:link_depends_no_shared_lib>
+   -Dexe=$<TARGET_FILE:link_depends_no_shared_exe>
+   -Dout=${CMAKE_CURRENT_BINARY_DIR}/link_depends_no_shared_check.txt
+   -P ${CMAKE_CURRENT_SOURCE_DIR}/link_depends_no_shared_check.cmake
+  )
+add_dependencies(link_depends_no_shared_check link_depends_no_shared_exe)
diff --git a/Tests/BuildDepends/Project/dep_custom2.cxx b/Tests/BuildDepends/Project/dep_custom2.cxx
new file mode 100644 (file)
index 0000000..ac9dee1
--- /dev/null
@@ -0,0 +1,2 @@
+#include <zot_custom.hxx.in>
+// some comment
diff --git a/Tests/BuildDepends/Project/link_depends_no_shared_check.cmake b/Tests/BuildDepends/Project/link_depends_no_shared_check.cmake
new file mode 100644 (file)
index 0000000..3a61137
--- /dev/null
@@ -0,0 +1,7 @@
+if(NOT EXISTS "${lib}" OR NOT EXISTS "${exe}")
+  file(REMOVE "${out}")
+elseif("${exe}" IS_NEWER_THAN "${lib}")
+  file(WRITE "${out}" "1\n")
+else()
+  file(WRITE "${out}" "0\n")
+endif()
diff --git a/Tests/BuildDepends/Project/link_depends_no_shared_exe.c b/Tests/BuildDepends/Project/link_depends_no_shared_exe.c
new file mode 100644 (file)
index 0000000..e9113a2
--- /dev/null
@@ -0,0 +1,9 @@
+#include "link_depends_no_shared_exe.h"
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+int link_depends_no_shared_lib(void);
+int main()
+{
+  return link_depends_no_shared_lib() + link_depends_no_shared_exe_value;
+}
diff --git a/Tests/BuildDepends/Project/link_depends_no_shared_lib.c b/Tests/BuildDepends/Project/link_depends_no_shared_lib.c
new file mode 100644 (file)
index 0000000..d226289
--- /dev/null
@@ -0,0 +1,8 @@
+#include "link_depends_no_shared_lib.h"
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int link_depends_no_shared_lib(void)
+{
+  return link_depends_no_shared_lib_value;
+}
index 195f107..0f7074b 100644 (file)
@@ -12,6 +12,7 @@ message("running: ${CMAKE_COMMAND}")
 execute_process(COMMAND "${CMAKE_COMMAND}"
   "@CMAKE_BUILD_TEST_SOURCE_DIR@"
   "-G@CMAKE_TEST_GENERATOR@"
+  -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
   WORKING_DIRECTORY "@CMAKE_BUILD_TEST_BINARY_DIR@"
   RESULT_VARIABLE RESULT)
 if(RESULT)
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6d0e646
--- /dev/null
@@ -0,0 +1,22 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(target_compile_definitions)
+
+add_executable(target_compile_definitions
+  "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
+)
+target_compile_definitions(target_compile_definitions
+  PRIVATE MY_PRIVATE_DEFINE
+  PUBLIC MY_PUBLIC_DEFINE
+  INTERFACE MY_INTERFACE_DEFINE
+)
+
+add_executable(consumer
+  "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
+)
+
+target_compile_definitions(consumer
+  PRIVATE $<TARGET_PROPERTY:target_compile_definitions,INTERFACE_COMPILE_DEFINITIONS>
+  -DDASH_D_DEFINE
+)
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
new file mode 100644 (file)
index 0000000..a391114
--- /dev/null
@@ -0,0 +1,18 @@
+
+#ifdef MY_PRIVATE_DEFINE
+#error Unexpected MY_PRIVATE_DEFINE
+#endif
+
+#ifndef MY_PUBLIC_DEFINE
+#error Expected MY_PUBLIC_DEFINE
+#endif
+
+#ifndef MY_INTERFACE_DEFINE
+#error Expected MY_INTERFACE_DEFINE
+#endif
+
+#ifndef DASH_D_DEFINE
+#error Expected DASH_D_DEFINE
+#endif
+
+int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_compile_definitions/main.cpp b/Tests/CMakeCommands/target_compile_definitions/main.cpp
new file mode 100644 (file)
index 0000000..addb33c
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef MY_PRIVATE_DEFINE
+#error Expected MY_PRIVATE_DEFINE
+#endif
+
+#ifndef MY_PUBLIC_DEFINE
+#error Expected MY_PUBLIC_DEFINE
+#endif
+
+#ifdef MY_INTERFACE_DEFINE
+#error Unexpected MY_INTERFACE_DEFINE
+#endif
+
+int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c03f0f8
--- /dev/null
@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(target_include_directories)
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/privateinclude")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/privateinclude/privateinclude.h" "#define PRIVATEINCLUDE_DEFINE\n")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/publicinclude")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/publicinclude/publicinclude.h" "#define PUBLICINCLUDE_DEFINE\n")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude/interfaceinclude.h" "#define INTERFACEINCLUDE_DEFINE\n")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/poison")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be included\n")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/cure")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cure/common.h" "#define CURE_DEFINE\n")
+
+add_executable(target_include_directories
+  "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
+)
+target_include_directories(target_include_directories
+  PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/privateinclude"
+  PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/publicinclude"
+  INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude"
+)
+
+target_include_directories(target_include_directories
+  PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/poison"
+)
+target_include_directories(target_include_directories
+  BEFORE PUBLIC "$<$<STREQUAL:$<TARGET_PROPERTY:target_include_directories,TYPE>,EXECUTABLE>:${CMAKE_CURRENT_BINARY_DIR}/cure>"
+)
+
+# Has no effect because the target type is not SHARED_LIBRARY:
+target_include_directories(target_include_directories
+  BEFORE PUBLIC "$<$<STREQUAL:$<TARGET_PROPERTY:target_include_directories,TYPE>,SHARED_LIBRARY>:${CMAKE_CURRENT_BINARY_DIR}/poison>"
+)
+
+add_executable(consumer
+  "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
+)
+
+target_include_directories(consumer
+  PRIVATE
+    $<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>
+  relative_dir
+)
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp
new file mode 100644 (file)
index 0000000..82b800a
--- /dev/null
@@ -0,0 +1,27 @@
+
+#include "common.h"
+#include "publicinclude.h"
+#include "interfaceinclude.h"
+#include "relative_dir.h"
+
+#ifdef PRIVATEINCLUDE_DEFINE
+#error Unexpected PRIVATEINCLUDE_DEFINE
+#endif
+
+#ifndef PUBLICINCLUDE_DEFINE
+#error Expected PUBLICINCLUDE_DEFINE
+#endif
+
+#ifndef INTERFACEINCLUDE_DEFINE
+#error Expected INTERFACEINCLUDE_DEFINE
+#endif
+
+#ifndef CURE_DEFINE
+#error Expected CURE_DEFINE
+#endif
+
+#ifndef RELATIVE_DIR_DEFINE
+#error Expected RELATIVE_DIR_DEFINE
+#endif
+
+int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/main.cpp b/Tests/CMakeCommands/target_include_directories/main.cpp
new file mode 100644 (file)
index 0000000..8434b97
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include "common.h"
+#include "privateinclude.h"
+#include "publicinclude.h"
+
+#ifndef PRIVATEINCLUDE_DEFINE
+#error Expected PRIVATEINCLUDE_DEFINE
+#endif
+
+#ifndef PUBLICINCLUDE_DEFINE
+#error Expected PUBLICINCLUDE_DEFINE
+#endif
+
+#ifdef INTERFACEINCLUDE_DEFINE
+#error Unexpected INTERFACEINCLUDE_DEFINE
+#endif
+
+#ifndef CURE_DEFINE
+#error Expected CURE_DEFINE
+#endif
+
+int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/relative_dir/relative_dir.h b/Tests/CMakeCommands/target_include_directories/relative_dir/relative_dir.h
new file mode 100644 (file)
index 0000000..7017b61
--- /dev/null
@@ -0,0 +1,2 @@
+
+#define RELATIVE_DIR_DEFINE
index 1faa888..3881644 100644 (file)
@@ -34,6 +34,13 @@ generate_export_header(depB)
 
 target_link_libraries(depB LINK_PRIVATE depA)
 
+add_library(libgenex SHARED libgenex.cpp)
+generate_export_header(libgenex)
+
+set_property(TARGET depB APPEND PROPERTY
+  LINK_LIBRARIES $<1:libgenex>
+)
+
 add_library(depC SHARED depC.cpp)
 generate_export_header(depC)
 
@@ -53,6 +60,57 @@ set_target_properties(targetA PROPERTIES LINK_INTERFACE_LIBRARIES "")
 
 assert_property(targetA LINK_INTERFACE_LIBRARIES "")
 
+add_subdirectory(subdir)
+target_link_libraries(targetA subdirlib)
+
 target_link_libraries(targetA depB depC)
 
 assert_property(targetA LINK_INTERFACE_LIBRARIES "")
+
+# Exclude depIfaceOnly from ALL so that it will only be built if something
+# depends on it. As it is in the link interface of depB, targetA
+# will depend on it. That dependency is what is being tested here.
+add_library(depIfaceOnly SHARED EXCLUDE_FROM_ALL depIfaceOnly.cpp)
+generate_export_header(depIfaceOnly)
+set_property(TARGET depB APPEND PROPERTY LINK_INTERFACE_LIBRARIES depIfaceOnly)
+
+add_library(depD SHARED depD.cpp)
+generate_export_header(depD)
+set_property(TARGET depD APPEND PROPERTY
+  LINK_INTERFACE_LIBRARIES
+    $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depA>
+)
+
+add_executable(targetB targetB.cpp)
+target_link_libraries(targetB depD)
+
+macro(create_header _name)
+  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
+endmacro()
+
+create_header(foo)
+create_header(bar)
+
+add_library(depG SHARED depG.cpp)
+generate_export_header(depG)
+target_include_directories(depG INTERFACE
+    "${CMAKE_CURRENT_BINARY_DIR}/foo"
+    "${CMAKE_CURRENT_BINARY_DIR}/bar"
+)
+target_compile_definitions(depG INTERFACE
+    TEST_DEF
+)
+
+
+add_executable(targetC targetC.cpp)
+if(NOT BORLAND AND NOT WATCOM)
+  # Linking to a target containing a + should be non-fatal, though it does
+  # not work at all on Borland or watcom
+  add_library(wrapc++ empty.cpp)
+  target_link_libraries(targetC wrapc++)
+endif()
+# The TARGET_PROPERTY expression is duplicated below to test that there is no
+# shortcutting of the evaluation by returning an empty string.
+set(_exe_test $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
+target_link_libraries(targetC $<$<AND:${_exe_test},${_exe_test}>:depG>)
index 97e5be2..4f46552 100644 (file)
@@ -3,9 +3,13 @@
 
 #include "depA.h"
 
+#include "libgenex.h"
+
 int DepB::foo()
 {
   DepA a;
 
-  return 0;
+  LibGenex lg;
+
+  return a.foo() + lg.foo();
 }
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.cpp b/Tests/CMakeCommands/target_link_libraries/depD.cpp
new file mode 100644 (file)
index 0000000..b02c76c
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include "depD.h"
+
+int DepD::foo()
+{
+  return 0;
+}
+
+DepA DepD::getA()
+{
+  DepA a;
+  return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.h b/Tests/CMakeCommands/target_link_libraries/depD.h
new file mode 100644 (file)
index 0000000..d24ff5f
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include "depd_export.h"
+
+#include "depA.h"
+
+struct DEPD_EXPORT DepD
+{
+  int foo();
+
+  DepA getA();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/depG.cpp b/Tests/CMakeCommands/target_link_libraries/depG.cpp
new file mode 100644 (file)
index 0000000..65b9655
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "depG.h"
+
+int DepG::foo()
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depG.h b/Tests/CMakeCommands/target_link_libraries/depG.h
new file mode 100644 (file)
index 0000000..1a36589
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "depg_export.h"
+
+struct DEPG_EXPORT DepG
+{
+  int foo();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp
new file mode 100644 (file)
index 0000000..3b90af0
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "depIfaceOnly.h"
+
+int DepIfaceOnly::foo()
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h
new file mode 100644 (file)
index 0000000..dddf6a5
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "depifaceonly_export.h"
+
+struct DEPIFACEONLY_EXPORT DepIfaceOnly
+{
+  int foo();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/empty.cpp b/Tests/CMakeCommands/target_link_libraries/empty.cpp
new file mode 100644 (file)
index 0000000..ab32cf6
--- /dev/null
@@ -0,0 +1 @@
+// No content
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.cpp b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp
new file mode 100644 (file)
index 0000000..c925c08
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "libgenex.h"
+
+int LibGenex::foo()
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.h b/Tests/CMakeCommands/target_link_libraries/libgenex.h
new file mode 100644 (file)
index 0000000..733f9b6
--- /dev/null
@@ -0,0 +1,12 @@
+
+#include "libgenex_export.h"
+
+#ifndef LIBGENEX_H
+#define LIBGENEX_H
+
+struct LIBGENEX_EXPORT LibGenex
+{
+  int foo();
+};
+
+#endif
diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9d7fa6c
--- /dev/null
@@ -0,0 +1,5 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+add_library(subdirlib SHARED subdirlib.cpp)
+generate_export_header(subdirlib)
diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp
new file mode 100644 (file)
index 0000000..cd2f1a2
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "subdirlib.h"
+
+int SubDirLibObject::foo() const
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h
new file mode 100644 (file)
index 0000000..e386f87
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifndef SUBDIRLIB_H
+#define SUBDIRLIB_H
+
+#include "subdirlib_export.h"
+
+struct SUBDIRLIB_EXPORT SubDirLibObject
+{
+  int foo() const;
+};
+
+#endif
index 3c6472e..d1321a1 100644 (file)
@@ -1,12 +1,19 @@
 
 #include "depB.h"
 #include "depC.h"
+#include "depIfaceOnly.h"
 
-int main(int argc, char **argv)
+#include "subdirlib.h"
+
+int main(int, char **)
 {
   DepA a;
   DepB b;
   DepC c;
 
-  return a.foo() + b.foo() + c.foo();
+  DepIfaceOnly iface_only;
+
+  SubDirLibObject sd;
+
+  return a.foo() + b.foo() + c.foo() + iface_only.foo() + sd.foo();
 }
diff --git a/Tests/CMakeCommands/target_link_libraries/targetB.cpp b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
new file mode 100644 (file)
index 0000000..0913a57
--- /dev/null
@@ -0,0 +1,10 @@
+
+#include "depD.h"
+
+int main(int, char **)
+{
+  DepD d;
+  DepA a = d.getA();
+
+  return d.foo() + a.foo();
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/targetC.cpp b/Tests/CMakeCommands/target_link_libraries/targetC.cpp
new file mode 100644 (file)
index 0000000..a4ef636
--- /dev/null
@@ -0,0 +1,16 @@
+
+#include "depG.h"
+
+#include "foo.h"
+#include "bar.h"
+
+#ifndef TEST_DEF
+#error Expected TEST_DEF definition
+#endif
+
+int main(int, char **)
+{
+  DepG g;
+
+  return g.foo();
+}
index bbf804b..44e9450 100644 (file)
@@ -8,18 +8,14 @@ macro(ADD_TEST_MACRO NAME COMMAND)
     "${CMake_SOURCE_DIR}/Tests/${dir}"
     "${CMake_BINARY_DIR}/Tests/${dir}"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project ${proj}
     ${${NAME}_EXTRA_OPTIONS}
     --test-command ${COMMAND} ${ARGN})
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
 endmacro()
 
-macro(REGEX_ESCAPE_STRING _OUT _IN)
-    # Escape special regex metacharacters with a backslash
-    string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}")
-endmacro()
+include(${CMAKE_CURRENT_SOURCE_DIR}/RegexEscapeString.cmake)
 
 include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
 
@@ -51,6 +47,36 @@ if(BUILD_TESTING)
     set(TEST_CompileCommandOutput 1)
   endif()
 
+  set(MAKE_IS_GNU )
+  if(${CMAKE_TEST_MAKEPROGRAM} MATCHES make)
+    execute_process(COMMAND ${CMAKE_TEST_MAKEPROGRAM} no_such_target --version
+      RESULT_VARIABLE res OUTPUT_VARIABLE out ERROR_VARIABLE out)
+    if("${res}" STREQUAL "0")
+      if("${out}" MATCHES "GNU")
+        set(MAKE_IS_GNU 1)
+      endif()
+    endif()
+  endif()
+
+  # some old versions of make simply cannot handle spaces in paths
+  if (MAKE_IS_GNU OR
+      "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR
+      "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland")
+    set(MAKE_SUPPORTS_SPACES 1)
+  else()
+    set(MAKE_SUPPORTS_SPACES 0)
+  endif()
+
+  set(build_generator_args
+    --build-generator ${CMAKE_TEST_GENERATOR}
+    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    )
+  if(CMAKE_TEST_GENERATOR_TOOLSET)
+    list(APPEND build_generator_args
+      --build-generator-toolset ${CMAKE_TEST_GENERATOR_TOOLSET}
+      )
+  endif()
+
   add_subdirectory(CMakeLib)
   add_subdirectory(CMakeOnly)
   add_subdirectory(RunCMake)
@@ -216,6 +242,7 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(PolicyScope PolicyScope)
   ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
   ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
+  ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)
@@ -257,6 +284,7 @@ if(BUILD_TESTING)
 
   # run test for BundleUtilities on supported platforms/compilers
   if(MSVC OR
+     MINGW OR
      CMAKE_SYSTEM_NAME MATCHES "Linux" OR
      CMAKE_SYSTEM_NAME MATCHES "Darwin")
   if(NOT "${CMAKE_TEST_GENERATOR}" STREQUAL "Watcom WMake")
@@ -265,8 +293,7 @@ if(BUILD_TESTING)
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/BundleUtilities"
       "${CMake_BINARY_DIR}/Tests/BundleUtilities"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project BundleUtilities
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities")
@@ -278,8 +305,7 @@ if(BUILD_TESTING)
         --build-and-test
         "${CMake_SOURCE_DIR}/Tests/Qt4Deploy"
         "${CMake_BINARY_DIR}/Tests/Qt4Deploy"
-        --build-generator ${CMAKE_TEST_GENERATOR}
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+        ${build_generator_args}
         --build-project Qt4Deploy
         --build-options
         -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
@@ -311,6 +337,19 @@ if(BUILD_TESTING)
 
   ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize)
 
+  add_test(Module.ExternalData ${CMAKE_CTEST_COMMAND}
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/Module/ExternalData"
+    "${CMake_BINARY_DIR}/Tests/Module/ExternalData"
+    ${build_generator_args}
+    --build-project ExternalDataTest
+    --build-noclean
+    --force-new-ctest-process
+    --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
+    --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
+    )
+  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Module/ExternalData")
+
   ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
 
   if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
@@ -336,8 +375,7 @@ if(BUILD_TESTING)
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/LinkFlags"
     "${CMake_BINARY_DIR}/Tests/LinkFlags"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project LinkFlags
     --build-target LinkFlags
     --build-options -DTEST_CONFIG=\${CTEST_CONFIGURATION_TYPE}
@@ -365,7 +403,8 @@ if(BUILD_TESTING)
   # mainly it tests that cmake doesn't crash when generating these project files.
   if(${CMAKE_TEST_GENERATOR} MATCHES "Unix Makefiles"  OR  ${CMAKE_TEST_GENERATOR} MATCHES "KDevelop")
     # check which generators we have
-    exec_program(${CMAKE_CMAKE_COMMAND} ARGS --help OUTPUT_VARIABLE cmakeOutput )
+    execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help
+      OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput)
     # check for the Eclipse generator
     if ("${cmakeOutput}" MATCHES Eclipse)
       add_test(Simple_EclipseGenerator ${CMAKE_CTEST_COMMAND}
@@ -374,6 +413,7 @@ if(BUILD_TESTING)
          "${CMake_BINARY_DIR}/Tests/Simple_EclipseGenerator"
          --build-two-config
          --build-generator "Eclipse CDT4 - Unix Makefiles"
+         --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
          --build-project Simple
          --test-command Simple)
@@ -388,6 +428,7 @@ if(BUILD_TESTING)
          "${CMake_BINARY_DIR}/Tests/Simple_CodeBlocksGenerator"
          --build-two-config
          --build-generator "CodeBlocks - Unix Makefiles"
+         --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
          --build-project Simple
          --test-command Simple)
@@ -401,6 +442,7 @@ if(BUILD_TESTING)
          "${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator"
          --build-two-config
          --build-generator "KDevelop3 - Unix Makefiles"
+         --build-generator-toolset "${CMAKE_TEST_GENERATOR_TOOLSET}"
          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
          --build-project Simple
          --test-command Simple)
@@ -419,8 +461,7 @@ if(BUILD_TESTING)
       "${CMake_SOURCE_DIR}/Tests/SubProject"
       "${CMake_BINARY_DIR}/Tests/SubProject"
       --build-project SubProject
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-target car
       --test-command car
       )
@@ -442,8 +483,7 @@ if(BUILD_TESTING)
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/SubProject${SubProject_SUBDIR}"
       "${CMake_BINARY_DIR}/Tests/SubProject${SubProject_SUBDIR}"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-nocmake
       --build-project foo
       --build-target foo
@@ -489,8 +529,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/Framework"
     "${CMake_BINARY_DIR}/Tests/Framework"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project Framework
     --build-options
     "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/Framework/Install"
@@ -502,8 +541,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/TargetName"
     "${CMake_BINARY_DIR}/Tests/TargetName"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project TargetName
     --test-command ${CMAKE_CMAKE_COMMAND} -E compare_files
     ${CMake_SOURCE_DIR}/Tests/TargetName/scripts/hello_world
@@ -515,8 +553,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/LibName"
     "${CMake_BINARY_DIR}/Tests/LibName"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project LibName
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/LibName/lib"
     --test-command foobar
@@ -528,8 +565,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/CustComDepend"
     "${CMake_BINARY_DIR}/Tests/CustComDepend"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project CustComDepend
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustComDepend/bin"
     --test-command foo bar.c
@@ -540,9 +576,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/ArgumentExpansion"
     "${CMake_BINARY_DIR}/Tests/ArgumentExpansion"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project ArgumentExpansion
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ArgumentExpansion/bin"
     )
   set_tests_properties(ArgumentExpansion PROPERTIES
@@ -553,9 +588,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/GeneratorExpression"
     "${CMake_BINARY_DIR}/Tests/GeneratorExpression"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project GeneratorExpression
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-options -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/GeneratorExpression")
@@ -565,22 +599,22 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/CustomCommand"
     "${CMake_BINARY_DIR}/Tests/CustomCommand"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project CustomCommand
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustomCommand/bin"
     --test-command CustomCommand
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand")
 
+  ADD_TEST_MACRO(EmptyDepends ${CMAKE_CTEST_COMMAND})
+
   add_test(CustomCommandWorkingDirectory  ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/CustomCommandWorkingDirectory"
     "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project TestWorkingDir
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --test-command working
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory")
@@ -589,9 +623,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
    #  --build-and-test
    #  "${CMake_SOURCE_DIR}/Tests/SimpleExclude"
    #  "${CMake_BINARY_DIR}/Tests/SimpleExclude"
-   #  --build-generator ${CMAKE_TEST_GENERATOR}
+   #  ${build_generator_args}
    #  --build-project SimpleExclude
-   #  --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
    #  --build-two-config
    #  --test-command t4
    #--test-command "${CMAKE_COMMAND}"
@@ -603,9 +636,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
 #    --build-and-test
 #    "${CMake_SOURCE_DIR}/Tests/SameName"
 #    "${CMake_BINARY_DIR}/Tests/SameName"
-#    --build-generator ${CMAKE_TEST_GENERATOR}
+#    ${build_generator_args}
 #    --build-project SameName
-#    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
 #    --build-two-config
 #    --test-command
 #    "${CMake_BINARY_DIR}/Tests/SameName/Exe1/mytest2")
@@ -614,9 +646,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/OutOfSource"
     "${CMake_BINARY_DIR}/Tests/OutOfSource"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project OutOfSource
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-two-config
     --test-command
     "${CMake_BINARY_DIR}/Tests/OutOfSource/SubDir/OutOfSourceSubdir/simple")
@@ -628,9 +659,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/BuildDepends"
     "${CMake_BINARY_DIR}/Tests/BuildDepends"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project BuildDepends
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BuildDepends")
 
@@ -640,9 +670,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/SimpleInstall"
     "${CMake_BINARY_DIR}/Tests/SimpleInstall"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project TestSimpleInstall
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-two-config
     --build-options
     "-DCMAKE_INSTALL_PREFIX:PATH=${SimpleInstallInstallDir}"
@@ -653,9 +682,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/SimpleInstallS2"
     "${CMake_BINARY_DIR}/Tests/SimpleInstallS2"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project TestSimpleInstall
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-two-config
     --build-options
     "-DCMAKE_INSTALL_PREFIX:PATH=${SimpleInstallInstallDir}"
@@ -695,6 +723,28 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     endif()
   endif()
 
+  # On Windows run the CPackWiXGenerator test
+  # if the WiX Toolset seems to be available
+  if(WIN32)
+    file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT)
+
+    find_program(WIX_LIGHT_EXECUTABLE light
+      PATHS "${WIX_ROOT}/bin"
+      DOC "WiX Toolset light.exe location")
+
+    if(WIX_LIGHT_EXECUTABLE)
+      add_test(CPackWiXGenerator ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator"
+        "${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+        ${build_generator_args}
+        --build-project CPackWiXGenerator
+        --test-command ${CMAKE_CMAKE_COMMAND}
+          "-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+          -P "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake")
+    endif()
+  endif()
+
   if(CTEST_RUN_CPackComponents)
     set(CPackComponents_EXTRA_OPTIONS)
     if(APPLE)
@@ -709,9 +759,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/CPackComponents"
       "${CMake_BINARY_DIR}/Tests/CPackComponents"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project CPackComponents
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --build-two-config
       --build-target package
       --build-options
@@ -742,7 +791,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     # ACTIVE_CPACK_GENERATORS variable
     # now contains the list of 'active generators'
     set(CPackComponentsForAll_EXTRA_OPTIONS)
-    set(CPackRun_CPackCommand "-DCPackCommand=${CMAKE_CPACK_COMMAND}")
     # set up list of CPack generators
     list(APPEND GENLST "ZIP")
     if(APPLE)
@@ -772,9 +820,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
           --build-and-test
           "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll"
           "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
-          --build-generator ${CMAKE_TEST_GENERATOR}
+          ${build_generator_args}
           --build-project CPackComponentsForAll
-          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
           --build-options
              -DCPACK_BINARY_${CPackGen}:BOOL=ON
              ${CPackRun_CPackComponentWay}
@@ -782,7 +829,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
              --graphviz=CPackComponentsForAll.dot
           --test-command ${CMAKE_CMAKE_COMMAND}
             "-DCPackComponentsForAll_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
-            "${CPackRun_CPackCommand}"
             "${CPackRun_CPackGen}"
             "${CPackRun_CPackComponentWay}"
             -P "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake")
@@ -811,13 +857,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/CPackTestAllGenerators"
       "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project CPackTestAllGenerators
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --test-command
       ${CMAKE_CMAKE_COMMAND}
         -D dir=${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators
-        -D cpack=${CMAKE_CPACK_COMMAND}
         -P ${CMake_SOURCE_DIR}/Tests/CPackTestAllGenerators/RunCPack.cmake
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators")
@@ -833,9 +877,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/X11"
     "${CMake_BINARY_DIR}/Tests/X11"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project UseX11
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-two-config
     ${X11_build_target_arg}
     --test-command  UseX11)
@@ -889,9 +932,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/LoadCommandOneConfig"
     "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project LoadCommand
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --test-command  LoadedCommand
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig")
@@ -902,9 +944,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_BINARY_DIR}/Tests/Complex"
     --build-two-config
     --build-config-sample "${CMAKE_CTEST_COMMAND}"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project Complex
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin"
     --build-options
     -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
@@ -916,9 +957,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/ComplexOneConfig"
     "${CMake_BINARY_DIR}/Tests/ComplexOneConfig"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project Complex
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin"
     --build-options
     -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
@@ -931,9 +971,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Example"
     "${CMake_BINARY_DIR}/Example"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project HELLO
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Example/Demo"
     --test-command helloDemo
     )
@@ -943,23 +982,31 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/Environment"
     "${CMake_BINARY_DIR}/Tests/Environment"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project EnvironmentProj
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
 
+  add_test(QtAutomocNoQt  ${CMAKE_CTEST_COMMAND}
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/QtAutomocNoQt"
+    "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt"
+    ${build_generator_args}
+    --build-project QtAutomocNoQt
+    --build-options -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
+    )
+  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt")
+
   if(QT4_WORKS AND QT_QTGUI_FOUND)
     add_test(QtAutomoc ${CMAKE_CTEST_COMMAND}
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
       "${CMake_BINARY_DIR}/Tests/QtAutomoc"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project QtAutomoc
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc"
       --force-new-ctest-process
       --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
@@ -967,14 +1014,27 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc")
   endif()
+  if(QT4_WORKS AND QT_QTGUI_FOUND)
+    add_test(Qt4Targets ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/Qt4Targets"
+      "${CMake_BINARY_DIR}/Tests/Qt4Targets"
+      ${build_generator_args}
+      --build-project Qt4Targets
+      --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets"
+      --force-new-ctest-process
+      --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+      --test-command ${CMAKE_CTEST_COMMAND} -V
+      )
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets")
+  endif()
 
   add_test(ExternalProject ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/ExternalProject"
     "${CMake_BINARY_DIR}/Tests/ExternalProject"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project ExternalProjectTest
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V
@@ -983,6 +1043,36 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
   set_tests_properties(ExternalProject PROPERTIES
     TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
 
+  add_test(ExternalProjectUpdateSetup ${CMAKE_CTEST_COMMAND}
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate"
+    "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate"
+    ${build_generator_args}
+    --build-project ExternalProjectUpdateTest
+    --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate"
+    --force-new-ctest-process
+    --test-command ${CMAKE_CTEST_COMMAND} -V
+    )
+  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate")
+  set_tests_properties(ExternalProjectUpdateSetup PROPERTIES
+    TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+
+  add_test(NAME ExternalProjectUpdate
+    COMMAND ${CMAKE_CMAKE_COMMAND}
+    -DExternalProjectUpdate_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate
+    -DExternalProjectUpdate_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate
+    -DCMAKE_TEST_GENERATOR=${CMAKE_TEST_GENERATOR}
+    -DCMAKE_TEST_GENERATOR_TOOLSET=${CMAKE_TEST_GENERATOR_TOOLSET}
+    -DCMAKE_TEST_MAKEPROGRAM=${CMAKE_TEST_MAKEPROGRAM}
+    -DCMAKE_CTEST_COMMAND=${CMAKE_CTEST_COMMAND}
+    -P ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
+    )
+  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate")
+  set_tests_properties(ExternalProjectUpdate PROPERTIES
+    TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT}
+    WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate
+    DEPENDS ExternalProjectUpdateSetup )
+
   # do each of the tutorial steps
   foreach(STP RANGE 1 7)
     add_test(TutorialStep${STP} ${CMAKE_CTEST_COMMAND}
@@ -990,8 +1080,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/Tutorial/Step${STP}"
       "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}"
       --build-two-config
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project Tutorial
       --test-command Tutorial 25.0)
   endforeach()
@@ -1001,9 +1090,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/Testing"
     "${CMake_BINARY_DIR}/Tests/Testing"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project Testing
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
     )
   set_tests_properties(testing PROPERTIES PASS_REGULAR_EXPRESSION "Passed")
@@ -1013,9 +1101,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/Wrapping"
     "${CMake_BINARY_DIR}/Tests/Wrapping"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project Wrapping
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --test-command wrapping
     )
@@ -1023,9 +1110,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/Wrapping"
     "${CMake_BINARY_DIR}/Tests/Wrapping"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project Wrapping
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
       --test-command qtwrapping
       )
@@ -1035,8 +1121,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/TestDriver"
     "${CMake_BINARY_DIR}/Tests/TestDriver"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
     --test-command TestDriverTest test1
@@ -1046,8 +1131,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/TestDriver"
     "${CMake_BINARY_DIR}/Tests/TestDriver"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
     --test-command TestDriverTest test2
@@ -1057,8 +1141,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/TestDriver"
     "${CMake_BINARY_DIR}/Tests/TestDriver"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
     --test-command TestDriverTest subdir/test3
@@ -1070,8 +1153,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/Dependency"
     "${CMake_BINARY_DIR}/Tests/Dependency"
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/Exec"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project Dependency
     --test-command exec
     )
@@ -1101,8 +1183,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut"
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Executable"
       --build-project Jump
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-options
       -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Lib
       --test-command jumpExecutable
@@ -1115,8 +1196,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
       --build-run-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
       --build-project Jump
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --test-command jumpExecutable
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Jump")
@@ -1125,9 +1205,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/Plugin"
       "${CMake_BINARY_DIR}/Tests/Plugin"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project Plugin
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --build-two-config
       --test-command bin/example)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Plugin")
@@ -1141,8 +1220,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
     "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project LinkLineOrder
     --test-command Exec1
     )
@@ -1151,8 +1229,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
     "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-project LinkLineOrder
     --test-command Exec2
     )
@@ -1172,8 +1249,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/LinkStatic"
       "${CMake_BINARY_DIR}/Tests/LinkStatic"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project LinkStatic
       --build-options -DMATH_LIBRARY:FILEPATH=/usr/lib/libm.a
       --test-command LinkStatic
@@ -1185,39 +1261,21 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Source/kwsys"
       "${CMake_BINARY_DIR}/Tests/kwsys"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project kwsys
       --test-command kwsysTestsCxx testIOS
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/kwsys")
   endif()
-  set(MAKE_IS_GNU )
-  if(${CMAKE_TEST_MAKEPROGRAM} MATCHES make)
-    exec_program(
-      ${CMAKE_TEST_MAKEPROGRAM} ARGS no_such_target --version
-      RETURN_VALUE res OUTPUT_VARIABLE out
-      )
-    if("${res}" EQUAL 0)
-      if("${out}" MATCHES "GNU")
-        set(MAKE_IS_GNU 1)
-      endif()
-    endif()
-  endif()
 
-  # only add this test on platforms that support it
-  # some old versions of make simply cannot handle spaces in paths
-  if (MAKE_IS_GNU OR
-      "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR
-      "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland")
+  if(MAKE_SUPPORTS_SPACES)
     add_test(SubDirSpaces ${CMAKE_CTEST_COMMAND}
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/SubDirSpaces"
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces"
       --build-exe-dir
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces/Executable Sources"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project SUBDIR
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces/ShouldBeHere"
@@ -1232,8 +1290,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/SubDir"
       "${CMake_BINARY_DIR}/Tests/SubDir"
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project SUBDIR
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
@@ -1245,8 +1302,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/SubDir"
       "${CMake_BINARY_DIR}/Tests/SubDir"
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project SUBDIR
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
@@ -1272,9 +1328,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/MakeClean"
       "${CMake_BINARY_DIR}/Tests/MakeClean"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project MakeClean
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --build-exe-dir "${CMake_BINARY_DIR}/MakeClean"
       --test-command check_clean
       )
@@ -1378,9 +1433,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/MFC"
       "${CMake_BINARY_DIR}/Tests/MFC"
       --build-two-config
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project mfc_driver
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --test-command ${CMAKE_CTEST_COMMAND}
         -C \${CTEST_CONFIGURATION_TYPE} -VV)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MFC")
@@ -1396,9 +1450,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/VSExternalInclude"
       "${CMake_BINARY_DIR}/Tests/VSExternalInclude"
       --build-two-config
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project VSExternalInclude
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --test-command VSExternalInclude)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExternalInclude")
 
@@ -1407,11 +1460,38 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/VSMidl"
       "${CMake_BINARY_DIR}/Tests/VSMidl"
       --build-two-config
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project VSMidl
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --test-command VSMidl)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
+
+    if(NOT MSVC60 AND NOT CMAKE_TEST_MAKEPROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
+      # The test (and tested property) works with .sln files, so it's skipped when:
+      # * Using VS6, which doesn't use .sln files
+      # * cmake --build is set up to use MSBuild, since the MSBuild invocation does not use the .sln file
+      set(_last_test "")
+      foreach(config ${CMAKE_CONFIGURATION_TYPES})
+        add_test(NAME VSExcludeFromDefaultBuild-${config} COMMAND ${CMAKE_CTEST_COMMAND}
+          --build-and-test
+          "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild"
+          "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild"
+          --build-config ${config}
+          --build-two-config
+          ${build_generator_args}
+          --build-project VSExcludeFromDefaultBuild
+          --test-command ${CMAKE_COMMAND}
+             -D "activeConfig=${config}"
+             -D "allConfigs=${CMAKE_CONFIGURATION_TYPES}"
+             -D "dir=${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild"
+             -P "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake")
+        if(_last_test)
+          set_property(TEST VSExcludeFromDefaultBuild-${config} PROPERTY DEPENDS ${_last_test})
+        endif()
+        set(_last_test "VSExcludeFromDefaultBuild-${config}")
+      endforeach()
+      unset(_last_test)
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild")
+    endif()
   endif()
 
   if (APPLE)
@@ -1423,8 +1503,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
         "${CMake_SOURCE_DIR}/Tests/BundleTest"
         "${CMake_BINARY_DIR}/Tests/BundleTest"
         --build-two-config
-        --build-generator ${CMAKE_TEST_GENERATOR}
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+        ${build_generator_args}
         --build-project BundleTest
         --build-target install
 #       --build-target package
@@ -1439,8 +1518,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
         "${CMake_SOURCE_DIR}/Tests/CFBundleTest"
         "${CMake_BINARY_DIR}/Tests/CFBundleTest"
         --build-two-config
-        --build-generator ${CMAKE_TEST_GENERATOR}
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+        ${build_generator_args}
         --build-project CFBundleTest
         --test-command
         ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE}
@@ -1459,8 +1537,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       "${CMake_SOURCE_DIR}/Tests/BundleGeneratorTest"
       "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest"
       --build-two-config
-      --build-generator ${CMAKE_TEST_GENERATOR}
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      ${build_generator_args}
       --build-project BundleGeneratorTest
       --build-target package
       --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/BundleGeneratorTest/InstallDirectory"
@@ -1472,8 +1549,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaSet"
     "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedUnusedViaSet
     --build-options "--warn-unused-vars")
@@ -1487,8 +1563,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaUnset"
     "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedUnusedViaUnset
     --build-options "--warn-unused-vars")
@@ -1502,8 +1577,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/VariableUsage"
     "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedCliUnused
     --build-options "-DUNUSED_CLI_VARIABLE=Unused")
@@ -1515,8 +1589,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/VariableUsage"
     "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUsed"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedCliUsed
     --build-options "-DUSED_VARIABLE=Usage proven")
@@ -1530,8 +1603,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/VariableUsage"
     "${CMake_BINARY_DIR}/Tests/WarnUninitialized"
-    --build-generator ${CMAKE_TEST_GENERATOR}
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+    ${build_generator_args}
     --build-noclean
     --build-project WarnUninitialized
     --build-options "--warn-uninitialized")
@@ -1543,9 +1615,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/TestsWorkingDirectory"
     "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project TestsWorkingDirectoryProj
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
     --force-new-ctest-process
     --test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE}
@@ -1834,6 +1905,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     )
 
   ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries)
+  ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories)
+  ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions)
 
   configure_file(
     "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
@@ -1878,6 +1951,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     --output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log"
     )
 
+  set(CTestLimitDashJ_EXTRA_OPTIONS --force-new-ctest-process)
+  add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4
+    --output-on-failure -C "\${CTestTest_CONFIG}")
+
   add_test(CTestTestPrintLabels ${CMAKE_CTEST_COMMAND} --print-labels)
   set_tests_properties(CTestTestPrintLabels PROPERTIES LABELS "Label1;Label2")
   set_tests_properties(CTestTestPrintLabels PROPERTIES PASS_REGULAR_EXPRESSION
@@ -2157,9 +2234,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-and-test
       "${CMake_SOURCE_DIR}/Tests/Fortran"
       "${CMake_BINARY_DIR}/Tests/Fortran"
-      --build-generator ${CMAKE_TEST_GENERATOR}
+      ${build_generator_args}
       --build-project testf
-      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --build-two-config
       --test-command testf)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Fortran")
@@ -2176,9 +2252,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
         --build-and-test
         "${CMake_SOURCE_DIR}/Tests/FortranC"
         "${CMake_BINARY_DIR}/Tests/FortranC"
-        --build-generator ${CMAKE_TEST_GENERATOR}
+        ${build_generator_args}
         --build-project FortranC
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
         --build-two-config
         --test-command CMakeFiles/FortranCInterface/FortranCInterface)
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/FortranC")
@@ -2199,9 +2274,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
           --build-and-test
           "${CMake_SOURCE_DIR}/Tests/Java"
           "${CMake_BINARY_DIR}/Tests/Java"
-          --build-generator ${CMAKE_TEST_GENERATOR}
+          ${build_generator_args}
           --build-project hello
-          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
           --build-two-config
           --build-run-dir "${CMake_BINARY_DIR}/Tests/Java/"
           --test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld)
@@ -2221,9 +2295,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
         --build-and-test
         "${CMake_SOURCE_DIR}/Tests/SimpleCOnly"
         "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc"
-        --build-generator ${CMAKE_TEST_GENERATOR}
+        ${build_generator_args}
         --build-project SimpleC
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
         --build-options
         "-DCMAKE_SYSTEM_NAME=Generic"
         "-DCMAKE_C_COMPILER=${SDCC_EXECUTABLE}")
@@ -2240,9 +2313,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
         --build-and-test
         "${CMake_SOURCE_DIR}/Tests/Simple"
         "${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win"
-        --build-generator ${CMAKE_TEST_GENERATOR}
+        ${build_generator_args}
         --build-project Simple
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
         --build-options
         "-DCMAKE_SYSTEM_NAME=Windows"
         "-DCMAKE_C_COMPILER=${MINGW_CC_LINUX2WIN_EXECUTABLE}"
@@ -2339,7 +2411,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
 
   if(TEST_CompileCommandOutput)
     set(CompileCommandOutput_EXTRA_OPTIONS
-      --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU})
+      --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES})
     ADD_TEST_MACRO(CompileCommandOutput
       "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands")
   endif()
@@ -2349,9 +2421,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     "${CMake_SOURCE_DIR}/Tests/IncludeDirectories"
     "${CMake_BINARY_DIR}/Tests/IncludeDirectories"
     --build-two-config
-    --build-generator ${CMAKE_TEST_GENERATOR}
+    ${build_generator_args}
     --build-project IncludeDirectories
-    --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
     --test-command IncludeDirectories)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
 
@@ -2368,6 +2439,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     set_tests_properties(KWStyle PROPERTIES
       WORKING_DIRECTORY ${CMake_BINARY_DIR}/Utilities/KWStyle)
   endif()
-endif()
 
-subdirs(CMakeTests)
+  add_subdirectory(CMakeTests)
+endif()
index 212c758..739593c 100644 (file)
@@ -70,8 +70,9 @@ endmacro()
 # If any of these modules reported that it was found a version number should have been
 # reported.
 
-foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG HSPELL
-        JASPER LIBLZMA LIBXML2 LIBXSLT PERL PKG_CONFIG PostgreSQL TIFF ZLIB)
+foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG
+        HSPELL ICOTOOL JASPER LIBLZMA LIBXML2 LIBXSLT PERL PKG_CONFIG
+        PostgreSQL TIFF ZLIB)
     check_version_string(${VTEST} ${VTEST}_VERSION_STRING)
 endforeach()
 
index 51a630f..be7ddbc 100644 (file)
@@ -32,9 +32,29 @@ add_CMakeOnly_test(SelectLibraryConfigurations)
 add_CMakeOnly_test(TargetScope)
 
 add_CMakeOnly_test(find_library)
+add_CMakeOnly_test(find_path)
 
 add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND}
   -DTEST=ProjectInclude
   -DCMAKE_ARGS=-DCMAKE_PROJECT_ProjectInclude_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectInclude/include.cmake
   -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
   )
+
+include(${CMAKE_SOURCE_DIR}/Modules/CMakeParseArguments.cmake)
+
+function(add_major_test module)
+  cmake_parse_arguments(MAJOR_TEST "NOLANG" "VERSION_VAR" "VERSIONS" ${ARGN})
+  foreach (_version IN LISTS MAJOR_TEST_VERSIONS)
+    add_test(CMakeOnly.MajorVersionSelection-${module}_${_version}
+      ${CMAKE_CMAKE_COMMAND}
+        -DTEST=MajorVersionSelection-${module}_${_version}
+        -DTEST_SOURCE=MajorVersionSelection
+        "-DCMAKE_ARGS=-DMAJOR_TEST_MODULE=${module};-DMAJOR_TEST_VERSION=${_version};-DMAJOR_TEST_NO_LANGUAGES=${MAJOR_TEST_NOLANG};-DMAJOR_TEST_VERSION_VAR=${MAJOR_TEST_VERSION_VAR}"
+        -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
+      )
+  endforeach ()
+endfunction()
+
+add_major_test(PythonLibs VERSIONS 2 3 VERSION_VAR PYTHONLIBS_VERSION_STRING)
+add_major_test(PythonInterp NOLANG VERSIONS 2 3 VERSION_VAR PYTHON_VERSION_STRING)
+add_major_test(Qt VERSIONS 3 4 VERSION_VAR QT_VERSION_STRING)
diff --git a/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt b/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt
new file mode 100644 (file)
index 0000000..74f5451
--- /dev/null
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 2.8)
+
+if (NOT MAJOR_TEST_MODULE OR NOT MAJOR_TEST_VERSION)
+  message(FATAL_ERROR "test selection variables not set up")
+endif ()
+
+if (MAJOR_TEST_NO_LANGUAGES)
+  project(major_detect_${MAJOR_TEST_MODULE}_${MAJOR_TEST_VERSION} NONE)
+else ()
+  project(major_detect_${MAJOR_TEST_MODULE}_${MAJOR_TEST_VERSION})
+endif ()
+
+find_package(${MAJOR_TEST_MODULE} ${MAJOR_TEST_VERSION})
+
+if (MAJOR_TEST_VERSION_VAR)
+  set(VERSION_VAR "${MAJOR_TEST_VERSION_VAR}")
+else ()
+  set(VERSION_VAR "${MAJOR_TEST_MODULE}_VERSION_STRING")
+endif ()
+
+string(TOUPPER "${MAJOR_TEST_MODULE}" MODULE_UPPER)
+
+if ( ( ${MAJOR_TEST_MODULE}_FOUND OR ${MODULE_UPPER}_FOUND ) AND "${VERSION_VAR}")
+  message(STATUS "${VERSION_VAR} is '${${VERSION_VAR}}'")
+  if ("${VERSION_VAR}" VERSION_LESS MAJOR_TEST_VERSION)
+    message(SEND_ERROR "Found version ${${VERSION_VAR}} is less than requested major version ${MAJOR_TEST_VERSION}")
+  endif ()
+  math(EXPR V_PLUS_ONE "${MAJOR_TEST_VERSION} + 1")
+  if ("${VERSION_VAR}" VERSION_GREATER V_PLUS_ONE)
+    message(SEND_ERROR "Found version ${${VERSION_VAR}} is greater than requested major version ${MAJOR_TEST_VERSION}")
+  endif ()
+endif ()
+
+if ( ( ${MAJOR_TEST_MODULE}_FOUND OR ${MODULE_UPPER}_FOUND ) AND ${MAJOR_TEST_MODULE}_VERSION_MAJOR)
+  message(STATUS "${MAJOR_TEST_MODULE}_VERSION_MAJOR is '${${MAJOR_TEST_MODULE}_VERSION_MAJOR}'")
+  if (NOT ${MAJOR_TEST_VERSION} EQUAL ${MAJOR_TEST_MODULE}_VERSION_MAJOR)
+    message(SEND_ERROR "We requested major version ${MAJOR_TEST_VERSION} but ${MAJOR_TEST_MODULE} set ${MAJOR_TEST_MODULE}_VERSION_MAJOR to ${${MAJOR_TEST_MODULE}_VERSION_MAJOR}")
+  endif ()
+endif ()
+
+if ( ( ${MAJOR_TEST_MODULE}_FOUND OR ${MODULE_UPPER}_FOUND ) AND ${MODULE_UPPER}_VERSION_MAJOR)
+  message(STATUS "${MODULE_UPPER}_VERSION_MAJOR is '${${MODULE_UPPER}_VERSION_MAJOR}'")
+  if (NOT ${MAJOR_TEST_VERSION} EQUAL ${MODULE_UPPER}_VERSION_MAJOR)
+    message(SEND_ERROR "We requested major version ${MAJOR_TEST_VERSION} but ${MAJOR_TEST_MODULE} set ${MODULE_UPPER}_VERSION_MAJOR to ${${MODULE_UPPER}_VERSION_MAJOR}")
+  endif ()
+endif ()
index 42af068..a266415 100644 (file)
@@ -1,10 +1,15 @@
-set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST}")
+if (NOT TEST_SOURCE)
+  set(TEST_SOURCE "${TEST}")
+endif ()
+
+set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST_SOURCE}")
 set(binary_dir "@CMAKE_CURRENT_BINARY_DIR@/${TEST}-build")
 file(REMOVE_RECURSE "${binary_dir}")
 file(MAKE_DIRECTORY "${binary_dir}")
 execute_process(
   COMMAND  ${CMAKE_COMMAND} ${CMAKE_ARGS}
   "${source_dir}" -G "@CMAKE_TEST_GENERATOR@"
+  -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
   WORKING_DIRECTORY "${binary_dir}"
   RESULT_VARIABLE result
   )
diff --git a/Tests/CMakeOnly/find_library/A/libtestA.a b/Tests/CMakeOnly/find_library/A/libtestA.a
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/CMakeOnly/find_library/B/libtestB.a b/Tests/CMakeOnly/find_library/B/libtestB.a
new file mode 100644 (file)
index 0000000..e69de29
index 08f9331..2d4ecaf 100644 (file)
@@ -3,34 +3,34 @@ project(FindLibraryTest NONE)
 
 set(CMAKE_FIND_DEBUG_MODE 1)
 
-macro(test_find_library expected)
-  get_filename_component(dir ${expected} PATH)
-  get_filename_component(name ${expected} NAME)
-  string(REGEX REPLACE "lib/?64" "lib" dir "${dir}")
+macro(test_find_library desc expected)
   unset(LIB CACHE)
-  find_library(LIB
-    NAMES ${name}
-    PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${dir}
-    NO_DEFAULT_PATH
-    )
+  find_library(LIB ${ARGN} NO_DEFAULT_PATH)
   if(LIB)
     # Convert to relative path for comparison to expected location.
     file(RELATIVE_PATH REL_LIB "${CMAKE_CURRENT_SOURCE_DIR}" "${LIB}")
 
-    # Debugging output.
-    if(CMAKE_FIND_DEBUG_MODE)
-      message(STATUS "Library ${expected} searched as ${dir}, found as [${REL_LIB}].")
-    endif()
-
     # Check and report failure.
     if(NOT "${REL_LIB}" STREQUAL "${expected}")
-      message(SEND_ERROR "Library ${l} should have been [${expected}] but was [${REL_LIB}]")
+      message(SEND_ERROR "Library ${expected} found as [${REL_LIB}]${desc}")
+    elseif(CMAKE_FIND_DEBUG_MODE)
+      message(STATUS "Library ${expected} found as [${REL_LIB}]${desc}")
     endif()
   else()
-    message(SEND_ERROR "Library ${expected} searched as ${dir}, NOT FOUND!")
+    message(SEND_ERROR "Library ${expected} NOT FOUND${desc}")
   endif()
 endmacro()
 
+macro(test_find_library_subst expected)
+  get_filename_component(dir ${expected} PATH)
+  get_filename_component(name ${expected} NAME)
+  string(REGEX REPLACE "lib/?64" "lib" dir "${dir}")
+  test_find_library(", searched as ${dir}" "${expected}"
+    NAMES ${name}
+    PATHS ${CMAKE_CURRENT_SOURCE_DIR}/${dir}
+    )
+endmacro()
+
 set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
 set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
@@ -44,7 +44,7 @@ foreach(lib
     lib/libtest3.a
     lib/libtest3.a
     )
-  test_find_library(${lib})
+  test_find_library_subst(${lib})
 endforeach()
 
 set(CMAKE_SIZEOF_VOID_P 8)
@@ -57,5 +57,18 @@ foreach(lib64
     lib64/A/libtest1.a
     lib64/libtest1.a
     )
-  test_find_library(${lib64})
+  test_find_library_subst(${lib64})
 endforeach()
+
+test_find_library("" A/libtestA.a
+  NAMES testA testB
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  )
+test_find_library("" B/libtestB.a
+  NAMES testB testA
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  )
+test_find_library("" A/libtestA.a
+  NAMES testB testA NAMES_PER_DIR
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A ${CMAKE_CURRENT_SOURCE_DIR}/B
+  )
diff --git a/Tests/CMakeOnly/find_path/CMakeLists.txt b/Tests/CMakeOnly/find_path/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0e64ed4
--- /dev/null
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 2.8)
+project(FindPathTest NONE)
+
+set(CMAKE_FIND_DEBUG_MODE 1)
+
+macro(test_find_path expected)
+  unset(HDR CACHE)
+  find_path(HDR ${ARGN}
+    NO_CMAKE_ENVIRONMENT_PATH
+    NO_SYSTEM_ENVIRONMENT_PATH
+    )
+  if(HDR)
+    # Convert to relative path for comparison to expected location.
+    file(RELATIVE_PATH REL_HDR "${CMAKE_CURRENT_SOURCE_DIR}" "${HDR}")
+
+    # Check and report failure.
+    if(NOT "${REL_HDR}" STREQUAL "${expected}")
+      message(SEND_ERROR "Header ${expected} found as [${REL_HDR}]")
+    elseif(CMAKE_FIND_DEBUG_MODE)
+      message(STATUS "Header ${expected} found as [${REL_HDR}]")
+    endif()
+  else()
+    message(SEND_ERROR "Header ${expected} NOT FOUND")
+  endif()
+endmacro()
+
+set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+set(CMAKE_LIBRARY_ARCHITECTURE arch)
+
+test_find_path(include NAMES test1.h)
+test_find_path(include/arch NAMES test1arch.h)
diff --git a/Tests/CMakeOnly/find_path/include/arch/test1arch.h b/Tests/CMakeOnly/find_path/include/arch/test1arch.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/CMakeOnly/find_path/include/test1.h b/Tests/CMakeOnly/find_path/include/test1.h
new file mode 100644 (file)
index 0000000..e69de29
index d34d4a6..b049995 100644 (file)
@@ -4,7 +4,8 @@ set(CMAKE_EXECUTABLE "${CMake_BIN_DIR}/cmake")
 macro(AddCMakeTest TestName PreArgs)
   configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TestName}Test.cmake.in"
     "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY IMMEDIATE)
-  add_test(CMake.${TestName} ${CMAKE_EXECUTABLE} ${PreArgs}
+  add_test(NAME CMake.${TestName}
+    COMMAND ${CMAKE_EXECUTABLE} ${PreArgs}
     -P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
 endmacro()
 
@@ -28,7 +29,7 @@ AddCMakeTest(String "")
 AddCMakeTest(Math "")
 AddCMakeTest(CMakeMinimumRequired "")
 AddCMakeTest(CompilerIdVendor "")
-AddCMakeTest(ProcessorCount "")
+AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
 AddCMakeTest(PushCheckState "")
 AddCMakeTest(While "")
 
index db92905..7be7b30 100644 (file)
@@ -1,30 +1,35 @@
 get_filename_component(CMakeTests_SRC_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+function(check_cmake_test_single prefix test testfile)
+  message(STATUS "Test ${prefix}-${test}...")
+  execute_process(
+    COMMAND ${CMAKE_COMMAND} -P "${testfile}"
+    WORKING_DIRECTORY "${CMakeTests_BIN_DIR}"
+    OUTPUT_VARIABLE stdout
+    ERROR_VARIABLE stderr
+    RESULT_VARIABLE result
+    )
+  string(REGEX REPLACE "\n" "\n out> " out " out> ${stdout}")
+  string(REGEX REPLACE "\n" "\n err> " err " err> ${stderr}")
+  if(NOT "${result}" STREQUAL "${${test}-RESULT}")
+    message(FATAL_ERROR
+      "Test ${test} result is [${result}], not [${${test}-RESULT}].\n"
+      "Test ${test} output:\n"
+      "${out}\n"
+      "${err}")
+  endif()
+  if(${test}-STDERR AND NOT "${err}" MATCHES "${${test}-STDERR}")
+    message(FATAL_ERROR
+      "Test ${test} stderr does not match\n  ${${test}-STDERR}\n"
+      "Test ${test} output:\n"
+      "${out}\n"
+      "${err}")
+  endif()
+endfunction()
+
 function(check_cmake_test prefix)
   get_filename_component(CMakeTests_BIN_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
   foreach(test ${ARGN})
-    message(STATUS "Test ${prefix}-${test}...")
-    execute_process(
-      COMMAND ${CMAKE_COMMAND} -P "${CMakeTests_SRC_DIR}/${prefix}-${test}.cmake"
-      WORKING_DIRECTORY "${CMakeTests_BIN_DIR}"
-      OUTPUT_VARIABLE stdout
-      ERROR_VARIABLE stderr
-      RESULT_VARIABLE result
-      )
-    string(REGEX REPLACE "\n" "\n out> " out " out> ${stdout}")
-    string(REGEX REPLACE "\n" "\n err> " err " err> ${stderr}")
-    if(NOT "${result}" STREQUAL "${${test}-RESULT}")
-      message(FATAL_ERROR
-        "Test ${test} result is [${result}], not [${${test}-RESULT}].\n"
-        "Test ${test} output:\n"
-        "${out}\n"
-        "${err}")
-    endif()
-    if(${test}-STDERR AND NOT "${err}" MATCHES "${${test}-STDERR}")
-      message(FATAL_ERROR
-        "Test ${test} stderr does not match\n  ${${test}-STDERR}\n"
-        "Test ${test} output:\n"
-        "${out}\n"
-        "${err}")
-    endif()
+    check_cmake_test_single("${prefix}" "${test}" "${CMakeTests_SRC_DIR}/${prefix}-${test}.cmake")
   endforeach()
 endfunction()
diff --git a/Tests/CMakeTests/File-Glob-NoArg.cmake b/Tests/CMakeTests/File-Glob-NoArg.cmake
new file mode 100644 (file)
index 0000000..486f366
--- /dev/null
@@ -0,0 +1,2 @@
+# Checking that the call without arguments get caught by the file global protection.
+file(GLOB)
diff --git a/Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake b/Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake
new file mode 100644 (file)
index 0000000..cc15c77
--- /dev/null
@@ -0,0 +1 @@
+file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")
diff --git a/Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake b/Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake
new file mode 100644 (file)
index 0000000..62390e7
--- /dev/null
@@ -0,0 +1,2 @@
+file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/DoesNotExist.cmake" output)
+message("~${output}~")
diff --git a/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake b/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake
new file mode 100644 (file)
index 0000000..d0e5fe3
--- /dev/null
@@ -0,0 +1,24 @@
+set(STAMP_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/FileTimestamp-Stamp")
+set(STAMP_FORMAT "%Y-%m-%d")
+
+string(TIMESTAMP timestamp1 "${STAMP_FORMAT}")
+
+file(WRITE "${STAMP_FILENAME}" "foo")
+file(TIMESTAMP "${STAMP_FILENAME}" timestamp2 "${STAMP_FORMAT}")
+
+string(TIMESTAMP timestamp3 "${STAMP_FORMAT}")
+
+message(STATUS "timestamp1 [${timestamp1}]")
+message(STATUS "timestamp2 [${timestamp2}]")
+message(STATUS "timestamp3 [${timestamp3}]")
+
+if(timestamp1 STREQUAL timestamp3)
+  if(NOT timestamp1 STREQUAL timestamp2)
+    message(FATAL_ERROR
+      "timestamp mismatch [${timestamp1}] != [${timestamp2}]")
+  else()
+    message("all timestamps match")
+  endif()
+else()
+  message(WARNING "this test may race when run at midnight")
+endif()
diff --git a/Tests/CMakeTests/File-TIMESTAMP-Works.cmake b/Tests/CMakeTests/File-TIMESTAMP-Works.cmake
new file mode 100644 (file)
index 0000000..4351b19
--- /dev/null
@@ -0,0 +1,2 @@
+file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" output UTC)
+message("~${output}~")
index 3c3d85d..61523e6 100644 (file)
@@ -12,6 +12,10 @@ set(Copy-NoDest-RESULT 1)
 set(Copy-NoDest-STDERR "given no DESTINATION")
 set(Copy-NoFile-RESULT 1)
 set(Copy-NoFile-STDERR "COPY cannot find.*/does_not_exist\\.txt")
+set(Glob-NoArg-RESULT 1)
+set(Glob-NoArg-STDERR "file must be called with at least two arguments")
+set(Make_Directory-NoArg-RESULT 1)
+set(Make-Directory-NoArg-STDERR "file must be called with at least two arguments")
 set(MD5-NoFile-RESULT 1)
 set(MD5-NoFile-STDERR "file MD5 failed to read file")
 set(MD5-BadArg1-RESULT 1)
@@ -32,6 +36,14 @@ set(SHA384-Works-RESULT 0)
 set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee")
 set(SHA512-Works-RESULT 0)
 set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51")
+set(TIMESTAMP-NoFile-RESULT 0)
+set(TIMESTAMP-NoFile-STDERR "~~")
+set(TIMESTAMP-BadArg1-RESULT 1)
+set(TIMESTAMP-BadArg1-STDERR "file sub-command TIMESTAMP requires at least two arguments")
+set(TIMESTAMP-NotBogus-RESULT 0)
+set(TIMESTAMP-NotBogus-STDERR "all timestamps match")
+set(TIMESTAMP-Works-RESULT 0)
+set(TIMESTAMP-Works-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]Z~")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(File
@@ -42,6 +54,8 @@ check_cmake_test(File
   Copy-LateArg
   Copy-NoDest
   Copy-NoFile
+  Glob-NoArg
+  Make_Directory-NoArg
   MD5-NoFile
   MD5-BadArg1
   MD5-BadArg2
@@ -52,8 +66,17 @@ check_cmake_test(File
   SHA256-Works
   SHA384-Works
   SHA512-Works
+  TIMESTAMP-NoFile
+  TIMESTAMP-BadArg1
+  TIMESTAMP-NotBogus
+  TIMESTAMP-Works
   )
 
+file(GLOB hum)
+if (NOT hum STREQUAL "")
+  message(FATAL_ERROR "file(GLOB hum) did not return an empty string.")
+endif()
+
 # Also execute each test listed in FileTestScript.cmake:
 #
 set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/FileTestScript.cmake")
diff --git a/Tests/CMakeTests/GetProperty-Doc-Properties.cmake b/Tests/CMakeTests/GetProperty-Doc-Properties.cmake
deleted file mode 100644 (file)
index 6c2c362..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS)
-get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS)
-
-if (NOT FOO_BRIEF STREQUAL "NOTFOUND")
-  message(SEND_ERROR "property FOO has BRIEF_DOCS set to '${FOO_BRIEF}'")
-endif ()
-
-if (NOT FOO_FULL STREQUAL "NOTFOUND")
-  message(SEND_ERROR "property FOO has FULL_DOCS set to '${FOO_FULL}'")
-endif ()
index ab96e5b..a858418 100644 (file)
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 
+get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS)
+get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS)
+
+if (NOT FOO_BRIEF STREQUAL "NOTFOUND")
+  message(SEND_ERROR "property FOO has BRIEF_DOCS set to '${FOO_BRIEF}'")
+endif ()
+
+if (NOT FOO_FULL STREQUAL "NOTFOUND")
+  message(SEND_ERROR "property FOO has FULL_DOCS set to '${FOO_FULL}'")
+endif ()
+
+get_property(test_brief GLOBAL PROPERTY ENABLED_FEATURES BRIEF_DOCS)
+get_property(test_full GLOBAL PROPERTY ENABLED_FEATURES FULL_DOCS)
+
+if(test_brief STREQUAL "NOTFOUND")
+  message(SEND_ERROR "property ENABLED_FEATURES has no BRIEF_DOCS")
+endif()
+
+if(test_full STREQUAL "NOTFOUND")
+  message(SEND_ERROR "property ENABLED_FEATURES has no FULL_DOCS")
+endif()
+
+set(test_var alpha)
+get_property(result VARIABLE PROPERTY test_var)
+if(NOT result STREQUAL "alpha")
+  message(SEND_ERROR "bad value of VARIABLE PROPERTY test_var: got '${result}' instead of 'alpha'")
+endif()
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
+REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
 set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*")
+set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*")
 
 check_cmake_test(GetProperty
   Missing-Argument
 )
 
 set(Bad-Scope-RESULT 1)
-set(Bad-Scope-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*")
+set(Bad-Scope-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*")
 
 check_cmake_test(GetProperty
   Bad-Scope
 )
 
 set(Bad-Argument-RESULT 1)
-set(Bad-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*")
+set(Bad-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*")
 
 check_cmake_test(GetProperty
   Bad-Argument
 )
 
 set(No-Property-RESULT 1)
-set(No-Property-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*")
+set(No-Property-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*")
 
 check_cmake_test(GetProperty
   No-Property
 )
 
-set(Doc-Properties-RESULT 0)
-
-check_cmake_test(GetProperty
-  Doc-Properties
-)
-
 set(Global-Name-RESULT 1)
-set(Global-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*")
+set(Global-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*")
 
 check_cmake_test(GetProperty
   Global-Name
 )
 
 set(Bad-Directory-RESULT 1)
-set(Bad-Directory-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*")
+set(Bad-Directory-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*")
 
 check_cmake_test(GetProperty
   Bad-Directory
 )
 
 set(No-Target-RESULT 1)
-set(No-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*")
+set(No-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*")
 
 check_cmake_test(GetProperty
   No-Target
 )
 
 set(Bad-Target-RESULT 1)
-set(Bad-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*")
+set(Bad-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*")
 
 check_cmake_test(GetProperty
   Bad-Target
 )
 
 set(No-Source-RESULT 1)
-set(No-Source-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*")
+set(No-Source-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*")
 
 check_cmake_test(GetProperty
   No-Source
 )
 
 set(No-Test-RESULT 1)
-set(No-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*")
+set(No-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*")
 
 check_cmake_test(GetProperty
   No-Test
 )
 
 set(Bad-Test-RESULT 1)
-set(Bad-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*")
+set(Bad-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*")
 
 check_cmake_test(GetProperty
   Bad-Test
 )
 
 set(Variable-Name-RESULT 1)
-set(Variable-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*")
+set(Variable-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*")
 
 check_cmake_test(GetProperty
   Variable-Name
 )
 
 set(No-Cache-RESULT 1)
-set(No-Cache-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*")
+set(No-Cache-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*")
 
 check_cmake_test(GetProperty
   No-Cache
index 639e226..74b8e32 100644 (file)
@@ -7,6 +7,9 @@ foreach(_arg "" 0 1 2 ${TRUE_NAMES} ${FALSE_NAMES})
   set(VAR_${_arg} "${_arg}")
 endforeach()
 
+include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
+REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
 macro(test_vars _old)
   # Variables set to false or not set.
   foreach(_var "" 0 ${FALSE_NAMES} UNDEFINED)
@@ -158,7 +161,7 @@ endforeach()
 test_vars("")
 
 set(Invalid-Argument-RESULT 1)
-set(Invalid-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*")
+set(Invalid-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(If
index dbe9500..e28d102 100644 (file)
@@ -99,33 +99,141 @@ set(linux64_test1_libs "${linux64_gcc_libs}")
 set(linux64_test1_dirs "${linux64_gcc_dirs}")
 list(APPEND platforms linux64_test1)
 
+# sunCC dummy.cxx -v # extra slashes
+set(linux64_test2_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/sun/sunstudio12/prod/lib/amd64//crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xa.o dummy.o -Y \"/opt/sun/sunstudio12/prod/lib//amd64:/lib64:/usr//lib64\" -Qy -lc /opt/sun/sunstudio12/prod/lib/amd64//libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
+set(linux64_test2_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
+set(linux64_test2_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
+list(APPEND platforms linux64_test2)
+
 #-----------------------------------------------------------------------------
 # Mac
 
+# gcc -arch i686 dummy.c -v -Wl,-v
+set(mac_i686_gcc_Wlv_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem
+collect2 version 4.2.1 (Apple Inc. build 5646) (i686 Darwin)
+/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccSiuUhD.o -v -lSystem -lgcc -lSystem
+@(#)PROGRAM:ld  PROJECT:ld64-95.2.12
+Library search paths:
+       /usr/lib/i686-apple-darwin10/4.2.1
+       /usr/lib/gcc/i686-apple-darwin10/4.2.1
+       /usr/lib/gcc/i686-apple-darwin10/4.2.1
+       /usr/lib/i686-apple-darwin10/4.2.1
+       /usr/lib
+       /usr/lib
+       /usr/local/lib
+Framework search paths:
+       /Library/Frameworks/
+       /System/Library/Frameworks/")
+set(mac_i686_gcc_Wlv_libs "")
+set(mac_i686_gcc_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
+set(mac_i686_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
+list(APPEND platforms mac_i686_gcc_Wlv)
+
 # gcc -arch i686 dummy.c -v
 set(mac_i686_gcc_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem")
 set(mac_i686_gcc_libs "")
 set(mac_i686_gcc_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
 list(APPEND platforms mac_i686_gcc)
 
+# g++ -arch i686 dummy.cxx -v -Wl,-v
+set(mac_i686_g++_Wlv_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem
+collect2 version 4.2.1 (Apple Inc. build 5646) (i686 Darwin)
+/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccWrBoVl.o -v -lstdc++ -lSystem -lgcc -lSystem
+@(#)PROGRAM:ld  PROJECT:ld64-95.2.12
+Library search paths:
+       /usr/lib/i686-apple-darwin10/4.2.1
+       /usr/lib/gcc/i686-apple-darwin10/4.2.1
+       /usr/lib/gcc/i686-apple-darwin10/4.2.1
+       /usr/lib/i686-apple-darwin10/4.2.1
+       /usr/lib
+       /usr/lib
+       /usr/local/lib
+Framework search paths:
+       /Library/Frameworks/
+       /System/Library/Frameworks/")
+set(mac_i686_g++_Wlv_libs "stdc++")
+set(mac_i686_g++_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
+set(mac_i686_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
+list(APPEND platforms mac_i686_g++_Wlv)
+
 # g++ -arch i686 dummy.cxx -v
 set(mac_i686_g++_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem")
 set(mac_i686_g++_libs "stdc++")
 set(mac_i686_g++_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
 list(APPEND platforms mac_i686_g++)
 
+# gfortran dummy.f -v -Wl,-v
+set(mac_i686_gfortran_Wlv_text " /usr/local/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//cc9zXNax.o -v -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem
+collect2 version 4.4.1 20090623 (prerelease) (i686 Darwin)
+/usr/bin/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//cc9zXNax.o -v -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem
+@(#)PROGRAM:ld  PROJECT:ld64-95.2.12
+Library search paths:
+       /usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1
+       /usr/local/lib
+       /usr/lib
+       /usr/local/lib
+Framework search paths:
+       /Library/Frameworks/
+       /System/Library/Frameworks/")
+set(mac_i686_gfortran_Wlv_libs "gfortranbegin;gfortran")
+set(mac_i686_gfortran_Wlv_dirs "/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/local/lib;/usr/lib")
+set(mac_i686_gfortran_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
+list(APPEND platforms mac_i686_gfortran_Wlv)
+
 # gfortran dummy.f -v
 set(mac_i686_gfortran_text " /usr/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/lib/gcc -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//ccgqbX5P.o -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem")
 set(mac_i686_gfortran_libs "gfortranbegin;gfortran")
 set(mac_i686_gfortran_dirs "/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/lib/gcc;/usr/lib")
 list(APPEND platforms mac_i686_gfortran)
 
+# gcc -arch ppc dummy.c -v -Wl,-v
+set(mac_ppc_gcc_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//cclziQY4.o -v -lgcc -lSystemStubs -lSystem
+collect2 version 4.2.1 (Apple Inc. build 5646) (Darwin/PowerPC)
+/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/ld -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//cclziQY4.o -v -lgcc -lSystemStubs -lSystem
+@(#)PROGRAM:ld  PROJECT:ld64-95.2.12
+Library search paths:
+       /usr/lib/powerpc-apple-darwin10/4.2.1
+       /usr/lib/gcc/powerpc-apple-darwin10/4.2.1
+       /usr/lib/gcc/powerpc-apple-darwin10/4.2.1
+       /usr/lib/powerpc-apple-darwin10/4.2.1
+       /usr/lib
+       /usr/lib
+       /usr/local/lib
+Framework search paths:
+       /Library/Frameworks/
+       /System/Library/Frameworks/")
+set(mac_ppc_gcc_Wlv_libs "")
+set(mac_ppc_gcc_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
+set(mac_ppc_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
+list(APPEND platforms mac_ppc_gcc_Wlv)
+
 # gcc -arch ppc dummy.c -v
 set(mac_ppc_gcc_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccdcolsP.o -lgcc -lSystemStubs -lSystem")
 set(mac_ppc_gcc_libs "")
 set(mac_ppc_gcc_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
 list(APPEND platforms mac_ppc_gcc)
 
+# g++ -arch ppc dummy.cxx -v -Wl,-v
+set(mac_ppc_g++_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccaFTkwq.o -v -lstdc++ -lgcc -lSystemStubs -lSystem
+collect2 version 4.2.1 (Apple Inc. build 5646) (Darwin/PowerPC)
+/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/ld -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccaFTkwq.o -v -lstdc++ -lgcc -lSystemStubs -lSystem
+@(#)PROGRAM:ld  PROJECT:ld64-95.2.12
+Library search paths:
+       /usr/lib/powerpc-apple-darwin10/4.2.1
+       /usr/lib/gcc/powerpc-apple-darwin10/4.2.1
+       /usr/lib/gcc/powerpc-apple-darwin10/4.2.1
+       /usr/lib/powerpc-apple-darwin10/4.2.1
+       /usr/lib
+       /usr/lib
+       /usr/local/lib
+Framework search paths:
+       /Library/Frameworks/
+       /System/Library/Frameworks/")
+set(mac_ppc_g++_Wlv_libs "stdc++")
+set(mac_ppc_g++_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
+set(mac_ppc_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
+list(APPEND platforms mac_ppc_g++_Wlv)
+
 # g++ -arch ppc dummy.cxx -v
 set(mac_ppc_g++_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccbjB6Lj.o -lstdc++ -lgcc -lSystemStubs -lSystem")
 set(mac_ppc_g++_libs "stdc++")
@@ -402,10 +510,10 @@ list(APPEND platforms msys_g77)
 # Test parsing for all above examples.
 
 foreach(p IN LISTS platforms)
-  cmake_parse_implicit_link_info("${${p}_text}" libs dirs log "${${p}_obj_regex}")
+  cmake_parse_implicit_link_info("${${p}_text}" libs dirs fwks log "${${p}_obj_regex}")
 
-  foreach(v libs dirs)
-    if(NOT "${${v}}" STREQUAL "${${p}_${v}}")
+  foreach(v libs dirs fwks)
+    if(DEFINED "${p}_${v}" AND NOT "${${v}}" STREQUAL "${${p}_${v}}")
       message(FATAL_ERROR
         "cmake_parse_implicit_link_info failed\n"
         "Expected '${p}' implicit ${v}\n"
diff --git a/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake b/Tests/CMakeTests/List-Get-CMP0007-Warn.cmake
new file mode 100644 (file)
index 0000000..0a9264f
--- /dev/null
@@ -0,0 +1,6 @@
+set(thelist "" NEW OLD)
+
+list(GET thelist 1 thevalue)
+if (NOT thevalue STREQUAL "OLD")
+    message(SEND_ERROR "returned element '${thevalue}', but expected 'OLD'")
+endif()
diff --git a/Tests/CMakeTests/List-Get-Invalid-Index.cmake b/Tests/CMakeTests/List-Get-Invalid-Index.cmake
new file mode 100644 (file)
index 0000000..178295a
--- /dev/null
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(GET mylist 3 result)
diff --git a/Tests/CMakeTests/List-Insert-Invalid-Index.cmake b/Tests/CMakeTests/List-Insert-Invalid-Index.cmake
new file mode 100644 (file)
index 0000000..4103d97
--- /dev/null
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(INSERT mylist 3 delta)
diff --git a/Tests/CMakeTests/List-Invalid-Subcommand.cmake b/Tests/CMakeTests/List-Invalid-Subcommand.cmake
new file mode 100644 (file)
index 0000000..f35a118
--- /dev/null
@@ -0,0 +1 @@
+list(NO_SUCH_SUBCOMMAND mylist)
diff --git a/Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake b/Tests/CMakeTests/List-Length-Too-Many-Arguments.cmake
new file mode 100644 (file)
index 0000000..327db6a
--- /dev/null
@@ -0,0 +1 @@
+list(LENGTH mylist result one_too_many)
diff --git a/Tests/CMakeTests/List-No-Arguments.cmake b/Tests/CMakeTests/List-No-Arguments.cmake
new file mode 100644 (file)
index 0000000..7916aaa
--- /dev/null
@@ -0,0 +1 @@
+list()
diff --git a/Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake b/Tests/CMakeTests/List-Remove_At-Invalid-Index.cmake
new file mode 100644 (file)
index 0000000..d4f3921
--- /dev/null
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(REMOVE_AT mylist 3)
diff --git a/Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake b/Tests/CMakeTests/List-Remove_At-Nonexistent-List.cmake
new file mode 100644 (file)
index 0000000..5266c7f
--- /dev/null
@@ -0,0 +1,2 @@
+unset(nosuchlist)
+list(REMOVE_AT nosuchlist 0)
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake b/Tests/CMakeTests/List-Remove_Duplicates-Nonexistent-List.cmake
new file mode 100644 (file)
index 0000000..218f227
--- /dev/null
@@ -0,0 +1,2 @@
+unset(nosuchlist)
+list(REMOVE_DUPLICATES nosuchlist)
diff --git a/Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake b/Tests/CMakeTests/List-Remove_Duplicates-Too-Many-Arguments.cmake
new file mode 100644 (file)
index 0000000..b5eb46e
--- /dev/null
@@ -0,0 +1 @@
+list(REMOVE_DUPLICATES mylist one_too_many)
diff --git a/Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake b/Tests/CMakeTests/List-Remove_Item-Nonexistent-List.cmake
new file mode 100644 (file)
index 0000000..079e7fb
--- /dev/null
@@ -0,0 +1,2 @@
+unset(nosuchlist)
+list(REMOVE_ITEM nosuchlist alpha)
diff --git a/Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake b/Tests/CMakeTests/List-Reverse-Nonexistent-List.cmake
new file mode 100644 (file)
index 0000000..977e2cc
--- /dev/null
@@ -0,0 +1,2 @@
+unset(nosuchlist)
+list(REVERSE nosuchlist)
diff --git a/Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake b/Tests/CMakeTests/List-Reverse-Too-Many-Arguments.cmake
new file mode 100644 (file)
index 0000000..3a554a0
--- /dev/null
@@ -0,0 +1 @@
+list(REVERSE mylist one_too_many)
diff --git a/Tests/CMakeTests/List-Sort-Nonexistent-List.cmake b/Tests/CMakeTests/List-Sort-Nonexistent-List.cmake
new file mode 100644 (file)
index 0000000..8f48e10
--- /dev/null
@@ -0,0 +1,2 @@
+unset(nosuchlist)
+list(SORT nosuchlist)
diff --git a/Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake b/Tests/CMakeTests/List-Sort-Too-Many-Arguments.cmake
new file mode 100644 (file)
index 0000000..81b195d
--- /dev/null
@@ -0,0 +1 @@
+list(SORT mylist one_too_many)
index a167503..77c34a9 100644 (file)
@@ -1,3 +1,8 @@
+include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
+REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
 macro(TEST command expected)
   if("x${result}" STREQUAL "x${expected}")
     #message("TEST \"${command}\" success: \"${result}\" expected: \"${expected}\"")
@@ -97,3 +102,89 @@ TEST("REVERSE empty result" "")
 
 list(SORT result)
 TEST("SORT empty result" "")
+
+set(No-Arguments-RESULT 1)
+set(No-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*")
+
+# these trigger top-level condition
+foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort)
+  set(${cmd}-No-Arguments-RESULT 1)
+  set(${cmd}-No-Arguments-STDERR ".*CMake Error at List-${cmd}-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*")
+  string(TOUPPER ${cmd} cmd_upper)
+  set(_test_file_name "${CMAKE_CURRENT_BINARY_DIR}/List-${cmd}-No-Arguments.cmake")
+  file(WRITE "${_test_file_name}" "list(${cmd_upper})\n")
+  check_cmake_test_single(List "${cmd}-No-Arguments" "${_test_file_name}")
+endforeach()
+
+set(Get-List-Only-STDERR "at least three")
+set(Find-List-Only-STDERR "three")
+set(Insert-List-Only-STDERR "at least three")
+set(Length-List-Only-STDERR "two")
+set(Remove_At-List-Only-STDERR "at least two")
+set(Remove_Item-List-Only-STDERR "two or more")
+
+foreach(cmd IN ITEMS Find Get Insert Length Remove_At Remove_Item)
+  string(TOUPPER ${cmd} cmd_upper)
+  set(${cmd}-List-Only-RESULT 1)
+  set(${cmd}-List-Only-STDERR ".*CMake Error at List-${cmd}-List-Only.cmake:1 \\(list\\):.*list sub-command ${cmd_upper} requires ${${cmd}-List-Only-STDERR} arguments.*")
+  set(_test_file_name "${CMAKE_CURRENT_BINARY_DIR}/List-${cmd}-List-Only.cmake")
+  file(WRITE "${_test_file_name}" "list(${cmd_upper} mylist)\n")
+  check_cmake_test_single(List "${cmd}-List-Only" "${_test_file_name}")
+endforeach()
+
+set(Length-Too-Many-Arguments-RESULT 1)
+set(Length-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Length-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command LENGTH requires two arguments.*")
+
+set(Reverse-Too-Many-Arguments-RESULT 1)
+set(Reverse-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Reverse-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REVERSE only takes one argument.*")
+
+set(Remove_Duplicates-Too-Many-Arguments-RESULT 1)
+set(Remove_Duplicates-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Remove_Duplicates-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REMOVE_DUPLICATES only takes one argument.*")
+
+set(Sort-Too-Many-Arguments-RESULT 1)
+set(Sort-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Sort-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command SORT only takes one argument.*")
+
+set(Invalid-Subcommand-RESULT 1)
+set(Invalid-Subcommand-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Invalid-Subcommand.cmake:1 \\(list\\):.*list does not recognize sub-command NO_SUCH_SUBCOMMAND.*")
+
+foreach(cmd Get Insert Remove_At)
+  set(${cmd}-Invalid-Index-RESULT 1)
+  set(${cmd}-Invalid-Index-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Invalid-Index.cmake:2 \\(list\\):.*list index: 3 out of range \\(-3, 2\\).*")
+endforeach()
+
+foreach(cmd Remove_Item Reverse Remove_Duplicates Sort Remove_At)
+  string(TOUPPER ${cmd} Cmd)
+  set(${cmd}-Nonexistent-List-RESULT 1)
+  set(${cmd}-Nonexistent-List-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Nonexistent-List.cmake:2 \\(list\\):.*sub-command ${Cmd} requires list to be present.*")
+endforeach()
+
+set(Get-CMP0007-Warn-RESULT 0)
+set(Get-CMP0007-Warn-STDERR ".*CMake Warning \\(dev\\) at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Get-CMP0007-Warn.cmake:3 \\(list\\):.*Policy CMP0007 is not set:.*")
+
+check_cmake_test(List
+  No-Arguments
+  Length-Too-Many-Arguments
+  Reverse-Too-Many-Arguments
+  Remove_Duplicates-Too-Many-Arguments
+  Sort-Too-Many-Arguments
+  Invalid-Subcommand
+  Get-Invalid-Index
+  Insert-Invalid-Index
+  Remove_Item-Nonexistent-List
+  Reverse-Nonexistent-List
+  Remove_Duplicates-Nonexistent-List
+  Sort-Nonexistent-List
+  Remove_At-Nonexistent-List
+  Remove_At-Invalid-Index
+  Get-CMP0007-Warn
+)
+
+set(thelist "" NEW OLD)
+
+foreach (_pol ${thelist})
+    cmake_policy(SET CMP0007 ${_pol})
+    list(GET thelist 1 thevalue)
+    if (NOT thevalue STREQUAL _pol)
+        message(SEND_ERROR "returned element '${thevalue}', but expected '${_pol}'")
+    endif()
+endforeach (_pol)
diff --git a/Tests/CMakeTests/Make_Directory-NoArg.cmake b/Tests/CMakeTests/Make_Directory-NoArg.cmake
new file mode 100644 (file)
index 0000000..25b6f89
--- /dev/null
@@ -0,0 +1 @@
+file(MAKE_DIRECTORY)
index 98f6ab1..f92dcc4 100644 (file)
@@ -9,10 +9,17 @@ message("### 3. ProcessorCount(...) function call is emitting output that it sho
 message("processor_count='${processor_count}'")
 
 execute_process(
-  COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx"
+  COMMAND "${KWSYS_TEST_EXE}"
   testSystemInformation
   OUTPUT_VARIABLE tsi_out
-  ERROR_VARIABLE tsi_err)
+  ERROR_VARIABLE tsi_err
+  RESULT_VARIABLE tsi_res
+)
+if (tsi_res)
+  message("executing \"${KWSYS_TEST_EXE}\" failed")
+  message(FATAL_ERROR "output: ${tsi_res}")
+endif ()
+
 string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2"
   system_info_processor_count "${tsi_out}")
 
diff --git a/Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake b/Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake
new file mode 100644 (file)
index 0000000..2d0fcc8
--- /dev/null
@@ -0,0 +1,11 @@
+string(TIMESTAMP output "%d;%H;%I;%j;%m;%M;%S;%U;%w;%y;%Y")
+message("~${output}~")
+
+list(LENGTH output output_length)
+
+set(expected_output_length 11)
+
+if(NOT output_length EQUAL ${expected_output_length})
+    message(FATAL_ERROR "expected ${expected_output_length} entries in output "
+        "with all specifiers; found ${output_length}")
+endif()
diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake
new file mode 100644 (file)
index 0000000..8f2d9f8
--- /dev/null
@@ -0,0 +1 @@
+string(TIMESTAMP)
diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake
new file mode 100644 (file)
index 0000000..c1e5126
--- /dev/null
@@ -0,0 +1 @@
+string(TIMESTAMP output_variable "%Y" UTF)
diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake
new file mode 100644 (file)
index 0000000..3d577df
--- /dev/null
@@ -0,0 +1 @@
+string(TIMESTAMP output_variable "%Y" UTC UTC)
diff --git a/Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake
new file mode 100644 (file)
index 0000000..eab2a45
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output "%S")
+message("~${output}~")
diff --git a/Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake
new file mode 100644 (file)
index 0000000..eab2a45
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output "%S")
+message("~${output}~")
diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake
new file mode 100644 (file)
index 0000000..d7c7dde
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output)
+message("~${output}~")
diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake
new file mode 100644 (file)
index 0000000..dad6a8d
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output UTC)
+message("~${output}~")
diff --git a/Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake b/Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake
new file mode 100644 (file)
index 0000000..ffc5656
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output "foobar%")
+message("~${output}~")
diff --git a/Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake b/Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake
new file mode 100644 (file)
index 0000000..0e145e5
--- /dev/null
@@ -0,0 +1,2 @@
+string(TIMESTAMP output "%g")
+message("~${output}~")
index 49e7dc9..a9fe428 100644 (file)
@@ -16,6 +16,26 @@ set(SHA384-Works-RESULT 0)
 set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee")
 set(SHA512-Works-RESULT 0)
 set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51")
+set(TIMESTAMP-BadArg1-RESULT 1)
+set(TIMESTAMP-BadArg1-STDERR "string sub-command TIMESTAMP requires at least one argument")
+set(TIMESTAMP-BadArg2-RESULT 1)
+set(TIMESTAMP-BadArg2-STDERR "string TIMESTAMP sub-command does not recognize option UTF")
+set(TIMESTAMP-BadArg3-RESULT 1)
+set(TIMESTAMP-BadArg3-STDERR "string sub-command TIMESTAMP takes at most three arguments")
+set(TIMESTAMP-DefaultFormatLocal-RESULT 0)
+set(TIMESTAMP-DefaultFormatLocal-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]~")
+set(TIMESTAMP-DefaultFormatUTC-RESULT 0)
+set(TIMESTAMP-DefaultFormatUTC-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]Z~")
+set(TIMESTAMP-CustomFormatLocal-RESULT 0)
+set(TIMESTAMP-CustomFormatLocal-STDERR "~([0-5][0-9])|60~")
+set(TIMESTAMP-CustomFormatUTC-RESULT 0)
+set(TIMESTAMP-CustomFormatUTC-STDERR "~([0-5][0-9])|60~")
+set(TIMESTAMP-UnknownSpecifier-RESULT 0)
+set(TIMESTAMP-UnknownSpecifier-STDERR "~%g~")
+set(TIMESTAMP-IncompleteSpecifier-RESULT 0)
+set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~")
+set(TIMESTAMP-AllSpecifiers-RESULT 0)
+set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(String
@@ -28,6 +48,16 @@ check_cmake_test(String
   SHA256-Works
   SHA384-Works
   SHA512-Works
+  TIMESTAMP-BadArg1
+  TIMESTAMP-BadArg2
+  TIMESTAMP-BadArg3
+  TIMESTAMP-DefaultFormatLocal
+  TIMESTAMP-DefaultFormatUTC
+  TIMESTAMP-CustomFormatLocal
+  TIMESTAMP-CustomFormatUTC
+  TIMESTAMP-UnknownSpecifier
+  TIMESTAMP-IncompleteSpecifier
+  TIMESTAMP-AllSpecifiers
   )
 
 # Execute each test listed in StringTestScript.cmake:
index 4cec291..d4cf7d7 100644 (file)
@@ -1,6 +1,9 @@
 set(NUMBERS "")
 set(COUNT 0)
 
+include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake")
+REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
 while(COUNT LESS 200)
     set(NUMBERS "${NUMBERS} ${COUNT}")
     set(COUNT "2${COUNT}")
@@ -16,8 +19,9 @@ if(NOT NUMBERS STREQUAL " 0 3 30 20 3 30")
     message(SEND_ERROR "while loop nesting error, result: '${NUMBERS}'")
 endif()
 
+
 set(Missing-Argument-RESULT 1)
-set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*")
+set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*")
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
 check_cmake_test(While
@@ -25,28 +29,28 @@ check_cmake_test(While
 )
 
 set(Missing-Endwhile-RESULT 1)
-set(Missing-Endwhile-STDERR ".*CMake Error in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*")
+set(Missing-Endwhile-STDERR ".*CMake Error in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*")
 
 check_cmake_test(While
   Missing-Endwhile
 )
 
 set(Endwhile-Mismatch-RESULT 0)
-set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*")
+set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*")
 
 check_cmake_test(While
   Endwhile-Mismatch
 )
 
 set(Endwhile-Alone-RESULT 1)
-set(Endwhile-Alone-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$")
+set(Endwhile-Alone-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$")
 
 check_cmake_test(While
   Endwhile-Alone
 )
 
 set(Endwhile-Alone-Args-RESULT 1)
-set(Endwhile-Alone-Args-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.  Or its arguments did not.*$")
+set(Endwhile-Alone-Args-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.  Or its arguments did not.*$")
 
 check_cmake_test(While
   Endwhile-Alone-Args
index 9a022c5..0b6d07d 100644 (file)
@@ -9,11 +9,10 @@ endif()
 if(NOT CPackGen)
   message(FATAL_ERROR "CPackGen not set")
 endif()
-get_filename_component(CPACK_LOCATION ${CMAKE_COMMAND} PATH)
-set(CPackCommand "${CPACK_LOCATION}/cpack")
-message("cpack = ${CPackCommand}")
-if(NOT CPackCommand)
-  message(FATAL_ERROR "CPackCommand not set")
+
+message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}")
+if(NOT CMAKE_CPACK_COMMAND)
+  message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set")
 endif()
 
 if(NOT CPackComponentWay)
@@ -92,7 +91,7 @@ endif()
 
 message("config_args = ${config_args}")
 message("config_verbose = ${config_verbose}")
-execute_process(COMMAND ${CPackCommand} ${config_verbose} -G ${CPackGen} ${config_args}
+execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${config_verbose} -G ${CPackGen} ${config_args}
     RESULT_VARIABLE CPack_result
     OUTPUT_VARIABLE CPack_output
     ERROR_VARIABLE CPack_error
index e0c241e..952d5f4 100644 (file)
@@ -1,14 +1,10 @@
-if(NOT DEFINED cpack)
-  message(FATAL_ERROR "cpack not defined")
-endif()
-
 if(NOT DEFINED dir)
   message(FATAL_ERROR "dir not defined")
 endif()
 
 # Analyze 'cpack --help' output for list of available generators:
 #
-execute_process(COMMAND ${cpack} --help
+execute_process(COMMAND ${CMAKE_CPACK_COMMAND} --help
   RESULT_VARIABLE result
   OUTPUT_VARIABLE stdout
   ERROR_VARIABLE stderr
@@ -43,7 +39,7 @@ message(STATUS "CPack generators='${generators}'")
 
 foreach(g ${generators})
   message(STATUS "Calling cpack -G ${g}...")
-  execute_process(COMMAND ${cpack} -G ${g}
+  execute_process(COMMAND ${CMAKE_CPACK_COMMAND} -G ${g}
     RESULT_VARIABLE result
     OUTPUT_VARIABLE stdout
     ERROR_VARIABLE stderr
diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ce02f11
--- /dev/null
@@ -0,0 +1,73 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(CPackWiXGenerator)
+
+add_library(mylib mylib.cpp)
+
+add_executable(mylibapp mylibapp.cpp)
+target_link_libraries(mylibapp mylib)
+
+install(TARGETS mylib
+  ARCHIVE
+  DESTINATION lib
+  COMPONENT libraries)
+
+install(TARGETS mylibapp
+  RUNTIME
+  DESTINATION bin
+  COMPONENT applications)
+
+install(FILES mylib.h "file with spaces.h"
+  DESTINATION include
+  COMPONENT headers)
+
+set(CPACK_GENERATOR "WIX")
+
+set(CPACK_PACKAGE_NAME "MyLib")
+set(CPACK_PACKAGE_VENDOR "CMake.org")
+set(CPACK_PACKAGE_CONTACT "somebody@cmake.org")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+  "MyLib - CPack Component Installation Example")
+
+set(CPACK_PACKAGE_VERSION_MAJOR "1")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
+
+set(CPACK_WIX_UPGRADE_GUID "BF20CE5E-7F7C-401D-8F7C-AB45E8D170E6")
+
+include(CPack)
+
+cpack_add_install_type(Full DISPLAY_NAME "Everything")
+cpack_add_install_type(Developer)
+
+cpack_add_component_group(Runtime)
+
+cpack_add_component_group(Development
+  EXPANDED
+  DESCRIPTION "All of the tools you'll ever need to develop software")
+
+cpack_add_component(applications
+  DISPLAY_NAME "MyLib Application"
+  DESCRIPTION "An extremely useful application that makes use of MyLib"
+  GROUP Runtime
+  INSTALL_TYPES Full)
+
+cpack_add_component(documentation
+  DISPLAY_NAME "MyLib Documentation"
+  DESCRIPTION "The extensive suite of MyLib Application documentation files"
+  GROUP Runtime
+  INSTALL_TYPES Full)
+
+cpack_add_component(libraries
+  DISPLAY_NAME "Libraries"
+  DESCRIPTION "Static libraries used to build programs with MyLib"
+  GROUP Development
+  INSTALL_TYPES Developer Full)
+
+cpack_add_component(headers
+  DISPLAY_NAME "C++ Headers"
+  DESCRIPTION "C/C++ header files for use with MyLib"
+  GROUP Development
+  DEPENDS libraries
+  INSTALL_TYPES Developer Full)
diff --git a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
new file mode 100644 (file)
index 0000000..30e33cf
--- /dev/null
@@ -0,0 +1,72 @@
+message(STATUS "=============================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackWiXGenerator_BINARY_DIR)
+  message(FATAL_ERROR "CPackWiXGenerator_BINARY_DIR not set")
+endif()
+
+message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
+message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
+message(STATUS "CPackWiXGenerator_BINARY_DIR: ${CPackWiXGenerator_BINARY_DIR}")
+
+execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+  RESULT_VARIABLE CPack_result
+  OUTPUT_VARIABLE CPack_output
+  ERROR_VARIABLE CPack_error
+  WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}")
+
+if(CPack_result)
+  message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+else ()
+  message(STATUS "CPack_output=${CPack_output}")
+endif()
+
+set(expected_file_mask "*.msi")
+file(GLOB installer_file "${expected_file_mask}")
+
+message(STATUS "installer_file='${installer_file}'")
+message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+if(NOT installer_file)
+  message(FATAL_ERROR "installer_file does not exist.")
+endif()
+
+function(run_wix_command command)
+  file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT)
+  set(WIX_PROGRAM "${WIX_ROOT}/bin/${command}.exe")
+
+  if(NOT EXISTS "${WIX_PROGRAM}")
+    message(FATAL_ERROR "Failed to find WiX Tool: ${WIX_PROGRAM}")
+  endif()
+
+  message(STATUS "Running WiX Tool: ${command} ${ARGN}")
+
+  execute_process(COMMAND "${WIX_PROGRAM}" ${ARGN}
+    RESULT_VARIABLE WIX_result
+    OUTPUT_VARIABLE WIX_output
+    ERROR_VARIABLE WIX_output
+    WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}")
+
+  message(STATUS "${command} Output: \n${WIX_output}")
+
+  if(WIX_result)
+    message(FATAL_ERROR "WiX ${command} failed: ${WIX_result}")
+  endif()
+endfunction()
+
+file(GLOB WXS_SOURCE_FILES
+  "${CPackWiXGenerator_BINARY_DIR}/_CPack_Packages/*/WIX/*.wxs")
+
+if(NOT WXS_SOURCE_FILES)
+  message(FATAL_ERROR "Failed finding WiX source files to validate.")
+endif()
+
+foreach(WXS_SOURCE_FILE IN LISTS WXS_SOURCE_FILES)
+  run_wix_command(wixcop "${WXS_SOURCE_FILE}")
+endforeach()
+
+# error SMOK1076 : ICE61: This product should remove only older
+# versions of itself. The Maximum version is not less
+# than the current product. (1.0.0 1.0.0)
+run_wix_command(smoke -nologo -wx -sw1076 "${installer_file}")
diff --git a/Tests/CPackWiXGenerator/file with spaces.h b/Tests/CPackWiXGenerator/file with spaces.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/CPackWiXGenerator/mylib.cpp b/Tests/CPackWiXGenerator/mylib.cpp
new file mode 100644 (file)
index 0000000..8ddac19
--- /dev/null
@@ -0,0 +1,7 @@
+#include "mylib.h"
+#include "stdio.h"
+
+void mylib_function()
+{
+  printf("This is mylib");
+}
diff --git a/Tests/CPackWiXGenerator/mylib.h b/Tests/CPackWiXGenerator/mylib.h
new file mode 100644 (file)
index 0000000..5d0a822
--- /dev/null
@@ -0,0 +1 @@
+void mylib_function();
diff --git a/Tests/CPackWiXGenerator/mylibapp.cpp b/Tests/CPackWiXGenerator/mylibapp.cpp
new file mode 100644 (file)
index 0000000..a438ac7
--- /dev/null
@@ -0,0 +1,6 @@
+#include "mylib.h"
+
+int main()
+{
+  mylib_function();
+}
index c7ac210..0bba6d6 100644 (file)
@@ -17,7 +17,10 @@ endif()
 
 message("cmake initial configure")
 execute_process(COMMAND ${CMAKE_COMMAND}
-  ${arg} -G "@CMAKE_TEST_GENERATOR@" ${CTEST_SOURCE_DIRECTORY}
+   ${arg}
+   -G "@CMAKE_TEST_GENERATOR@"
+   -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
+   ${CTEST_SOURCE_DIRECTORY}
   WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
   RESULT_VARIABLE rv)
 if(NOT rv STREQUAL 0)
index 5ceb7c3..83267a4 100644 (file)
@@ -1,4 +1,5 @@
 set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_PROJECT_NAME "CTestConfig")
 set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig")
 set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-script")
diff --git a/Tests/CTestLimitDashJ/CMakeLists.txt b/Tests/CTestLimitDashJ/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0c5950c
--- /dev/null
@@ -0,0 +1,50 @@
+cmake_minimum_required(VERSION 2.8)
+project(CTestLimitDashJ NONE)
+
+# This file demonstrates http://public.kitware.com/Bug/view.php?id=12904
+# when configured with CMake 2.8.10.2 and earlier, and when running
+# "ctest -j 4" in the resulting build tree. This example is hard-coded
+# to assume -j 4 just to reproduce the issue easily. Adjust the
+# FAIL_REGULAR_EXPRESSION and PROCESSORS values to reproduce this problem
+# with a different ctest -j value...
+
+if(EXISTS "${CMAKE_BINARY_DIR}/Testing/Temporary/CTestCostData.txt")
+  message(STATUS "Removing CTestCostData.txt to force ordering by COST PROPERTY value rather than prior run data")
+  file(REMOVE "${CMAKE_BINARY_DIR}/Testing/Temporary/CTestCostData.txt")
+endif()
+
+include(CTest)
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/CreateSleepDelete.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/CreateSleepDelete.cmake
+  @ONLY
+  )
+
+foreach(n RANGE 1 100)
+  add_test(NAME t${n}
+    COMMAND ${CMAKE_CTEST_COMMAND}
+      -D basefilename=f${n}
+      -S ${CMAKE_CURRENT_BINARY_DIR}/CreateSleepDelete.cmake
+    )
+  set_property(TEST t${n} PROPERTY FAIL_REGULAR_EXPRESSION "(c='[5-9]'|c='[1-9][0-9]+')")
+endforeach()
+
+set_property(TEST t1 PROPERTY RUN_SERIAL 1)
+set_property(TEST t1 PROPERTY PROCESSORS 4)
+
+set_property(TEST t51 PROPERTY RUN_SERIAL 1)
+set_property(TEST t51 PROPERTY PROCESSORS 4)
+
+foreach(n RANGE 2 50)
+  set_property(TEST t${n} PROPERTY DEPENDS t1)
+endforeach()
+set_property(TEST t1 PROPERTY DEPENDS t51)
+set_property(TEST t51 PROPERTY DEPENDS t100)
+
+foreach(n 50)
+  set_property(TEST t${n} PROPERTY COST 6)
+endforeach()
+foreach(n RANGE 52 99)
+  set_property(TEST t${n} PROPERTY COST 3)
+endforeach()
diff --git a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake
new file mode 100644 (file)
index 0000000..b09307f
--- /dev/null
@@ -0,0 +1,48 @@
+set(CTEST_RUN_CURRENT_SCRIPT 0)
+
+if(NOT DEFINED basefilename)
+  message(FATAL_ERROR "pass -Dbasefilename=f1")
+endif()
+
+if(NOT DEFINED ext)
+  set(ext "jkqvxz")
+endif()
+
+if(NOT DEFINED sleep_interval)
+  set(sleep_interval 1)
+endif()
+
+get_filename_component(self_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(filename "${self_dir}/${basefilename}.${ext}")
+
+# count files
+file(GLOB f1 *.${ext})
+list(LENGTH f1 c1)
+message("c='${c1}'")
+
+# write a new file
+message("Writing file: filename='${filename}'")
+file(WRITE "${filename}" "${filename}")
+
+# count files again
+file(GLOB f2 *.${ext})
+list(LENGTH f2 c2)
+message("c='${c2}'")
+
+# snooze
+message("Sleeping: sleep_interval='${sleep_interval}'")
+ctest_sleep(${sleep_interval})
+
+# count files again
+file(GLOB f3 *.${ext})
+list(LENGTH f3 c3)
+message("c='${c3}'")
+
+# delete the file we wrote earlier
+message("Removing file: filename='${filename}'")
+file(REMOVE "${filename}")
+
+# count files again
+file(GLOB f4 *.${ext})
+list(LENGTH f4 c4)
+message("c='${c4}'")
index d21dafa..214bff8 100644 (file)
@@ -41,6 +41,7 @@ set (CTEST_INITIAL_CACHE "
 SITE:STRING=@SITE@
 BUILDNAME:STRING=SmallAndFast-@BUILDNAME@
 CMAKE_GENERATOR:INTERNAL=@CMAKE_GENERATOR@
+CMAKE_GENERATOR_TOOLSET:INTERNAL=@CMAKE_GENERATOR_TOOLSET@
 CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
 CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
 CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
index ec756dd..26a77a7 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Source/kwsys")
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTest2/kwsysBin")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_MEMORYCHECK_COMMAND           "@MEMORYCHECK_COMMAND@")
 set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "@MEMORYCHECK_SUPPRESSIONS_FILE@")
index 2421b13..03ebd04 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestBadEx
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestBadExe")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 6317500..efc53fb 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestParal
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestParallel")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index feaa5c3..42225d3 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestConfi
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir1")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index f489114..010fe1c 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestConfi
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestConfigFileInBuildDir2")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 8661767..bfb3d9a 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestCostS
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestCostSerial")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 4e27bc2..492966c 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestCrash
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestCrash")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 22f3377..e9c9a4e 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestCycle
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestCycle")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 49fc443..002958b 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestDepen
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestDepends")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 3944006..36a09cf 100644 (file)
@@ -21,6 +21,7 @@ set(CTEST_SOURCE_DIRECTORY              "@source@")
 set(CTEST_BINARY_DIRECTORY              "@build@")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 6edd9dd..3c4d219 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestFailu
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index f09594c..a133e2a 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestFailu
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestFailure")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 2730a61..b5f758b 100644 (file)
@@ -1,3 +1,5 @@
+REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+
 foreach (_retval 0 1)
   file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.c" "int main(){return ${_retval};}\n")
 endforeach ()
@@ -49,7 +51,7 @@ string(REPLACE "+" "\\+" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
 
 foreach (_unkn Unknown UnknownQuoted)
     set_tests_properties(CTestTestMemcheck${_unkn} PROPERTIES
-        PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/${_unkn}/test.cmake\n")
+        PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${_unkn}/test.cmake\n")
 endforeach ()
 
 set_tests_properties(CTestTestMemcheckNotExist PROPERTIES
@@ -67,7 +69,7 @@ foreach (_pp Pre Post)
     string(TOLOWER ${_pp} _pp_lower)
     set_tests_properties(CTestTestMemcheckDummyValgrindFail${_pp}
         PROPERTIES
-        PASS_REGULAR_EXPRESSION "\nProblem running command: ${CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n")
+        PASS_REGULAR_EXPRESSION "\nProblem running command: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n")
 endforeach ()
 
 set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck
@@ -75,7 +77,7 @@ set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck
     PASS_REGULAR_EXPRESSION "\n2/2 Test #2: RunCMakeAgain .*\n1/1 MemCheck #1: RunCMake .*${NORMAL_CTEST_OUTPUT}")
 
 set_tests_properties(CTestTestMemcheckDummyPurify PROPERTIES
-    PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CMAKE_CURRENT_BINARY_DIR}/DummyPurify/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyPurify/test.cmake\n")
+    PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyPurify/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyPurify/test.cmake\n")
 
 set_tests_properties(CTestTestMemcheckDummyBC PROPERTIES
-    PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CMAKE_CURRENT_BINARY_DIR}/DummyBC/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error parsing XML in stream at line 1: no element found\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyBC/test.cmake\n")
+    PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyBC/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error parsing XML in stream at line 1: no element found\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyBC/test.cmake\n")
index 5005498..1b16433 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyBC")
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyBC")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 0df4f68..0c8795c 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyPurify"
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyPurify")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index e341fed..c3941c1 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyValgrin
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyValgrind")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 7c1aa66..90e2ac5 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyValgrin
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyValgrindFailPost")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index b2d7bb1..fd17f63 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyValgrin
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyValgrindFailPre")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 031a232..37aaaeb 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyValgrin
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyValgrindIgnoreMemcheck")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 44c416e..11f14a9 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/DummyValgrin
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/DummyValgrindPrePost")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 78db7e2..43f7542 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/NotExist")
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/NotExist")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index c0b7839..0830bf0 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/Unknown")
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/Unknown")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index e2bfb60..1b1f702 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMAKE_CURRENT_SOURCE_DIR@/UnknownQuote
 set(CTEST_BINARY_DIRECTORY              "@CMAKE_CURRENT_BINARY_DIR@/UnknownQuoted")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 0418755..a0d9fb3 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestParal
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestParallel")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 571cc50..1e7e344 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestResou
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestResourceLock")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 9115a61..8ad6137 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestSched
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestScheduler")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index c3920a4..6804789 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestStopT
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestStopTime")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index d1d87ad..526d453 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestSubdi
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestSubdir")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index e34dc07..40241ff 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestTimeo
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestTimeout")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 2c0fc38..19abc89 100644 (file)
@@ -8,6 +8,7 @@ set(CTEST_BUILD_NAME                    "CTestTest-@BUILDNAME@-Upload")
 set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestUpload")
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestUpload")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 
 CTEST_START(Experimental)
index 285a191..745e5bc 100644 (file)
@@ -9,6 +9,7 @@ set(CTEST_SOURCE_DIRECTORY              "@CMake_SOURCE_DIR@/Tests/CTestTestZeroT
 set(CTEST_BINARY_DIRECTORY              "@CMake_BINARY_DIR@/Tests/CTestTestZeroTimeout")
 set(CTEST_CVS_COMMAND                   "@CVSCOMMAND@")
 set(CTEST_CMAKE_GENERATOR               "@CMAKE_TEST_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET       "@CMAKE_TEST_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_COVERAGE_COMMAND              "@COVERAGE_COMMAND@")
 set(CTEST_NOTES_FILES                   "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
index 0c01291..f6939de 100644 (file)
@@ -76,6 +76,8 @@ run_child(WORKING_DIRECTORY ${TOP}/module
 # Import initial content into the repository.
 message("Importing content...")
 create_content(import)
+file(WRITE ${TOP}/import/HEAD "HEAD\n")
+file(WRITE ${TOP}/import/master "master\n")
 
 # Import the content into the repository.
 run_child(WORKING_DIRECTORY ${TOP}/import
@@ -157,19 +159,19 @@ update_content(user-source files_added files_removed dirs_added)
 if(dirs_added)
   run_child(
     WORKING_DIRECTORY ${TOP}/user-source
-    COMMAND ${GIT} add ${dirs_added}
+    COMMAND ${GIT} add -- ${dirs_added}
     )
 endif()
 run_child(
   WORKING_DIRECTORY ${TOP}/user-source
-  COMMAND ${GIT} add ${files_added}
+  COMMAND ${GIT} add -- ${files_added}
   )
 run_child(
   WORKING_DIRECTORY ${TOP}/user-source
-  COMMAND ${GIT} rm ${files_removed}
+  COMMAND ${GIT} rm -- ${files_removed}
   )
 run_child(WORKING_DIRECTORY ${TOP}/user-source/module
-  COMMAND ${GIT} checkout master
+  COMMAND ${GIT} checkout master --
   )
 run_child(
   WORKING_DIRECTORY ${TOP}/user-source
index 20001e6..69cfdb8 100644 (file)
@@ -37,6 +37,9 @@ endif()
 if(DEFINED MSVC11)
   math(EXPR msvc_total "${msvc_total} + 1")
 endif()
+if(DEFINED MSVC12)
+  math(EXPR msvc_total "${msvc_total} + 1")
+endif()
 
 echo_var(MSVC)
 echo_var(MSVC60)
@@ -46,6 +49,7 @@ echo_var(MSVC80)
 echo_var(MSVC90)
 echo_var(MSVC10)
 echo_var(MSVC11)
+echo_var(MSVC12)
 echo_var(MSVC_IDE)
 
 if(MSVC)
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd0a37d
--- /dev/null
@@ -0,0 +1,84 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CompatibleInterface)
+
+include(GenerateExportHeader)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(iface1 empty.cpp)
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_BOOL
+    BOOL_PROP1
+    BOOL_PROP2
+    BOOL_PROP3
+    BOOL_PROP4
+)
+set_property(TARGET iface1 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_STRING
+    STRING_PROP1
+    STRING_PROP2
+    STRING_PROP3
+)
+
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
+
+add_executable(CompatibleInterface main.cpp)
+target_link_libraries(CompatibleInterface iface1)
+
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
+
+target_compile_definitions(CompatibleInterface
+  PRIVATE
+    $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
+    $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
+    $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
+    $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
+)
+
+
+add_library(iface2 SHARED iface2.cpp)
+generate_export_header(iface2)
+
+set_property(TARGET iface2 APPEND PROPERTY
+  COMPATIBLE_INTERFACE_STRING
+    Iface2_PROP
+)
+
+# For the LINK_LIBRARIES and related properties, we should not evaluate
+# properties defined only in the interface - they should be implicitly zero
+set_property(TARGET iface2
+  APPEND PROPERTY
+    LINK_INTERFACE_LIBRARIES $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP4>>:nonexistant>
+)
+target_link_libraries(CompatibleInterface iface2
+      $<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:nonexistant>
+)
+# Test that this does not segfault:
+target_compile_definitions(CompatibleInterface
+  PRIVATE
+    $<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:SOME_DEFINE>
+)
+
+# The COMPATIBLE_INTERFACE_* properties are only read from dependencies
+# in the interface. Populating it on the CompatibleInterface target does
+# not have any affect on the interpretation of the INTERFACE variants
+# in dependencies.
+set_property(TARGET iface1 PROPERTY
+  INTERFACE_NON_RELEVANT_PROP ON
+)
+set_property(TARGET iface2 PROPERTY
+  INTERFACE_NON_RELEVANT_PROP ON
+)
+set_property(TARGET CompatibleInterface APPEND PROPERTY
+  COMPATIBLE_INTERFACE_BOOL
+    NON_RELEVANT_PROP
+)
diff --git a/Tests/CompatibleInterface/empty.cpp b/Tests/CompatibleInterface/empty.cpp
new file mode 100644 (file)
index 0000000..0032329
--- /dev/null
@@ -0,0 +1 @@
+// no content
diff --git a/Tests/CompatibleInterface/iface2.cpp b/Tests/CompatibleInterface/iface2.cpp
new file mode 100644 (file)
index 0000000..a9b5015
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "iface2.h"
+
+int Iface2::foo()
+{
+  return 0;
+}
diff --git a/Tests/CompatibleInterface/iface2.h b/Tests/CompatibleInterface/iface2.h
new file mode 100644 (file)
index 0000000..ef4ebee
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef IFACE2_H
+#define IFACE2_H
+
+#include "iface2_export.h"
+
+class IFACE2_EXPORT Iface2
+{
+public:
+  int foo();
+};
+
+#endif
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
new file mode 100644 (file)
index 0000000..f5e6e38
--- /dev/null
@@ -0,0 +1,32 @@
+
+#ifndef BOOL_PROP1
+#error Expected BOOL_PROP1
+#endif
+
+#ifndef BOOL_PROP2
+#error Expected BOOL_PROP2
+#endif
+
+#ifndef BOOL_PROP3
+#error Expected BOOL_PROP3
+#endif
+
+#ifndef STRING_PROP1
+#error Expected STRING_PROP1
+#endif
+
+#ifndef STRING_PROP2
+#error Expected STRING_PROP2
+#endif
+
+#ifndef STRING_PROP3
+#error Expected STRING_PROP3
+#endif
+
+#include "iface2.h"
+
+int main(int argc, char **argv)
+{
+  Iface2 if2;
+  return if2.foo();
+}
index e7d91bf..d3e9a3e 100644 (file)
@@ -7,10 +7,19 @@ if ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 6")
     add_definitions(-DNO_SPACES_IN_DEFINE_VALUES)
 endif()
 
+# Use compile flags to tell executables which config is built
+# without depending on the compile definitions functionality.
+foreach(c DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
+  set(CMAKE_C_FLAGS_${c} "${CMAKE_C_FLAGS_${c}} -DTEST_CONFIG_${c}")
+  set(CMAKE_CXX_FLAGS_${c} "${CMAKE_CXX_FLAGS_${c}} -DTEST_CONFIG_${c}")
+endforeach()
+
+set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
+  "BUILD_CONFIG_NAME=\"$<CONFIGURATION>\""
+  )
+
 add_subdirectory(add_definitions_command)
 add_subdirectory(target_prop)
 add_subdirectory(add_definitions_command_with_target_prop)
 
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummyexecutable.cpp" "int main(int, char **) { return 0; }\n")
-
-add_executable(CompileDefinitions "${CMAKE_CURRENT_BINARY_DIR}/dummyexecutable.cpp")
+add_executable(CompileDefinitions runtest.c)
index a6372af..d3886a1 100644 (file)
@@ -3,5 +3,6 @@ project(add_definitions_command)
 
 add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun")
 add_definitions(-DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun" -DCMAKE_IS_FUN -DCMAKE_IS=Fun)
+add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug> -DBUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
 
 add_executable(add_definitions_command_executable ../compiletest.cpp)
index e415390..5587f7f 100644 (file)
@@ -12,3 +12,6 @@ set_property(TARGET add_definitions_command_with_target_prop_executable APPEND P
 add_definitions(-DCMAKE_IS_FUN)
 
 set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS=Fun CMAKE_IS_="Fun")
+
+add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug>)
+set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS BUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>)
index f18e59e..14b8eab 100644 (file)
@@ -45,6 +45,30 @@ enum {
 // TEST_GENERATOR_EXPRESSIONS
 #endif
 
+#ifndef BUILD_IS_DEBUG
+# error "BUILD_IS_DEBUG not defined!"
+#endif
+#ifndef BUILD_IS_NOT_DEBUG
+# error "BUILD_IS_NOT_DEBUG not defined!"
+#endif
+
+// Check per-config definitions.
+#ifdef TEST_CONFIG_DEBUG
+# if !BUILD_IS_DEBUG
+#  error "BUILD_IS_DEBUG false with TEST_CONFIG_DEBUG!"
+# endif
+# if BUILD_IS_NOT_DEBUG
+#  error "BUILD_IS_NOT_DEBUG true with TEST_CONFIG_DEBUG!"
+# endif
+#else
+# if BUILD_IS_DEBUG
+#  error "BUILD_IS_DEBUG true without TEST_CONFIG_DEBUG!"
+# endif
+# if !BUILD_IS_NOT_DEBUG
+#  error "BUILD_IS_NOT_DEBUG false without TEST_CONFIG_DEBUG!"
+# endif
+#endif
+
 int main(int argc, char **argv)
 {
   return 0;
diff --git a/Tests/CompileDefinitions/runtest.c b/Tests/CompileDefinitions/runtest.c
new file mode 100644 (file)
index 0000000..02d2cad
--- /dev/null
@@ -0,0 +1,47 @@
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#ifndef BUILD_CONFIG_NAME
+# error "BUILD_CONFIG_NAME not defined!"
+#endif
+
+int main()
+{
+  char build_config_name[] = BUILD_CONFIG_NAME;
+  char* c;
+  for(c = build_config_name; *c; ++c)
+    {
+    *c = (char)tolower((int)*c);
+    }
+  fprintf(stderr, "build_config_name=\"%s\"\n", build_config_name);
+#ifdef TEST_CONFIG_DEBUG
+  if(strcmp(build_config_name, "debug") != 0)
+    {
+    fprintf(stderr, "build_config_name is not \"debug\"\n");
+    return 1;
+    }
+#endif
+#ifdef TEST_CONFIG_RELEASE
+  if(strcmp(build_config_name, "release") != 0)
+    {
+    fprintf(stderr, "build_config_name is not \"release\"\n");
+    return 1;
+    }
+#endif
+#ifdef TEST_CONFIG_MINSIZEREL
+  if(strcmp(build_config_name, "minsizerel") != 0)
+    {
+    fprintf(stderr, "build_config_name is not \"minsizerel\"\n");
+    return 1;
+    }
+#endif
+#ifdef TEST_CONFIG_RELWITHDEBINFO
+  if(strcmp(build_config_name, "relwithdebinfo") != 0)
+    {
+    fprintf(stderr, "build_config_name is not \"relwithdebinfo\"\n");
+    return 1;
+    }
+#endif
+  return 0;
+}
index abdf257..1ef2d6d 100644 (file)
@@ -14,3 +14,8 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
     "$<0:GE_NOT_DEFINED>"
     "$<1:ARGUMENT;LIST>"
 )
+
+set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
+  BUILD_IS_DEBUG=$<CONFIG:Debug>
+  BUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>
+  )
index 432dbf8..2613f27 100644 (file)
@@ -91,7 +91,7 @@ remove_definitions(-DCOMPLEX_DEFINED)
 add_custom_command(TARGET complex PRE_BUILD
                    COMMAND ${CREATE_FILE_EXE}
                    ARGS "${Complex_BINARY_DIR}/Executable/prebuild.txt")
-add_custom_command(TARGET complex PRE_BUILD
+add_custom_command(TARGET complex PRE_LINK
                    COMMAND ${CREATE_FILE_EXE}
                    ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt")
 add_custom_command(TARGET complex POST_BUILD
diff --git a/Tests/EmptyDepends/CMakeLists.txt b/Tests/EmptyDepends/CMakeLists.txt
new file mode 100644 (file)
index 0000000..832d9dc
--- /dev/null
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.8)
+project(EmptyDepends)
+
+include(CTest)
+
+set(extra_dep)
+
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/qrc_my.cxx
+  COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/qrc_my.cxx"
+  DEPENDS "${extra_dep}" "${CMAKE_BINARY_DIR}/my.qrc")
+
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/my.qrc
+  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/my.qrc)
+
+add_library(qrc STATIC ${CMAKE_BINARY_DIR}/qrc_my.cxx)
index d6593e8..b8368fc 100644 (file)
@@ -41,9 +41,11 @@ add_custom_command(
     --build-project Export
     --build-target install
     --build-generator ${CMAKE_GENERATOR}
+    --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
     --build-makeprogram ${CMAKE_MAKE_PROGRAM}
     --build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
-    )
+  VERBATIM
+  )
 add_custom_target(ExportTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/ExportProject)
 add_dependencies(ExportTarget CleanupTarget)
 set_property(
@@ -61,9 +63,11 @@ add_custom_command(
    --build-noclean
    --build-project Import
    --build-generator ${CMAKE_GENERATOR}
+   --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
    --build-makeprogram ${CMAKE_MAKE_PROGRAM}
    --build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
-   )
+  VERBATIM
+  )
 add_custom_target(ImportTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/ImportProject)
 add_dependencies(ImportTarget ExportTarget)
 set_property(
index e19ab88..be48483 100644 (file)
@@ -90,14 +90,176 @@ set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
 # Test exporting dependent libraries into different exports
 add_library(testLibRequired testLibRequired.c)
 add_library(testLibDepends testLibDepends.c)
-target_link_libraries(testLibDepends testLibRequired)
+target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired)
 
-install(TARGETS testLibRequired EXPORT RequiredExp DESTINATION lib )
-install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
+macro(add_include_lib _libName)
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n")
+  add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c")
+  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
+  set_property(TARGET ${_libName} APPEND PROPERTY
+      INTERFACE_INCLUDE_DIRECTORIES
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_libName}>"
+        "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/${_libName}>"
+      )
+  if (NOT "${ARGV1}" STREQUAL "NO_HEADER")
+      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n")
+      install(FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h"
+          DESTINATION include/${_libName}
+      )
+  endif()
+endmacro()
 
-install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib )
-install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends)
+add_include_lib(testLibIncludeRequired1)
+add_include_lib(testLibIncludeRequired2)
+add_include_lib(testLibIncludeRequired3 NO_HEADER)
+# Generate testLibIncludeRequired4 in the testLibIncludeRequired3 directory
+# with an error. If the includes from testLibIncludeRequired3 appear first,
+# the error will be hit.
+# Below, the '3' library appears before the '4' library
+# but we are testing that the INSTALL_INTERFACE causes it not to be used
+# at build time.
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" "#error Should not be included\n")
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h"
+    DESTINATION include/testLibIncludeRequired3
+)
+add_include_lib(testLibIncludeRequired4)
+add_include_lib(testLibIncludeRequired5 NO_HEADER)
+# Generate testLibIncludeRequired6 in the testLibIncludeRequired5 directory
+# with an error. If the includes from testLibIncludeRequired5 appear first,
+# the error will be hit.
+# Below, the '5' library appears before the '6' library
+# but we are testing that when the installed IMPORTED target is used, from
+# the Import side of this unit test, the '6' include from the '5' directory
+# will not be used because it is in the BUILD_INTERFACE only.
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" "#error Should not be included\n")
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h"
+    DESTINATION include/testLibIncludeRequired5
+)
+add_include_lib(testLibIncludeRequired6)
 
+set_property(TARGET testLibRequired APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES
+    $<TARGET_PROPERTY:testLibIncludeRequired1,INTERFACE_INCLUDE_DIRECTORIES>
+    $<TARGET_PROPERTY:$<1:$<TARGET_NAME:testLibIncludeRequired2>>,INTERFACE_INCLUDE_DIRECTORIES>
+    $<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired3,INTERFACE_INCLUDE_DIRECTORIES>>
+    $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired4,INTERFACE_INCLUDE_DIRECTORIES>>
+    $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
+    $<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired6,INTERFACE_INCLUDE_DIRECTORIES>>
+    # The BUILD_INTERFACE entry from above is duplicated below. This is to test that
+    # the INSTALL_INTERFACE entry bound by a BUILD_INTERFACE entry on either side is
+    # preprocessed correctly on install(EXPORT).
+    $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
+    # Test that the below is non-fatal
+    $<$<STREQUAL:one,two>:$<TARGET_PROPERTY:not_a_target,INTERFACE_INCLUDE_DIRECTORIES>>
+)
+
+set_property(TARGET testLibRequired APPEND PROPERTY
+  INTERFACE_COMPILE_DEFINITIONS
+    testLibRequired_IFACE_DEFINE
+    $<BUILD_INTERFACE:BuildOnly_DEFINE>
+    $<INSTALL_INTERFACE:InstallOnly_DEFINE>
+)
+
+include(GenerateExportHeader)
+
+add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
+generate_export_header(testSharedLibRequired)
+set_property(TARGET testSharedLibRequired
+  PROPERTY
+    INTERFACE_POSITION_INDEPENDENT_CODE ON
+)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+install(FILES
+  "${CMAKE_CURRENT_SOURCE_DIR}/testSharedLibRequired.h"
+  "${CMAKE_CURRENT_BINARY_DIR}/testsharedlibrequired_export.h"
+    DESTINATION include/testSharedLibRequired
+)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/testSharedLibRequired>"
+                                "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
+)
+set_property(TARGET testSharedLibRequired
+  APPEND PROPERTY
+    COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP
+)
+set_property(TARGET testSharedLibRequired
+  PROPERTY
+    INTERFACE_CUSTOM_PROP ON
+)
+set_property(TARGET testSharedLibRequired
+  APPEND PROPERTY
+    COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
+)
+set_property(TARGET testSharedLibRequired
+  PROPERTY
+    INTERFACE_CUSTOM_STRING testcontent
+)
+
+add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+generate_export_header(testSharedLibDepends)
+
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES
+    $<TARGET_PROPERTY:testSharedLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
+)
+install(FILES
+  "${CMAKE_CURRENT_SOURCE_DIR}/testSharedLibDepends.h"
+  "${CMAKE_CURRENT_BINARY_DIR}/testsharedlibdepends_export.h"
+    DESTINATION include/testSharedLibDepends
+)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/testSharedLibDepends>"
+                                "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
+)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  LINK_INTERFACE_LIBRARIES
+    $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
+)
+
+# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
+target_link_libraries(testSharedLibDepends LINK_PRIVATE testSharedLibRequired)
+
+install(TARGETS testLibRequired
+                testLibIncludeRequired1
+                testLibIncludeRequired2
+                testLibIncludeRequired3
+                testLibIncludeRequired4
+                testLibIncludeRequired5
+                testLibIncludeRequired6
+                testSharedLibRequired
+        EXPORT RequiredExp DESTINATION lib )
+install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
+
+install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
+install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
+
+file(WRITE
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
+  "
+if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION VERSION_LESS 2.3 AND NOT \${CMAKE_FIND_PACKAGE_NAME}_INTERFACES)
+  set(\${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES 1)
+endif()
+include(\"\${CMAKE_CURRENT_LIST_DIR}/testLibRequiredTargets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIRS \"${CMAKE_CURRENT_BINARY_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}\" )
+"
+)
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file( testLibRequiredConfigVersion.cmake VERSION 2.5 COMPATIBILITY AnyNewerVersion)
+
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfigVersion.cmake"
+  DESTINATION lib/cmake/testLibRequired
+)
 
 # Install and export from install tree.
 install(
@@ -143,9 +305,12 @@ if(WIN32)
   install(TARGETS testLib5 RUNTIME DESTINATION bin)
 endif()
 
+add_subdirectory(sublib) # For CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE test.
+
 # Export from build tree.
 export(TARGETS testExe1 testLib1 testLib2 testLib3
-  testExe2libImp testLib3Imp testLib3ImpDep
+  testExe2libImp testLib3Imp testLib3ImpDep subdirlib
+  testSharedLibRequired testSharedLibDepends
   NAMESPACE bld_
   FILE ExportBuildTree.cmake
   )
diff --git a/Tests/ExportImport/Export/sublib/CMakeLists.txt b/Tests/ExportImport/Export/sublib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a5c6413
--- /dev/null
@@ -0,0 +1,6 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(subdirlib SHARED subdir.cpp)
+generate_export_header(subdirlib)
diff --git a/Tests/ExportImport/Export/sublib/subdir.cpp b/Tests/ExportImport/Export/sublib/subdir.cpp
new file mode 100644 (file)
index 0000000..35b0743
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "subdir.h"
+
+int SubDirObject::foo()
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/sublib/subdir.h b/Tests/ExportImport/Export/sublib/subdir.h
new file mode 100644 (file)
index 0000000..3a4b73d
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifndef SUBDIR_H
+#define SUBDIR_H
+
+#include "subdirlib_export.h"
+
+struct SUBDIRLIB_EXPORT SubDirObject
+{
+  int foo();
+};
+
+#endif
index 2849b33..fb5a002 100644 (file)
@@ -1,4 +1,20 @@
 
+#include "testLibIncludeRequired1.h"
+#include "testLibIncludeRequired2.h"
+#include "testLibIncludeRequired4.h"
+
+#ifndef testLibRequired_IFACE_DEFINE
+#error Expected testLibRequired_IFACE_DEFINE
+#endif
+
+#ifndef BuildOnly_DEFINE
+#error Expected BuildOnly_DEFINE
+#endif
+
+#ifdef InstallOnly_DEFINE
+#error Unexpected InstallOnly_DEFINE
+#endif
+
 extern int testLibRequired(void);
 
 int testLibDepends(void) { return testLibRequired(); }
diff --git a/Tests/ExportImport/Export/testSharedLibDepends.cpp b/Tests/ExportImport/Export/testSharedLibDepends.cpp
new file mode 100644 (file)
index 0000000..e279207
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include "testSharedLibDepends.h"
+
+int TestSharedLibDepends::foo()
+{
+  TestSharedLibRequired req;
+  return req.foo();
+}
diff --git a/Tests/ExportImport/Export/testSharedLibDepends.h b/Tests/ExportImport/Export/testSharedLibDepends.h
new file mode 100644 (file)
index 0000000..b93143a
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef TESTSHAREDLIBDEPENDS_H
+#define TESTSHAREDLIBDEPENDS_H
+
+#include "testsharedlibdepends_export.h"
+
+#include "testSharedLibRequired.h"
+
+struct TESTSHAREDLIBDEPENDS_EXPORT TestSharedLibDepends
+{
+  int foo();
+};
+
+#endif
diff --git a/Tests/ExportImport/Export/testSharedLibRequired.cpp b/Tests/ExportImport/Export/testSharedLibRequired.cpp
new file mode 100644 (file)
index 0000000..1ac34aa
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "testSharedLibRequired.h"
+
+int TestSharedLibRequired::foo()
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/testSharedLibRequired.h b/Tests/ExportImport/Export/testSharedLibRequired.h
new file mode 100644 (file)
index 0000000..edaddd4
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifndef TESTSHAREDLIBREQUIRED_H
+#define TESTSHAREDLIBREQUIRED_H
+
+#include "testsharedlibrequired_export.h"
+
+struct TESTSHAREDLIBREQUIRED_EXPORT TestSharedLibRequired
+{
+  int foo();
+};
+
+#endif
index 8841792..0337130 100644 (file)
@@ -5,8 +5,8 @@ include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake)
 include(${CMAKE_INSTALL_PREFIX}/lib/exp/exp.cmake)
 
 # Import two exports, where the Depends one depends on an exported target from the Required one:
-include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibRequired/testLibRequiredConfig.cmake)
-include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibDepends/testLibDependsConfig.cmake)
+include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibRequired/testLibRequiredTargets.cmake)
+include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibDepends/testLibDependsTargets.cmake)
 
 # Try referencing an executable imported from the install tree.
 add_custom_command(
@@ -152,3 +152,50 @@ check_function_exists(testLib1 HAVE_TESTLIB1_FUNCTION)
 if (NOT HAVE_TESTLIB1_FUNCTION)
   message(SEND_ERROR "Using imported target testLib2 in check_function_exists() failed !")
 endif()
+
+#-----------------------------------------------------------------------------
+# Test that dependent imported targets have usable
+# INTERFACE_COMPILE_DEFINITIONS and INTERFACE_INCLUDE_DIRECTORIES
+
+add_executable(deps_iface deps_iface.c)
+target_link_libraries(deps_iface testLibDepends)
+
+add_executable(deps_shared_iface deps_shared_iface.cpp)
+target_link_libraries(deps_shared_iface testSharedLibDepends)
+target_compile_definitions(deps_shared_iface
+  PRIVATE
+    $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
+    $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+    $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
+)
+
+if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+  include(CheckCXXCompilerFlag)
+  check_cxx_compiler_flag(-fPIE run_pic_test)
+else()
+  if (CMAKE_CXX_COMPILER_ID MATCHES "PGI"
+      OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale"
+      OR CMAKE_SYSTEM_NAME MATCHES "IRIX64"
+      OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+    set(run_pic_test 0)
+  else()
+    set(run_pic_test 1)
+  endif()
+endif()
+
+if (run_pic_test)
+  target_compile_definitions(deps_shared_iface PRIVATE CHECK_PIC_WORKS)
+endif()
+
+#-----------------------------------------------------------------------------
+# Test that targets imported from the build tree have their dependencies
+# evaluated correctly. The above already tests the same for the install tree.
+
+add_executable(deps_shared_iface2 deps_shared_iface.cpp)
+target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
+target_compile_definitions(deps_shared_iface2
+  PRIVATE TEST_SUBDIR_LIB
+  $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
+  $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+  $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
+)
diff --git a/Tests/ExportImport/Import/A/deps_iface.c b/Tests/ExportImport/Import/A/deps_iface.c
new file mode 100644 (file)
index 0000000..e73ca26
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include "testLibIncludeRequired1.h"
+#include "testLibIncludeRequired2.h"
+#include "testLibIncludeRequired6.h"
+
+#ifndef testLibRequired_IFACE_DEFINE
+#error Expected testLibRequired_IFACE_DEFINE
+#endif
+
+#ifdef BuildOnly_DEFINE
+#error Unexpected BuildOnly_DEFINE
+#endif
+
+#ifndef InstallOnly_DEFINE
+#error Expected InstallOnly_DEFINE
+#endif
+
+extern int testLibDepends(void);
+
+
+int main()
+{
+  return testLibDepends();
+}
diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp
new file mode 100644 (file)
index 0000000..2f0e74a
--- /dev/null
@@ -0,0 +1,41 @@
+
+
+#include "testSharedLibDepends.h"
+
+#ifdef CHECK_PIC_WORKS
+#if defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__)
+#error Expected by INTERFACE_POSITION_INDEPENDENT_CODE property of dependency
+#endif
+#endif
+
+#ifndef PIC_PROPERTY_IS_ON
+#error Expected PIC_PROPERTY_IS_ON
+#endif
+
+#ifndef CUSTOM_PROPERTY_IS_ON
+#error Expected CUSTOM_PROPERTY_IS_ON
+#endif
+
+#ifndef CUSTOM_STRING_IS_MATCH
+#error Expected CUSTOM_STRING_IS_MATCH
+#endif
+
+#ifdef TEST_SUBDIR_LIB
+#include "subdir.h"
+#endif
+
+int main(int,char **)
+{
+  TestSharedLibDepends dep;
+  TestSharedLibRequired req;
+
+#ifdef TEST_SUBDIR_LIB
+  SubDirObject sdo;
+#endif
+
+  return dep.foo() + req.foo()
+#ifdef TEST_SUBDIR_LIB
+                   + sdo.foo()
+#endif
+                              ;
+}
index 3fc78a2..9c2d597 100644 (file)
@@ -17,3 +17,5 @@ add_executable(imp_testTransExe1 imp_testTransExe1.c)
 target_link_libraries(imp_testTransExe1 imp_lib1)
 add_executable(imp_testTransExe1b imp_testTransExe1.c)
 target_link_libraries(imp_testTransExe1b imp_lib1b)
+
+add_subdirectory(try_compile)
diff --git a/Tests/ExportImport/Import/try_compile/CMakeLists.txt b/Tests/ExportImport/Import/try_compile/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5600dff
--- /dev/null
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+find_package(testLibRequired 2.5 REQUIRED)
+
+include(CheckCXXSourceCompiles)
+
+set(CMAKE_REQUIRED_LIBRARIES Req::testSharedLibRequired)
+check_cxx_source_compiles(
+  "
+#include \"testSharedLibRequired.h\"
+int main(int argc, char **argv)
+{
+  TestSharedLibRequired req;
+  return req.foo();
+}
+" SHARED_LIB_REQUIRED)
+
+if(NOT SHARED_LIB_REQUIRED)
+  message(SEND_ERROR "try_compile with IMPORTED targets failed!\n\n${OUTPUT}")
+endif()
index 3f8e827..602ff0f 100644 (file)
@@ -50,6 +50,8 @@ if(NOT DEFINED can_build_tutorial_step5)
   endif()
 endif()
 
+add_custom_target(NonExternalProjectTarget
+  COMMAND ${CMAKE_COMMAND} -E echo NonExternalProjectTarget)
 
 # Empty projects that test all the known ExternalProject_Add argument key words:
 #
@@ -94,7 +96,7 @@ ExternalProject_Add(${proj}
   CVS_REPOSITORY ""
   CVS_MODULE ""
   CVS_TAG ""
-  DEPENDS "MinimalNoOpProject"
+  DEPENDS "MinimalNoOpProject" NonExternalProjectTarget
   DOWNLOAD_COMMAND ""
   INSTALL_COMMAND ""
   PATCH_COMMAND ""
@@ -638,6 +640,17 @@ if(do_svn_tests)
     "${binary_base}/TutorialStep1-SVN-trunk/Tutorial" 98)
 endif()
 
+if(do_git_tests)
+  add_test(TutorialStep1-GIT-byhash
+    "${binary_base}/TutorialStep1-GIT-byhash/Tutorial" 100)
+
+  add_test(TutorialStep1-GIT-bytag
+    "${binary_base}/TutorialStep1-GIT-bytag/Tutorial" 99)
+
+  add_test(TutorialStep1-GIT-master
+    "${binary_base}/TutorialStep1-GIT-master/Tutorial" 98)
+endif()
+
 
 # InstallTree tests:
 #
diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c33e90b
--- /dev/null
@@ -0,0 +1,94 @@
+cmake_minimum_required(VERSION 2.8)
+project(ExternalProjectUpdateTest NONE)
+
+include(ExternalProject)
+
+find_package(Git)
+
+option(ExternalProjectUpdateTest_USE_FOLDERS "Enable folder grouping in IDEs." ON)
+if(ExternalProjectUpdateTest_USE_FOLDERS)
+  set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+else()
+  set_property(GLOBAL PROPERTY USE_FOLDERS OFF)
+endif()
+
+set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER
+  "CMakePredefinedTargets-in-ExternalProjectUpdateTest")
+
+set(base "${CMAKE_BINARY_DIR}/CMakeExternals")
+set(binary_base "${base}/Build")
+set_property(DIRECTORY PROPERTY EP_BASE ${base})
+set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+
+set(do_git_tests 0)
+
+if(GIT_EXECUTABLE)
+  set(do_git_tests 1)
+
+  execute_process(
+    COMMAND "${GIT_EXECUTABLE}" --version
+    OUTPUT_VARIABLE ov
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}")
+  message(STATUS "git_version='${git_version}'")
+
+  if(git_version VERSION_LESS 1.6.5)
+    message(STATUS "No ExternalProject git tests with git client less than version 1.6.5")
+    set(do_git_tests 0)
+  endif()
+endif()
+
+# This should be specified from the command line.
+if(NOT TEST_GIT_TAG)
+  set(TEST_GIT_TAG origin/master)
+endif()
+
+if(do_git_tests)
+  set(local_git_repo "../../LocalRepositories/GIT")
+
+  # Unzip/untar the git repository in our source folder so that other
+  # projects below may use it to test git args of ExternalProject_Add
+  #
+  set(proj SetupLocalGITRepository)
+  ExternalProject_Add(${proj}
+    SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT
+    URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo.tgz
+    BUILD_COMMAND ""
+    CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+    INSTALL_COMMAND ""
+  )
+  set_property(TARGET ${proj}
+    PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+  set(proj TutorialStep1-GIT)
+  ExternalProject_Add(${proj}
+    GIT_REPOSITORY "${local_git_repo}"
+    GIT_TAG ${TEST_GIT_TAG}
+    CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+    INSTALL_COMMAND ""
+    DEPENDS "SetupLocalGITRepository"
+  )
+  set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+endif()
+
+
+# Test the testable built/installed products:
+#
+enable_testing()
+
+
+# Do at least a smoke test of a built executable from each
+# project's build directory...
+#
+# BuildTree tests:
+#
+
+if(do_git_tests)
+  add_test(TutorialStep1-GIT
+    "${binary_base}/TutorialStep1-GIT/Tutorial" 81)
+endif()
+
+message(STATUS "do_git_tests='${do_git_tests}'")
+message(STATUS "GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
new file mode 100644 (file)
index 0000000..b6f848a
--- /dev/null
@@ -0,0 +1,94 @@
+# Set the ExternalProject GIT_TAG to desired_tag, and make sure the
+# resulting checked out version is resulting_sha and rebuild.
+# This check's the correct behavior of the ExternalProject UPDATE_COMMAND.
+# Also verify that a fetch only occurs when fetch_expected is 1.
+macro(check_a_tag desired_tag resulting_sha fetch_expected)
+  message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag}" )
+
+  # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git
+  # fetch'.
+  set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/.git/FETCH_HEAD )
+  file( REMOVE ${FETCH_HEAD_file} )
+
+  # Configure
+  execute_process(COMMAND ${CMAKE_COMMAND}
+    -G ${CMAKE_TEST_GENERATOR} -T "${CMAKE_TEST_GENERATOR_TOOLSET}"
+    -DTEST_GIT_TAG:STRING=${desired_tag}
+    ${ExternalProjectUpdate_SOURCE_DIR}
+    WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR "Could not configure the project.")
+  endif()
+
+  # Build
+  execute_process(COMMAND ${CMAKE_COMMAND}
+    --build ${ExternalProjectUpdate_BINARY_DIR}
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR "Could not build the project.")
+  endif()
+
+  # Check the resulting SHA
+  execute_process(COMMAND ${GIT_EXECUTABLE}
+    rev-list --max-count=1 HEAD
+    WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
+    RESULT_VARIABLE error_code
+    OUTPUT_VARIABLE tag_sha
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(error_code)
+    message(FATAL_ERROR "Could not check the sha.")
+  endif()
+
+  if(NOT (${tag_sha} STREQUAL ${resulting_sha}))
+    message(FATAL_ERROR "UPDATE_COMMAND produced
+  ${tag_sha}
+when
+  ${resulting_sha}
+was expected."
+    )
+  endif()
+
+  if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected})
+    message( FATAL_ERROR "Fetch did NOT occur when it was expected.")
+  endif()
+  if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected})
+    message( FATAL_ERROR "Fetch DID occur when it was not expected.")
+  endif()
+endmacro()
+
+find_package(Git)
+set(do_git_tests 0)
+if(GIT_EXECUTABLE)
+  set(do_git_tests 1)
+
+  execute_process(
+    COMMAND "${GIT_EXECUTABLE}" --version
+    OUTPUT_VARIABLE ov
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}")
+  message(STATUS "git_version='${git_version}'")
+
+  if(git_version VERSION_LESS 1.6.5)
+    message(STATUS "No ExternalProject git tests with git client less than version 1.6.5")
+    set(do_git_tests 0)
+  endif()
+endif()
+
+if(do_git_tests)
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 1)
+  # With the Git UPDATE_COMMAND performance patch, this will not required a
+  # 'git fetch'
+  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 0)
+  check_a_tag(tag2          5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 1)
+  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 0)
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+  # This is a remote symbolic ref, so it will always trigger a 'git fetch'
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+endif()
diff --git a/Tests/ExternalProjectUpdate/gitrepo.tgz b/Tests/ExternalProjectUpdate/gitrepo.tgz
new file mode 100644 (file)
index 0000000..87090ab
Binary files /dev/null and b/Tests/ExternalProjectUpdate/gitrepo.tgz differ
index bca149b..a77713f 100644 (file)
@@ -43,6 +43,16 @@ if(NOT LOTSOFCOMPONENTS_FOUND)
   message(SEND_ERROR "LotsOfComponents not found !")
 endif()
 
+find_package(SomePackage)
+if(NOT SomePackage_FOUND)
+  message(SEND_ERROR "SomePackage with FOUND_VAR SomePackage_FOUND not found !")
+endif()
+
+find_package(UpperCasePackage)
+if(NOT UPPERCASEPACKAGE_FOUND)
+  message(SEND_ERROR "UpperCasePackage with FOUND_VAR UPPERCASEPACKAGE_FOUND not found !")
+endif()
+
 #-----------------------------------------------------------------------------
 # Test system package registry if possible.
 set(CMakeTestSystemPackage "")
diff --git a/Tests/FindPackageTest/FindSomePackage.cmake b/Tests/FindPackageTest/FindSomePackage.cmake
new file mode 100644 (file)
index 0000000..83d1d0e
--- /dev/null
@@ -0,0 +1,6 @@
+set(SOP_FOO TRUE)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(SomePackage REQUIRED_VARS SOP_FOO
+                                              FOUND_VAR SomePackage_FOUND )
diff --git a/Tests/FindPackageTest/FindUpperCasePackage.cmake b/Tests/FindPackageTest/FindUpperCasePackage.cmake
new file mode 100644 (file)
index 0000000..66c2fea
--- /dev/null
@@ -0,0 +1,6 @@
+set(UCP_FOO TRUE)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(UpperCasePackage REQUIRED_VARS UCP_FOO
+                                                   FOUND_VAR UPPERCASEPACKAGE_FOUND )
index 6e78f42..cda5fed 100644 (file)
@@ -197,6 +197,7 @@ if(TEST_MODULE_DEPENDS)
          --build-two-config
          --build-project ExtFort
          --build-generator ${CMAKE_GENERATOR}
+         --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
          --build-makeprogram ${CMAKE_MAKE_PROGRAM}
          --build-options -DCMAKE_Fortran_COMPILER:STRING=${CMAKE_Fortran_COMPILER}
                          -DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}
@@ -205,7 +206,8 @@ if(TEST_MODULE_DEPENDS)
                          -DCMAKE_Fortran_FLAGS_MINSIZEREL:STRING=${CMAKE_Fortran_FLAGS_MINSIZEREL}
                          -DCMAKE_Fortran_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_Fortran_FLAGS_RELWITHDEBINFO}
                          ${External_BUILD_TYPE}
-         )
+    VERBATIM
+    )
   add_custom_target(ExternalTarget ALL DEPENDS ${testf_BINARY_DIR}/ExternalProject)
 
   # Test module output directory if available.
index 0b82f0e..3436309 100644 (file)
@@ -15,6 +15,7 @@ set(COMMAND)
 execute_process(
   WORKING_DIRECTORY "${bld}"
   COMMAND ${CMAKE_COMMAND} "${src}" -G "@CMAKE_TEST_GENERATOR@"
+                           -T "@CMAKE_TEST_GENERATOR_TOOLSET@"
                            "-DFortranC_TEST_FLAGS=1"
                            "-DCMAKE_C_COMPILER=${bld}/cc.sh"
                            "-DCMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@"
index bb31476..0008c16 100644 (file)
@@ -1,7 +1,7 @@
 cmake_minimum_required (VERSION 2.8.8)
-project(GeneratorExpression NONE)
+project(GeneratorExpression CXX)
 
-add_custom_target(check ALL
+add_custom_target(check-part1 ALL
   COMMAND ${CMAKE_COMMAND}
     -Dtest_0=$<0:nothing>
     -Dtest_0_with_comma=$<0:-Wl,--no-undefined>
@@ -14,6 +14,9 @@ add_custom_target(check ALL
     -Dtest_and_1=$<AND:1>
     -Dtest_and_1_0=$<AND:1,0>
     -Dtest_and_1_1=$<AND:1,1>
+    # Ordinarily, the 'invalidcontent' would cause an error, but
+    # the '0' makes the AND abort early.
+    -Dtest_and_0_invalidcontent=$<AND:0,invalidcontent>
     -Dtest_config_0=$<CONFIG:$<CONFIGURATION>x>
     -Dtest_config_1=$<CONFIG:$<CONFIGURATION>>
     -Dtest_config_debug=$<CONFIG:Debug>$<CONFIG:DEBUG>$<CONFIG:DeBuG>
@@ -28,6 +31,7 @@ add_custom_target(check ALL
     -Dtest_or_1=$<OR:1>
     -Dtest_or_1_0=$<OR:1,0>
     -Dtest_or_1_1=$<OR:1,1>
+    -Dtest_or_1_invalidcontent=$<OR:1,invalidcontent>
     -Dtest_bool_notfound=$<BOOL:NOTFOUND>
     -Dtest_bool_foo_notfound=$<BOOL:Foo-NOTFOUND>
     -Dtest_bool_true=$<BOOL:True>
@@ -43,16 +47,46 @@ add_custom_target(check ALL
     -Dtest_strequal_no_yes=$<STREQUAL:No,Yes>
     -Dtest_strequal_angle_r=$<STREQUAL:$<ANGLE-R>,$<ANGLE-R>>
     -Dtest_strequal_comma=$<STREQUAL:$<COMMA>,$<COMMA>>
+    -Dtest_strequal_semicolon=$<STREQUAL:$<SEMICOLON>,$<SEMICOLON>>
     -Dtest_strequal_angle_r_comma=$<STREQUAL:$<ANGLE-R>,$<COMMA>>
     -Dtest_strequal_both_empty=$<STREQUAL:,>
     -Dtest_strequal_one_empty=$<STREQUAL:something,>
     -Dtest_angle_r=$<ANGLE-R>
     -Dtest_comma=$<COMMA>
+    -Dtest_semicolon=$<SEMICOLON>
     -Dtest_colons_1=$<1::>
     -Dtest_colons_2=$<1:::>
     -Dtest_colons_3=$<1:Qt5::Core>
     -Dtest_colons_4=$<1:C:\\CMake>
     -Dtest_colons_5=$<1:C:/CMake>
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 2)"
+  VERBATIM
+  )
+
+add_library(empty1 empty.cpp)
+target_include_directories(empty1 PUBLIC /empty1/public)
+target_include_directories(empty1 PRIVATE /empty1/private)
+
+add_library(empty2 empty.cpp)
+target_include_directories(empty2 PUBLIC /empty2/public)
+
+add_library(empty3 empty.cpp)
+target_include_directories(empty3 PUBLIC /empty3/public)
+target_include_directories(empty3 PRIVATE /empty3/private)
+
+add_library(empty4 empty.cpp)
+target_include_directories(empty4 PUBLIC /empty4/public)
+
+target_link_libraries(empty1 LINK_PUBLIC empty2)
+target_link_libraries(empty2 LINK_PUBLIC empty3 empty4)
+target_link_libraries(empty3 LINK_PUBLIC empty2 empty4)
+
+add_library(empty5 empty.cpp)
+target_include_directories(empty5 PRIVATE /empty5/private1 /empty5/private2)
+
+add_custom_target(check-part2 ALL
+  COMMAND ${CMAKE_COMMAND}
     -Dtest_incomplete_1=$<
     -Dtest_incomplete_2=$<something
     -Dtest_incomplete_3=$<something:
@@ -74,7 +108,19 @@ add_custom_target(check ALL
     -Dtest_incomplete_19=$<1:some,thing$<ANGLE-R>
     -Dtest_incomplete_20=$<CONFIGURATION$<ANGLE-R>
     -Dtest_incomplete_21=$<BOOL:something$<ANGLE-R>
-    -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
-  COMMAND ${CMAKE_COMMAND} -E echo "check done"
+    -Dtest_build_interface=$<BUILD_INTERFACE:build>
+    -Dtest_install_interface=$<INSTALL_INTERFACE:install>
+    -Dtest_target_name_1=$<TARGET_NAME:tgt,ok>
+    -Dtest_target_name_2=$<TARGET_NAME:tgt:ok>
+    -Dtest_target_includes1=$<TARGET_PROPERTY:empty1,INTERFACE_INCLUDE_DIRECTORIES>
+    -Dtest_target_includes2=$<TARGET_PROPERTY:empty2,INTERFACE_INCLUDE_DIRECTORIES>
+    -Dtest_target_includes3=$<TARGET_PROPERTY:empty3,INTERFACE_INCLUDE_DIRECTORIES>
+    -Dtest_target_includes4=$<TARGET_PROPERTY:empty1,INCLUDE_DIRECTORIES>
+    -Dtest_target_includes5=$<TARGET_PROPERTY:empty2,INCLUDE_DIRECTORIES>
+    -Dtest_target_includes6=$<TARGET_PROPERTY:empty3,INCLUDE_DIRECTORIES>
+    -Dtest_target_includes7=$<TARGET_PROPERTY:empty1,INTERFACE_INCLUDE_DIRECTORIES>
+    -Dtest_target_includes8=$<TARGET_PROPERTY:empty5,INCLUDE_DIRECTORIES>
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake
+  COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)"
   VERBATIM
   )
diff --git a/Tests/GeneratorExpression/check-common.cmake b/Tests/GeneratorExpression/check-common.cmake
new file mode 100644 (file)
index 0000000..8ffebd7
--- /dev/null
@@ -0,0 +1,5 @@
+macro(check var val)
+  if(NOT "${${var}}" STREQUAL "${val}")
+    message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
+  endif()
+endmacro()
similarity index 59%
rename from Tests/GeneratorExpression/check.cmake
rename to Tests/GeneratorExpression/check-part1.cmake
index 8745d57..9bef159 100644 (file)
@@ -1,8 +1,5 @@
-macro(check var val)
-  if(NOT "${${var}}" STREQUAL "${val}")
-    message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
-  endif()
-endmacro()
+
+include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
 
 message(STATUS "config=[${config}]")
 check(test_0 "")
@@ -15,6 +12,7 @@ check(test_and_0_1 "0")
 check(test_and_1 "1")
 check(test_and_1_0 "0")
 check(test_and_1_1 "1")
+check(test_and_0_invalidcontent "0")
 check(test_config_0 "0")
 check(test_config_1 "1")
 foreach(c debug release relwithdebinfo minsizerel)
@@ -30,6 +28,7 @@ check(test_or_0_1 "1")
 check(test_or_1 "1")
 check(test_or_1_0 "1")
 check(test_or_1_1 "1")
+check(test_or_1_invalidcontent "1")
 check(test_bool_notfound "0")
 check(test_bool_foo_notfound "0")
 check(test_bool_true "1")
@@ -45,34 +44,15 @@ check(test_strequal_yes_no "0")
 check(test_strequal_no_yes "0")
 check(test_strequal_angle_r "1")
 check(test_strequal_comma "1")
+check(test_strequal_semicolon "1")
 check(test_strequal_angle_r_comma "0")
 check(test_strequal_both_empty "1")
 check(test_strequal_one_empty "0")
 check(test_angle_r ">")
 check(test_comma ",")
+check(test_semicolon ";")
 check(test_colons_1 ":")
 check(test_colons_2 "::")
 check(test_colons_3 "Qt5::Core")
 check(test_colons_4 "C:\\\\CMake")
 check(test_colons_5 "C:/CMake")
-check(test_incomplete_1 "$<")
-check(test_incomplete_2 "$<something")
-check(test_incomplete_3 "$<something:")
-check(test_incomplete_4 "$<something:,")
-check(test_incomplete_5 "$something:,>")
-check(test_incomplete_6 "<something:,>")
-check(test_incomplete_7 "$<something::")
-check(test_incomplete_8 "$<something:,")
-check(test_incomplete_9 "$<something:,,")
-check(test_incomplete_10 "$<something:,:")
-check(test_incomplete_11 "$<something,,")
-check(test_incomplete_12 "$<,,")
-check(test_incomplete_13 "$<somespecialthing")
-check(test_incomplete_14 "$<>")
-check(test_incomplete_15 "$<some$<thing")
-check(test_incomplete_16 "$<BOOL:something")
-check(test_incomplete_17 "some$thing")
-check(test_incomplete_18 "$<1:some,thing")
-check(test_incomplete_19 "$<1:some,thing>")
-check(test_incomplete_20 "$<CONFIGURATION>")
-check(test_incomplete_21 "$<BOOL:something>")
diff --git a/Tests/GeneratorExpression/check-part2.cmake b/Tests/GeneratorExpression/check-part2.cmake
new file mode 100644 (file)
index 0000000..3f7187c
--- /dev/null
@@ -0,0 +1,36 @@
+
+include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
+
+check(test_incomplete_1 "$<")
+check(test_incomplete_2 "$<something")
+check(test_incomplete_3 "$<something:")
+check(test_incomplete_4 "$<something:,")
+check(test_incomplete_5 "$something:,>")
+check(test_incomplete_6 "<something:,>")
+check(test_incomplete_7 "$<something::")
+check(test_incomplete_8 "$<something:,")
+check(test_incomplete_9 "$<something:,,")
+check(test_incomplete_10 "$<something:,:")
+check(test_incomplete_11 "$<something,,")
+check(test_incomplete_12 "$<,,")
+check(test_incomplete_13 "$<somespecialthing")
+check(test_incomplete_14 "$<>")
+check(test_incomplete_15 "$<some$<thing")
+check(test_incomplete_16 "$<BOOL:something")
+check(test_incomplete_17 "some$thing")
+check(test_incomplete_18 "$<1:some,thing")
+check(test_incomplete_19 "$<1:some,thing>")
+check(test_incomplete_20 "$<CONFIGURATION>")
+check(test_incomplete_21 "$<BOOL:something>")
+check(test_build_interface "build")
+check(test_install_interface "")
+check(test_target_name_1 "tgt,ok")
+check(test_target_name_2 "tgt:ok")
+check(test_target_includes1 "/empty1/public;/empty2/public;/empty3/public;/empty4/public")
+check(test_target_includes2 "/empty2/public;/empty3/public;/empty4/public")
+check(test_target_includes3 "/empty3/public;/empty2/public;/empty4/public")
+check(test_target_includes4 "/empty1/public;/empty1/private;/empty2/public;/empty3/public;/empty4/public")
+check(test_target_includes5 "/empty2/public;/empty3/public;/empty2/public;/empty4/public")
+check(test_target_includes6 "/empty3/public;/empty3/private;/empty2/public;/empty3/public;/empty4/public")
+check(test_target_includes7 "/empty1/public;/empty2/public;/empty3/public;/empty4/public")
+check(test_target_includes8 "/empty5/private1;/empty5/private2")
diff --git a/Tests/GeneratorExpression/empty.cpp b/Tests/GeneratorExpression/empty.cpp
new file mode 100644 (file)
index 0000000..c539901
--- /dev/null
@@ -0,0 +1,2 @@
+
+// empty
index 60f5e5e..3e3ecc9 100644 (file)
@@ -47,3 +47,25 @@ else()
 endif()
 
 add_subdirectory(TargetIncludeDirectories)
+
+set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES "${CMAKE_BINARY_DIR}")
+get_property(propContent DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+if (NOT propContent STREQUAL "${CMAKE_BINARY_DIR}")
+  message(SEND_ERROR "Setting DIRECTORY property failed.")
+endif()
+set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+get_property(propContentAfter DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+if (NOT propContentAfter STREQUAL "")
+  message(SEND_ERROR "Clearing DIRECTORY property failed.")
+endif()
+
+add_library(empty_entry_test SHARED empty.cpp)
+set_target_properties(empty_entry_test PROPERTIES INCLUDE_DIRECTORIES "")
+include_directories(/one/two
+  " "
+  "  "
+)
+get_target_property(incs empty_entry_test INCLUDE_DIRECTORIES)
+if (NOT incs STREQUAL ";/one/two")
+  message(SEND_ERROR "Empty include_directories entry was not ignored.")
+endif()
index 7cb1b42..4a5aa30 100644 (file)
@@ -37,6 +37,37 @@ include_directories("sing$<1:/ting>")
 
 include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/arguments;${CMAKE_CURRENT_BINARY_DIR}/list>")
 
+create_header(fee)
+create_header(fiy)
+create_header(foh)
+create_header(fum)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp" "#include \"fee.h\"\n")
+add_library(lib1 "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp")
+set_property(TARGET lib1 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fee")
+set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy")
+set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${CMAKE_CURRENT_BINARY_DIR}/foh>")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp" "#include \"fiy.h\"\n")
+add_library(lib2 "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp")
+set_property(TARGET lib2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fum;$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>")
+set_property(TARGET lib2 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n#include \"fum.h\"\nint main(int,char**) { return 0; }\n")
+add_executable(exe3 "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp")
+set_property(TARGET exe3 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib2,INTERFACE_INCLUDE_DIRECTORIES>")
+
+# Test cycles
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n")
+add_library(lib3 "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp")
+set_property(TARGET lib3 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$<TARGET_PROPERTY:lib4,INTERFACE_INCLUDE_DIRECTORIES>")
+set_property(TARGET lib3 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$<TARGET_PROPERTY:lib4,INTERFACE_INCLUDE_DIRECTORIES>")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n")
+add_library(lib4 "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp")
+set_property(TARGET lib4 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>")
+set_property(TARGET lib4 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>")
+
 add_library(somelib::withcolons UNKNOWN IMPORTED)
 set_property(TARGET somelib::withcolons PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/target")
 set_property(TARGET somelib::withcolons PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/target")
@@ -45,3 +76,74 @@ set_property(TARGET TargetIncludeDirectories
   APPEND PROPERTY INCLUDE_DIRECTORIES
   "$<TARGET_PROPERTY:somelib::withcolons,INTERFACE_INCLUDE_DIRECTORIES>"
 )
+
+add_custom_target(test_custom_target
+        "some_bogus_custom_tool"
+        $<TARGET_PROPERTY:TargetIncludeDirectories,COMPILE_DEFINITIONS>
+        WORKING_DIRECTORY
+        "${CMAKE_CURRENT_SOURCE_DIR}")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bad")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bad/common.h" "#error Should not be included\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/good")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/good/common.h" "#include \"othergood.h\"\n")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/othergood")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "// No error\n")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp" "// No content \n")
+add_library(libothergood "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp")
+set_property(TARGET libothergood APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/othergood"
+)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp" "// No content \n")
+add_library(libgood "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp")
+set_property(TARGET libgood APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES
+    "${CMAKE_CURRENT_BINARY_DIR}/good;$<TARGET_PROPERTY:libothergood,INTERFACE_INCLUDE_DIRECTORIES>"
+)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp" "// No content \n")
+add_library(libbad "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp")
+set_property(TARGET libbad APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bad"
+)
+
+add_library(lib6 SHARED other.cpp)
+add_library(lib7 SHARED other.cpp)
+target_link_libraries(lib7 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:lib6>)
+target_include_directories(lib7 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:/lib7/include>)
+add_custom_target(head_target_test "some_bogus_custom_tool \"$<TARGET_PROPERTY:lib7,INCLUDE_DIRECTORIES>$<TARGET_PROPERTY:lib7,INTERFACE_INCLUDE_DIRECTORIES>\"")
+
+add_library(includes_source_good empty.cpp)
+target_include_directories(includes_source_good
+  INTERFACE
+    "${CMAKE_CURRENT_BINARY_DIR}/good"
+    "${CMAKE_CURRENT_BINARY_DIR}/othergood/"
+)
+add_library(includes_source_bad empty.cpp)
+target_include_directories(includes_source_bad
+  INTERFACE
+    "${CMAKE_CURRENT_BINARY_DIR}/bad"
+)
+
+add_library(includes_proxy SHARED empty.cpp)
+target_link_libraries(includes_proxy includes_source_good)
+target_link_libraries(includes_proxy LINK_INTERFACE_LIBRARIES includes_source_bad)
+add_executable(copy_includes copy_includes.cpp)
+target_include_directories(copy_includes PRIVATE $<TARGET_PROPERTY:includes_proxy,INCLUDE_DIRECTORIES>)
+
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n")
+add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp")
+
+# Assuming the link order must be:
+target_link_libraries(lib5 libbad libgood)
+
+# Oops!.
+# As include directory order and link order are the same when using target_link_libraries, we have to
+# get the libgood includes in before the libbad includes.
+# We do that with this command:
+target_include_directories(lib5
+  BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES>
+)
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp
new file mode 100644 (file)
index 0000000..fed4c03
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include "common.h"
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp
new file mode 100644 (file)
index 0000000..7279c5e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty(void)
+{
+  return 0;
+}
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/other.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/other.cpp
new file mode 100644 (file)
index 0000000..6673471
--- /dev/null
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int other() {
+  return 0;
+}
diff --git a/Tests/IncludeDirectories/empty.cpp b/Tests/IncludeDirectories/empty.cpp
new file mode 100644 (file)
index 0000000..1787013
--- /dev/null
@@ -0,0 +1,4 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty() { return 0; }
diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8312dca
--- /dev/null
@@ -0,0 +1,44 @@
+cmake_minimum_required(VERSION 2.8.10.20130115)
+project(ExternalDataTest NONE)
+
+include(CTest)
+
+include(ExternalData)
+
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
+  set(slash /)
+endif()
+set(ExternalData_URL_TEMPLATES
+  "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(ExternalData_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/ExternalData")
+file(REMOVE_RECURSE ${ExternalData_BINARY_ROOT}) # clean test
+
+if(MAKE_SUPPORTS_SPACES)
+  set(Data1CheckSpaces -D "DataSpace=DATA{Data Space.dat}")
+endif()
+
+ExternalData_Add_Test(Data1
+  NAME Data1Check
+  COMMAND ${CMAKE_COMMAND}
+    -D Data=DATA{Data.dat}
+    ${Data1CheckSpaces}
+    -D SeriesA=DATA{SeriesA.dat,:}
+    -D SeriesB=DATA{SeriesB.dat,:}
+    -D SeriesC=DATA{SeriesC.dat,:}
+    -D SeriesD=DATA{SeriesD.dat,:}
+    -D SeriesAn=DATA{SeriesAn1.dat,:}
+    -D SeriesBn=DATA{SeriesBn_1.dat,:}
+    -D SeriesCn=DATA{SeriesCn.1.dat,:}
+    -D SeriesDn=DATA{SeriesDn-1.dat,:}
+    -D SeriesMixed=DATA{SeriesMixed.1.dat,:}
+    -D Paired=DATA{PairedA.dat,PairedB.dat}
+    -D Meta=DATA{MetaTop.dat,REGEX:Meta[ABC].dat}
+    -D Directory=DATA{Directory/,A.dat,REGEX:[BC].dat}
+    -D "Semicolons=DATA{Data.dat}\\;DATA{Data.dat}"
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/Data1Check.cmake
+  )
+ExternalData_Add_Target(Data1)
+
+add_subdirectory(Data2)
+add_subdirectory(Data3)
diff --git a/Tests/Module/ExternalData/Data Space.dat.md5 b/Tests/Module/ExternalData/Data Space.dat.md5
new file mode 100644 (file)
index 0000000..70e39bd
--- /dev/null
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data.dat.md5 b/Tests/Module/ExternalData/Data.dat.md5
new file mode 100644 (file)
index 0000000..70e39bd
--- /dev/null
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data1Check.cmake b/Tests/Module/ExternalData/Data1Check.cmake
new file mode 100644 (file)
index 0000000..5770245
--- /dev/null
@@ -0,0 +1,68 @@
+file(STRINGS "${Data}" lines LIMIT_INPUT 1024)
+if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
+  message(SEND_ERROR "Input file:\n  ${Data}\ndoes not have expected content, but [[${lines}]]")
+endif()
+if(DEFINED DataSpace)
+  file(STRINGS "${DataSpace}" lines LIMIT_INPUT 1024)
+  if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
+    message(SEND_ERROR "Input file:\n  ${DataSpace}\ndoes not have expected content, but [[${lines}]]")
+  endif()
+endif()
+set(SeriesAn1 "1\\.dat")
+set(SeriesBn1 "_1\\.dat")
+set(SeriesCn1 "\\.1\\.dat")
+set(SeriesDn1 "-1\\.dat")
+set(SeriesAl 1 2 3)
+set(SeriesBl _1 _2 _3)
+set(SeriesCl .1 .2 .3)
+set(SeriesDl -1 -2 -3)
+foreach(s A B C D)
+  foreach(n "" ${Series${s}l})
+    string(REGEX REPLACE "\\.dat$" "${n}.dat" file "${Series${s}}")
+    if(NOT EXISTS "${file}")
+      message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+    endif()
+  endforeach()
+endforeach()
+foreach(s A B C D)
+  foreach(n ${Series${s}l})
+    string(REGEX REPLACE "${Series${s}n1}$" "${n}.dat" file "${Series${s}n}")
+    if(NOT EXISTS "${file}")
+      message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+    endif()
+  endforeach()
+endforeach()
+foreach(n .1 .2 .3 .4)
+  string(REGEX REPLACE "\\.1\\.dat$" "${n}.dat" file "${SeriesMixed}")
+  if(NOT EXISTS "${file}")
+    message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+  endif()
+endforeach()
+foreach(n A B)
+  string(REGEX REPLACE "A\\.dat$" "${n}.dat" file "${Paired}")
+  if(NOT EXISTS "${file}")
+    message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+  endif()
+endforeach()
+foreach(n Top A B C)
+  string(REGEX REPLACE "Top\\.dat$" "${n}.dat" file "${Meta}")
+  if(NOT EXISTS "${file}")
+    message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+  endif()
+endforeach()
+foreach(n A B C)
+  set(file "${Directory}/${n}.dat")
+  if(NOT EXISTS "${file}")
+    message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+  endif()
+endforeach()
+list(LENGTH Semicolons len)
+if("${len}" EQUAL 2)
+  foreach(file ${Semicolons})
+    if(NOT EXISTS "${file}")
+      message(SEND_ERROR "Input file:\n  ${file}\ndoes not exist!")
+    endif()
+  endforeach()
+else()
+  message(SEND_ERROR "Semicolons value:\n  ${Semicolons}\nis not a list of length 2.")
+endif()
diff --git a/Tests/Module/ExternalData/Data2.dat.md5 b/Tests/Module/ExternalData/Data2.dat.md5
new file mode 100644 (file)
index 0000000..70e39bd
--- /dev/null
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data2/CMakeLists.txt b/Tests/Module/ExternalData/Data2/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c5b79ac
--- /dev/null
@@ -0,0 +1,11 @@
+set(ExternalData_SERIES_PARSE "([0-9]+)(_\\.my\\.dat)$")
+set(ExternalData_SERIES_MATCH "([0-9]+)")
+ExternalData_Add_Test(Data2
+  NAME Data2Check
+  COMMAND ${CMAKE_COMMAND}
+    -D Data2=DATA{../Data2.dat}
+    -D Data2b=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data2b.dat}
+    -D SeriesC=DATA{SeriesC_1_.my.dat,:}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/Data2Check.cmake
+  )
+ExternalData_Add_Target(Data2)
diff --git a/Tests/Module/ExternalData/Data2/Data2Check.cmake b/Tests/Module/ExternalData/Data2/Data2Check.cmake
new file mode 100644 (file)
index 0000000..d5b0c7b
--- /dev/null
@@ -0,0 +1,12 @@
+foreach(d "${Data2}" "${Data2b}")
+  file(STRINGS "${d}" lines LIMIT_INPUT 1024)
+  if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
+    message(SEND_ERROR "Input file:\n  ${d}\ndoes not have expected content, but [[${lines}]]")
+  endif()
+endforeach()
+foreach(n 1 2 3)
+  string(REGEX REPLACE "_1_\\.my\\.dat$" "_${n}_.my.dat" SeriesCFile "${SeriesC}")
+  if(NOT EXISTS "${SeriesCFile}")
+    message(SEND_ERROR "Input file:\n  ${SeriesCFile}\ndoes not exist!")
+  endif()
+endforeach()
diff --git a/Tests/Module/ExternalData/Data2/SeriesC_1_.my.dat.md5 b/Tests/Module/ExternalData/Data2/SeriesC_1_.my.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/Data2/SeriesC_2_.my.dat.md5 b/Tests/Module/ExternalData/Data2/SeriesC_2_.my.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/Data2/SeriesC_3_.my.dat.md5 b/Tests/Module/ExternalData/Data2/SeriesC_3_.my.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/Data2b.dat.md5 b/Tests/Module/ExternalData/Data2b.dat.md5
new file mode 100644 (file)
index 0000000..70e39bd
--- /dev/null
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data3/CMakeLists.txt b/Tests/Module/ExternalData/Data3/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a7c2b6e
--- /dev/null
@@ -0,0 +1,14 @@
+set(Store0 ${CMAKE_BINARY_DIR}/ExternalData/Other)
+set(Store1 ${CMAKE_BINARY_DIR}/ExternalData/Objects)
+set(ExternalData_OBJECT_STORES ${Store0} ${Store1})
+ExternalData_Add_Test(Data3
+  NAME Data3Check
+  COMMAND ${CMAKE_COMMAND}
+    -D Data=DATA{Data.dat}
+    -D Other=DATA{Other.dat}
+    -D Store0=${Store0}
+    -D Store1=${Store1}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/Data3Check.cmake
+  )
+ExternalData_Add_Target(Data3)
+add_dependencies(Data3 Data1 Data2)
diff --git a/Tests/Module/ExternalData/Data3/Data.dat.md5 b/Tests/Module/ExternalData/Data3/Data.dat.md5
new file mode 100644 (file)
index 0000000..70e39bd
--- /dev/null
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/ExternalData/Data3/Data3Check.cmake b/Tests/Module/ExternalData/Data3/Data3Check.cmake
new file mode 100644 (file)
index 0000000..de98839
--- /dev/null
@@ -0,0 +1,25 @@
+if(NOT EXISTS "${Data}")
+  message(SEND_ERROR "Input file:\n  ${Data}\ndoes not exist!")
+endif()
+if(NOT EXISTS "${Other}")
+  message(SEND_ERROR "Input file:\n  ${Other}\ndoes not exist!")
+endif()
+# Verify that the 'Data' object was found in the second store location left
+# from Data1 target downloads and that the 'Other' object was downloaded to
+# our first store location.  Neither object should exist in the other store.
+foreach(should_exist
+    "${Store0}/MD5/aaad162b85f60d1eb57ca71a23e8efd7"
+    "${Store1}/MD5/8c018830e3efa5caf3c7415028335a57"
+    )
+  if(NOT EXISTS ${should_exist})
+    message(SEND_ERROR "Store file:\n  ${should_exist}\nshould exist!")
+  endif()
+endforeach()
+foreach(should_not_exist
+    "${Store0}/MD5/8c018830e3efa5caf3c7415028335a57"
+    "${Store1}/MD5/aaad162b85f60d1eb57ca71a23e8efd7"
+    )
+  if(EXISTS ${should_not_exist})
+    message(SEND_ERROR "Store file:\n  ${should_not_exist}\nshould not exist!")
+  endif()
+endforeach()
diff --git a/Tests/Module/ExternalData/Data3/Other.dat.md5 b/Tests/Module/ExternalData/Data3/Other.dat.md5
new file mode 100644 (file)
index 0000000..5312faa
--- /dev/null
@@ -0,0 +1 @@
+aaad162b85f60d1eb57ca71a23e8efd7
diff --git a/Tests/Module/ExternalData/Directory/A.dat.md5 b/Tests/Module/ExternalData/Directory/A.dat.md5
new file mode 100644 (file)
index 0000000..4a78fc7
--- /dev/null
@@ -0,0 +1 @@
+9d980b06c2f0fec3d4872d68175b9822
diff --git a/Tests/Module/ExternalData/Directory/B.dat.md5 b/Tests/Module/ExternalData/Directory/B.dat.md5
new file mode 100644 (file)
index 0000000..4557a21
--- /dev/null
@@ -0,0 +1 @@
+8f4add4581551facf27237e6577fd662
diff --git a/Tests/Module/ExternalData/Directory/C.dat.md5 b/Tests/Module/ExternalData/Directory/C.dat.md5
new file mode 100644 (file)
index 0000000..a7f23dd
--- /dev/null
@@ -0,0 +1 @@
+c1030719c95f3435d8abc39c0d442946
diff --git a/Tests/Module/ExternalData/MD5/.gitattributes b/Tests/Module/ExternalData/MD5/.gitattributes
new file mode 100644 (file)
index 0000000..3e51d39
--- /dev/null
@@ -0,0 +1 @@
+*               -crlf
diff --git a/Tests/Module/ExternalData/MD5/08cfcf221f76ace7b906b312284e73d7 b/Tests/Module/ExternalData/MD5/08cfcf221f76ace7b906b312284e73d7
new file mode 100644 (file)
index 0000000..a689e3c
--- /dev/null
@@ -0,0 +1 @@
+MetaTop
diff --git a/Tests/Module/ExternalData/MD5/30ba0acdee9096b3b9fc6c69362c6b42 b/Tests/Module/ExternalData/MD5/30ba0acdee9096b3b9fc6c69362c6b42
new file mode 100644 (file)
index 0000000..5491241
--- /dev/null
@@ -0,0 +1 @@
+Series.3
diff --git a/Tests/Module/ExternalData/MD5/31eff09e84fca01415f8cd9d82ec432b b/Tests/Module/ExternalData/MD5/31eff09e84fca01415f8cd9d82ec432b
new file mode 100644 (file)
index 0000000..4d0475e
--- /dev/null
@@ -0,0 +1 @@
+Series.1
diff --git a/Tests/Module/ExternalData/MD5/401767f22a456b3522953722090a2c36 b/Tests/Module/ExternalData/MD5/401767f22a456b3522953722090a2c36
new file mode 100644 (file)
index 0000000..9dec116
--- /dev/null
@@ -0,0 +1 @@
+PairedA
diff --git a/Tests/Module/ExternalData/MD5/8c018830e3efa5caf3c7415028335a57 b/Tests/Module/ExternalData/MD5/8c018830e3efa5caf3c7415028335a57
new file mode 100644 (file)
index 0000000..fa701e2
--- /dev/null
@@ -0,0 +1 @@
+Input file already transformed.
diff --git a/Tests/Module/ExternalData/MD5/8f4add4581551facf27237e6577fd662 b/Tests/Module/ExternalData/MD5/8f4add4581551facf27237e6577fd662
new file mode 100644 (file)
index 0000000..69ba09c
--- /dev/null
@@ -0,0 +1 @@
+MetaB
diff --git a/Tests/Module/ExternalData/MD5/9d980b06c2f0fec3d4872d68175b9822 b/Tests/Module/ExternalData/MD5/9d980b06c2f0fec3d4872d68175b9822
new file mode 100644 (file)
index 0000000..000e7b2
--- /dev/null
@@ -0,0 +1 @@
+MetaA
diff --git a/Tests/Module/ExternalData/MD5/aaad162b85f60d1eb57ca71a23e8efd7 b/Tests/Module/ExternalData/MD5/aaad162b85f60d1eb57ca71a23e8efd7
new file mode 100644 (file)
index 0000000..df0510c
--- /dev/null
@@ -0,0 +1 @@
+Another input file already transformed.
diff --git a/Tests/Module/ExternalData/MD5/c1030719c95f3435d8abc39c0d442946 b/Tests/Module/ExternalData/MD5/c1030719c95f3435d8abc39c0d442946
new file mode 100644 (file)
index 0000000..3fac5e6
--- /dev/null
@@ -0,0 +1 @@
+MetaC
diff --git a/Tests/Module/ExternalData/MD5/ce38ea6c3c1e00fa6405dd64b8bf6da0 b/Tests/Module/ExternalData/MD5/ce38ea6c3c1e00fa6405dd64b8bf6da0
new file mode 100644 (file)
index 0000000..362d4b4
--- /dev/null
@@ -0,0 +1 @@
+SeriesMixed.1
diff --git a/Tests/Module/ExternalData/MD5/ecfa1ecd417d4253af81ae04d1bd6581 b/Tests/Module/ExternalData/MD5/ecfa1ecd417d4253af81ae04d1bd6581
new file mode 100644 (file)
index 0000000..8c414f5
--- /dev/null
@@ -0,0 +1 @@
+PairedB
diff --git a/Tests/Module/ExternalData/MD5/f41c94425d01ecbbee70440b951cb058 b/Tests/Module/ExternalData/MD5/f41c94425d01ecbbee70440b951cb058
new file mode 100644 (file)
index 0000000..3503da4
--- /dev/null
@@ -0,0 +1 @@
+Series
diff --git a/Tests/Module/ExternalData/MD5/f7ab5a04aae9cb9a520e70b20b9c8ed7 b/Tests/Module/ExternalData/MD5/f7ab5a04aae9cb9a520e70b20b9c8ed7
new file mode 100644 (file)
index 0000000..29d727b
--- /dev/null
@@ -0,0 +1 @@
+Series.2
diff --git a/Tests/Module/ExternalData/MetaA.dat.md5 b/Tests/Module/ExternalData/MetaA.dat.md5
new file mode 100644 (file)
index 0000000..4a78fc7
--- /dev/null
@@ -0,0 +1 @@
+9d980b06c2f0fec3d4872d68175b9822
diff --git a/Tests/Module/ExternalData/MetaB.dat.md5 b/Tests/Module/ExternalData/MetaB.dat.md5
new file mode 100644 (file)
index 0000000..4557a21
--- /dev/null
@@ -0,0 +1 @@
+8f4add4581551facf27237e6577fd662
diff --git a/Tests/Module/ExternalData/MetaC.dat.md5 b/Tests/Module/ExternalData/MetaC.dat.md5
new file mode 100644 (file)
index 0000000..a7f23dd
--- /dev/null
@@ -0,0 +1 @@
+c1030719c95f3435d8abc39c0d442946
diff --git a/Tests/Module/ExternalData/MetaTop.dat.md5 b/Tests/Module/ExternalData/MetaTop.dat.md5
new file mode 100644 (file)
index 0000000..1906cbf
--- /dev/null
@@ -0,0 +1 @@
+08cfcf221f76ace7b906b312284e73d7
diff --git a/Tests/Module/ExternalData/PairedA.dat.md5 b/Tests/Module/ExternalData/PairedA.dat.md5
new file mode 100644 (file)
index 0000000..1ffe035
--- /dev/null
@@ -0,0 +1 @@
+401767f22a456b3522953722090a2c36
diff --git a/Tests/Module/ExternalData/PairedB.dat.md5 b/Tests/Module/ExternalData/PairedB.dat.md5
new file mode 100644 (file)
index 0000000..89c942b
--- /dev/null
@@ -0,0 +1 @@
+ecfa1ecd417d4253af81ae04d1bd6581
diff --git a/Tests/Module/ExternalData/SHA1/.gitattributes b/Tests/Module/ExternalData/SHA1/.gitattributes
new file mode 100644 (file)
index 0000000..3e51d39
--- /dev/null
@@ -0,0 +1 @@
+*               -crlf
diff --git a/Tests/Module/ExternalData/SHA1/2af59a7022024974f3b8521b7ed8137c996a79f1 b/Tests/Module/ExternalData/SHA1/2af59a7022024974f3b8521b7ed8137c996a79f1
new file mode 100644 (file)
index 0000000..a388540
--- /dev/null
@@ -0,0 +1 @@
+SeriesMixed.2
diff --git a/Tests/Module/ExternalData/SHA224/.gitattributes b/Tests/Module/ExternalData/SHA224/.gitattributes
new file mode 100644 (file)
index 0000000..3e51d39
--- /dev/null
@@ -0,0 +1 @@
+*               -crlf
diff --git a/Tests/Module/ExternalData/SHA224/3b679da7908562fe1cc28db47ffb89bae025f4551dceb343a5869174 b/Tests/Module/ExternalData/SHA224/3b679da7908562fe1cc28db47ffb89bae025f4551dceb343a5869174
new file mode 100644 (file)
index 0000000..e806d98
--- /dev/null
@@ -0,0 +1 @@
+SeriesMixed.3
diff --git a/Tests/Module/ExternalData/SHA256/.gitattributes b/Tests/Module/ExternalData/SHA256/.gitattributes
new file mode 100644 (file)
index 0000000..3e51d39
--- /dev/null
@@ -0,0 +1 @@
+*               -crlf
diff --git a/Tests/Module/ExternalData/SHA256/969171a0dd70d49ce096bd3e8178c7e26c711c9b20dbcaa3853d869d3871f133 b/Tests/Module/ExternalData/SHA256/969171a0dd70d49ce096bd3e8178c7e26c711c9b20dbcaa3853d869d3871f133
new file mode 100644 (file)
index 0000000..e3d1e0c
--- /dev/null
@@ -0,0 +1 @@
+SeriesMixed.4
diff --git a/Tests/Module/ExternalData/SeriesA.dat.md5 b/Tests/Module/ExternalData/SeriesA.dat.md5
new file mode 100644 (file)
index 0000000..be2d687
--- /dev/null
@@ -0,0 +1 @@
+f41c94425d01ecbbee70440b951cb058
diff --git a/Tests/Module/ExternalData/SeriesA1.dat.md5 b/Tests/Module/ExternalData/SeriesA1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesA2.dat.md5 b/Tests/Module/ExternalData/SeriesA2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesA3.dat.md5 b/Tests/Module/ExternalData/SeriesA3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesAn1.dat.md5 b/Tests/Module/ExternalData/SeriesAn1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesAn2.dat.md5 b/Tests/Module/ExternalData/SeriesAn2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesAn3.dat.md5 b/Tests/Module/ExternalData/SeriesAn3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesB.dat.md5 b/Tests/Module/ExternalData/SeriesB.dat.md5
new file mode 100644 (file)
index 0000000..be2d687
--- /dev/null
@@ -0,0 +1 @@
+f41c94425d01ecbbee70440b951cb058
diff --git a/Tests/Module/ExternalData/SeriesB_1.dat.md5 b/Tests/Module/ExternalData/SeriesB_1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesB_2.dat.md5 b/Tests/Module/ExternalData/SeriesB_2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesB_3.dat.md5 b/Tests/Module/ExternalData/SeriesB_3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesBn_1.dat.md5 b/Tests/Module/ExternalData/SeriesBn_1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesBn_2.dat.md5 b/Tests/Module/ExternalData/SeriesBn_2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesBn_3.dat.md5 b/Tests/Module/ExternalData/SeriesBn_3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesC.1.dat.md5 b/Tests/Module/ExternalData/SeriesC.1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesC.2.dat.md5 b/Tests/Module/ExternalData/SeriesC.2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesC.3.dat.md5 b/Tests/Module/ExternalData/SeriesC.3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesC.dat.md5 b/Tests/Module/ExternalData/SeriesC.dat.md5
new file mode 100644 (file)
index 0000000..be2d687
--- /dev/null
@@ -0,0 +1 @@
+f41c94425d01ecbbee70440b951cb058
diff --git a/Tests/Module/ExternalData/SeriesCn.1.dat.md5 b/Tests/Module/ExternalData/SeriesCn.1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesCn.2.dat.md5 b/Tests/Module/ExternalData/SeriesCn.2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesCn.3.dat.md5 b/Tests/Module/ExternalData/SeriesCn.3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesD-1.dat.md5 b/Tests/Module/ExternalData/SeriesD-1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesD-2.dat.md5 b/Tests/Module/ExternalData/SeriesD-2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesD-3.dat.md5 b/Tests/Module/ExternalData/SeriesD-3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesD.dat.md5 b/Tests/Module/ExternalData/SeriesD.dat.md5
new file mode 100644 (file)
index 0000000..be2d687
--- /dev/null
@@ -0,0 +1 @@
+f41c94425d01ecbbee70440b951cb058
diff --git a/Tests/Module/ExternalData/SeriesDn-1.dat.md5 b/Tests/Module/ExternalData/SeriesDn-1.dat.md5
new file mode 100644 (file)
index 0000000..f22e266
--- /dev/null
@@ -0,0 +1 @@
+31eff09e84fca01415f8cd9d82ec432b
diff --git a/Tests/Module/ExternalData/SeriesDn-2.dat.md5 b/Tests/Module/ExternalData/SeriesDn-2.dat.md5
new file mode 100644 (file)
index 0000000..2b917e7
--- /dev/null
@@ -0,0 +1 @@
+f7ab5a04aae9cb9a520e70b20b9c8ed7
diff --git a/Tests/Module/ExternalData/SeriesDn-3.dat.md5 b/Tests/Module/ExternalData/SeriesDn-3.dat.md5
new file mode 100644 (file)
index 0000000..b9c9760
--- /dev/null
@@ -0,0 +1 @@
+30ba0acdee9096b3b9fc6c69362c6b42
diff --git a/Tests/Module/ExternalData/SeriesMixed.1.dat.md5 b/Tests/Module/ExternalData/SeriesMixed.1.dat.md5
new file mode 100644 (file)
index 0000000..f962d8f
--- /dev/null
@@ -0,0 +1 @@
+ce38ea6c3c1e00fa6405dd64b8bf6da0
diff --git a/Tests/Module/ExternalData/SeriesMixed.2.dat.sha1 b/Tests/Module/ExternalData/SeriesMixed.2.dat.sha1
new file mode 100644 (file)
index 0000000..43a3540
--- /dev/null
@@ -0,0 +1 @@
+2af59a7022024974f3b8521b7ed8137c996a79f1
diff --git a/Tests/Module/ExternalData/SeriesMixed.3.dat.sha224 b/Tests/Module/ExternalData/SeriesMixed.3.dat.sha224
new file mode 100644 (file)
index 0000000..a18e40e
--- /dev/null
@@ -0,0 +1 @@
+3b679da7908562fe1cc28db47ffb89bae025f4551dceb343a5869174
diff --git a/Tests/Module/ExternalData/SeriesMixed.4.dat.sha256 b/Tests/Module/ExternalData/SeriesMixed.4.dat.sha256
new file mode 100644 (file)
index 0000000..67fc3c2
--- /dev/null
@@ -0,0 +1 @@
+969171a0dd70d49ce096bd3e8178c7e26c711c9b20dbcaa3853d869d3871f133
index 36c86e7..55778ea 100644 (file)
@@ -13,6 +13,6 @@ add_custom_command(
   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
                                    ${CMAKE_CURRENT_BINARY_DIR}/a1.c
   )
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 add_library(A OBJECT a1.c a2.c)
+target_include_directories(A PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
index 32d8ceb..a567f96 100644 (file)
@@ -10,7 +10,11 @@ if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
   set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
 endif()
 
-add_definitions(-DB_DEF)
 add_library(B OBJECT b1.c b2.c)
+target_include_directories(B PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(B PUBLIC B_DEF)
+
 add_library(Bexport OBJECT b1${vs6}.c b2${vs6}.c)
 set_property(TARGET Bexport PROPERTY COMPILE_DEFINITIONS Bexport)
+target_include_directories(Bexport PRIVATE $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(Bexport PRIVATE $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
index 11b22f4..3489c71 100644 (file)
@@ -4,8 +4,15 @@
 #ifndef B_DEF
 # error "B_DEF not defined"
 #endif
+
 #if defined(_WIN32) && defined(Bexport)
 # define EXPORT_B __declspec(dllexport)
 #else
 # define EXPORT_B
 #endif
+
+#if defined(_WIN32) && defined(SHARED_B)
+# define IMPORT_B __declspec(dllimport)
+#else
+# define IMPORT_B
+#endif
index 8723415..13a07b4 100644 (file)
@@ -26,6 +26,9 @@ endif()
 
 # Test static library without its own sources.
 add_library(ABstatic STATIC ${dummy} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+target_include_directories(ABstatic PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABstatic PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
+
 add_executable(UseABstatic mainAB.c)
 target_link_libraries(UseABstatic ABstatic)
 
@@ -41,12 +44,17 @@ endif()
 
 # Test shared library without its own sources.
 add_library(ABshared SHARED ${dummy} ${ABshared_SRCS})
+target_include_directories(ABshared PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABshared PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
+
 add_executable(UseABshared mainAB.c)
 set_property(TARGET UseABshared PROPERTY COMPILE_DEFINITIONS SHARED_B ${NO_A})
 target_link_libraries(UseABshared ABshared)
 
 # Test executable without its own sources.
 add_library(ABmain OBJECT mainAB.c)
+target_include_directories(ABmain PUBLIC $<TARGET_PROPERTY:B,INTERFACE_INCLUDE_DIRECTORIES>)
+target_compile_definitions(ABmain PUBLIC $<TARGET_PROPERTY:B,INTERFACE_COMPILE_DEFINITIONS>)
 add_executable(UseABinternal ${dummy}
   $<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
   )
index 556898b..38db205 100644 (file)
@@ -1,8 +1,6 @@
-#if defined(_WIN32) && defined(SHARED_B)
-# define IMPORT_B __declspec(dllimport)
-#else
-# define IMPORT_B
-#endif
+
+#include "b.h"
+
 extern IMPORT_B int b1(void);
 extern IMPORT_B int b2(void);
 #ifndef NO_A
index 78746e7..ad119cc 100644 (file)
@@ -40,6 +40,9 @@ endif()
 if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
   set(PP_VS110 1)
 endif()
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 12")
+  set(PP_VS120 1)
+endif()
 
 # Some tests below check the PP_* variables set above.  They are meant
 # to test the case that the build tool is at fault.  Other tests below
@@ -55,7 +58,8 @@ endif()
 # must not have it escaped inside the configured header.
 set(STRING_EXTRA "")
 
-if(NOT BORLAND AND NOT PP_VS70 AND NOT PP_VS100 AND NOT PP_VS110)
+if(NOT BORLAND AND NOT PP_VS70
+    AND NOT PP_VS100 AND NOT PP_VS110 AND NOT PP_VS120)
   # Borland, VS70 IDE: ;
   # The Borland compiler will simply not accept a non-escaped semicolon
   # on the command line.  If it is escaped \; then the escape character
diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d0c9c66
--- /dev/null
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(Qt4Targets)
+
+cmake_policy(SET CMP0020 NEW)
+
+find_package(Qt4 REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_executable(Qt4Targets WIN32 main.cpp)
+target_link_libraries(Qt4Targets Qt4::QtGui)
+
+if (WIN32)
+  if (TARGET Qt4::QAxServer)
+    add_executable(activeqtexe WIN32 activeqtexe.cpp)
+    set_property(TARGET activeqtexe PROPERTY QT4_NO_LINK_QTMAIN ON)
+    target_link_libraries(activeqtexe Qt4::QAxServer Qt4::QtGui)
+  endif()
+endif()
diff --git a/Tests/Qt4Targets/activeqtexe.cpp b/Tests/Qt4Targets/activeqtexe.cpp
new file mode 100644 (file)
index 0000000..d4a9121
--- /dev/null
@@ -0,0 +1,36 @@
+
+#include <QApplication>
+
+#ifndef QT_QAXSERVER_LIB
+#error Expected QT_QAXSERVER_LIB
+#endif
+
+#include <QAxFactory>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject *parent = 0)
+     : QObject(parent)
+ {
+ }
+};
+
+QAXFACTORY_DEFAULT(MyObject,
+                    "{4dc3f340-a6f7-44e4-a79b-3e9217685fbd}",
+                    "{9ee49617-7d5c-441a-b833-4b068d41d751}",
+                    "{13eca64b-ee2a-4f3c-aa04-5d9d975779a7}",
+                    "{ce947ee3-0403-4fdc-895a-4fe779344b46}",
+                    "{8de435ce-8d2a-46ac-b3b3-cb800d0547c7}");
+
+int main(int argc, char **argv)
+{
+  QApplication app(argc, argv);
+
+  QAxFactory::isServer();
+
+  return app.exec();
+}
+
+#include "activeqtexe.moc"
diff --git a/Tests/Qt4Targets/main.cpp b/Tests/Qt4Targets/main.cpp
new file mode 100644 (file)
index 0000000..3c98c99
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include <QApplication>
+#include <QWidget>
+
+#include <QString>
+
+#ifndef QT_CORE_LIB
+#error Expected QT_CORE_LIB
+#endif
+
+#ifndef QT_GUI_LIB
+#error Expected QT_GUI_LIB
+#endif
+
+int main(int argc, char **argv)
+{
+  QApplication app(argc, argv);
+
+  QWidget w;
+  w.setWindowTitle(QString::fromLatin1("SomeTitle"));
+  w.show();
+
+  return 0;
+}
diff --git a/Tests/QtAutomoc/Adir/CMakeLists.txt b/Tests/QtAutomoc/Adir/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1712223
--- /dev/null
@@ -0,0 +1,8 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+add_library(libA SHARED libA.cpp)
+target_link_libraries(libA LINK_PUBLIC Qt4::QtCore)
+generate_export_header(libA)
diff --git a/Tests/QtAutomoc/Adir/libA.cpp b/Tests/QtAutomoc/Adir/libA.cpp
new file mode 100644 (file)
index 0000000..3968c44
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include "libA.h"
+
+LibA::LibA(QObject *parent)
+  : QObject(parent)
+{
+
+}
+
+int LibA::foo()
+{
+  return 0;
+}
diff --git a/Tests/QtAutomoc/Adir/libA.h b/Tests/QtAutomoc/Adir/libA.h
new file mode 100644 (file)
index 0000000..03ad1e0
--- /dev/null
@@ -0,0 +1,18 @@
+
+#ifndef LIBA_H
+#define LIBA_H
+
+#include "liba_export.h"
+
+#include <QObject>
+
+class LIBA_EXPORT LibA : public QObject
+{
+  Q_OBJECT
+public:
+  explicit LibA(QObject *parent = 0);
+
+  int foo();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/Bdir/CMakeLists.txt b/Tests/QtAutomoc/Bdir/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d9d4aa7
--- /dev/null
@@ -0,0 +1,10 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+add_library(libB SHARED libB.cpp)
+generate_export_header(libB)
+
+# set_property(TARGET libB APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
+target_link_libraries(libB LINK_PUBLIC libA)
diff --git a/Tests/QtAutomoc/Bdir/libB.cpp b/Tests/QtAutomoc/Bdir/libB.cpp
new file mode 100644 (file)
index 0000000..72f2cfa
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include "libB.h"
+
+LibB::LibB(QObject *parent)
+  : QObject(parent)
+{
+
+}
+
+int LibB::foo()
+{
+  return a.foo();
+}
diff --git a/Tests/QtAutomoc/Bdir/libB.h b/Tests/QtAutomoc/Bdir/libB.h
new file mode 100644 (file)
index 0000000..510c17f
--- /dev/null
@@ -0,0 +1,21 @@
+
+#ifndef LIBB_H
+#define LIBB_H
+
+#include "libb_export.h"
+
+#include <QObject>
+#include "libA.h"
+
+class LIBB_EXPORT LibB : public QObject
+{
+  Q_OBJECT
+public:
+  explicit LibB(QObject *parent = 0);
+
+  int foo();
+private:
+  LibA a;
+};
+
+#endif
index 5e3686d..fd624c8 100644 (file)
@@ -13,11 +13,34 @@ add_definitions(-DFOO -DSomeDefine="Barx")
 # enable relaxed mode so automoc can handle all the special cases:
 set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
 
-# create an executable and a library target, both requiring automoc:
+# create an executable and two library targets, each requiring automoc:
 add_library(codeeditorLib STATIC codeeditor.cpp)
 
-add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp private_slot.cpp)
-
-set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE)
-
-target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
+add_library(privateSlot OBJECT private_slot.cpp)
+
+add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
+               xyz.cpp yaf.cpp $<TARGET_OBJECTS:privateSlot>)
+
+set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
+
+include(GenerateExportHeader)
+# The order is relevant here. B depends on A, and B headers depend on A
+# headers both subdirectories use CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE and we
+# test that CMAKE_AUTOMOC successfully reads the include directories
+# for the build interface from those targets. There has previously been
+# a bug where caching of the include directories happened before
+# extracting the includes to pass to moc.
+add_subdirectory(Bdir)
+add_subdirectory(Adir)
+add_library(libC SHARED libC.cpp)
+set_target_properties(libC PROPERTIES AUTOMOC TRUE)
+generate_export_header(libC)
+target_link_libraries(libC LINK_PUBLIC libB)
+
+target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} libC)
+
+add_library(empty STATIC empty.cpp)
+set_target_properties(empty PROPERTIES AUTOMOC TRUE)
+target_link_libraries(empty no_link_language)
+add_library(no_link_language STATIC empty.h)
+set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
diff --git a/Tests/QtAutomoc/empty.cpp b/Tests/QtAutomoc/empty.cpp
new file mode 100644 (file)
index 0000000..ab32cf6
--- /dev/null
@@ -0,0 +1 @@
+// No content
diff --git a/Tests/QtAutomoc/empty.h b/Tests/QtAutomoc/empty.h
new file mode 100644 (file)
index 0000000..4566142
--- /dev/null
@@ -0,0 +1,9 @@
+
+#include <QObject>
+
+class Empty : public QObject
+{
+  Q_OBJECT
+public:
+  explicit Empty(QObject *parent = 0) {}
+};
diff --git a/Tests/QtAutomoc/libC.cpp b/Tests/QtAutomoc/libC.cpp
new file mode 100644 (file)
index 0000000..8d61cb1
--- /dev/null
@@ -0,0 +1,13 @@
+
+#include "libC.h"
+
+LibC::LibC(QObject *parent)
+  : QObject(parent)
+{
+
+}
+
+int LibC::foo()
+{
+  return b.foo();
+}
diff --git a/Tests/QtAutomoc/libC.h b/Tests/QtAutomoc/libC.h
new file mode 100644 (file)
index 0000000..4fb4a2c
--- /dev/null
@@ -0,0 +1,22 @@
+
+#ifndef LIBC_H
+#define LIBC_H
+
+#include "libc_export.h"
+
+#include <QObject>
+#include "libB.h"
+
+class LIBC_EXPORT LibC : public QObject
+{
+  Q_OBJECT
+public:
+  explicit LibC(QObject *parent = 0);
+
+
+  int foo();
+private:
+  LibB b;
+};
+
+#endif
index 738f677..d952171 100644 (file)
@@ -48,6 +48,7 @@
 #include "abc.h"
 #include "xyz.h"
 #include "yaf.h"
+#include "libC.h"
 
 int main(int argv, char **args)
 {
@@ -78,5 +79,8 @@ int main(int argv, char **args)
   Yaf yaf;
   yaf.doYaf();
 
+  LibC lc;
+  lc.foo();
+
   return app.exec();
 }
diff --git a/Tests/QtAutomocNoQt/CMakeLists.txt b/Tests/QtAutomocNoQt/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b26e471
--- /dev/null
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(QtAutomocNoQt)
+
+set(CMAKE_AUTOMOC ON)
+
+add_executable(hello main.c)
diff --git a/Tests/QtAutomocNoQt/main.c b/Tests/QtAutomocNoQt/main.c
new file mode 100644 (file)
index 0000000..8488f4e
--- /dev/null
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RegexEscapeString.cmake b/Tests/RegexEscapeString.cmake
new file mode 100644 (file)
index 0000000..92aed17
--- /dev/null
@@ -0,0 +1,4 @@
+macro(REGEX_ESCAPE_STRING _OUT _IN)
+    # Escape special regex metacharacters with a backslash
+    string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}")
+endmacro()
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt
new file mode 100644 (file)
index 0000000..a21cb6a
--- /dev/null
@@ -0,0 +1,2 @@
+  Target "foo" links to item " bar " which has leading or trailing
+  whitespace.  This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake b/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake
new file mode 100644 (file)
index 0000000..7c61961
--- /dev/null
@@ -0,0 +1,9 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt
new file mode 100644 (file)
index 0000000..782e45c
--- /dev/null
@@ -0,0 +1,2 @@
+  Target "bat" links to item " bar " which has leading or trailing
+  whitespace.  This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake b/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake
new file mode 100644 (file)
index 0000000..d6ed72c
--- /dev/null
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 OLD)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bing SHARED empty.cpp)
+add_library(bung SHARED empty.cpp)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(bat SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
+target_link_libraries(bing "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+target_link_libraries(bung "$<$<TARGET_POLICY:CMP0004>: bar >")
+
+# The line below causes the error because the policy is NEW when bat
+# is created.
+target_link_libraries(bat "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt
new file mode 100644 (file)
index 0000000..eed53e7
--- /dev/null
@@ -0,0 +1,2 @@
+  Target "foo" links to item " bat " which has leading or trailing
+  whitespace.  This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake b/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake
new file mode 100644 (file)
index 0000000..eab680a
--- /dev/null
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bat SHARED empty.cpp)
+
+# The negation here avoids the error.
+target_link_libraries(foo "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+
+# The below line causes the error.
+target_link_libraries(foo "$<$<TARGET_POLICY:CMP0004>: bat >")
diff --git a/Tests/RunCMake/CMP0004/CMakeLists.txt b/Tests/RunCMake/CMP0004/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0004/RunCMakeTest.cmake b/Tests/RunCMake/CMP0004/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..950d0ed
--- /dev/null
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0004-OLD)
+run_cmake(CMP0004-NEW)
+run_cmake(CMP0004-policy-genex)
diff --git a/Tests/RunCMake/CMP0004/empty.cpp b/Tests/RunCMake/CMP0004/empty.cpp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake b/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake
new file mode 100644 (file)
index 0000000..3091e66
--- /dev/null
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0019 NEW)
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake b/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake
new file mode 100644 (file)
index 0000000..0f02f9c
--- /dev/null
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0019 OLD)
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
new file mode 100644 (file)
index 0000000..03faef9
--- /dev/null
@@ -0,0 +1,40 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0019 is not set: Do not re-expand variables in include and link
+  information.  Run "cmake --help-policy CMP0019" for policy details.  Use
+  the cmake_policy command to set the policy and suppress this warning.
+
+  The following variable evaluations were encountered:
+
+  Evaluated directory INCLUDE_DIRECTORIES
+
+    /usr/include/\${VAR_INCLUDE};/usr/include/normal
+
+  as
+
+    /usr/include/VAL_INCLUDE;/usr/include/normal
+
+  Evaluated target some_target INCLUDE_DIRECTORIES
+
+    /usr/include/\${VAR_INCLUDE};/usr/include/normal
+
+  as
+
+    /usr/include/VAL_INCLUDE;/usr/include/normal
+
+  Evaluated link directory
+
+    /usr/lib/\${VAR_LINK_DIRS}
+
+  as
+
+    /usr/lib/VAL_LINK_DIRS
+
+  Evaluated link library
+
+    \${VAR_LINK_LIBS}
+
+  as
+
+    VAL_LINK_LIBS
+
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake b/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake
new file mode 100644 (file)
index 0000000..a419f30
--- /dev/null
@@ -0,0 +1 @@
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-code.cmake b/Tests/RunCMake/CMP0019/CMP0019-code.cmake
new file mode 100644 (file)
index 0000000..26c0e5b
--- /dev/null
@@ -0,0 +1,9 @@
+set(VAR_INCLUDE "VAL_INCLUDE")
+set(VAR_LINK_DIRS "VAL_LINK_DIRS")
+set(VAR_LINK_LIBS "VAL_LINK_LIBS")
+add_custom_target(some_target)
+include_directories("/usr/include/\${VAR_INCLUDE}" /usr/include/normal)
+link_directories("/usr/lib/\${VAR_LINK_DIRS}"  /usr/lib/normal)
+link_libraries("\${VAR_LINK_LIBS}" normal)
+add_custom_target(other_target)
+set_property(TARGET other_target PROPERTY INCLUDE_DIRECTORIES "")
diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0019/RunCMakeTest.cmake b/Tests/RunCMake/CMP0019/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..119fc2b
--- /dev/null
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0019-WARN)
+run_cmake(CMP0019-OLD)
+run_cmake(CMP0019-NEW)
index 8c67625..402c8a9 100644 (file)
@@ -39,23 +39,50 @@ macro(add_RunCMake_test test)
   add_test(RunCMake.${test} ${CMAKE_CMAKE_COMMAND}
     -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
     -DRunCMake_GENERATOR=${CMAKE_TEST_GENERATOR}
+    -DRunCMake_GENERATOR_TOOLSET=${CMAKE_TEST_GENERATOR_TOOLSET}
     -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test}
     -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test}
+    ${${test}_ARGS}
     -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake"
     )
 endmacro()
 
+if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3)
+  set(GeneratorToolset_ARGS -DXCODE_BELOW_3=1)
+endif()
+
+add_RunCMake_test(CMP0019)
+add_RunCMake_test(CTest)
+if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
+  add_RunCMake_test(CompilerChange)
+endif()
+add_RunCMake_test(ExternalData)
+add_RunCMake_test(FPHSA)
 add_RunCMake_test(GeneratorExpression)
+add_RunCMake_test(GeneratorToolset)
 add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
 add_RunCMake_test(ObjectLibrary)
+if(NOT WIN32)
+  add_RunCMake_test(PositionIndependentCode)
+endif()
+add_RunCMake_test(CompatibleInterface)
 
+add_RunCMake_test(add_dependencies)
 add_RunCMake_test(build_command)
 add_RunCMake_test(find_package)
 add_RunCMake_test(include)
 add_RunCMake_test(include_directories)
 add_RunCMake_test(list)
+add_RunCMake_test(CMP0004)
+
+find_package(Qt4 QUIET)
+find_package(Qt5Core QUIET)
+if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
+  add_RunCMake_test(IncompatibleQt)
+endif()
 
 if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
   add_RunCMake_test(include_external_msproject)
+  add_RunCMake_test(SolutionGlobalSections)
 endif()
diff --git a/Tests/RunCMake/CTest/BeforeProject-result.txt b/Tests/RunCMake/CTest/BeforeProject-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTest/BeforeProject-stderr.txt b/Tests/RunCMake/CTest/BeforeProject-stderr.txt
new file mode 100644 (file)
index 0000000..354896b
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/CTest.cmake:[0-9]+ \(build_command\):
+  build_command\(\) requires CMAKE_MAKE_PROGRAM to be defined.  Call project\(\)
+  or enable_language\(\) first.
+Call Stack \(most recent call first\):
+  BeforeProject.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CTest/BeforeProject.cmake b/Tests/RunCMake/CTest/BeforeProject.cmake
new file mode 100644 (file)
index 0000000..903ca69
--- /dev/null
@@ -0,0 +1,2 @@
+include(CTest)
+project(${RunCMake_TEST} NONE)
diff --git a/Tests/RunCMake/CTest/CMakeLists.txt b/Tests/RunCMake/CTest/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f6e84c0
--- /dev/null
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8)
+if(NOT NoProject)
+  project(${RunCMake_TEST} NONE)
+endif()
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CTest/RunCMakeTest.cmake b/Tests/RunCMake/CTest/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..a6f6842
--- /dev/null
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS -DNoProject=1)
+run_cmake(BeforeProject)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
new file mode 100644 (file)
index 0000000..68dd8d6
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt
new file mode 100644 (file)
index 0000000..1a925b6
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
+  COMPATIBLE_INTERFACE_BOOL property.  This is not allowed.  Only
+  user-defined properties may appear listed in the COMPATIBLE_INTERFACE_BOOL
+  property.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake
new file mode 100644 (file)
index 0000000..5feb4d5
--- /dev/null
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL INCLUDE_DIRECTORIES)
+set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES OFF)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt
new file mode 100644 (file)
index 0000000..0476da9
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: Property SOMEPROP on target "user" does
+not match the INTERFACE_SOMEPROP property requirement
+of dependency "foo".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake
new file mode 100644 (file)
index 0000000..90543e8
--- /dev/null
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP OFF)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt
new file mode 100644 (file)
index 0000000..d885c09
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_SOMEPROP property of "bar" does
+not agree with the value of SOMEPROP already determined
+for "user".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake
new file mode 100644 (file)
index 0000000..69be796
--- /dev/null
@@ -0,0 +1,10 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP OFF)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt
new file mode 100644 (file)
index 0000000..8556ee0
--- /dev/null
@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be FALSE because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake
new file mode 100644 (file)
index 0000000..ccfad0a
--- /dev/null
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt
new file mode 100644 (file)
index 0000000..5a8f99d
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Property "SOMETHING" appears in both the COMPATIBLE_INTERFACE_BOOL and the
+  COMPATIBLE_INTERFACE_STRING property in the dependencies of target "user".
+  This is not allowed.  A property may only require compatibility in a
+  boolean interpretation or a string interpretation, but not both.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake
new file mode 100644 (file)
index 0000000..711368a
--- /dev/null
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMETHING)
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMETHING)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt
new file mode 100644 (file)
index 0000000..6a293b4
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
+  COMPATIBLE_INTERFACE_STRING property.  This is not allowed.  Only
+  user-defined properties may appear listed in the
+  COMPATIBLE_INTERFACE_STRING property.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
new file mode 100644 (file)
index 0000000..5772856
--- /dev/null
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt
new file mode 100644 (file)
index 0000000..0476da9
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: Property SOMEPROP on target "user" does
+not match the INTERFACE_SOMEPROP property requirement
+of dependency "foo".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake
new file mode 100644 (file)
index 0000000..187f29f
--- /dev/null
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP different)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt
new file mode 100644 (file)
index 0000000..d885c09
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_SOMEPROP property of "bar" does
+not agree with the value of SOMEPROP already determined
+for "user".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake
new file mode 100644 (file)
index 0000000..73cc3fc
--- /dev/null
@@ -0,0 +1,10 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP foo)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP bar)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt
new file mode 100644 (file)
index 0000000..723daec
--- /dev/null
@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be empty because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake
new file mode 100644 (file)
index 0000000..af3ce8f
--- /dev/null
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..9768151
--- /dev/null
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(InterfaceBool-mismatch-depends)
+run_cmake(InterfaceBool-mismatch-depend-self)
+run_cmake(InterfaceBool-mismatched-use)
+run_cmake(InterfaceBool-builtin-prop)
+run_cmake(InterfaceString-mismatch-depends)
+run_cmake(InterfaceString-mismatch-depend-self)
+run_cmake(InterfaceString-mismatched-use)
+run_cmake(InterfaceString-builtin-prop)
+run_cmake(InterfaceString-Bool-Conflict)
diff --git a/Tests/RunCMake/CompatibleInterface/main.cpp b/Tests/RunCMake/CompatibleInterface/main.cpp
new file mode 100644 (file)
index 0000000..65eddcf
--- /dev/null
@@ -0,0 +1,5 @@
+
+int main(int argc, char **argv)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerChange/CMakeLists.txt b/Tests/RunCMake/CompilerChange/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3b92518
--- /dev/null
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8)
+if(NOT RunCMake_TEST)
+  set(RunCMake_TEST "$ENV{RunCMake_TEST}") # needed when cache is deleted
+endif()
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt
new file mode 100644 (file)
index 0000000..4745b25
--- /dev/null
@@ -0,0 +1,5 @@
+You have changed variables that require your cache to be deleted.
+Configure will be re-run and you may have to reset some variables.
+The following variables have changed:
+CMAKE_C_COMPILER= *(
+|$)
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake
new file mode 100644 (file)
index 0000000..c87ec49
--- /dev/null
@@ -0,0 +1,3 @@
+enable_language(C)
+message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/FindCompiler.cmake b/Tests/RunCMake/CompilerChange/FindCompiler.cmake
new file mode 100644 (file)
index 0000000..297ab2f
--- /dev/null
@@ -0,0 +1,2 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt
new file mode 100644 (file)
index 0000000..17621b7
--- /dev/null
@@ -0,0 +1 @@
+-- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc1.sh"
diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler.cmake b/Tests/RunCMake/CompilerChange/FirstCompiler.cmake
new file mode 100644 (file)
index 0000000..c87ec49
--- /dev/null
@@ -0,0 +1,3 @@
+enable_language(C)
+message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..d383716
--- /dev/null
@@ -0,0 +1,58 @@
+include(RunCMake)
+
+# Detect the compiler in use in the current environment.
+run_cmake(FindCompiler)
+include(${RunCMake_BINARY_DIR}/FindCompiler-build/cc.cmake)
+if(NOT CMAKE_C_COMPILER)
+  message(FATAL_ERROR "FindCompiler provided no compiler!")
+endif()
+if(NOT IS_ABSOLUTE "${CMAKE_C_COMPILER}")
+  message(FATAL_ERROR "FindCompiler provided non-absolute path \"${CMAKE_C_COMPILER}\"!")
+endif()
+if(NOT EXISTS "${CMAKE_C_COMPILER}")
+  message(FATAL_ERROR "FindCompiler provided non-existing path \"${CMAKE_C_COMPILER}\"!")
+endif()
+
+# Now that we have the full compiler path, hide CC.
+unset(ENV{CC})
+
+# Wrap around the real compiler so we can change the compiler
+# path without changing the underlying compiler.
+set(ccIn ${RunCMake_SOURCE_DIR}/cc.sh.in)
+set(cc1 ${RunCMake_BINARY_DIR}/cc1.sh)
+set(cc2 ${RunCMake_BINARY_DIR}/cc2.sh)
+set(cc3 CMAKE_C_COMPILER-NOTFOUND)
+configure_file(${ccIn} ${cc1} @ONLY IMMEDIATE)
+configure_file(${ccIn} ${cc2} @ONLY IMMEDIATE)
+
+# Use a single build tree for remaining tests without cleaning.
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeCompiler-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+
+# Check build with compiler wrapper 1.
+set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc1})
+set(ENV{RunCMake_TEST} "FirstCompiler")
+run_cmake(FirstCompiler)
+include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
+if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc1}")
+  message(FATAL_ERROR "FirstCompiler built with compiler:\n  ${CMAKE_C_COMPILER}\nand not with:\n  ${cc1}")
+endif()
+
+# Check rebuild with compiler wrapper 2.
+set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc2})
+set(ENV{RunCMake_TEST} "SecondCompiler")
+run_cmake(SecondCompiler)
+include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
+if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc2}")
+  message(FATAL_ERROR "SecondCompiler built with compiler:\n  ${CMAKE_C_COMPILER}\nand not with:\n  ${cc2}")
+endif()
+
+# Check failure with an empty compiler string.
+set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=)
+set(ENV{RunCMake_TEST} "EmptyCompiler")
+run_cmake(EmptyCompiler)
+include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
+if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc3}")
+  message(FATAL_ERROR "Empty built with compiler:\n  ${CMAKE_C_COMPILER}\nand not with:\n  ${cc3}")
+endif()
diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt
new file mode 100644 (file)
index 0000000..3a01c53
--- /dev/null
@@ -0,0 +1,4 @@
+You have changed variables that require your cache to be deleted.
+Configure will be re-run and you may have to reset some variables.
+The following variables have changed:
+CMAKE_C_COMPILER=.*/Tests/RunCMake/CompilerChange/cc2.sh
diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt
new file mode 100644 (file)
index 0000000..26ca964
--- /dev/null
@@ -0,0 +1 @@
+-- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc2.sh"
diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler.cmake b/Tests/RunCMake/CompilerChange/SecondCompiler.cmake
new file mode 100644 (file)
index 0000000..c87ec49
--- /dev/null
@@ -0,0 +1,3 @@
+enable_language(C)
+message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerChange/cc.sh.in b/Tests/RunCMake/CompilerChange/cc.sh.in
new file mode 100755 (executable)
index 0000000..1d400e6
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec "@CMAKE_C_COMPILER@" "$@"
diff --git a/Tests/RunCMake/ExternalData/BadHashAlgo1-result.txt b/Tests/RunCMake/ExternalData/BadHashAlgo1-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadHashAlgo1-stderr.txt b/Tests/RunCMake/ExternalData/BadHashAlgo1-stderr.txt
new file mode 100644 (file)
index 0000000..f68f0be
--- /dev/null
@@ -0,0 +1,8 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Unknown hash algorithm specified by ExternalData_LINK_CONTENT:
+
+    BAD
+Call Stack \(most recent call first\):
+  .*
+  BadHashAlgo1.cmake:3 \(ExternalData_Expand_Arguments\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadHashAlgo1.cmake b/Tests/RunCMake/ExternalData/BadHashAlgo1.cmake
new file mode 100644 (file)
index 0000000..19e2e41
--- /dev/null
@@ -0,0 +1,3 @@
+include(ExternalData)
+set(ExternalData_LINK_CONTENT BAD)
+ExternalData_Expand_Arguments(Data args DATA{BadHashAlgo1.txt})
diff --git a/Tests/RunCMake/ExternalData/BadHashAlgo1.txt b/Tests/RunCMake/ExternalData/BadHashAlgo1.txt
new file mode 100644 (file)
index 0000000..bfa2818
--- /dev/null
@@ -0,0 +1 @@
+Sample input file that should not be transformed.
diff --git a/Tests/RunCMake/ExternalData/BadOption1-result.txt b/Tests/RunCMake/ExternalData/BadOption1-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadOption1-stderr.txt b/Tests/RunCMake/ExternalData/BadOption1-stderr.txt
new file mode 100644 (file)
index 0000000..b63d098
--- /dev/null
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Unknown option "Bad/Option" in argument
+
+    DATA{Data.txt,Bad/Option}
+
+Call Stack \(most recent call first\):
+  .*
+  BadOption1.cmake:2 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadOption1.cmake b/Tests/RunCMake/ExternalData/BadOption1.cmake
new file mode 100644 (file)
index 0000000..1303d7f
--- /dev/null
@@ -0,0 +1,5 @@
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Data.txt,Bad/Option}
+  )
diff --git a/Tests/RunCMake/ExternalData/BadOption2-result.txt b/Tests/RunCMake/ExternalData/BadOption2-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadOption2-stderr.txt b/Tests/RunCMake/ExternalData/BadOption2-stderr.txt
new file mode 100644 (file)
index 0000000..d114c8a
--- /dev/null
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Unknown option "Bad:Option" in argument
+
+    DATA{Data.txt,Bad:Option}
+
+Call Stack \(most recent call first\):
+  .*
+  BadOption2.cmake:2 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadOption2.cmake b/Tests/RunCMake/ExternalData/BadOption2.cmake
new file mode 100644 (file)
index 0000000..6269b06
--- /dev/null
@@ -0,0 +1,5 @@
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Data.txt,Bad:Option}
+  )
diff --git a/Tests/RunCMake/ExternalData/BadSeries1-result.txt b/Tests/RunCMake/ExternalData/BadSeries1-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadSeries1-stderr.txt b/Tests/RunCMake/ExternalData/BadSeries1-stderr.txt
new file mode 100644 (file)
index 0000000..3099be5
--- /dev/null
@@ -0,0 +1,19 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  ExternalData_SERIES_PARSE is set to
+
+    NotASeriesRegex
+
+  which is not of the form
+
+    \(<number>\)\(<suffix>\)\$
+
+  Fix the regular expression or set variables
+
+    ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
+    ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
+    ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number
+
+Call Stack \(most recent call first\):
+  .*
+  BadSeries1.cmake:3 \(ExternalData_Expand_Arguments\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadSeries1.cmake b/Tests/RunCMake/ExternalData/BadSeries1.cmake
new file mode 100644 (file)
index 0000000..7d71210
--- /dev/null
@@ -0,0 +1,3 @@
+include(ExternalData)
+set(ExternalData_SERIES_PARSE NotASeriesRegex)
+ExternalData_Expand_Arguments(Data args DATA{Data.txt,:})
diff --git a/Tests/RunCMake/ExternalData/BadSeries2-result.txt b/Tests/RunCMake/ExternalData/BadSeries2-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadSeries2-stderr.txt b/Tests/RunCMake/ExternalData/BadSeries2-stderr.txt
new file mode 100644 (file)
index 0000000..3a02c25
--- /dev/null
@@ -0,0 +1,16 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data file referenced by argument
+
+    DATA{Data.txt,:}
+
+  corresponds to path
+
+    Data.txt
+
+  that does not match regular expression
+
+    \(x\)\(y\)\$
+Call Stack \(most recent call first\):
+  .*
+  BadSeries2.cmake:3 \(ExternalData_Expand_Arguments\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadSeries2.cmake b/Tests/RunCMake/ExternalData/BadSeries2.cmake
new file mode 100644 (file)
index 0000000..e81993b
--- /dev/null
@@ -0,0 +1,3 @@
+include(ExternalData)
+set(ExternalData_SERIES_PARSE "(x)(y)$")
+ExternalData_Expand_Arguments(Data args DATA{Data.txt,:})
diff --git a/Tests/RunCMake/ExternalData/BadSeries3-result.txt b/Tests/RunCMake/ExternalData/BadSeries3-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/BadSeries3-stderr.txt b/Tests/RunCMake/ExternalData/BadSeries3-stderr.txt
new file mode 100644 (file)
index 0000000..594cb6f
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Series option ":" not allowed with associated files.
+Call Stack \(most recent call first\):
+  .*
+  BadSeries3.cmake:2 \(ExternalData_Expand_Arguments\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/BadSeries3.cmake b/Tests/RunCMake/ExternalData/BadSeries3.cmake
new file mode 100644 (file)
index 0000000..b640df8
--- /dev/null
@@ -0,0 +1,2 @@
+include(ExternalData)
+ExternalData_Expand_Arguments(Data args DATA{PairA.txt,PairB.txt,:})
diff --git a/Tests/RunCMake/ExternalData/CMakeLists.txt b/Tests/RunCMake/ExternalData/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExternalData/Data.txt.md5 b/Tests/RunCMake/ExternalData/Data.txt.md5
new file mode 100644 (file)
index 0000000..93b3485
--- /dev/null
@@ -0,0 +1 @@
+e8bb14af900b998b5a3df7e21dd07d58
diff --git a/Tests/RunCMake/ExternalData/Directory1-result.txt b/Tests/RunCMake/ExternalData/Directory1-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/Directory1-stderr.txt b/Tests/RunCMake/ExternalData/Directory1-stderr.txt
new file mode 100644 (file)
index 0000000..85c250f
--- /dev/null
@@ -0,0 +1,14 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data file referenced by argument
+
+    DATA{Directory1}
+
+  corresponds to source tree path
+
+    Directory1
+
+  that does not exist as a file \(with or without an extension\)!
+Call Stack \(most recent call first\):
+  .*
+  Directory1.cmake:3 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/Directory1.cmake b/Tests/RunCMake/ExternalData/Directory1.cmake
new file mode 100644 (file)
index 0000000..68f1b54
--- /dev/null
@@ -0,0 +1,6 @@
+include(CTest)
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Directory1}
+  )
diff --git a/Tests/RunCMake/ExternalData/Directory1/DirData1.txt b/Tests/RunCMake/ExternalData/Directory1/DirData1.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/ExternalData/Directory2-result.txt b/Tests/RunCMake/ExternalData/Directory2-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/Directory2-stderr.txt b/Tests/RunCMake/ExternalData/Directory2-stderr.txt
new file mode 100644 (file)
index 0000000..92c9a2f
--- /dev/null
@@ -0,0 +1,10 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data directory referenced by argument
+
+    DATA{Directory2/}
+
+  must list associated files.
+Call Stack \(most recent call first\):
+  .*
+  Directory2.cmake:3 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/Directory2.cmake b/Tests/RunCMake/ExternalData/Directory2.cmake
new file mode 100644 (file)
index 0000000..30b992e
--- /dev/null
@@ -0,0 +1,6 @@
+include(CTest)
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Directory2/}
+  )
diff --git a/Tests/RunCMake/ExternalData/Directory2.md5 b/Tests/RunCMake/ExternalData/Directory2.md5
new file mode 100644 (file)
index 0000000..93b3485
--- /dev/null
@@ -0,0 +1 @@
+e8bb14af900b998b5a3df7e21dd07d58
diff --git a/Tests/RunCMake/ExternalData/Directory2/DirData2.txt b/Tests/RunCMake/ExternalData/Directory2/DirData2.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/ExternalData/Directory3-result.txt b/Tests/RunCMake/ExternalData/Directory3-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/Directory3-stderr.txt b/Tests/RunCMake/ExternalData/Directory3-stderr.txt
new file mode 100644 (file)
index 0000000..56a341e
--- /dev/null
@@ -0,0 +1,14 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data file referenced by argument
+
+    DATA{Directory3/\*}
+
+  corresponds to source tree path
+
+    Directory3/.
+
+  that does not exist as a file \(with or without an extension\)!
+Call Stack \(most recent call first\):
+  .*
+  Directory3.cmake:3 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/Directory3.cmake b/Tests/RunCMake/ExternalData/Directory3.cmake
new file mode 100644 (file)
index 0000000..55d8be9
--- /dev/null
@@ -0,0 +1,6 @@
+include(CTest)
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Directory3/*}
+  )
diff --git a/Tests/RunCMake/ExternalData/Directory3/DirData3.txt b/Tests/RunCMake/ExternalData/Directory3/DirData3.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/ExternalData/Directory4-result.txt b/Tests/RunCMake/ExternalData/Directory4-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/Directory4-stderr.txt b/Tests/RunCMake/ExternalData/Directory4-stderr.txt
new file mode 100644 (file)
index 0000000..dcb8522
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Series option ":" not allowed with directories.
+Call Stack \(most recent call first\):
+  .*
+  Directory4.cmake:3 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/Directory4.cmake b/Tests/RunCMake/ExternalData/Directory4.cmake
new file mode 100644 (file)
index 0000000..7d3d638
--- /dev/null
@@ -0,0 +1,6 @@
+include(CTest)
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Directory4/,:}
+  )
diff --git a/Tests/RunCMake/ExternalData/Directory4/DirData4.txt b/Tests/RunCMake/ExternalData/Directory4/DirData4.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Tests/RunCMake/ExternalData/Directory5-result.txt b/Tests/RunCMake/ExternalData/Directory5-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/Directory5-stderr.txt b/Tests/RunCMake/ExternalData/Directory5-stderr.txt
new file mode 100644 (file)
index 0000000..8e54aec
--- /dev/null
@@ -0,0 +1,14 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data directory referenced by argument
+
+    DATA{Directory5/}
+
+  corresponds to source tree path
+
+    Directory5
+
+  that does not exist as a directory!
+Call Stack \(most recent call first\):
+  .*
+  Directory5.cmake:3 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/Directory5.cmake b/Tests/RunCMake/ExternalData/Directory5.cmake
new file mode 100644 (file)
index 0000000..931589e
--- /dev/null
@@ -0,0 +1,6 @@
+include(CTest)
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{Directory5/}
+  )
diff --git a/Tests/RunCMake/ExternalData/LinkContentMD5-stdout.txt b/Tests/RunCMake/ExternalData/LinkContentMD5-stdout.txt
new file mode 100644 (file)
index 0000000..f77fca9
--- /dev/null
@@ -0,0 +1,3 @@
+-- Linked ToLink.txt.md5 to ExternalData MD5/c18ff9804c8deec9eaeb17063cda8b7b
+-- Raw data correctly transformed to content link!
+-- Staged content exists!
diff --git a/Tests/RunCMake/ExternalData/LinkContentMD5.cmake b/Tests/RunCMake/ExternalData/LinkContentMD5.cmake
new file mode 100644 (file)
index 0000000..41b4dee
--- /dev/null
@@ -0,0 +1,22 @@
+include(ExternalData)
+set(ExternalData_LINK_CONTENT MD5)
+set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR})
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData)
+set(input ${CMAKE_CURRENT_BINARY_DIR}/ToLink.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/ToLink.txt)
+set(staged "${CMAKE_CURRENT_BINARY_DIR}/.ExternalData_MD5_c18ff9804c8deec9eaeb17063cda8b7b")
+file(REMOVE ${staged})
+file(REMOVE ${input}.md5)
+file(WRITE ${input} "To be transformed into a content link.")
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Raw data correctly transformed to content link!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
+if(EXISTS "${staged}")
+  message(STATUS "Staged content exists!")
+else()
+  message(FATAL_ERROR "Staged content missing!")
+endif()
diff --git a/Tests/RunCMake/ExternalData/LinkContentSHA1-stdout.txt b/Tests/RunCMake/ExternalData/LinkContentSHA1-stdout.txt
new file mode 100644 (file)
index 0000000..9a8eb2e
--- /dev/null
@@ -0,0 +1,3 @@
+-- Linked ToLink.txt.sha1 to ExternalData SHA1/114ee5dda251457fd2df63bec91d3b8db43aba58
+-- Raw data correctly transformed to content link!
+-- Staged content exists!
diff --git a/Tests/RunCMake/ExternalData/LinkContentSHA1.cmake b/Tests/RunCMake/ExternalData/LinkContentSHA1.cmake
new file mode 100644 (file)
index 0000000..f78501c
--- /dev/null
@@ -0,0 +1,22 @@
+include(ExternalData)
+set(ExternalData_LINK_CONTENT SHA1)
+set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR})
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData)
+set(input ${CMAKE_CURRENT_BINARY_DIR}/ToLink.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/ToLink.txt)
+set(staged "${CMAKE_CURRENT_BINARY_DIR}/.ExternalData_SHA1_114ee5dda251457fd2df63bec91d3b8db43aba58")
+file(REMOVE ${staged})
+file(REMOVE ${input}.sha1)
+file(WRITE ${input} "To be transformed into a content link.")
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Raw data correctly transformed to content link!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
+if(EXISTS "${staged}")
+  message(STATUS "Staged content exists!")
+else()
+  message(FATAL_ERROR "Staged content missing!")
+endif()
diff --git a/Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt b/Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt
new file mode 100644 (file)
index 0000000..953ea68
--- /dev/null
@@ -0,0 +1,5 @@
+-- Linked Dir/ToLink.txt.md5 to ExternalData MD5/c18ff9804c8deec9eaeb17063cda8b7b
+-- Raw data correctly transformed to content link!
+-- Staged content exists!
+-- Staged content is correct!
+-- Staged content was correctly not re-staged!
diff --git a/Tests/RunCMake/ExternalData/LinkDirectory1.cmake b/Tests/RunCMake/ExternalData/LinkDirectory1.cmake
new file mode 100644 (file)
index 0000000..541fc79
--- /dev/null
@@ -0,0 +1,37 @@
+include(ExternalData)
+set(ExternalData_LINK_CONTENT MD5)
+set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR})
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData)
+set(input ${CMAKE_CURRENT_BINARY_DIR}/Dir)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/Dir)
+set(staged "${input}/.ExternalData_MD5_c18ff9804c8deec9eaeb17063cda8b7b")
+set(content "To be transformed into a content link.")
+file(REMOVE ${staged})
+file(REMOVE_RECURSE ${input})
+file(WRITE ${input}/ToLink.txt "${content}")
+ExternalData_Expand_Arguments(Data args "DATA{${input}/,REGEX:.*}")
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Raw data correctly transformed to content link!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
+if(EXISTS "${staged}")
+  message(STATUS "Staged content exists!")
+else()
+  message(FATAL_ERROR "Staged content missing!")
+endif()
+
+# Expand again to check whether staged content is ignored.
+ExternalData_Expand_Arguments(Data args "DATA{${input}/,REGEX:.*}")
+file(STRINGS "${staged}" staged_content LIMIT_INPUT 1024)
+if("${content}" STREQUAL "${staged_content}")
+  message(STATUS "Staged content is correct!")
+else()
+  message(STATUS "Staged content is incorrect!")
+endif()
+if(EXISTS "${staged}.md5")
+  message(FATAL_ERROR "Staged content was incorrectly re-staged!")
+else()
+  message(STATUS "Staged content was correctly not re-staged!")
+endif()
diff --git a/Tests/RunCMake/ExternalData/MissingData-result.txt b/Tests/RunCMake/ExternalData/MissingData-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/MissingData-stderr.txt b/Tests/RunCMake/ExternalData/MissingData-stderr.txt
new file mode 100644 (file)
index 0000000..e794f95
--- /dev/null
@@ -0,0 +1,14 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data file referenced by argument
+
+    DATA{MissingData.txt}
+
+  corresponds to source tree path
+
+    MissingData.txt
+
+  that does not exist as a file \(with or without an extension\)!
+Call Stack \(most recent call first\):
+  .*
+  MissingData.cmake:2 \(ExternalData_Add_Test\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/MissingData.cmake b/Tests/RunCMake/ExternalData/MissingData.cmake
new file mode 100644 (file)
index 0000000..b3c8a5c
--- /dev/null
@@ -0,0 +1,5 @@
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{MissingData.txt}
+  )
diff --git a/Tests/RunCMake/ExternalData/NoLinkInSource-stderr.txt b/Tests/RunCMake/ExternalData/NoLinkInSource-stderr.txt
new file mode 100644 (file)
index 0000000..496ad8a
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Warning at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  ExternalData_LINK_CONTENT cannot be used in-source
+Call Stack \(most recent call first\):
+  .*
+  NoLinkInSource.cmake:8 \(ExternalData_Expand_Arguments\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/NoLinkInSource-stdout.txt b/Tests/RunCMake/ExternalData/NoLinkInSource-stdout.txt
new file mode 100644 (file)
index 0000000..18946f0
--- /dev/null
@@ -0,0 +1 @@
+-- Data reference correctly not transformed!
diff --git a/Tests/RunCMake/ExternalData/NoLinkInSource.cmake b/Tests/RunCMake/ExternalData/NoLinkInSource.cmake
new file mode 100644 (file)
index 0000000..cbf45eb
--- /dev/null
@@ -0,0 +1,14 @@
+include(ExternalData)
+set(ExternalData_LINK_CONTENT MD5)
+set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR})
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR})
+set(input ${CMAKE_CURRENT_BINARY_DIR}/ToLink.txt)
+file(REMOVE ${input}.md5)
+file(WRITE ${input} "To be transformed into a content link.")
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${input}")
+  message(STATUS "Data reference correctly not transformed!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected no transformation.")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NoURLTemplates-result.txt b/Tests/RunCMake/ExternalData/NoURLTemplates-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt b/Tests/RunCMake/ExternalData/NoURLTemplates-stderr.txt
new file mode 100644 (file)
index 0000000..ad059d4
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  ExternalData_URL_TEMPLATES is not set!
+Call Stack \(most recent call first\):
+  NoURLTemplates.cmake:2 \(ExternalData_Add_Target\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ExternalData/NoURLTemplates.cmake b/Tests/RunCMake/ExternalData/NoURLTemplates.cmake
new file mode 100644 (file)
index 0000000..8f0e069
--- /dev/null
@@ -0,0 +1,2 @@
+include(ExternalData)
+ExternalData_Add_Target(Data)
diff --git a/Tests/RunCMake/ExternalData/NormalData1-stdout.txt b/Tests/RunCMake/ExternalData/NormalData1-stdout.txt
new file mode 100644 (file)
index 0000000..2f2c770
--- /dev/null
@@ -0,0 +1 @@
+-- Data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/NormalData1.cmake b/Tests/RunCMake/ExternalData/NormalData1.cmake
new file mode 100644 (file)
index 0000000..d6cc384
--- /dev/null
@@ -0,0 +1,13 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(input Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NormalData2-stdout.txt b/Tests/RunCMake/ExternalData/NormalData2-stdout.txt
new file mode 100644 (file)
index 0000000..2f2c770
--- /dev/null
@@ -0,0 +1 @@
+-- Data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/NormalData2.cmake b/Tests/RunCMake/ExternalData/NormalData2.cmake
new file mode 100644 (file)
index 0000000..c979b48
--- /dev/null
@@ -0,0 +1,14 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData)
+set(input Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NormalData3-stdout.txt b/Tests/RunCMake/ExternalData/NormalData3-stdout.txt
new file mode 100644 (file)
index 0000000..2f2c770
--- /dev/null
@@ -0,0 +1 @@
+-- Data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/NormalData3.cmake b/Tests/RunCMake/ExternalData/NormalData3.cmake
new file mode 100644 (file)
index 0000000..e991122
--- /dev/null
@@ -0,0 +1,14 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData)
+set(input ${CMAKE_CURRENT_SOURCE_DIR}/Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NormalDataSub1-stdout.txt b/Tests/RunCMake/ExternalData/NormalDataSub1-stdout.txt
new file mode 100644 (file)
index 0000000..2f2c770
--- /dev/null
@@ -0,0 +1 @@
+-- Data reference correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/NormalDataSub1.cmake b/Tests/RunCMake/ExternalData/NormalDataSub1.cmake
new file mode 100644 (file)
index 0000000..015e94c
--- /dev/null
@@ -0,0 +1,13 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(input SubDirectory1/Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/SubDirectory1/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/NotUnderRoot-result.txt b/Tests/RunCMake/ExternalData/NotUnderRoot-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExternalData/NotUnderRoot-stderr.txt b/Tests/RunCMake/ExternalData/NotUnderRoot-stderr.txt
new file mode 100644 (file)
index 0000000..1f2eb1c
--- /dev/null
@@ -0,0 +1,12 @@
+CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Data file referenced by argument
+
+    DATA{../NotUnderRoot.txt}
+
+  does not lie under the top-level source directory
+
+    .*/Tests/RunCMake/ExternalData
+
+Call Stack \(most recent call first\):
+  .*
+  NotUnderRoot.cmake:2 \(ExternalData_Add_Test\)
diff --git a/Tests/RunCMake/ExternalData/NotUnderRoot.cmake b/Tests/RunCMake/ExternalData/NotUnderRoot.cmake
new file mode 100644 (file)
index 0000000..c7942d6
--- /dev/null
@@ -0,0 +1,5 @@
+include(ExternalData)
+ExternalData_Add_Test(Data
+  NAME Test
+  COMMAND ${CMAKE_COMMAND} -E echo DATA{../NotUnderRoot.txt}
+  )
diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..8fba82c
--- /dev/null
@@ -0,0 +1,28 @@
+include(RunCMake)
+
+run_cmake(BadHashAlgo1)
+run_cmake(BadOption1)
+run_cmake(BadOption2)
+run_cmake(BadSeries1)
+run_cmake(BadSeries2)
+run_cmake(BadSeries3)
+run_cmake(Directory1)
+run_cmake(Directory2)
+run_cmake(Directory3)
+run_cmake(Directory4)
+run_cmake(Directory5)
+run_cmake(LinkContentMD5)
+run_cmake(LinkContentSHA1)
+run_cmake(LinkDirectory1)
+run_cmake(MissingData)
+run_cmake(NoLinkInSource)
+run_cmake(NoURLTemplates)
+run_cmake(NormalData1)
+run_cmake(NormalData2)
+run_cmake(NormalData3)
+run_cmake(NormalDataSub1)
+run_cmake(NotUnderRoot)
+run_cmake(Semicolon1)
+run_cmake(Semicolon2)
+run_cmake(Semicolon3)
+run_cmake(SubDirectory1)
diff --git a/Tests/RunCMake/ExternalData/Semicolon1-stdout.txt b/Tests/RunCMake/ExternalData/Semicolon1-stdout.txt
new file mode 100644 (file)
index 0000000..361baeb
--- /dev/null
@@ -0,0 +1 @@
+-- Data arguments correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/Semicolon1.cmake b/Tests/RunCMake/ExternalData/Semicolon1.cmake
new file mode 100644 (file)
index 0000000..c832860
--- /dev/null
@@ -0,0 +1,14 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(input Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}} "a\\;b" "c;d" DATA{${input}})
+set(expect "${output};a\\;b;c;d;${output}")
+if("x${args}" STREQUAL "x${expect}")
+  message(STATUS "Data arguments correctly transformed!")
+else()
+  message(FATAL_ERROR "Data arguments transformed to:\n  ${args}\n"
+    "but we expected:\n  ${expect}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/Semicolon2-stdout.txt b/Tests/RunCMake/ExternalData/Semicolon2-stdout.txt
new file mode 100644 (file)
index 0000000..361baeb
--- /dev/null
@@ -0,0 +1 @@
+-- Data arguments correctly transformed!
diff --git a/Tests/RunCMake/ExternalData/Semicolon2.cmake b/Tests/RunCMake/ExternalData/Semicolon2.cmake
new file mode 100644 (file)
index 0000000..1a1ae5f
--- /dev/null
@@ -0,0 +1,14 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(input Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args "DATA{${input}};a\\;b;c;d;DATA{${input}}")
+set(expect "${output};a\\;b;c;d;${output}")
+if("x${args}" STREQUAL "x${expect}")
+  message(STATUS "Data arguments correctly transformed!")
+else()
+  message(FATAL_ERROR "Data arguments transformed to:\n  ${args}\n"
+    "but we expected:\n  ${expect}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/Semicolon3-stdout.txt b/Tests/RunCMake/ExternalData/Semicolon3-stdout.txt
new file mode 100644 (file)
index 0000000..ca4a360
--- /dev/null
@@ -0,0 +1 @@
+-- Data arguments correctly not transformed!
diff --git a/Tests/RunCMake/ExternalData/Semicolon3.cmake b/Tests/RunCMake/ExternalData/Semicolon3.cmake
new file mode 100644 (file)
index 0000000..2ae99da
--- /dev/null
@@ -0,0 +1,12 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+set(input "DATA{a;b}")
+ExternalData_Expand_Arguments(Data args "${input}")
+if("x${args}" STREQUAL "x${input}")
+  message(STATUS "Data arguments correctly not transformed!")
+else()
+  message(FATAL_ERROR "Data arguments transformed to:\n  ${args}\n"
+    "but we expected:\n  ${input}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/SubDirectory1-stdout.txt b/Tests/RunCMake/ExternalData/SubDirectory1-stdout.txt
new file mode 100644 (file)
index 0000000..03924cb
--- /dev/null
@@ -0,0 +1,3 @@
+-- Data reference correctly transformed in parent dir 1!
+-- Data reference correctly transformed in parent dir 2!
+-- Data reference correctly transformed in current dir!
diff --git a/Tests/RunCMake/ExternalData/SubDirectory1.cmake b/Tests/RunCMake/ExternalData/SubDirectory1.cmake
new file mode 100644 (file)
index 0000000..2989471
--- /dev/null
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
+  )
+add_subdirectory(SubDirectory1)
diff --git a/Tests/RunCMake/ExternalData/SubDirectory1/CMakeLists.txt b/Tests/RunCMake/ExternalData/SubDirectory1/CMakeLists.txt
new file mode 100644 (file)
index 0000000..881ff5c
--- /dev/null
@@ -0,0 +1,29 @@
+set(input ../Data.txt)
+set(output ${CMAKE_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed in parent dir 1!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
+
+set(input ${CMAKE_CURRENT_SOURCE_DIR}/../Data.txt)
+set(output ${CMAKE_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed in parent dir 2!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
+
+set(input Data.txt)
+set(output ${CMAKE_CURRENT_BINARY_DIR}/Data.txt)
+ExternalData_Expand_Arguments(Data args DATA{${input}})
+if("x${args}" STREQUAL "x${output}")
+  message(STATUS "Data reference correctly transformed in current dir!")
+else()
+  message(FATAL_ERROR "Data reference transformed to:\n  ${args}\n"
+    "but we expected:\n  ${output}")
+endif()
diff --git a/Tests/RunCMake/ExternalData/SubDirectory1/Data.txt.md5 b/Tests/RunCMake/ExternalData/SubDirectory1/Data.txt.md5
new file mode 100644 (file)
index 0000000..93b3485
--- /dev/null
@@ -0,0 +1 @@
+e8bb14af900b998b5a3df7e21dd07d58
diff --git a/Tests/RunCMake/FPHSA/BadFoundVar-result.txt b/Tests/RunCMake/FPHSA/BadFoundVar-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt b/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt
new file mode 100644 (file)
index 0000000..4c739d8
--- /dev/null
@@ -0,0 +1,7 @@
+CMake Error at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
+  The argument for FOUND_VAR is "badfoundvar_FOUND", but only
+  "BadFoundVar_FOUND" and "BADFOUNDVAR_FOUND" are valid names.
+Call Stack \(most recent call first\):
+  FindBadFoundVar.cmake:5 \(find_package_handle_standard_args\)
+  BadFoundVar.cmake:3 \(find_package\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/FPHSA/BadFoundVar.cmake b/Tests/RunCMake/FPHSA/BadFoundVar.cmake
new file mode 100644 (file)
index 0000000..07d4322
--- /dev/null
@@ -0,0 +1,3 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+
+find_package(BadFoundVar REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/CMakeLists.txt b/Tests/RunCMake/FPHSA/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FPHSA/FindBadFoundVar.cmake b/Tests/RunCMake/FPHSA/FindBadFoundVar.cmake
new file mode 100644 (file)
index 0000000..152df5c
--- /dev/null
@@ -0,0 +1,6 @@
+set(BFV_FOO TRUE)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(BadFoundVar REQUIRED_VARS BFV_FOO
+                                              FOUND_VAR badfoundvar_FOUND )
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..0d48fa9
--- /dev/null
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(BadFoundVar)
index 36302db..0e48ba4 100644 (file)
@@ -41,4 +41,13 @@ CMake Error at BadAND.cmake:1 \(add_custom_target\):
 
   Parameters to \$<AND> must resolve to either '0' or '1'.
 Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadAND.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<AND:1,nothing>
+
+  Parameters to \$<AND> must resolve to either '0' or '1'.
+Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)$
index 265e414..8a7993f 100644 (file)
@@ -4,4 +4,5 @@ add_custom_target(check ALL COMMAND check
   $<AND:,>
   $<AND:01>
   $<AND:nothing>
+  $<AND:1,nothing>
   VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/BadInstallPrefix-result.txt b/Tests/RunCMake/GeneratorExpression/BadInstallPrefix-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadInstallPrefix-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadInstallPrefix-stderr.txt
new file mode 100644 (file)
index 0000000..271eb6e
--- /dev/null
@@ -0,0 +1,9 @@
+CMake Error at BadInstallPrefix.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<INSTALL_PREFIX>
+
+  INSTALL_PREFIX is a marker for install\(EXPORT\) only.  It should never be
+  evaluated.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/BadInstallPrefix.cmake b/Tests/RunCMake/GeneratorExpression/BadInstallPrefix.cmake
new file mode 100644 (file)
index 0000000..fcfc3eb
--- /dev/null
@@ -0,0 +1,3 @@
+add_custom_target(check ALL COMMAND check
+  $<INSTALL_PREFIX>/include
+  VERBATIM)
index d4ccab7..eb26328 100644 (file)
@@ -41,4 +41,13 @@ CMake Error at BadOR.cmake:1 \(add_custom_target\):
 
   Parameters to \$<OR> must resolve to either '0' or '1'.
 Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadOR.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<OR:0,nothing>
+
+  Parameters to \$<OR> must resolve to either '0' or '1'.
+Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)$
index 0813400..c0309da 100644 (file)
@@ -4,4 +4,5 @@ add_custom_target(check ALL COMMAND check
   $<OR:,>
   $<OR:01>
   $<OR:nothing>
+  $<OR:0,nothing>
   VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt b/Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt
new file mode 100644 (file)
index 0000000..969393a
--- /dev/null
@@ -0,0 +1,8 @@
+CMake Error at BadTargetName.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<TARGET_NAME:\$<1:tgt>>
+
+  \$<TARGET_NAME> expression requires literal input.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName.cmake b/Tests/RunCMake/GeneratorExpression/BadTargetName.cmake
new file mode 100644 (file)
index 0000000..e125cab
--- /dev/null
@@ -0,0 +1,3 @@
+add_custom_target(check ALL COMMAND check
+  $<TARGET_NAME:$<1:tgt>>
+  VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-result.txt b/Tests/RunCMake/GeneratorExpression/BadZero-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt
new file mode 100644 (file)
index 0000000..40db4ae
--- /dev/null
@@ -0,0 +1,17 @@
+CMake Error at BadZero.cmake:2 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<0>
+
+  \$<0> expression requires a parameter.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at BadZero.cmake:2 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<0,>
+
+  Expression did not evaluate to a known generator expression
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/BadZero.cmake b/Tests/RunCMake/GeneratorExpression/BadZero.cmake
new file mode 100644 (file)
index 0000000..559a9fa
--- /dev/null
@@ -0,0 +1,5 @@
+
+add_custom_target(check ALL COMMAND check
+  $<0>
+  $<0,>
+  VERBATIM)
index 18a47ae..62bf29b 100644 (file)
@@ -5,3 +5,6 @@ run_cmake(BadOR)
 run_cmake(BadAND)
 run_cmake(BadNOT)
 run_cmake(BadStrEqual)
+run_cmake(BadZero)
+run_cmake(BadTargetName)
+run_cmake(BadInstallPrefix)
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolset-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolset-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolset-stderr.txt
new file mode 100644 (file)
index 0000000..bf1f190
--- /dev/null
@@ -0,0 +1,10 @@
+CMake Error:
+  Generator
+
+    .*
+
+  does not support toolset specification, but toolset
+
+    Bad Toolset
+
+  was specified.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolset.cmake b/Tests/RunCMake/GeneratorToolset/BadToolset.cmake
new file mode 100644 (file)
index 0000000..2fc38e5
--- /dev/null
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorToolset/CMakeLists.txt b/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorToolset/NoToolset-result.txt b/Tests/RunCMake/GeneratorToolset/NoToolset-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/NoToolset-stderr.txt b/Tests/RunCMake/GeneratorToolset/NoToolset-stderr.txt
new file mode 100644 (file)
index 0000000..bc6f741
--- /dev/null
@@ -0,0 +1,4 @@
+CMake Error at NoToolset.cmake:2 \(message\):
+  CMAKE_GENERATOR_TOOLSET is empty as expected.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorToolset/NoToolset.cmake b/Tests/RunCMake/GeneratorToolset/NoToolset.cmake
new file mode 100644 (file)
index 0000000..f1f1ecd
--- /dev/null
@@ -0,0 +1,7 @@
+if("x${CMAKE_GENERATOR_TOOLSET}" STREQUAL "x")
+  message(FATAL_ERROR "CMAKE_GENERATOR_TOOLSET is empty as expected.")
+else()
+  message(FATAL_ERROR
+    "CMAKE_GENERATOR_TOOLSET is \"${CMAKE_GENERATOR_TOOLSET}\" "
+    "but should be empty!")
+endif()
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..1ccc1ad
--- /dev/null
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+set(RunCMake_GENERATOR_TOOLSET "")
+run_cmake(NoToolset)
+
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012]|Xcode" AND NOT XCODE_BELOW_3)
+  set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
+  run_cmake(TestToolset)
+else()
+  set(RunCMake_GENERATOR_TOOLSET "Bad Toolset")
+  run_cmake(BadToolset)
+endif()
+
+set(RunCMake_GENERATOR_TOOLSET "")
+set(RunCMake_TEST_OPTIONS -T "Extra Toolset")
+run_cmake(TwoToolsets)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolset-result.txt b/Tests/RunCMake/GeneratorToolset/TestToolset-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolset-stderr.txt b/Tests/RunCMake/GeneratorToolset/TestToolset-stderr.txt
new file mode 100644 (file)
index 0000000..d5726af
--- /dev/null
@@ -0,0 +1,4 @@
+CMake Error at TestToolset.cmake:2 \(message\):
+  CMAKE_GENERATOR_TOOLSET is "Test Toolset" as expected.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolset.cmake b/Tests/RunCMake/GeneratorToolset/TestToolset.cmake
new file mode 100644 (file)
index 0000000..6f83bef
--- /dev/null
@@ -0,0 +1,7 @@
+if("x${CMAKE_GENERATOR_TOOLSET}" STREQUAL "xTest Toolset")
+  message(FATAL_ERROR "CMAKE_GENERATOR_TOOLSET is \"Test Toolset\" as expected.")
+else()
+  message(FATAL_ERROR
+    "CMAKE_GENERATOR_TOOLSET is \"${CMAKE_GENERATOR_TOOLSET}\" "
+    "but should be \"Test Toolset\"!")
+endif()
diff --git a/Tests/RunCMake/GeneratorToolset/TwoToolsets-result.txt b/Tests/RunCMake/GeneratorToolset/TwoToolsets-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/TwoToolsets-stderr.txt b/Tests/RunCMake/GeneratorToolset/TwoToolsets-stderr.txt
new file mode 100644 (file)
index 0000000..9fa817f
--- /dev/null
@@ -0,0 +1 @@
+CMake Error: Multiple -T options not allowed
diff --git a/Tests/RunCMake/GeneratorToolset/TwoToolsets.cmake b/Tests/RunCMake/GeneratorToolset/TwoToolsets.cmake
new file mode 100644 (file)
index 0000000..2fc38e5
--- /dev/null
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/IncompatibleQt/CMakeLists.txt b/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
new file mode 100644 (file)
index 0000000..68dd8d6
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/IncompatibleQt/IncompatibleQt-result.txt b/Tests/RunCMake/IncompatibleQt/IncompatibleQt-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/IncompatibleQt/IncompatibleQt-stderr.txt b/Tests/RunCMake/IncompatibleQt/IncompatibleQt-stderr.txt
new file mode 100644 (file)
index 0000000..4eaaa95
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_QT_MAJOR_VERSION property of "Qt5::Core" does
+not agree with the value of QT_MAJOR_VERSION already determined
+for "mainexe".
diff --git a/Tests/RunCMake/IncompatibleQt/IncompatibleQt.cmake b/Tests/RunCMake/IncompatibleQt/IncompatibleQt.cmake
new file mode 100644 (file)
index 0000000..4fccdc4
--- /dev/null
@@ -0,0 +1,6 @@
+
+find_package(Qt4 REQUIRED)
+find_package(Qt5Core REQUIRED)
+
+add_executable(mainexe main.cpp)
+target_link_libraries(mainexe Qt4::QtCore Qt5::Core)
diff --git a/Tests/RunCMake/IncompatibleQt/RunCMakeTest.cmake b/Tests/RunCMake/IncompatibleQt/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..322c291
--- /dev/null
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(IncompatibleQt)
diff --git a/Tests/RunCMake/IncompatibleQt/main.cpp b/Tests/RunCMake/IncompatibleQt/main.cpp
new file mode 100644 (file)
index 0000000..140a7c1
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include <QCoreApplication>
+
+int main(int argc, char **argv)
+{
+  QCoreApplication app(argc, argv);
+  return app.exec();
+}
diff --git a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
new file mode 100644 (file)
index 0000000..22577da
--- /dev/null
@@ -0,0 +1,8 @@
+
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} CXX)
+
+# MSVC creates extra targets which pollute the stderr unless we set this.
+set(CMAKE_SUPPRESS_REGENERATION TRUE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt
new file mode 100644 (file)
index 0000000..cb07109
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict" does
+not match the INTERFACE_POSITION_INDEPENDENT_CODE property requirement
+of dependency "piciface".
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake
new file mode 100644 (file)
index 0000000..242bec3
--- /dev/null
@@ -0,0 +1,7 @@
+
+add_library(piciface UNKNOWN IMPORTED)
+set_property(TARGET piciface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_executable(conflict "main.cpp")
+set_property(TARGET conflict PROPERTY POSITION_INDEPENDENT_CODE OFF)
+target_link_libraries(conflict piciface)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt
new file mode 100644 (file)
index 0000000..ecd0492
--- /dev/null
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_POSITION_INDEPENDENT_CODE property of "picoff" does
+not agree with the value of POSITION_INDEPENDENT_CODE already determined
+for "conflict".
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake
new file mode 100644 (file)
index 0000000..215d08d
--- /dev/null
@@ -0,0 +1,9 @@
+
+add_library(picon UNKNOWN IMPORTED)
+set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_library(picoff UNKNOWN IMPORTED)
+set_property(TARGET picoff PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF)
+
+add_executable(conflict "main.cpp")
+target_link_libraries(conflict picon picoff)
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt
new file mode 100644 (file)
index 0000000..0254e55
--- /dev/null
@@ -0,0 +1,4 @@
+Property POSITION_INDEPENDENT_CODE on target "conflict" is
+implied to be FALSE because it was used to determine the link libraries
+already. The INTERFACE_POSITION_INDEPENDENT_CODE property on
+dependency "picon" is in conflict.
diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake
new file mode 100644 (file)
index 0000000..bf669bf
--- /dev/null
@@ -0,0 +1,12 @@
+
+add_library(picoff UNKNOWN IMPORTED)
+
+add_library(picon UNKNOWN IMPORTED)
+set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
+
+add_executable(conflict "main.cpp")
+target_link_libraries(conflict picon)
+set_property(TARGET conflict APPEND PROPERTY
+  LINK_LIBRARIES
+    $<$<NOT:$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>>:picoff>
+)
diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..64a340c
--- /dev/null
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(Conflict1)
+run_cmake(Conflict2)
+run_cmake(Conflict3)
diff --git a/Tests/RunCMake/PositionIndependentCode/main.cpp b/Tests/RunCMake/PositionIndependentCode/main.cpp
new file mode 100644 (file)
index 0000000..31ba482
--- /dev/null
@@ -0,0 +1,5 @@
+
+int main(int,char**)
+{
+  return 0;
+}
index c3c161a..00faa4c 100644 (file)
@@ -26,12 +26,22 @@ function(run_cmake test)
     endif()
   endforeach()
   set(RunCMake_TEST_SOURCE_DIR "${top_src}")
-  set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
-  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  if(NOT RunCMake_TEST_BINARY_DIR)
+    set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
+  endif()
+  if(NOT RunCMake_TEST_NO_CLEAN)
+    file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  endif()
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  if(NOT DEFINED RunCMake_TEST_OPTIONS)
+    set(RunCMake_TEST_OPTIONS "")
+  endif()
   execute_process(
     COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
-              -G "${RunCMake_GENERATOR}" -DRunCMake_TEST=${test}
+              -G "${RunCMake_GENERATOR}"
+              -T "${RunCMake_GENERATOR_TOOLSET}"
+              -DRunCMake_TEST=${test}
+              ${RunCMake_TEST_OPTIONS}
     WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
     OUTPUT_VARIABLE actual_stdout
     ERROR_VARIABLE actual_stderr
diff --git a/Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt b/Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake
new file mode 100644 (file)
index 0000000..0f7e370
--- /dev/null
@@ -0,0 +1,5 @@
+parseGlobalSections(pre post MorePost)
+testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces")
+testGlobalSection(post TestSec4 Key6=Value1 "Key7=Value with spaces" Key8=ValueWithoutSpaces)
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePost.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePost.cmake
new file mode 100644 (file)
index 0000000..2eb3f60
--- /dev/null
@@ -0,0 +1,2 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec2 Key1=Value1 "Key2=Value with spaces")
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec4 Key6=Value1 "Key7=Value with spaces" "Key8 =ValueWithoutSpaces")
diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake
new file mode 100644 (file)
index 0000000..45e7419
--- /dev/null
@@ -0,0 +1,5 @@
+parseGlobalSections(pre post MorePre)
+testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces")
+testGlobalSection(pre TestSec3 Key3=Value1 "Key4=Value with spaces" Key5=ValueWithoutSpaces)
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePre.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePre.cmake
new file mode 100644 (file)
index 0000000..07f4eb8
--- /dev/null
@@ -0,0 +1,2 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec1 Key1=Value1 "Key2=Value with spaces")
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec3 Key3=Value1 "Key4=Value with spaces" "Key5 = ValueWithoutSpaces")
diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake
new file mode 100644 (file)
index 0000000..6af5156
--- /dev/null
@@ -0,0 +1,4 @@
+parseGlobalSections(pre post OnePost)
+testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces")
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePost.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePost.cmake
new file mode 100644 (file)
index 0000000..2295cfb
--- /dev/null
@@ -0,0 +1 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec2 Key1=Value1 "Key2=Value with spaces")
diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake
new file mode 100644 (file)
index 0000000..70b18b2
--- /dev/null
@@ -0,0 +1,4 @@
+parseGlobalSections(pre post OnePre)
+testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces")
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePre.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePre.cmake
new file mode 100644 (file)
index 0000000..1499b47
--- /dev/null
@@ -0,0 +1 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec1 Key1=Value1 "Key2=Value with spaces")
diff --git a/Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake b/Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake
new file mode 100644 (file)
index 0000000..a19e2e1
--- /dev/null
@@ -0,0 +1,4 @@
+parseGlobalSections(pre post Override1)
+testGlobalSection(post TestSec Key2=Value2 Key3=Value3)
+testGlobalSection(post ExtensibilityGlobals Key1=Value1)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/Override1.cmake b/Tests/RunCMake/SolutionGlobalSections/Override1.cmake
new file mode 100644 (file)
index 0000000..a726c9f
--- /dev/null
@@ -0,0 +1,2 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_ExtensibilityGlobals Key1=Value1)
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec Key2=Value2 Key3=Value3)
diff --git a/Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake b/Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake
new file mode 100644 (file)
index 0000000..d9656e1
--- /dev/null
@@ -0,0 +1,4 @@
+parseGlobalSections(pre post Override2)
+testGlobalSection(pre TestSec Key2=Value2 Key3=Value3)
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns Key1=Value1)
diff --git a/Tests/RunCMake/SolutionGlobalSections/Override2.cmake b/Tests/RunCMake/SolutionGlobalSections/Override2.cmake
new file mode 100644 (file)
index 0000000..0ce43cc
--- /dev/null
@@ -0,0 +1,2 @@
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_ExtensibilityAddIns Key1=Value1)
+set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec Key2=Value2 Key3=Value3)
diff --git a/Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake
new file mode 100644 (file)
index 0000000..322a689
--- /dev/null
@@ -0,0 +1,6 @@
+parseGlobalSections(pre post PrePost)
+testGlobalSection(post Postsec Key1=Value2)
+testGlobalSection(pre Presec Key1=Value1 "Key2=Value with some spaces")
+testGlobalSection(post Emptysec)
+testGlobalSection(post ExtensibilityGlobals)
+testGlobalSection(post ExtensibilityAddIns)
diff --git a/Tests/RunCMake/SolutionGlobalSections/PrePost.cmake b/Tests/RunCMake/SolutionGlobalSections/PrePost.cmake
new file mode 100644 (file)
index 0000000..976c341
--- /dev/null
@@ -0,0 +1,4 @@
+set_directory_properties(PROPERTIES
+  VS_GLOBAL_SECTION_POST_Postsec Key1=Value2
+  VS_GLOBAL_SECTION_PRE_Presec "Key1=Value1;Key2= Value with some spaces"
+  VS_GLOBAL_SECTION_POST_Emptysec "")
diff --git a/Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake b/Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..6ae158d
--- /dev/null
@@ -0,0 +1,10 @@
+include(RunCMake)
+include(${CMAKE_CURRENT_LIST_DIR}/solution_parsing.cmake)
+
+run_cmake(OnePre)
+run_cmake(OnePost)
+run_cmake(MorePre)
+run_cmake(MorePost)
+run_cmake(PrePost)
+run_cmake(Override1)
+run_cmake(Override2)
diff --git a/Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake b/Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake
new file mode 100644 (file)
index 0000000..dd158ef
--- /dev/null
@@ -0,0 +1,60 @@
+macro(error text)
+  set(RunCMake_TEST_FAILED "${text}")
+  return()
+endmacro()
+
+
+macro(parseGlobalSections arg_out_pre arg_out_post testName)
+  set(out_pre ${arg_out_pre})
+  set(out_post ${arg_out_post})
+  set(sln "${RunCMake_TEST_BINARY_DIR}/${testName}.sln")
+  if(NOT EXISTS "${sln}")
+    error("Expected solution file ${sln} does not exist")
+  endif()
+  file(STRINGS "${sln}" lines)
+  set(sectionLines "")
+  set(store FALSE)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "^\t*Global\n?$")
+      set(store TRUE)
+    elseif(line MATCHES "^\t*EndGlobal\n?$")
+      set(store FALSE)
+    elseif(store)
+      list(APPEND sectionLines "${line}")
+    endif()
+  endforeach()
+  set(sectionName "")
+  set(sectionType "")
+  foreach(line IN LISTS sectionLines)
+    if(line MATCHES "^\t*GlobalSection\\((.*)\\) *= *(pre|post)Solution\n?$")
+      set(sectionName "${CMAKE_MATCH_1}")
+      set(sectionType ${CMAKE_MATCH_2})
+      list(APPEND ${out_${sectionType}} "${sectionName}")
+      if(DEFINED ${out_${sectionType}}_${sectionName})
+        error("Section ${sectionName} defined twice")
+      endif()
+      set(${out_${sectionType}}_${sectionName} "")
+    elseif(line MATCHES "\t*EndGlobalSection\n?$")
+      set(sectionName "")
+      set(sectionType "")
+    elseif(sectionName)
+      string(REGEX MATCH "^\t*([^=]*)=([^\n]*)\n?$" matches "${line}")
+      if(NOT matches)
+        error("Bad syntax in solution file: '${line}'")
+      endif()
+      string(STRIP "${CMAKE_MATCH_1}" key)
+      string(STRIP "${CMAKE_MATCH_2}" value)
+      list(APPEND ${out_${sectionType}}_${sectionName} "${key}=${value}")
+    endif()
+  endforeach()
+endmacro()
+
+
+macro(testGlobalSection prefix sectionName)
+  if(NOT DEFINED ${prefix}_${sectionName})
+    error("Section ${sectionName} does not exist")
+  endif()
+  if(NOT "${${prefix}_${sectionName}}" STREQUAL "${ARGN}")
+    error("Section ${sectionName} content mismatch\n  expected: ${ARGN}\n  actual: ${${prefix}_${sectionName}}")
+  endif()
+endmacro()
index 3287d19..9c146e0 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName1.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:Invali/dTarget,INCLUDE_DIRECTORIES>
 
   Target name not supported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)
index e527e22..451888c 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName2.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:Invali/dTarget,Invali/dProperty>
 
-  Target name and property name not supported.$
+  Target name and property name not supported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index 517debb..39692c4 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName3.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:Invali/dProperty>
 
-  Property name not supported.$
+  Property name not supported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index eab6fb6..c3aa1b1 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName4.cmake:9 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:foo,Invali/dProperty>
 
-  Property name not supported.$
+  Property name not supported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index e2b4fc6..1c6fad4 100644 (file)
@@ -1,7 +1,9 @@
-CMake Error:
+CMake Error at BadInvalidName5.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:,>
 
   \$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name and
   property name.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index e94f52f..8b147dc 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName6.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:,ValidProperty>
 
   \$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty target name.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index 2548215..dad6bf8 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName7.cmake:9 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:foo,>
 
   \$<TARGET_PROPERTY:...> expression requires a non-empty property name.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index 2a98f6f..4e8c14c 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadInvalidName8.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:>
 
   \$<TARGET_PROPERTY:...> expression requires a non-empty property name.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
index d2ac7a9..3b3bab0 100644 (file)
@@ -1,6 +1,8 @@
-CMake Error:
+CMake Error at BadNonTarget.cmake:7 \(include_directories\):
   Error evaluating generator expression:
 
     \$<TARGET_PROPERTY:NonExistant,INCLUDE_DIRECTORIES>
 
-  Target "NonExistant" not found.$
+  Target "NonExistant" not found.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:8 \(include\)$
diff --git a/Tests/RunCMake/add_dependencies/CMakeLists.txt b/Tests/RunCMake/add_dependencies/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e8db6b0
--- /dev/null
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_dependencies/NoTarget-result.txt b/Tests/RunCMake/add_dependencies/NoTarget-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_dependencies/NoTarget-stderr.txt b/Tests/RunCMake/add_dependencies/NoTarget-stderr.txt
new file mode 100644 (file)
index 0000000..6af2707
--- /dev/null
@@ -0,0 +1,9 @@
+CMake Error at NoTarget.cmake:1 \(add_dependencies\):
+  Cannot add target-level dependencies to non-existent target "foo".
+
+  The add_dependencies works for top-level logical targets created by the
+  add_executable, add_library, or add_custom_target commands.  If you want to
+  add file-level dependencies see the DEPENDS option of the add_custom_target
+  and add_custom_command commands.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_dependencies/NoTarget.cmake b/Tests/RunCMake/add_dependencies/NoTarget.cmake
new file mode 100644 (file)
index 0000000..9037694
--- /dev/null
@@ -0,0 +1 @@
+add_dependencies(foo bar)
diff --git a/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake b/Tests/RunCMake/add_dependencies/RunCMakeTest.cmake
new file mode 100644 (file)
index 0000000..30b7e67
--- /dev/null
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(NoTarget)
diff --git a/Tests/RunCMake/build_command/BeforeProject-result.txt b/Tests/RunCMake/build_command/BeforeProject-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/build_command/BeforeProject-stderr.txt b/Tests/RunCMake/build_command/BeforeProject-stderr.txt
new file mode 100644 (file)
index 0000000..d3d7661
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error at BeforeProject.cmake:[0-9]+ \(build_command\):
+  build_command\(\) requires CMAKE_MAKE_PROGRAM to be defined.  Call project\(\)
+  or enable_language\(\) first.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/build_command/BeforeProject.cmake b/Tests/RunCMake/build_command/BeforeProject.cmake
new file mode 100644 (file)
index 0000000..15788d1
--- /dev/null
@@ -0,0 +1,2 @@
+build_command(MAKECOMMAND_DEFAULT_VALUE)
+project(${RunCMake_TEST} NONE)
index 0fbb948..f6e84c0 100644 (file)
@@ -1,59 +1,5 @@
 cmake_minimum_required(VERSION 2.8)
-project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
-
-# This CMakeLists file is *sometimes expected* to result in a configure error.
-#
-# expect this to succeed:
-# ../bin/Release/cmake -G Xcode
-#   ../../CMake/Tests/CMakeCommands/build_command
-#
-# expect this to fail:
-# ../bin/Release/cmake -DTEST_ERROR_CONDITIONS:BOOL=ON -G Xcode
-#   ../../CMake/Tests/CMakeCommands/build_command
-#
-# This project exists merely to test the CMake command 'build_command'...
-# ...even purposefully calling it with known-bad argument lists to cover
-# error handling code.
-#
-
-set(cmd "initial")
-
-message("0. begin")
-
-if(TEST_ERROR_CONDITIONS)
-  # Test with no arguments (an error):
-  build_command()
-  message("1. cmd='${cmd}'")
-
-  # Test with unknown arguments (also an error):
-  build_command(cmd BOGUS STUFF)
-  message("2. cmd='${cmd}'")
-
-  build_command(cmd STUFF BOGUS)
-  message("3. cmd='${cmd}'")
-else()
-  message("(skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF)")
+if(NOT NoProject)
+  project(${RunCMake_TEST} NONE)
 endif()
-
-# Test the one arg signature with none of the optional KEYWORD arguments:
-build_command(cmd)
-message("4. cmd='${cmd}'")
-
-# Test the two-arg legacy signature:
-build_command(legacy_cmd ${CMAKE_BUILD_TOOL})
-message("5. legacy_cmd='${legacy_cmd}'")
-message("   CMAKE_BUILD_TOOL='${CMAKE_BUILD_TOOL}'")
-
-# Test the optional KEYWORDs:
-build_command(cmd CONFIGURATION hoohaaConfig)
-message("6. cmd='${cmd}'")
-
-build_command(cmd PROJECT_NAME hoohaaProject)
-message("7. cmd='${cmd}'")
-
-build_command(cmd TARGET hoohaaTarget)
-message("8. cmd='${cmd}'")
-
-set(cmd "final")
-message("9. cmd='${cmd}'")
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/build_command/ErrorsCommon.cmake b/Tests/RunCMake/build_command/ErrorsCommon.cmake
new file mode 100644 (file)
index 0000000..d224539
--- /dev/null
@@ -0,0 +1,55 @@
+# This CMakeLists file is *sometimes expected* to result in a configure error.
+#
+# expect this to succeed:
+# ../bin/Release/cmake -G Xcode
+#   ../../CMake/Tests/CMakeCommands/build_command
+#
+# expect this to fail:
+# ../bin/Release/cmake -DTEST_ERROR_CONDITIONS:BOOL=ON -G Xcode
+#   ../../CMake/Tests/CMakeCommands/build_command
+#
+# This project exists merely to test the CMake command 'build_command'...
+# ...even purposefully calling it with known-bad argument lists to cover
+# error handling code.
+#
+
+set(cmd "initial")
+
+message("0. begin")
+
+if(TEST_ERROR_CONDITIONS)
+  # Test with no arguments (an error):
+  build_command()
+  message("1. cmd='${cmd}'")
+
+  # Test with unknown arguments (also an error):
+  build_command(cmd BOGUS STUFF)
+  message("2. cmd='${cmd}'")
+
+  build_command(cmd STUFF BOGUS)
+  message("3. cmd='${cmd}'")
+else()
+  message("(skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF)")
+endif()
+
+# Test the one arg signature with none of the optional KEYWORD arguments:
+build_command(cmd)
+message("4. cmd='${cmd}'")
+
+# Test the two-arg legacy signature:
+build_command(legacy_cmd ${CMAKE_BUILD_TOOL})
+message("5. legacy_cmd='${legacy_cmd}'")
+message("   CMAKE_BUILD_TOOL='${CMAKE_BUILD_TOOL}'")
+
+# Test the optional KEYWORDs:
+build_command(cmd CONFIGURATION hoohaaConfig)
+message("6. cmd='${cmd}'")
+
+build_command(cmd PROJECT_NAME hoohaaProject)
+message("7. cmd='${cmd}'")
+
+build_command(cmd TARGET hoohaaTarget)
+message("8. cmd='${cmd}'")
+
+set(cmd "final")
+message("9. cmd='${cmd}'")
index 0be7475..47a84d6 100644 (file)
@@ -1,12 +1,21 @@
-CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+CMake Error at ErrorsCommon.cmake:[0-9]+ \(build_command\):
   build_command requires at least one argument naming a CMake variable
+Call Stack \(most recent call first\):
+  ErrorsON.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
 
 +
 1. cmd='initial'
-CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+CMake Error at ErrorsCommon.cmake:[0-9]+ \(build_command\):
   build_command unknown argument "BOGUS"
+Call Stack \(most recent call first\):
+  ErrorsON.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
 
 +
 2. cmd='initial'
-CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+CMake Error at ErrorsCommon.cmake:[0-9]+ \(build_command\):
   build_command unknown argument "STUFF"
+Call Stack \(most recent call first\):
+  ErrorsON.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
index 4525c57..eaa1d77 100644 (file)
@@ -2,3 +2,7 @@ include(RunCMake)
 
 run_cmake(ErrorsOFF)
 run_cmake(ErrorsON)
+
+set(RunCMake_TEST_OPTIONS -DNoProject=1)
+run_cmake(BeforeProject)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt
new file mode 100644 (file)
index 0000000..0d4379e
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*RunCMake/include_directories/BinaryDirectoryInInterface-build/foo"
+
+  which is prefixed in the build directory.
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake
new file mode 100644 (file)
index 0000000..8754540
--- /dev/null
@@ -0,0 +1,11 @@
+
+project(BinaryDirectoryInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+  DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/DebugIncludes-result.txt b/Tests/RunCMake/include_directories/DebugIncludes-result.txt
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
new file mode 100644 (file)
index 0000000..63aec90
--- /dev/null
@@ -0,0 +1,44 @@
+CMake Debug Log at DebugIncludes.cmake:8 \(include_directories\):
+  Used includes for target lll:
+
+   \* .*/Tests/RunCMake/include_directories/one
+   \* .*/Tests/RunCMake/include_directories/two
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at DebugIncludes.cmake:13 \(set_property\):
+  Used includes for target lll:
+
+   \* .*/Tests/RunCMake/include_directories/three
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at DebugIncludes.cmake:18 \(include_directories\):
+  Used includes for target lll:
+
+   \* .*/Tests/RunCMake/include_directories/four
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at DebugIncludes.cmake:33 \(set_property\):
+  Used includes for target lll:
+
+   \* .*/Tests/RunCMake/include_directories/five
+   \* .*/Tests/RunCMake/include_directories/six
+   \* .*/Tests/RunCMake/include_directories/seven
+
+Call Stack \(most recent call first\):
+  DebugIncludes.cmake:44 \(some_macro\)
+  DebugIncludes.cmake:47 \(some_function\)
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at DebugIncludes.cmake:30 \(target_link_libraries\):
+  Used includes for target lll:
+
+   \* .*/Tests/RunCMake/include_directories/eight
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include_directories/DebugIncludes.cmake b/Tests/RunCMake/include_directories/DebugIncludes.cmake
new file mode 100644 (file)
index 0000000..de36899
--- /dev/null
@@ -0,0 +1,47 @@
+
+project(DebugIncludes)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES INCLUDE_DIRECTORIES)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp" "enum { dummy };\n")
+
+include_directories(
+  "${CMAKE_CURRENT_SOURCE_DIR}/one"
+  "${CMAKE_CURRENT_SOURCE_DIR}/two"
+)
+
+set_property(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES
+                          "${CMAKE_CURRENT_SOURCE_DIR}/three")
+
+add_library(lll "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp")
+
+include_directories(
+  "${CMAKE_CURRENT_SOURCE_DIR}/two"
+  "${CMAKE_CURRENT_SOURCE_DIR}/three"
+  "${CMAKE_CURRENT_SOURCE_DIR}/four"
+)
+
+add_library(foo "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp")
+target_include_directories(foo
+  INTERFACE
+    "${CMAKE_CURRENT_SOURCE_DIR}/seven"
+    "${CMAKE_CURRENT_SOURCE_DIR}/eight"
+)
+target_link_libraries(lll foo)
+
+macro(some_macro)
+  set_property(TARGET lll APPEND PROPERTY
+      INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/one"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/three"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/four"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/five"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/six"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/seven"
+  )
+endmacro()
+
+function(some_function)
+  some_macro()
+endfunction()
+
+some_function()
diff --git a/Tests/RunCMake/include_directories/ImportedTarget-result.txt b/Tests/RunCMake/include_directories/ImportedTarget-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/ImportedTarget-stderr.txt b/Tests/RunCMake/include_directories/ImportedTarget-stderr.txt
new file mode 100644 (file)
index 0000000..da26052
--- /dev/null
@@ -0,0 +1,13 @@
+CMake Error in CMakeLists.txt:
+  Imported target "imported" includes non-existent path
+
+    "/does/not/exist"
+
+  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:
+
+  \* The path was deleted, renamed, or moved to another location.
+
+  \* An install or uninstall procedure did not complete successfully.
+
+  \* The installation package was faulty and references files it does not
+  provide.
diff --git a/Tests/RunCMake/include_directories/ImportedTarget.cmake b/Tests/RunCMake/include_directories/ImportedTarget.cmake
new file mode 100644 (file)
index 0000000..e1a20b1
--- /dev/null
@@ -0,0 +1,9 @@
+
+project(ImportedTarget)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+
+add_library(imported UNKNOWN IMPORTED)
+set_property(TARGET imported PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
+
+target_link_libraries(testTarget imported)
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt b/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt b/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt
new file mode 100644 (file)
index 0000000..490c700
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" contains relative path in its
+  INTERFACE_INCLUDE_DIRECTORIES:
+
+    "foo"
diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex.cmake b/Tests/RunCMake/include_directories/RelativePathInGenex.cmake
new file mode 100644 (file)
index 0000000..f72cf3a
--- /dev/null
@@ -0,0 +1,8 @@
+
+project(RelativePathInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>")
+
+add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_link_libraries(userTarget testTarget)
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt b/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt b/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt
new file mode 100644 (file)
index 0000000..f6cdb53
--- /dev/null
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains
+  relative path:
+
+    "foo"
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake b/Tests/RunCMake/include_directories/RelativePathInInterface.cmake
new file mode 100644 (file)
index 0000000..f2ce54a
--- /dev/null
@@ -0,0 +1,11 @@
+
+project(RelativePathInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo")
+
+install(TARGETS testTarget EXPORT testTargets
+  DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
index aee3f79..f516086 100644 (file)
@@ -1,3 +1,10 @@
 include(RunCMake)
 
 run_cmake(NotFoundContent)
+run_cmake(DebugIncludes)
+run_cmake(TID-bad-target)
+run_cmake(SourceDirectoryInInterface)
+run_cmake(BinaryDirectoryInInterface)
+run_cmake(RelativePathInInterface)
+run_cmake(ImportedTarget)
+run_cmake(RelativePathInGenex)
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt
new file mode 100644 (file)
index 0000000..9346b99
--- /dev/null
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*RunCMake/include_directories/foo"
+
+  which is prefixed in the source directory.
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake
new file mode 100644 (file)
index 0000000..c9a9c45
--- /dev/null
@@ -0,0 +1,11 @@
+
+project(SourceDirectoryInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+  DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/TID-bad-target-result.txt b/Tests/RunCMake/include_directories/TID-bad-target-result.txt
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt b/Tests/RunCMake/include_directories/TID-bad-target-stderr.txt
new file mode 100644 (file)
index 0000000..481e358
--- /dev/null
@@ -0,0 +1,4 @@
+CMake Error at TID-bad-target.cmake:6 \(target_include_directories\):
+  target_include_directories called with non-compilable target type
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include_directories/TID-bad-target.cmake b/Tests/RunCMake/include_directories/TID-bad-target.cmake
new file mode 100644 (file)
index 0000000..32201c1
--- /dev/null
@@ -0,0 +1,6 @@
+
+add_custom_target(check ALL
+  COMMAND ${CMAKE_COMMAND} -E echo check
+)
+
+target_include_directories(check PRIVATE somedir)
diff --git a/Tests/RunCMake/include_directories/empty.cpp b/Tests/RunCMake/include_directories/empty.cpp
new file mode 100644 (file)
index 0000000..e69de29
index ecbc054..df3bf49 100644 (file)
@@ -96,7 +96,9 @@ CMAKE_CXX_LINK_EXECUTABLE == "${CMAKE_CXX_LINK_EXECUTABLE}"
 // implicit link info
 CMAKE_C_IMPLICIT_LINK_LIBRARIES == "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}"
 CMAKE_C_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}"
+CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES == "${CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES}"
 CMAKE_CXX_IMPLICIT_LINK_LIBRARIES == "${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}"
 CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}"
+CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES == "${CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES}"
 
 XCODE_VERSION == "${XCODE_VERSION}"
diff --git a/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt b/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d30414b
--- /dev/null
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(VSExcludeFromDefaultBuild)
+
+# First step is to clear all .exe files in output so that possible past
+# failures of this test do not prevent it from succeeding.
+add_custom_target(ClearExes ALL
+  COMMAND "${CMAKE_COMMAND}"
+    -Ddir=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/ClearExes.cmake
+  VERBATIM)
+
+# Make sure ClearExes is executed before other targets are built
+function(add_test_executable target)
+  add_executable("${target}" ${ARGN})
+  add_dependencies("${target}" ClearExes)
+endfunction()
+
+add_test_executable(DefaultBuilt main.c)
+
+add_test_executable(AlwaysBuilt main.c)
+set_target_properties(AlwaysBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD FALSE)
+
+add_test_executable(NeverBuilt main.c)
+set_target_properties(NeverBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
+
+foreach(config ${CMAKE_CONFIGURATION_TYPES})
+  string(TOUPPER ${config} Config)
+  add_test_executable(BuiltIn${config} main.c)
+  set_target_properties(BuiltIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_DEFAULT_BUILD_${Config} FALSE)
+  add_test_executable(ExcludedIn${config} main.c)
+  set_target_properties(ExcludedIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD_${Config} TRUE)
+endforeach()
diff --git a/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake b/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake
new file mode 100644 (file)
index 0000000..ece30ad
--- /dev/null
@@ -0,0 +1,4 @@
+file(GLOB exeFiles "${dir}/*.exe")
+foreach(exeFile IN LISTS exeFiles)
+  file(REMOVE "${exeFile}")
+endforeach()
diff --git a/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake b/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake
new file mode 100644 (file)
index 0000000..8fb00bf
--- /dev/null
@@ -0,0 +1,23 @@
+message(STATUS "Testing configuration ${activeConfig}.")
+
+macro(TestExists exeName)
+  set(exeFile "${dir}/${activeConfig}/${exeName}.exe")
+  if(${ARGN} EXISTS "${exeFile}")
+    message(STATUS "File ${exeFile} was correctly found ${ARGN} to exist.")
+  else()
+    message(FATAL_ERROR "File ${exeFile} was expected ${ARGN} to exist!")
+  endif()
+endmacro()
+
+TestExists(DefaultBuilt)
+TestExists(AlwaysBuilt)
+TestExists(NeverBuilt NOT)
+foreach(config ${allConfigs})
+  if(config STREQUAL activeConfig)
+    TestExists(BuiltIn${config})
+    TestExists(ExcludedIn${config} NOT)
+  else()
+    TestExists(BuiltIn${config} NOT)
+    TestExists(ExcludedIn${config})
+  endif()
+endforeach()
diff --git a/Tests/VSExcludeFromDefaultBuild/main.c b/Tests/VSExcludeFromDefaultBuild/main.c
new file mode 100644 (file)
index 0000000..8488f4e
--- /dev/null
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
index 399ac69..8fc2871 100644 (file)
@@ -6,7 +6,7 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
 else()
   set(PROJECT_EXT vcproj)
 endif()
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[01]")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012]")
   set(PROJECT_EXT vcxproj)
 endif()
 
@@ -18,13 +18,21 @@ set(LIB2_BINARY_DIR ${VSExternalInclude_BINARY_DIR}/Lib2)
 make_directory("${LIB2_BINARY_DIR}")
 
 # generate lib1
-exec_program("${CMAKE_COMMAND}" "${LIB1_BINARY_DIR}"  ARGS -G\"${CMAKE_GENERATOR}\"
-  \"${VSExternalInclude_SOURCE_DIR}/Lib1\" OUTPUT_VARIABLE OUT)
+execute_process(
+  COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib1"
+  WORKING_DIRECTORY ${LIB1_BINARY_DIR}
+  OUTPUT_VARIABLE OUT
+  ERROR_VARIABLE OUT
+  )
 message("CMAKE Ran with the following output:\n\"${OUT}\"")
 
 # generate lib2
-exec_program("${CMAKE_COMMAND}" "${LIB2_BINARY_DIR}"  ARGS -G\"${CMAKE_GENERATOR}\"
-  \"${VSExternalInclude_SOURCE_DIR}/Lib2\" OUTPUT_VARIABLE OUT)
+execute_process(
+  COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -T "${CMAKE_GENERATOR_TOOLSET}" "${VSExternalInclude_SOURCE_DIR}/Lib2"
+  WORKING_DIRECTORY ${LIB2_BINARY_DIR}
+  OUTPUT_VARIABLE OUT
+  ERROR_VARIABLE OUT
+  )
 message("CMAKE Ran with the following output:\n\"${OUT}\"")
 
 
@@ -46,7 +54,7 @@ add_dependencies(VSExternalInclude lib2)
 # and the sln file can no longer be the only source
 # of that depend.  So, for VS 10 make the executable
 # depend on lib1 and lib2
-if(MSVC10 OR MSVC11)
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012]")
   add_dependencies(VSExternalInclude lib1)
 endif()
 
index 1cb01c5..9dfac86 100644 (file)
@@ -1,3 +1,4 @@
+set(CMAKE_SUPPRESS_REGENERATION 1)
 project(LIB1)
 
 set(SOURCES lib1.cpp)
index f726c3f..f451354 100644 (file)
@@ -1,3 +1,4 @@
+set(CMAKE_SUPPRESS_REGENERATION 1)
 project(VSEXTERNAL_LIB2)
 
 include_directories(${VSEXTERNAL_LIB2_SOURCE_DIR}/../Lib1)
index d308a81..a35d111 100755 (executable)
@@ -47,18 +47,16 @@ if test -z "$HOOKS_ALLOW_KWSYS"; then
 
 '"$(echo "$files" | sed 's/^/  /')"'
 
-cannot be committed through Git.  KWSys is kept in a CVS repository
-shared by several projects.  A robot replays changes committed there
-into the Source/kwsys directory in CMake.  Please send changes to
-this directory separately.  Run
+should not be made directly in CMake.  KWSys is kept in its own Git
+repository and shared by several projects.  Please visit
 
-  git reset HEAD -- Source/kwsys
+  http://public.kitware.com/Wiki/KWSys/Git
 
-to unstage these changes and then
+to contribute changes directly to KWSys.  Run
 
-  git diff -- Source/kwsys > kwsys.patch
+  git reset HEAD -- Source/kwsys
 
-to construct the patch.  Alternatively, set environment variable
+to unstage these changes.  Alternatively, set environment variable
 
   HOOKS_ALLOW_KWSYS=1
 
index 060a520..b71cdfb 100644 (file)
@@ -253,7 +253,9 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined.
 #  else
 #   define @KWIML@_ABI_SIZEOF_LONG_LONG 0
 #  endif
-# elif defined(__hpux) && !defined(__GNUC__) /* Old HP: no __HP_cc/__HP_aCC above */
+# elif defined(__GNUC__) /* GNU */
+#  define @KWIML@_ABI_SIZEOF_LONG_LONG 8
+# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */
 #  define @KWIML@_ABI_SIZEOF_LONG_LONG 8
 # endif
 #endif
@@ -414,6 +416,18 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined.
 #elif defined(__SYSC_ZARCH__)
 # define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
 
+/* VAX */
+#elif defined(__vax__)
+# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
+
+/* Aarch64 */
+#elif defined(__aarch64__)
+# if !defined(__AARCH64EB__)
+#  define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE
+# else
+#  define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG
+# endif
+
 /* Unknown CPU */
 #elif !defined(@KWIML@_ABI_NO_ERROR_ENDIAN)
 # error "Byte order of target CPU unknown."
index ef000a1..320612c 100644 (file)
@@ -376,7 +376,6 @@ MARK_AS_ADVANCED(RANDOM_FILE)
 #sigaction \
 #signal \
 #getpass_r \
-#strlcat \
 #getpwuid \
 #geteuid \
 #dlopen \
@@ -428,7 +427,6 @@ CHECK_SYMBOL_EXISTS(closesocket   "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
 CHECK_SYMBOL_EXISTS(setvbuf       "${CURL_INCLUDES}" HAVE_SETVBUF)
 CHECK_SYMBOL_EXISTS(sigsetjmp     "${CURL_INCLUDES}" HAVE_SIGSETJMP)
 CHECK_SYMBOL_EXISTS(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
-CHECK_SYMBOL_EXISTS(strlcat       "${CURL_INCLUDES}" HAVE_STRLCAT)
 CHECK_SYMBOL_EXISTS(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
 CHECK_SYMBOL_EXISTS(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
 CHECK_SYMBOL_EXISTS(utime         "${CURL_INCLUDES}" HAVE_UTIME)
index b4515ce..57ab30b 100644 (file)
@@ -76,7 +76,6 @@ IF(NOT UNIX)
     SET(HAVE_SETVBUF 0)
     SET(HAVE_SIGSETJMP 0)
     SET(HAVE_GETPASS_R 0)
-    SET(HAVE_STRLCAT 0)
     SET(HAVE_GETPWUID 0)
     SET(HAVE_GETEUID 0)
     SET(HAVE_UTIME 1)
index 86d1093..c98b10f 100644 (file)
 /* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
 
-/* Define to 1 if you have the `strlcat' function. */
-/* #undef HAVE_STRLCAT */
-
 /* Define to 1 if you have the `strlcpy' function. */
 /* #undef HAVE_STRLCPY */
 
index e18af8f..148722b 100644 (file)
 /* Define to 1 if you have the <string.h> header file. */
 #cmakedefine HAVE_STRING_H ${HAVE_STRING_H}
 
-/* Define to 1 if you have the `strlcat' function. */
-#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT}
-
 /* Define to 1 if you have the `strlcpy' function. */
 #cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY}
 
index 3319e69..e0e947b 100644 (file)
@@ -199,8 +199,15 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
    * This is currently not supporting "Identification Protocol (RFC1413)".
    */
   socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
-  if (proxy_name)
-    strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8);
+  if(proxy_name) {
+    size_t plen = strlen(proxy_name);
+    if(plen >= sizeof(socksreq) - 8) {
+      failf(data, "Too long SOCKS proxy name, can't use!\n");
+      return CURLE_COULDNT_CONNECT;
+    }
+    /* copy the proxy name WITH trailing zero */
+    memcpy(socksreq + 8, proxy_name, plen+1);
+  }
 
   /*
    * Make connection
index 76ad524..83796f6 100644 (file)
@@ -99,45 +99,3 @@ char *Curl_strcasestr(const char *haystack, const char *needle)
   }
   return NULL;
 }
-
-#ifndef HAVE_STRLCAT
-/*
- * The strlcat() function appends the NUL-terminated string src to the end
- * of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
- * nating the result.
- *
- * The strlcpy() and strlcat() functions return the total length of the
- * string they tried to create.  For strlcpy() that means the length of src.
- * For strlcat() that means the initial length of dst plus the length of
- * src. While this may seem somewhat confusing it was done to make trunca-
- * tion detection simple.
- *
- *
- */
-size_t Curl_strlcat(char *dst, const char *src, size_t siz)
-{
-  char *d = dst;
-  const char *s = src;
-  size_t n = siz;
-  size_t dlen;
-
-  /* Find the end of dst and adjust bytes left but don't go past end */
-  while (n-- != 0 && *d != '\0')
-    d++;
-  dlen = d - dst;
-  n = siz - dlen;
-
-  if (n == 0)
-    return(dlen + strlen(s));
-  while (*s != '\0') {
-    if (n != 1) {
-      *d++ = *s;
-      n--;
-    }
-    s++;
-  }
-  *d = '\0';
-
-  return(dlen + (s - src));     /* count does not include NUL */
-}
-#endif
index b3caa73..6718c3c 100644 (file)
@@ -35,9 +35,4 @@
 /* case insensitive strstr() */
 char *Curl_strcasestr(const char *haystack, const char *needle);
 
-#ifndef HAVE_STRLCAT
-#define strlcat(x,y,z) Curl_strlcat(x,y,z)
-#endif
-size_t strlcat(char *dst, const char *src, size_t siz);
-
 #endif
index bbf58fd..3c039f7 100644 (file)
@@ -64,7 +64,13 @@ archive_be16dec(const void *pp)
 {
        unsigned char const *p = (unsigned char const *)pp;
 
-       return ((p[0] << 8) | p[1]);
+       /* Store into unsigned temporaries before left shifting, to avoid
+       promotion to signed int and then left shifting into the sign bit,
+       which is undefined behaviour. */
+       unsigned int p1 = p[1];
+       unsigned int p0 = p[0];
+
+       return ((p0 << 8) | p1);
 }
 
 static inline uint32_t
@@ -72,7 +78,15 @@ archive_be32dec(const void *pp)
 {
        unsigned char const *p = (unsigned char const *)pp;
 
-       return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+       /* Store into unsigned temporaries before left shifting, to avoid
+       promotion to signed int and then left shifting into the sign bit,
+       which is undefined behaviour. */
+       unsigned int p3 = p[3];
+       unsigned int p2 = p[2];
+       unsigned int p1 = p[1];
+       unsigned int p0 = p[0];
+
+       return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3);
 }
 
 static inline uint64_t
@@ -88,7 +102,13 @@ archive_le16dec(const void *pp)
 {
        unsigned char const *p = (unsigned char const *)pp;
 
-       return ((p[1] << 8) | p[0]);
+       /* Store into unsigned temporaries before left shifting, to avoid
+       promotion to signed int and then left shifting into the sign bit,
+       which is undefined behaviour. */
+       unsigned int p1 = p[1];
+       unsigned int p0 = p[0];
+
+       return ((p1 << 8) | p0);
 }
 
 static inline uint32_t
@@ -96,7 +116,15 @@ archive_le32dec(const void *pp)
 {
        unsigned char const *p = (unsigned char const *)pp;
 
-       return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+       /* Store into unsigned temporaries before left shifting, to avoid
+       promotion to signed int and then left shifting into the sign bit,
+       which is undefined behaviour. */
+       unsigned int p3 = p[3];
+       unsigned int p2 = p[2];
+       unsigned int p1 = p[1];
+       unsigned int p0 = p[0];
+
+       return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0);
 }
 
 static inline uint64_t
index a4c4aa8..5c2addb 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -93,6 +93,19 @@ else
   cmake_system_openvms=false
 fi
 
+# Determine whether this is Linux
+if echo "${cmake_system}" | grep Linux >/dev/null 2>&1; then
+  cmake_system_linux=true
+  # find out if it is a HP PA-RISC machine
+  if uname -m | grep parisc >/dev/null 2>&1; then
+    cmake_machine_parisc=true
+  else
+    cmake_machine_parisc=false
+  fi
+else
+  cmake_system_linux=false
+fi
+
 # Choose the generator to use for bootstrapping.
 if ${cmake_system_mingw}; then
   # Bootstrapping from an MSYS prompt.
@@ -146,7 +159,9 @@ if ${cmake_system_mingw}; then
     cmake_default_prefix="c:/Program Files/CMake"
   fi
 elif ${cmake_system_haiku}; then
-  cmake_default_prefix=`/bin/finddir B_COMMON_DIRECTORY`
+  cmake_default_prefix=`finddir B_COMMON_DIRECTORY`
+  cmake_man_dir="/documentation/man"
+  cmake_doc_dir="/documentation/doc/cmake-${cmake_version}"
 else
   cmake_default_prefix="/usr/local"
 fi
@@ -199,6 +214,7 @@ CMAKE_CXX_SOURCES="\
   cmMakefile \
   cmExportFileGenerator \
   cmExportInstallFileGenerator \
+  cmExportTryCompileFileGenerator \
   cmExportSet \
   cmExportSetMap \
   cmInstallDirectoryGenerator \
@@ -271,18 +287,11 @@ if ${cmake_system_mingw}; then
     ProcessWin32 \
     String \
     System"
-  KWSYS_C_MINGW_SOURCES="\
-    ProcessFwd9x \
-    EncodeExecutable"
-  KWSYS_C_GENERATED_SOURCES="\
-    cmsysProcessFwd9xEnc"
 else
   KWSYS_C_SOURCES="\
     ProcessUNIX \
     String \
     System"
-  KWSYS_C_MINGW_SOURCES=""
-  KWSYS_C_GENERATED_SOURCES=""
 fi
 
 KWSYS_CXX_SOURCES="\
@@ -678,6 +687,14 @@ if ${cmake_system_haiku}; then
   cmake_ld_flags="${LDFLAGS} -lroot -lbe"
 fi
 
+if ${cmake_system_linux}; then
+  # avoid binutils problem with large binaries, e.g. when building CMake in debug mode
+  # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230
+  if ${cmake_machine_parisc}; then
+    cmake_ld_flags="${LDFLAGS} -Wl,--unique=.text.*"
+  fi
+fi
+
 #-----------------------------------------------------------------------------
 # Detect known toolchains on some platforms.
 cmake_toolchains=''
@@ -1330,7 +1347,7 @@ cmake_compiler_settings_comment="/*
  * Sources:
  * ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES}
  * kwSys Sources:
- * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}
+ * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}
  */
 "
 
@@ -1426,7 +1443,7 @@ done
 # Generate Makefile
 dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h"
 objs=""
-for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_GENERATED_SOURCES}; do
+for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
   objs="${objs} ${a}.o"
 done
 
@@ -1467,7 +1484,7 @@ for a in ${CMAKE_C_SOURCES}; do
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "       ${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
-for a in ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}; do
+for a in ${KWSYS_C_SOURCES}; do
   src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.c"`
   src_flags=`eval echo \\${cmake_c_flags_\${a}}`
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
@@ -1479,20 +1496,6 @@ for a in ${KWSYS_CXX_SOURCES}; do
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "       ${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
-if ${cmake_system_mingw}; then
-  src=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9xEnc.c"`
-  in=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9x.exe"`
-  cmd=`cmake_escape "${cmake_bootstrap_dir}/cmsysEncodeExecutable.exe"`
-  a="cmsysProcessFwd9xEnc"
-  echo "${cmd} : EncodeExecutable.o" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "       ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} EncodeExecutable.o -o ${cmd}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "${in} : ProcessFwd9x.o" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "       ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} ProcessFwd9x.o -o ${in}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "${src} : ${cmd} ${in}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "       ${cmd} ${in} ${src} cmsys ProcessFwd9x" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "       ${cmake_c_compiler} ${cmake_c_flags} -I`cmake_escape \"${cmake_source_dir}/Source/kwsys\"` -DKWSYS_NAMESPACE=cmsys -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
-fi
 echo '
 rebuild_cache:
        cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"