summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt40
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx2
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx11
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx4
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx3
-rw-r--r--Source/CPack/cpack.cxx10
-rw-r--r--Source/CTest/cmCTestBZR.cxx1
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx10
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx37
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h2
-rw-r--r--Source/CTest/cmCTestGIT.cxx2
-rw-r--r--Source/CTest/cmCTestGenericHandler.cxx2
-rw-r--r--Source/CTest/cmCTestGenericHandler.h3
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx6
-rw-r--r--Source/CTest/cmCTestLaunch.cxx5
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx16
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx159
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h4
-rw-r--r--Source/CTest/cmCTestP4.cxx2
-rw-r--r--Source/CTest/cmCTestRunTest.cxx3
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx46
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx33
-rw-r--r--Source/CTest/cmCTestTestCommand.h1
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx36
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx4
-rw-r--r--Source/CTest/cmProcess.cxx19
-rw-r--r--Source/CTest/cmProcess.h7
-rw-r--r--Source/CursesDialog/CMakeLists.txt3
-rw-r--r--Source/QtDialog/CMakeLists.txt65
-rw-r--r--Source/QtDialog/Info.plist.in2
-rw-r--r--Source/QtIFW/CMake.Dialogs.QtGUI.qs21
-rw-r--r--Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in21
-rw-r--r--Source/QtIFW/CMake.qs.in22
-rw-r--r--Source/QtIFW/installscript.qs.in8
-rw-r--r--Source/bindexplib.cxx428
-rw-r--r--Source/cmAlgorithms.h84
-rw-r--r--Source/cmArchiveWrite.cxx46
-rw-r--r--Source/cmArchiveWrite.h1
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx4
-rw-r--r--Source/cmCMakePolicyCommand.cxx16
-rw-r--r--Source/cmCPackPropertiesGenerator.cxx16
-rw-r--r--Source/cmCPackPropertiesGenerator.h6
-rw-r--r--Source/cmCPluginAPI.cxx22
-rw-r--r--Source/cmCTest.cxx73
-rw-r--r--Source/cmCTest.h6
-rw-r--r--Source/cmCacheManager.cxx11
-rw-r--r--Source/cmCallVisualStudioMacro.cxx2
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx7
-rw-r--r--Source/cmCommandArgumentParserHelper.h8
-rw-r--r--Source/cmCommonTargetGenerator.cxx414
-rw-r--r--Source/cmCommonTargetGenerator.h95
-rw-r--r--Source/cmComputeComponentGraph.h4
-rw-r--r--Source/cmComputeLinkDepends.cxx37
-rw-r--r--Source/cmComputeLinkDepends.h26
-rw-r--r--Source/cmComputeLinkInformation.cxx102
-rw-r--r--Source/cmComputeLinkInformation.h43
-rw-r--r--Source/cmComputeTargetDepends.cxx84
-rw-r--r--Source/cmComputeTargetDepends.h16
-rw-r--r--Source/cmConditionEvaluator.cxx42
-rw-r--r--Source/cmConditionEvaluator.h1
-rw-r--r--Source/cmCoreTryCompile.cxx18
-rw-r--r--Source/cmCryptoHash.cxx2
-rw-r--r--Source/cmCurl.cxx2
-rw-r--r--Source/cmCustomCommand.cxx55
-rw-r--r--Source/cmCustomCommand.h10
-rw-r--r--Source/cmCustomCommandGenerator.cxx28
-rw-r--r--Source/cmCustomCommandGenerator.h4
-rw-r--r--Source/cmDefinitions.cxx14
-rw-r--r--Source/cmDefinitions.h17
-rw-r--r--Source/cmDependsFortran.cxx525
-rw-r--r--Source/cmDependsFortran.h19
-rw-r--r--Source/cmDependsFortranParser.h96
-rw-r--r--Source/cmDocumentation.h1
-rw-r--r--Source/cmExecProgramCommand.cxx6
-rw-r--r--Source/cmExportBuildFileGenerator.cxx47
-rw-r--r--Source/cmExportBuildFileGenerator.h7
-rw-r--r--Source/cmExportCommand.cxx6
-rw-r--r--Source/cmExportFileGenerator.cxx64
-rw-r--r--Source/cmExportFileGenerator.h12
-rw-r--r--Source/cmExportInstallFileGenerator.cxx22
-rw-r--r--Source/cmExportInstallFileGenerator.h3
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx8
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx14
-rw-r--r--Source/cmExportTryCompileFileGenerator.h8
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx30
-rw-r--r--Source/cmExtraCodeBlocksGenerator.h5
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx18
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx3
-rw-r--r--Source/cmExtraKateGenerator.cxx1
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx1
-rw-r--r--Source/cmFileCommand.cxx31
-rw-r--r--Source/cmFindBase.cxx4
-rw-r--r--Source/cmFindLibraryCommand.cxx1
-rw-r--r--Source/cmFindPackageCommand.cxx2
-rw-r--r--Source/cmFortranLexer.cxx (renamed from Source/cmDependsFortranLexer.cxx)451
-rw-r--r--Source/cmFortranLexer.h (renamed from Source/cmDependsFortranLexer.h)76
-rw-r--r--Source/cmFortranLexer.in.l (renamed from Source/cmDependsFortranLexer.in.l)38
-rw-r--r--Source/cmFortranParser.cxx (renamed from Source/cmDependsFortranParser.cxx)1051
-rw-r--r--Source/cmFortranParser.h175
-rw-r--r--Source/cmFortranParser.y (renamed from Source/cmDependsFortranParser.y)157
-rw-r--r--Source/cmFortranParserImpl.cxx408
-rw-r--r--Source/cmFortranParserTokens.h (renamed from Source/cmDependsFortranParserTokens.h)105
-rw-r--r--Source/cmFunctionCommand.cxx34
-rw-r--r--Source/cmGeneratorExpression.cxx6
-rw-r--r--Source/cmGeneratorExpression.h5
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx2
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx42
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h15
-rw-r--r--Source/cmGeneratorExpressionNode.cxx87
-rw-r--r--Source/cmGeneratorTarget.cxx3414
-rw-r--r--Source/cmGeneratorTarget.h309
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx19
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx43
-rw-r--r--Source/cmGetDirectoryPropertyCommand.h5
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx24
-rw-r--r--Source/cmGetPropertyCommand.cxx31
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx6
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx6
-rw-r--r--Source/cmGetTestPropertyCommand.cxx6
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx34
-rw-r--r--Source/cmGhsMultiTargetGenerator.h3
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx4
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h3
-rw-r--r--Source/cmGlobalCommonGenerator.cxx21
-rw-r--r--Source/cmGlobalCommonGenerator.h27
-rw-r--r--Source/cmGlobalGenerator.cxx553
-rw-r--r--Source/cmGlobalGenerator.h107
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx5
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h3
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx28
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h3
-rw-r--r--Source/cmGlobalKdevelopGenerator.cxx8
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx6
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx28
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx64
-rw-r--r--Source/cmGlobalNinjaGenerator.h26
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx150
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h19
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx18
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx9
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h5
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx4
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx92
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h8
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx26
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h2
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx133
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h9
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx127
-rw-r--r--Source/cmGlobalXCodeGenerator.h4
-rw-r--r--Source/cmGraphVizWriter.cxx7
-rw-r--r--Source/cmGraphVizWriter.h15
-rw-r--r--Source/cmIfCommand.cxx9
-rw-r--r--Source/cmIncludeCommand.cxx1
-rw-r--r--Source/cmInstallCommand.cxx13
-rw-r--r--Source/cmInstallExportGenerator.cxx13
-rw-r--r--Source/cmInstallExportGenerator.h8
-rw-r--r--Source/cmInstallFilesCommand.cxx2
-rw-r--r--Source/cmInstallFilesGenerator.cxx21
-rw-r--r--Source/cmInstallFilesGenerator.h11
-rw-r--r--Source/cmInstallGenerator.h2
-rw-r--r--Source/cmInstallProgramsCommand.cxx2
-rw-r--r--Source/cmInstallTargetGenerator.cxx88
-rw-r--r--Source/cmInstallTargetGenerator.h20
-rw-r--r--Source/cmInstalledFile.cxx4
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx2
-rw-r--r--Source/cmLinkItem.h121
-rw-r--r--Source/cmLinkedTree.h195
-rw-r--r--Source/cmListCommand.cxx12
-rw-r--r--Source/cmListFileCache.cxx60
-rw-r--r--Source/cmListFileCache.h53
-rw-r--r--Source/cmLocalCommonGenerator.cxx39
-rw-r--r--Source/cmLocalCommonGenerator.h37
-rw-r--r--Source/cmLocalGenerator.cxx962
-rw-r--r--Source/cmLocalGenerator.h153
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx7
-rw-r--r--Source/cmLocalGhsMultiGenerator.h3
-rw-r--r--Source/cmLocalNinjaGenerator.cxx70
-rw-r--r--Source/cmLocalNinjaGenerator.h15
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx93
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h43
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx11
-rw-r--r--Source/cmLocalVisualStudio10Generator.h4
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx159
-rw-r--r--Source/cmLocalVisualStudio6Generator.h5
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx120
-rw-r--r--Source/cmLocalVisualStudio7Generator.h4
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx10
-rw-r--r--Source/cmLocalVisualStudioGenerator.h4
-rw-r--r--Source/cmLocalXCodeGenerator.cxx5
-rw-r--r--Source/cmLocalXCodeGenerator.h4
-rw-r--r--Source/cmMacroCommand.cxx30
-rw-r--r--Source/cmMakeDepend.cxx2
-rw-r--r--Source/cmMakefile.cxx1369
-rw-r--r--Source/cmMakefile.h278
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx12
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx79
-rw-r--r--Source/cmMakefileTargetGenerator.cxx442
-rw-r--r--Source/cmMakefileTargetGenerator.h54
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx2
-rw-r--r--Source/cmMessageCommand.cxx16
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx84
-rw-r--r--Source/cmNinjaTargetGenerator.cxx334
-rw-r--r--Source/cmNinjaTargetGenerator.h37
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx6
-rw-r--r--Source/cmOSXBundleGenerator.cxx16
-rw-r--r--Source/cmOrderDirectories.cxx8
-rw-r--r--Source/cmOrderDirectories.h11
-rw-r--r--Source/cmOutputConverter.cxx1056
-rw-r--r--Source/cmOutputConverter.h181
-rw-r--r--Source/cmPolicies.cxx47
-rw-r--r--Source/cmPolicies.h13
-rw-r--r--Source/cmProcessTools.cxx2
-rw-r--r--Source/cmProcessTools.h6
-rw-r--r--Source/cmProjectCommand.cxx5
-rw-r--r--Source/cmProperty.cxx7
-rw-r--r--Source/cmProperty.h6
-rw-r--r--Source/cmPropertyDefinitionMap.cxx8
-rw-r--r--Source/cmPropertyDefinitionMap.h4
-rw-r--r--Source/cmPropertyMap.cxx29
-rw-r--r--Source/cmPropertyMap.h18
-rw-r--r--Source/cmQtAutoGenerators.cxx144
-rw-r--r--Source/cmQtAutoGenerators.h6
-rw-r--r--Source/cmScriptGenerator.h3
-rw-r--r--Source/cmSetCommand.cxx2
-rw-r--r--Source/cmSetPropertyCommand.cxx10
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx6
-rw-r--r--Source/cmSourceFile.cxx19
-rw-r--r--Source/cmSourceFile.h4
-rw-r--r--Source/cmStandardIncludes.h8
-rw-r--r--Source/cmState.cxx1162
-rw-r--r--Source/cmState.h206
-rw-r--r--Source/cmStringCommand.cxx42
-rw-r--r--Source/cmStringCommand.h1
-rw-r--r--Source/cmSystemTools.cxx142
-rw-r--r--Source/cmSystemTools.h9
-rw-r--r--Source/cmTarget.cxx3786
-rw-r--r--Source/cmTarget.h426
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx3
-rw-r--r--Source/cmTargetDepend.h13
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx23
-rw-r--r--Source/cmTest.cxx18
-rw-r--r--Source/cmTestGenerator.cxx35
-rw-r--r--Source/cmTestGenerator.h4
-rw-r--r--Source/cmVariableWatchCommand.cxx16
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx236
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx14
-rw-r--r--Source/cmXCode21Object.cxx2
-rw-r--r--Source/cmXCodeObject.cxx6
-rw-r--r--Source/cmXMLSafe.cxx8
-rw-r--r--Source/cmXMLSafe.h8
-rw-r--r--Source/cmake.cxx332
-rw-r--r--Source/cmake.h37
-rw-r--r--Source/cmakemain.cxx10
-rw-r--r--Source/cmcmd.cxx72
-rw-r--r--Source/ctest.cxx1
-rw-r--r--Source/kwsys/CMakeLists.txt15
-rw-r--r--Source/kwsys/CONTRIBUTING.rst2
-rw-r--r--Source/kwsys/CTestCustom.cmake.in15
-rw-r--r--Source/kwsys/EncodingC.c14
-rw-r--r--Source/kwsys/Process.h.in131
-rw-r--r--Source/kwsys/ProcessUNIX.c357
-rw-r--r--Source/kwsys/ProcessWin32.c613
-rw-r--r--Source/kwsys/System.c585
-rw-r--r--Source/kwsys/System.h.in98
-rw-r--r--Source/kwsys/SystemInformation.cxx98
-rw-r--r--Source/kwsys/SystemInformation.hxx.in4
-rw-r--r--Source/kwsys/SystemTools.cxx75
-rw-r--r--Source/kwsys/SystemTools.hxx.in6
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx13
-rw-r--r--Source/kwsys/testProcess.c267
-rw-r--r--Source/kwsys/testSystemInformation.cxx1
-rw-r--r--Source/kwsys/testSystemTools.cxx22
281 files changed, 15557 insertions, 11504 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a7adb51..16b9ea1 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -88,7 +88,7 @@ option(CMAKE_REGENERATE_YACCLEX
"Regenerate YACC and LEXX files" OFF)
mark_as_advanced(CMAKE_REGENERATE_YACCLEX)
if(CMAKE_REGENERATE_YACCLEX)
- set(parsersLexers cmDependsFortran cmCommandArgument cmExpr)
+ set(parsersLexers cmFortran cmCommandArgument cmExpr)
find_program(YACC_EXECUTABLE
NAMES yacc bison
PATHS /usr/bin
@@ -165,6 +165,8 @@ set(SRCS
cmCommandArgumentLexer.cxx
cmCommandArgumentParser.cxx
cmCommandArgumentParserHelper.cxx
+ cmCommonTargetGenerator.cxx
+ cmCommonTargetGenerator.h
cmComputeComponentGraph.cxx
cmComputeComponentGraph.h
cmComputeLinkDepends.cxx
@@ -191,9 +193,6 @@ set(SRCS
cmDependsC.h
cmDependsFortran.cxx
cmDependsFortran.h
- cmDependsFortranLexer.cxx
- cmDependsFortranParser.cxx
- cmDependsFortranParser.h
cmDependsJava.cxx
cmDependsJava.h
cmDependsJavaLexer.cxx
@@ -241,6 +240,11 @@ set(SRCS
cmFileLockResult.h
cmFileTimeComparison.cxx
cmFileTimeComparison.h
+ cmFortranLexer.cxx
+ cmFortranLexer.h
+ cmFortranParser.cxx
+ cmFortranParser.h
+ cmFortranParserImpl.cxx
cmGeneratedFileStream.cxx
cmGeneratorExpressionContext.cxx
cmGeneratorExpressionContext.h
@@ -260,6 +264,8 @@ set(SRCS
cmGeneratorExpression.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
+ cmGlobalCommonGenerator.cxx
+ cmGlobalCommonGenerator.h
cmGlobalGenerator.cxx
cmGlobalGenerator.h
cmGlobalGeneratorFactory.h
@@ -281,9 +287,13 @@ set(SRCS
cmInstallTargetGenerator.cxx
cmInstallDirectoryGenerator.h
cmInstallDirectoryGenerator.cxx
+ cmLinkedTree.h
+ cmLinkItem.h
cmListFileCache.cxx
cmListFileCache.h
cmListFileLexer.c
+ cmLocalCommonGenerator.cxx
+ cmLocalCommonGenerator.h
cmLocalGenerator.cxx
cmLocalGenerator.h
cmLocalUnixMakefileGenerator3.cxx
@@ -299,6 +309,8 @@ set(SRCS
cmMakefileUtilityTargetGenerator.cxx
cmOSXBundleGenerator.cxx
cmOSXBundleGenerator.h
+ cmOutputConverter.cxx
+ cmOutputConverter.h
cmNewLineStyle.h
cmNewLineStyle.cxx
cmOrderDirectories.cxx
@@ -427,6 +439,7 @@ if (WIN32)
set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h
+ bindexplib.cxx
)
if(NOT UNIX)
@@ -543,9 +556,10 @@ if(APPLE)
target_link_libraries(CMakeLib "-framework CoreFoundation")
endif()
-if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW)
- # We need the rpcrt4 library for at least the VS7-VC10 generators.
- target_link_libraries(CMakeLib rpcrt4)
+if(WIN32 AND NOT UNIX)
+ # We need the rpcrt4 library on Windows.
+ # We need the crypt32 library on Windows for crypto/cert APIs.
+ target_link_libraries(CMakeLib rpcrt4 crypt32)
endif()
#
@@ -731,9 +745,17 @@ endif()
include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
-install(TARGETS cmake ctest cpack DESTINATION bin)
+# Install tools
+
+set(_tools cmake ctest cpack)
+
if(APPLE)
- install(TARGETS cmakexbuild DESTINATION bin)
+ list(APPEND _tools cmakexbuild)
endif()
+foreach(_tool ${_tools})
+ CMake_OPTIONAL_COMPONENT(${_tool})
+ install(TARGETS ${_tool} DESTINATION bin ${COMPONENT})
+endforeach()
+
install(FILES cmCPluginAPI.h DESTINATION ${CMAKE_DATA_DIR}/include)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index e1bffac..33ad704 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 3)
-set(CMake_VERSION_PATCH 1)
-#set(CMake_VERSION_RC 0)
+set(CMake_VERSION_PATCH 20150831)
+#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 09e123c..43d34ee 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -191,7 +191,7 @@ int cmCPackIFWGenerator::PackageFiles()
}
}
// TODO: set correct name for multipackages
- if (this->packageFileNames.size() > 0)
+ if (!this->packageFileNames.empty())
{
ifwCmd += " " + packageFileNames[0];
}
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 1d7afbd..c271517 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -11,17 +11,18 @@
============================================================================*/
#include <cmsys/SystemTools.hxx>
#include <cmsys/Process.h>
-#include <cmsys/ios/iostream>
#include <cmsys/FStream.hxx>
+#include <iostream>
+
#include <CoreFoundation/CoreFoundation.h>
// For the PATH_MAX constant
#include <sys/syslimits.h>
#define DebugError(x) \
- ofs << x << cmsys_ios::endl; \
- cmsys_ios::cout << x << cmsys_ios::endl
+ ofs << x << std::endl; \
+ std::cout << x << std::endl
int main(int argc, char* argv[])
{
@@ -77,7 +78,7 @@ int main(int argc, char* argv[])
std::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
fullScriptPath);
- ofs << fullScriptPath.c_str() << cmsys_ios::endl;
+ ofs << fullScriptPath.c_str() << std::endl;
std::vector<const char*> args;
args.push_back(fullScriptPath.c_str());
int cc;
@@ -109,7 +110,7 @@ int main(int argc, char* argv[])
data[i] = ' ';
}
}
- cmsys_ios::cout.write(data, length);
+ std::cout.write(data, length);
}
cmsysProcess_WaitForExit(cp, 0);
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index b3eb7b2..6f25e50 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -217,7 +217,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
{
std::string defaultRef = "WixUI_InstallDir";
- if(this->Components.size())
+ if(!this->Components.empty())
{
defaultRef = "WixUI_FeatureTree";
}
@@ -1005,7 +1005,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
shortcut.workingDirectoryId = directoryId;
shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
- if(desktopExecutables.size() &&
+ if(!desktopExecutables.empty() &&
std::find(desktopExecutables.begin(),
desktopExecutables.end(),
executableName)
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index aeec968..fc0d3d3 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -71,7 +71,7 @@ void cmWIXAccessControlList::CreatePermissionElement(
this->SourceWriter.BeginElement("Permission");
this->SourceWriter.AddAttribute("User", user);
- if(domain.size())
+ if(!domain.empty())
{
this->SourceWriter.AddAttribute("Domain", domain);
}
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index b5202e0..5a8dc63 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -79,7 +79,7 @@ bool cmWIXPatch::CheckForUnappliedFragments()
fragmentList += "'";
}
- if(fragmentList.size())
+ if(!fragmentList.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Some XML patch fragments did not have matching IDs: " <<
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 219fca8..8d38e9b 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -128,7 +128,7 @@ void cmWIXSourceWriter::AddAttribute(
void cmWIXSourceWriter::AddAttributeUnlessEmpty(
std::string const& key, std::string const& value)
{
- if(value.size())
+ if(!value.empty())
{
AddAttribute(key, value);
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index bf4df60..92a4b2b 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -716,8 +716,10 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cm.AddCMakePaths();
cm.SetProgressCallback(cmCPackGeneratorProgress, this);
cmGlobalGenerator gg(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(
+ new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(
+ gg.CreateLocalGenerator(mf.get()));
std::string realInstallDirectory = tempInstallDirectory;
if ( !installSubDirectory.empty() && installSubDirectory != "/" )
{
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2de2bc4..6cdda28 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -49,7 +49,7 @@ int cmCPackNSISGenerator::PackageFiles()
// TODO: Fix nsis to force out file name
std::string nsisInFileName = this->FindTemplate("NSIS.template.in");
- if ( nsisInFileName.size() == 0 )
+ if (nsisInFileName.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPack error: Could not find NSIS installer template file."
@@ -58,7 +58,7 @@ int cmCPackNSISGenerator::PackageFiles()
}
std::string nsisInInstallOptions
= this->FindTemplate("NSIS.InstallOptions.ini.in");
- if ( nsisInInstallOptions.size() == 0 )
+ if (nsisInInstallOptions.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPack error: Could not find NSIS installer options file."
@@ -536,7 +536,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if(cpackPackageDesktopLinksVector.size() &&
+ if(!cpackPackageDesktopLinksVector.empty() &&
std::find(cpackPackageDesktopLinksVector.begin(),
cpackPackageDesktopLinksVector.end(),
execName)
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index e5da5cf..109dcb7 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -19,7 +19,6 @@
#include "cmMakefile.h"
#include "cmCPackLog.h"
-#include <cmsys/ios/sstream>
#include <cmsys/FStream.hxx>
#include <sys/types.h>
#include <sys/stat.h>
@@ -85,7 +84,7 @@ int cmCPackSTGZGenerator::PackageFiles()
int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
{
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Writing header" << std::endl);
- cmsys_ios::ostringstream str;
+ std::ostringstream str;
int counter = 0;
std::string inLicFile = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index c2fe763..cb9cbc4 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -202,8 +202,10 @@ int main (int argc, char const* const* argv)
cminst.SetHomeOutputDirectory("");
cminst.GetState()->RemoveUnscriptableCommands();
cmGlobalGenerator cmgg(&cminst);
- cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.MakeLocalGenerator());
- cmMakefile* globalMF = cmlg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> globalMF(
+ new cmMakefile(&cmgg, cminst.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> cmlg(
+ cmgg.CreateLocalGenerator(globalMF.get()));
#if defined(__CYGWIN__)
globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
#endif
@@ -357,8 +359,8 @@ int main (int argc, char const* const* argv)
++it )
{
const char* gen = it->c_str();
- cmMakefile::ScopePushPop raii(globalMF);
- cmMakefile* mf = globalMF;
+ cmMakefile::ScopePushPop raii(globalMF.get());
+ cmMakefile* mf = globalMF.get();
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Specified generator: " << gen << std::endl);
if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 3014a93..587b583 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -14,7 +14,6 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
-#include "cmXMLSafe.h"
#include <cmsys/RegularExpression.hxx>
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index e141b60..6dbb245 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -920,7 +920,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
char* data;
int length;
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
" Each symbol represents " << tick_len << " bytes of output."
<< std::endl
<< (this->UseCTestLaunch? "" :
@@ -968,7 +968,7 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command,
this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingQueue);
this->ProcessBuffer(0, 0, tick, tick_len, ofs,
&this->BuildProcessingErrorQueue);
- cmCTestOptionalLog(this->CTest, OUTPUT, " Size of output: "
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size of output: "
<< ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl,
this->Quiet);
@@ -1175,12 +1175,12 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
while ( this->BuildOutputLogSize > (tick * tick_len) )
{
tick ++;
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar,
- this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT,
+ this->LastTickChar, this->Quiet);
tickDisplayed = true;
if ( tick % tick_line_len == 0 && tick > 0 )
{
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Size: "
+ cmCTestOptionalLog(this->CTest, HANDLER_PROGRESS_OUTPUT, " Size: "
<< ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl
<< " ", this->Quiet);
}
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f92f19a..20807c8 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -27,8 +27,6 @@
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Glob.hxx>
-#include <cmsys/stl/iterator>
-#include <cmsys/stl/algorithm>
#include <cmsys/FStream.hxx>
#include <stdlib.h>
@@ -446,7 +444,7 @@ int cmCTestCoverageHandler::ProcessHandler()
}
std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
- if ( file_count == 0 )
+ if (file_count == 0 && this->ExtraCoverageGlobs.empty())
{
cmCTestOptionalLog(this->CTest, WARNING,
" Cannot find any coverage files. Ignoring Coverage request."
@@ -1474,7 +1472,12 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
<< std::endl, this->Quiet);
std::vector<std::string> files;
- this->FindLCovFiles(files);
+ if (!this->FindLCovFiles(files))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while finding LCov files.\n");
+ return 0;
+ }
std::vector<std::string>::iterator it;
if (files.empty())
@@ -1745,18 +1748,28 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
}
//----------------------------------------------------------------------------
-void cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
+bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
{
cmsys::Glob gl;
gl.RecurseOff(); // No need of recurse if -prof_dir${BUILD_DIR} flag is
// used while compiling.
gl.RecurseThroughSymlinksOff();
std::string prevBinaryDir;
- cmSystemTools::ChangeDirectory(
- this->CTest->GetCTestConfiguration("BuildDirectory"));
+ std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
+ if (cmSystemTools::ChangeDirectory(buildDir))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error changing directory to " << buildDir << std::endl);
+ return false;
+ }
// Run profmerge to merge all *.dyn files into dpi files
- cmSystemTools::RunSingleCommand("profmerge");
+ if (!cmSystemTools::RunSingleCommand("profmerge"))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while running profmerge.\n");
+ return false;
+ }
prevBinaryDir = cmSystemTools::GetCurrentWorkingDirectory().c_str();
@@ -1766,10 +1779,16 @@ void cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
daGlob += "/*.dpi";
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
" looking for dpi files in: " << daGlob << std::endl, this->Quiet);
- gl.FindFiles(daGlob);
+ if (!gl.FindFiles(daGlob))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error while finding files matching " << daGlob << std::endl);
+ return false;
+ }
files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Now searching in: " << daGlob << std::endl, this->Quiet);
+ return true;
}
//----------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 2ca123a..7102d1e 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -75,7 +75,7 @@ private:
//! Handle coverage using Intel's LCov
int HandleLCovCoverage(cmCTestCoverageHandlerContainer* cont);
- void FindLCovFiles(std::vector<std::string>& files);
+ bool FindLCovFiles(std::vector<std::string>& files);
//! Handle coverage using xdebug php coverage
int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 6b84bab..bbb3b9d 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -14,10 +14,8 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmAlgorithms.h"
-#include "cmXMLSafe.h"
#include <cmsys/RegularExpression.hxx>
-#include <cmsys/ios/sstream>
#include <cmsys/Process.h>
#include <cmsys/FStream.hxx>
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index 81eb0a8..ad79ba2 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -23,6 +23,7 @@ cmCTestGenericHandler::cmCTestGenericHandler()
this->SubmitIndex = 0;
this->AppendXML = false;
this->Quiet = false;
+ this->TestLoad = 0;
}
//----------------------------------------------------------------------
@@ -70,6 +71,7 @@ void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
void cmCTestGenericHandler::Initialize()
{
this->AppendXML = false;
+ this->TestLoad = 0;
this->Options.clear();
t_StringToString::iterator it;
for ( it = this->PersistentOptions.begin();
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
index 8567dd7..4b7ae79 100644
--- a/Source/CTest/cmCTestGenericHandler.h
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -89,6 +89,8 @@ public:
void SetAppendXML(bool b) { this->AppendXML = b; }
void SetQuiet(bool b) { this->Quiet = b; }
bool GetQuiet() { return this->Quiet; }
+ void SetTestLoad(unsigned long load) { this->TestLoad = load; }
+ unsigned long GetTestLoad() const { return this->TestLoad; }
protected:
bool StartResultingXML(cmCTest::Part part,
@@ -97,6 +99,7 @@ protected:
bool AppendXML;
bool Quiet;
+ unsigned long TestLoad;
cmSystemTools::OutputOption HandlerVerbose;
cmCTest *CTest;
t_StringToString Options;
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 3003e8a..3579aee 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -109,6 +109,12 @@ bool cmCTestHandlerCommand
this->Quiet);
}
+ if(const char* changeId =
+ this->Makefile->GetDefinition("CTEST_CHANGE_ID"))
+ {
+ this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
+ }
+
cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
cmCTestGenericHandler* handler = this->InitializeHandler();
if ( !handler )
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 0f588c5..fb0cce6 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -738,8 +738,9 @@ void cmCTestLaunch::LoadConfig()
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmGlobalGenerator gg(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(
+ gg.CreateLocalGenerator(mf.get()));
std::string fname = this->LogDir;
fname += "CTestLaunchConfig.cmake";
if(cmSystemTools::FileExists(fname.c_str()) &&
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 8f26716..acf527a 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -80,8 +80,8 @@ public:
int i = 0;
for(; atts[i] != 0; i+=2)
{
- ostr << " " << cmXMLSafe(atts[i])
- << " - " << cmXMLSafe(atts[i+1]) << "\n";
+ ostr << " " << atts[i]
+ << " - " << atts[i+1] << "\n";
}
ostr << "\n";
this->Log += ostr.str();
@@ -856,7 +856,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
defects++;
ostr << "<b>" << this->ResultStrings[idx] << "</b> ";
}
- ostr << cmXMLSafe(*i) << std::endl;
+ ostr << *i << std::endl;
}
log = ostr.str();
if(defects)
@@ -908,7 +908,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
results[failure] ++;
defects ++;
}
- ostr << cmXMLSafe(*i) << std::endl;
+ ostr << *i << std::endl;
}
log = ostr.str();
@@ -1056,7 +1056,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
defects ++;
}
totalOutputSize += lines[cc].size();
- ostr << cmXMLSafe(lines[cc]) << std::endl;
+ ostr << lines[cc] << std::endl;
}
else
{
@@ -1070,11 +1070,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
{
totalOutputSize += lines[*i].size();
- cmCTestOptionalLog(this->CTest, DEBUG, "before xml safe "
- << lines[*i] << std::endl, this->Quiet);
- cmCTestOptionalLog(this->CTest, DEBUG, "after xml safe "
- << cmXMLSafe(lines[*i]) << std::endl, this->Quiet);
- ostr << cmXMLSafe(lines[*i]) << std::endl;
+ ostr << lines[*i] << std::endl;
if(!unlimitedOutput && totalOutputSize >
static_cast<size_t>(this->CustomMaximumFailedTestOutputSize))
{
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index bd090db..4832186 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -13,12 +13,15 @@
#include "cmProcess.h"
#include "cmStandardIncludes.h"
#include "cmCTest.h"
+#include "cmCTestScriptHandler.h"
#include "cmSystemTools.h"
#include <stdlib.h>
#include <stack>
#include <list>
#include <float.h>
+#include <math.h>
#include <cmsys/FStream.hxx>
+#include <cmsys/SystemInformation.hxx>
class TestComparator
{
@@ -40,10 +43,12 @@ private:
cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
{
this->ParallelLevel = 1;
+ this->TestLoad = 0;
this->Completed = 0;
this->RunningCount = 0;
this->StopTimePassed = false;
this->HasCycles = false;
+ this->SerialTestRunning = false;
}
cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler()
@@ -83,6 +88,11 @@ void cmCTestMultiProcessHandler::SetParallelLevel(size_t level)
this->ParallelLevel = level < 1 ? 1 : level;
}
+void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load)
+{
+ this->TestLoad = load;
+}
+
//---------------------------------------------------------
void cmCTestMultiProcessHandler::RunTests()
{
@@ -172,6 +182,11 @@ void cmCTestMultiProcessHandler::LockResources(int index)
this->LockedResources.insert(
this->Properties[index]->LockedResources.begin(),
this->Properties[index]->LockedResources.end());
+
+ if (this->Properties[index]->RunSerial)
+ {
+ this->SerialTestRunning = true;
+ }
}
//---------------------------------------------------------
@@ -198,17 +213,20 @@ inline size_t cmCTestMultiProcessHandler::GetProcessorsUsed(int test)
{
size_t processors =
static_cast<int>(this->Properties[test]->Processors);
- //If this is set to run serially, it must run alone.
- //Also, if processors setting is set higher than the -j
+ //If processors setting is set higher than the -j
//setting, we default to using all of the process slots.
- if(this->Properties[test]->RunSerial
- || processors > this->ParallelLevel)
+ if (processors > this->ParallelLevel)
{
processors = this->ParallelLevel;
}
return processors;
}
+std::string cmCTestMultiProcessHandler::GetName(int test)
+{
+ return this->Properties[test]->Name;
+}
+
//---------------------------------------------------------
bool cmCTestMultiProcessHandler::StartTest(int test)
{
@@ -248,22 +266,136 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ // Don't start any new tests if one with the RUN_SERIAL property
+ // is already running.
+ if (this->SerialTestRunning)
+ {
+ return;
+ }
+
+ bool allTestsFailedTestLoadCheck = false;
+ bool usedFakeLoadForTesting = false;
+ size_t minProcessorsRequired = this->ParallelLevel;
+ std::string testWithMinProcessors = "";
+
+ cmsys::SystemInformation info;
+
+ unsigned long systemLoad = 0;
+ size_t spareLoad = 0;
+ if (this->TestLoad > 0)
+ {
+ // Activate possible wait.
+ allTestsFailedTestLoadCheck = true;
+
+ // Check for a fake load average value used in testing.
+ if (const char* fake_load_value =
+ cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING"))
+ {
+ usedFakeLoadForTesting = true;
+ if (!cmSystemTools::StringToULong(fake_load_value, &systemLoad))
+ {
+ cmSystemTools::Error("Failed to parse fake load value: ",
+ fake_load_value);
+ }
+ }
+ // If it's not set, look up the true load average.
+ else
+ {
+ systemLoad = static_cast<unsigned long>(ceil(info.GetLoadAverage()));
+ }
+ spareLoad = (this->TestLoad > systemLoad ?
+ this->TestLoad - systemLoad : 0);
+
+ // Don't start more tests than the spare load can support.
+ if (numToStart > spareLoad)
+ {
+ numToStart = spareLoad;
+ }
+ }
+
TestList copy = this->SortedTests;
for(TestList::iterator test = copy.begin(); test != copy.end(); ++test)
{
+ // Take a nap if we're currently performing a RUN_SERIAL test.
+ if (this->SerialTestRunning)
+ {
+ break;
+ }
+ // We can only start a RUN_SERIAL test if no other tests are also running.
+ if (this->Properties[*test]->RunSerial && this->RunningCount > 0)
+ {
+ continue;
+ }
+
size_t processors = GetProcessorsUsed(*test);
+ bool testLoadOk = true;
+ if (this->TestLoad > 0)
+ {
+ if (processors <= spareLoad)
+ {
+ cmCTestLog(this->CTest, DEBUG,
+ "OK to run " << GetName(*test) <<
+ ", it requires " << processors <<
+ " procs & system load is: " <<
+ systemLoad << std::endl);
+ allTestsFailedTestLoadCheck = false;
+ }
+ else
+ {
+ testLoadOk = false;
+ }
+ }
- if(processors <= numToStart && this->StartTest(*test))
+ if (processors <= minProcessorsRequired)
{
- if(this->StopTimePassed)
- {
- return;
- }
- numToStart -= processors;
+ minProcessorsRequired = processors;
+ testWithMinProcessors = GetName(*test);
+ }
+
+ if(testLoadOk && processors <= numToStart && this->StartTest(*test))
+ {
+ if(this->StopTimePassed)
+ {
+ return;
+ }
+
+ numToStart -= processors;
}
else if(numToStart == 0)
{
- return;
+ break;
+ }
+ }
+
+ if (allTestsFailedTestLoadCheck)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***** WAITING, ");
+ if (this->SerialTestRunning)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ "Waiting for RUN_SERIAL test to finish.");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ "System Load: " << systemLoad << ", "
+ "Max Allowed Load: " << this->TestLoad << ", "
+ "Smallest test " << testWithMinProcessors <<
+ " requires " << minProcessorsRequired);
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "*****" << std::endl);
+
+ if (usedFakeLoadForTesting)
+ {
+ // Break out of the infinite loop of waiting for our fake load
+ // to come down.
+ this->StopTimePassed = true;
+ }
+ else
+ {
+ // Wait between 1 and 5 seconds before trying again.
+ cmCTestScriptHandler::SleepInSeconds(
+ cmSystemTools::RandomSeed() % 5 + 1);
}
}
}
@@ -319,6 +451,11 @@ bool cmCTestMultiProcessHandler::CheckOutput()
this->WriteCheckpoint(test);
this->UnlockResources(test);
this->RunningCount -= GetProcessorsUsed(test);
+ if (this->Properties[test]->RunSerial)
+ {
+ this->SerialTestRunning = false;
+ }
+
delete p;
}
return true;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 6440fbc..ed3e155 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -37,6 +37,7 @@ public:
void SetTests(TestMap& tests, PropertiesMap& properties);
// Set the max number of tests that can be run at the same time.
void SetParallelLevel(size_t);
+ void SetTestLoad(unsigned long load);
virtual void RunTests();
void PrintTestList();
void PrintLabels();
@@ -93,6 +94,7 @@ protected:
bool CheckCycles();
int FindMaxIndex();
inline size_t GetProcessorsUsed(int index);
+ std::string GetName(int index);
void LockResources(int index);
void UnlockResources(int index);
@@ -116,11 +118,13 @@ protected:
std::set<std::string> LockedResources;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
+ unsigned long TestLoad;
std::set<cmCTestRunTest*> RunningTests; // current running tests
cmCTestTestHandler * TestHandler;
cmCTest* CTest;
bool HasCycles;
bool Quiet;
+ bool SerialTestRunning;
};
#endif
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 31002a6..5e0c54a 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -13,10 +13,8 @@
#include "cmCTest.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
#include <cmsys/RegularExpression.hxx>
-#include <cmsys/ios/sstream>
#include <cmsys/Process.h>
#include <sys/types.h>
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index d9e4bd4..d108592 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -57,8 +57,7 @@ bool cmCTestRunTest::CheckOutput()
// Process has terminated and all output read.
return false;
}
- else if(p == cmsysProcess_Pipe_STDOUT ||
- p == cmsysProcess_Pipe_STDERR)
+ else if(p == cmsysProcess_Pipe_STDOUT)
{
// Store this line of output.
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 047bd98..c1ba279 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -125,42 +125,25 @@ void cmCTestScriptHandler::Initialize()
// what time in seconds did this script start running
this->ScriptStartTime = 0;
+ delete this->Makefile;
this->Makefile = 0;
- if (this->LocalGenerator)
- {
- delete this->LocalGenerator;
- }
+
+ delete this->LocalGenerator;
this->LocalGenerator = 0;
- if (this->GlobalGenerator)
- {
- delete this->GlobalGenerator;
- }
+
+ delete this->GlobalGenerator;
this->GlobalGenerator = 0;
- if (this->CMake)
- {
- delete this->CMake;
- }
+
+ delete this->CMake;
}
//----------------------------------------------------------------------
cmCTestScriptHandler::~cmCTestScriptHandler()
{
- // local generator owns the makefile
- this->Makefile = 0;
- if (this->LocalGenerator)
- {
- delete this->LocalGenerator;
- }
- this->LocalGenerator = 0;
- if (this->GlobalGenerator)
- {
- delete this->GlobalGenerator;
- }
- this->GlobalGenerator = 0;
- if (this->CMake)
- {
- delete this->CMake;
- }
+ delete this->Makefile;
+ delete this->LocalGenerator;
+ delete this->GlobalGenerator;
+ delete this->CMake;
}
@@ -334,6 +317,7 @@ void cmCTestScriptHandler::CreateCMake()
delete this->CMake;
delete this->GlobalGenerator;
delete this->LocalGenerator;
+ delete this->Makefile;
}
this->CMake = new cmake;
this->CMake->SetHomeDirectory("");
@@ -341,8 +325,10 @@ void cmCTestScriptHandler::CreateCMake()
this->CMake->AddCMakePaths();
this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
- this->LocalGenerator = this->GlobalGenerator->MakeLocalGenerator();
- this->Makefile = this->LocalGenerator->GetMakefile();
+ cmState::Snapshot snapshot = this->CMake->GetCurrentSnapshot();
+ this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+ this->LocalGenerator =
+ this->GlobalGenerator->CreateLocalGenerator(this->Makefile);
this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest);
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 8b357ac..b7d8318 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -26,6 +26,7 @@ cmCTestTestCommand::cmCTestTestCommand()
this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
+ this->Arguments[ctt_TEST_LOAD] = "TEST_LOAD";
this->Arguments[ctt_LAST] = 0;
this->Last = ctt_LAST;
}
@@ -103,6 +104,38 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
{
this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
}
+
+ // Test load is determined by: TEST_LOAD argument,
+ // or CTEST_TEST_LOAD script variable, or ctest --test-load
+ // command line argument... in that order.
+ unsigned long testLoad;
+ const char* ctestTestLoad
+ = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
+ if(this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD])
+ {
+ if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], &testLoad))
+ {
+ testLoad = 0;
+ cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : "
+ << this->Values[ctt_TEST_LOAD] << std::endl);
+ }
+ }
+ else if(ctestTestLoad && *ctestTestLoad)
+ {
+ if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad))
+ {
+ testLoad = 0;
+ cmCTestLog(this->CTest, WARNING,
+ "Invalid value for 'CTEST_TEST_LOAD' : " <<
+ ctestTestLoad << std::endl);
+ }
+ }
+ else
+ {
+ testLoad = this->CTest->GetTestLoad();
+ }
+ handler->SetTestLoad(testLoad);
+
handler->SetQuiet(this->Quiet);
return handler;
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index a1e5f36..0dfca97 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -60,6 +60,7 @@ protected:
ctt_PARALLEL_LEVEL,
ctt_SCHEDULE_RANDOM,
ctt_STOP_TIME,
+ ctt_TEST_LOAD,
ctt_LAST
};
};
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 2af09cb..f9678e7 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -656,9 +656,8 @@ int cmCTestTestHandler::ProcessHandler()
void cmCTestTestHandler::PrintLabelSummary()
{
cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
- cmCTestTestHandler::TestResultsVector::iterator ri =
- this->TestResults.begin();
std::map<std::string, double> labelTimes;
+ std::map<std::string, int> labelCounts;
std::set<std::string> labels;
// initialize maps
std::string::size_type maxlen = 0;
@@ -676,10 +675,12 @@ void cmCTestTestHandler::PrintLabelSummary()
}
labels.insert(*l);
labelTimes[*l] = 0;
+ labelCounts[*l] = 0;
}
}
}
- ri = this->TestResults.begin();
+ cmCTestTestHandler::TestResultsVector::iterator ri =
+ this->TestResults.begin();
// fill maps
for(; ri != this->TestResults.end(); ++ri)
{
@@ -691,6 +692,7 @@ void cmCTestTestHandler::PrintLabelSummary()
l != p.Labels.end(); ++l)
{
labelTimes[*l] += result.ExecutionTime;
+ ++labelCounts[*l];
}
}
}
@@ -705,10 +707,21 @@ void cmCTestTestHandler::PrintLabelSummary()
{
std::string label = *i;
label.resize(maxlen +3, ' ');
+
char buf[1024];
sprintf(buf, "%6.2f sec", labelTimes[*i]);
+
+ std::ostringstream labelCountStr;
+ labelCountStr << "(" << labelCounts[*i] << " test";
+ if (labelCounts[*i] > 1)
+ {
+ labelCountStr << "s";
+ }
+ labelCountStr << ")";
+
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n"
- << label << " = " << buf, this->Quiet );
+ << label << " = " << buf << " " << labelCountStr.str(),
+ this->Quiet );
if ( this->LogFile )
{
*this->LogFile << "\n" << *i << " = "
@@ -1062,6 +1075,14 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed,
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
parallel->SetQuiet(this->Quiet);
+ if(this->TestLoad > 0)
+ {
+ parallel->SetTestLoad(this->TestLoad);
+ }
+ else
+ {
+ parallel->SetTestLoad(this->CTest->GetTestLoad());
+ }
*this->LogFile << "Start testing: "
<< this->CTest->CurrentTime() << std::endl
@@ -1571,8 +1592,9 @@ void cmCTestTestHandler::GetListOfTests()
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmGlobalGenerator gg(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(
+ gg.CreateLocalGenerator(mf.get()));
mf->AddDefinition("CTEST_CONFIGURATION_TYPE",
this->CTest->GetConfigType().c_str());
@@ -2070,7 +2092,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
}
current = next;
}
- else // Bad byte will be handled by cmXMLSafe.
+ else // Bad byte will be handled by cmXMLWriter.
{
++current;
}
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index 8494d28..963e501 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -283,13 +283,13 @@ int cmCTestUpdateHandler::ProcessHandler()
{
xml.Content("Update command failed:\n");
xml.Content(vc->GetUpdateCommandLine());
- cmCTestLog(this->CTest, ERROR_MESSAGE, " Update command failed: "
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Update command failed: "
<< vc->GetUpdateCommandLine() << "\n");
}
xml.EndElement(); // UpdateReturnStatus
xml.EndElement(); // Update
xml.EndDocument();
- return numUpdated;
+ return updated? numUpdated : -1;
}
//----------------------------------------------------------------------
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index e1bd02b..0c25f40 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -62,6 +62,7 @@ bool cmProcess::StartProcess()
this->WorkingDirectory.c_str());
}
cmsysProcess_SetTimeout(this->Process, this->Timeout);
+ cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1);
cmsysProcess_Execute(this->Process);
return (cmsysProcess_GetState(this->Process)
== cmsysProcess_State_Executing);
@@ -124,14 +125,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
for(;;)
{
// Look for lines already buffered.
- if(this->StdOut.GetLine(line))
+ if(this->Output.GetLine(line))
{
return cmsysProcess_Pipe_STDOUT;
}
- else if(this->StdErr.GetLine(line))
- {
- return cmsysProcess_Pipe_STDERR;
- }
// Check for more data from the process.
char* data;
@@ -143,11 +140,7 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
}
else if(p == cmsysProcess_Pipe_STDOUT)
{
- this->StdOut.insert(this->StdOut.end(), data, data+length);
- }
- else if(p == cmsysProcess_Pipe_STDERR)
- {
- this->StdErr.insert(this->StdErr.end(), data, data+length);
+ this->Output.insert(this->Output.end(), data, data+length);
}
else // p == cmsysProcess_Pipe_None
{
@@ -157,14 +150,10 @@ int cmProcess::GetNextOutputLine(std::string& line, double timeout)
}
// Look for partial last lines.
- if(this->StdOut.GetLast(line))
+ if(this->Output.GetLast(line))
{
return cmsysProcess_Pipe_STDOUT;
}
- else if(this->StdErr.GetLast(line))
- {
- return cmsysProcess_Pipe_STDERR;
- }
// No more data. Wait for process exit.
if(!cmsysProcess_WaitForExit(this->Process, &timeout))
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 1479df0..eddeeab 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -48,8 +48,7 @@ public:
* Read one line of output but block for no more than timeout.
* Returns:
* cmsysProcess_Pipe_None = Process terminated and all output read
- * cmsysProcess_Pipe_STDOUT = Line came from stdout
- * cmsysProcess_Pipe_STDOUT = Line came from stderr
+ * cmsysProcess_Pipe_STDOUT = Line came from stdout or stderr
* cmsysProcess_Pipe_Timeout = Timeout expired while waiting
*/
int GetNextOutputLine(std::string& line, double timeout);
@@ -68,13 +67,11 @@ private:
bool GetLine(std::string& line);
bool GetLast(std::string& line);
};
- Buffer StdErr;
- Buffer StdOut;
+ Buffer Output;
std::string Command;
std::string WorkingDirectory;
std::vector<std::string> Arguments;
std::vector<const char*> ProcessArgs;
- std::string Output;
int Id;
int ExitValue;
};
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 7d4e88c..93ff425 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -47,4 +47,5 @@ else()
target_link_libraries(ccmake cmForm)
endif()
-install(TARGETS ccmake DESTINATION bin)
+CMake_OPTIONAL_COMPONENT(ccmake)
+install(TARGETS ccmake DESTINATION bin ${COMPONENT})
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 168f57d..ad6a7fb 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -14,6 +14,7 @@ project(QtDialog)
if(POLICY CMP0020)
cmake_policy(SET CMP0020 NEW) # Drop when CMake >= 2.8.11 required
endif()
+CMake_OPTIONAL_COMPONENT(cmake-gui)
find_package(Qt5Widgets QUIET)
if (Qt5Widgets_FOUND)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
@@ -35,30 +36,46 @@ if (Qt5Widgets_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
- # We need to install Cocoa platform plugin and add qt.conf for Qt5 on Mac.
+ # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
# FIXME: This should be part of Qt5 CMake scripts, but unfortunatelly
- # Qt5 Mac support is missing there.
- if(APPLE)
+ # Qt5 support is missing there.
+ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
if(EXISTS "${_qt_plugin_path}")
get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
- set(_qt_plugin_dest "PlugIns/${_qt_plugin_type}")
+ if(APPLE)
+ set(_qt_plugin_dir "PlugIns")
+ elseif(WIN32)
+ set(_qt_plugin_dir "plugins")
+ endif()
+ set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
install(FILES "${_qt_plugin_path}"
- DESTINATION "${_qt_plugin_dest}")
+ DESTINATION "${_qt_plugin_dest}"
+ ${COMPONENT})
set(${_qt_plugins_var}
"${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
else()
message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif()
endmacro()
- install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- "[Paths]\nPlugins = PlugIns\n")
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
- DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources")
+ if(APPLE)
+ install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+ ${COMPONENT})
+ elseif(WIN32)
+ install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+ DESTINATION bin
+ ${COMPONENT})
+ endif()
endif()
if(WIN32 AND TARGET Qt5::Core)
@@ -130,7 +147,8 @@ endif()
if(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
install(FILES ${CMake_SOURCE_DIR}/Licenses/LGPLv2.1.txt
- DESTINATION ${CMAKE_DATA_DIR}/Licenses)
+ DESTINATION ${CMAKE_DATA_DIR}/Licenses
+ ${COMPONENT})
set_property(SOURCE CMakeSetupDialog.cxx
PROPERTY COMPILE_DEFINITIONS CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL)
endif()
@@ -163,30 +181,39 @@ if(APPLE)
)
endif()
set(CMAKE_INSTALL_DESTINATION_ARGS
- BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
+ BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" ${COMPONENT})
-install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS})
+install(TARGETS cmake-gui
+ RUNTIME DESTINATION bin ${COMPONENT}
+ ${CMAKE_INSTALL_DESTINATION_ARGS})
if(UNIX AND NOT APPLE)
foreach (size IN ITEMS 32 128)
install(
FILES "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png"
DESTINATION "share/icons/hicolor/${size}x${size}/apps"
+ ${COMPONENT}
RENAME "CMakeSetup.png")
endforeach ()
# install a desktop file so CMake appears in the application start menu
# with an icon
- install(FILES CMake.desktop DESTINATION share/applications )
- install(FILES cmakecache.xml DESTINATION share/mime/packages )
+ install(FILES CMake.desktop
+ DESTINATION share/applications
+ ${COMPONENT})
+ install(FILES cmakecache.xml
+ DESTINATION share/mime/packages
+ ${COMPONENT})
endif()
if(APPLE)
- install(CODE "execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)")
+ install(CODE "
+ execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)
+ " ${COMPONENT})
endif()
-if(APPLE OR WIN32)
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
# install rules for including 3rd party libs such as Qt
# if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
@@ -197,7 +224,7 @@ if(APPLE OR WIN32)
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
- ")
+ " ${COMPONENT})
endif()
set(CMAKE_PACKAGE_QTGUI TRUE)
diff --git a/Source/QtDialog/Info.plist.in b/Source/QtDialog/Info.plist.in
index b9c4af5..00a27c3 100644
--- a/Source/QtDialog/Info.plist.in
+++ b/Source/QtDialog/Info.plist.in
@@ -28,5 +28,7 @@
<string>public.app-category.developer-tools</string>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>NSHighResolutionCapable</key>
+ <true/>
</dict>
</plist>
diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
new file mode 100644
index 0000000..219a0a9
--- /dev/null
+++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs
@@ -0,0 +1,21 @@
+// Component: CMake.Dialogs.QtGUI
+
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/bin/cmake-gui.exe",
+ installer.value("StartMenuDir") + "/CMake (cmake-gui).lnk");
+
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
new file mode 100644
index 0000000..5c929e8
--- /dev/null
+++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
@@ -0,0 +1,21 @@
+// Component: CMake.Documentation.SphinxHTML
+
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/html/index.html",
+ installer.value("StartMenuDir") + "/CMake Documentation.lnk");
+
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in
new file mode 100644
index 0000000..828cc7c
--- /dev/null
+++ b/Source/QtIFW/CMake.qs.in
@@ -0,0 +1,22 @@
+function Component()
+{
+ // Default constructor
+}
+
+Component.prototype.createOperations = function()
+{
+ // Create shortcut
+ if (installer.value("os") === "win") {
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
+ installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+
+ component.addOperation("CreateShortcut",
+ installer.value("TargetDir") + "/cmake-maintenance.exe",
+ installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+ }
+
+ // Call default implementation
+ component.createOperations();
+}
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
index 570dba1..3411e34 100644
--- a/Source/QtIFW/installscript.qs.in
+++ b/Source/QtIFW/installscript.qs.in
@@ -5,20 +5,20 @@ function Component()
Component.prototype.createOperations = function()
{
- // call default implementation to actually install applications!
- component.createOperations();
-
// Create shortcut
if (installer.value("os") === "win") {
@_CPACK_IFW_SHORTCUT_OPTIONAL@
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/cmake.org.html",
+ installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
installer.value("StartMenuDir") + "/CMake Web Site.lnk");
component.addOperation("CreateShortcut",
installer.value("TargetDir") + "/cmake-maintenance.exe",
installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
}
+
+ // Call default implementation
+ component.createOperations();
}
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 0000000..11e3f34
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,428 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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.
+============================================================================*/
+/*-------------------------------------------------------------------------
+ Portions of this source have been derived from the 'bindexplib' tool
+ provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
+ Permission has been granted by Pere Mato <pere.mato@cern.ch> to distribute
+ this derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
+/*
+*----------------------------------------------------------------------
+* Program: dumpexts.exe
+* Author: Gordon Chaffee
+*
+* History: The real functionality of this file was written by
+* Matt Pietrek in 1993 in his pedump utility. I've
+* modified it to dump the externals in a bunch of object
+* files to create a .def file.
+*
+* Notes: Visual C++ puts an underscore before each exported symbol.
+* This file removes them. I don't know if this is a problem
+* this other compilers. If _MSC_VER is defined,
+* the underscore is removed. If not, it isn't. To get a
+* full dump of an object file, use the -f option. This can
+* help determine the something that may be different with a
+* compiler other than Visual C++.
+* ======================================
+* Corrections (Axel 2006-04-04):
+* Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ * As soon as an object file contains an /EXPORT directive (which
+ * is generated by the compiler when a symbol is declared as
+ * declspec(dllexport)) no to-be-exported symbols are printed,
+ * as the linker will see these directives, and if those directives
+ * are present we only export selectively (i.e. we trust the
+ * programmer).
+ *
+ * ======================================
+* ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+* The "(vector) deleting destructor" MUST not be exported
+* To recognize it the following test are introduced:
+* "@@UAEPAXI@Z" scalar deleting dtor
+* "@@QAEPAXI@Z" vector deleting dtor
+* "AEPAXI@Z" vector deleting dtor with thunk adjustor
+* ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+* It created a wrong EXPORTS for the global pointers and constants.
+* The Section Header has been involved to discover the missing information
+* Now the pointers are correctly supplied supplied with "DATA" descriptor
+* the constants with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+* It didn't work for C++ code with global variables and class definitons
+* The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+
+#include <cmsys/Encoding.hxx>
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+typedef struct cmANON_OBJECT_HEADER_BIGOBJ {
+ /* same as ANON_OBJECT_HEADER_V2 */
+ WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN
+ WORD Sig2; // Must be 0xffff
+ WORD Version; // >= 2 (implies the Flags field is present)
+ WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx
+ DWORD TimeDateStamp;
+ CLSID ClassID; // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
+ DWORD SizeOfData; // Size of data that follows the header
+ DWORD Flags; // 0x1 -> contains metadata
+ DWORD MetaDataSize; // Size of CLR metadata
+ DWORD MetaDataOffset; // Offset of CLR metadata
+
+ /* bigobj specifics */
+ DWORD NumberOfSections; // extended from WORD
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+} cmANON_OBJECT_HEADER_BIGOBJ;
+
+typedef struct _cmIMAGE_SYMBOL_EX {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short; // if 0, use LongName
+ DWORD Long; // offset into string table
+ } Name;
+ DWORD LongName[2]; // PBYTE [2]
+ } N;
+ DWORD Value;
+ LONG SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} cmIMAGE_SYMBOL_EX;
+typedef cmIMAGE_SYMBOL_EX UNALIGNED *cmPIMAGE_SYMBOL_EX;
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER
+ pImageFileHeader)
+{
+ return (PIMAGE_SECTION_HEADER)
+ ((DWORD_PTR)pImageFileHeader +
+ IMAGE_SIZEOF_FILE_HEADER +
+ pImageFileHeader->SizeOfOptionalHeader);
+}
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(cmANON_OBJECT_HEADER_BIGOBJ*
+ pImageFileHeader)
+{
+ return (PIMAGE_SECTION_HEADER)
+ ((DWORD_PTR)pImageFileHeader +
+ sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+ size_t len;
+ const char* hint;
+
+ if (!start || !find || !size) {
+ size = 0;
+ return 0;
+ }
+ len = strlen(find);
+
+ while ((hint = (const char*) memchr(start, find[0], size-len+1))) {
+ size -= (hint - start);
+ if (!strncmp(hint, find, len))
+ return hint;
+ start = hint + 1;
+ }
+
+ size = 0;
+ return 0;
+}
+
+template <
+ // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
+ class ObjectHeaderType,
+ // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
+ class SymbolTableType>
+class DumpSymbols
+{
+public:
+ /*
+ *----------------------------------------------------------------------
+ * Constructor --
+ *
+ * Initialize variables from pointer to object header.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ DumpSymbols(ObjectHeaderType* ih,
+ FILE* fout) {
+ this->ObjectImageHeader = ih;
+ this->SymbolTable = (SymbolTableType*)
+ ((DWORD_PTR)this->ObjectImageHeader
+ + this->ObjectImageHeader->PointerToSymbolTable);
+ this->FileOut = fout;
+ this->SectionHeaders =
+ GetSectionHeaderOffset(this->ObjectImageHeader);
+ this->ImportFlag = true;
+ this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * HaveExportedObjects --
+ *
+ * Returns true if export directives (declspec(dllexport)) exist.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ bool HaveExportedObjects() {
+ WORD i = 0;
+ size_t size = 0;
+ const char * rawdata = 0;
+ PIMAGE_SECTION_HEADER pDirectivesSectionHeader = 0;
+ PIMAGE_SECTION_HEADER pSectionHeaders = this->SectionHeaders;
+ for(i = 0; (i < this->ObjectImageHeader->NumberOfSections &&
+ !pDirectivesSectionHeader); i++)
+ if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+ pDirectivesSectionHeader = &pSectionHeaders[i];
+ if (!pDirectivesSectionHeader) return 0;
+
+ rawdata=(const char*)
+ this->ObjectImageHeader+pDirectivesSectionHeader->PointerToRawData;
+ if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+ size = pDirectivesSectionHeader->SizeOfRawData;
+ const char* posImportFlag = rawdata;
+ while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+ const char* lookingForDict = posImportFlag + 9;
+ if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+ !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+ posImportFlag = lookingForDict;
+ continue;
+ }
+
+ const char* lookingForDATA = posImportFlag + 9;
+ while (*(++lookingForDATA) && *lookingForDATA != ' ');
+ lookingForDATA -= 5;
+ // ignore DATA exports
+ if (strncmp(lookingForDATA, ",DATA", 5)) break;
+ posImportFlag = lookingForDATA + 5;
+ }
+ if(posImportFlag) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * DumpObjFile --
+ *
+ * Dump an object file's exported symbols.
+ *----------------------------------------------------------------------
+ */
+ void DumpObjFile() {
+ if(!HaveExportedObjects()) {
+ this->DumpExternalsObjects();
+ }
+ }
+
+ /*
+ *----------------------------------------------------------------------
+ * DumpExternalsObjects --
+ *
+ * Dumps a COFF symbol table from an OBJ.
+ *----------------------------------------------------------------------
+ */
+ void DumpExternalsObjects() {
+ unsigned i;
+ PSTR stringTable;
+ std::string symbol;
+ DWORD SectChar;
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&this->SymbolTable[this->SymbolCount];
+ SymbolTableType* pSymbolTable = this->SymbolTable;
+ for ( i=0; i < this->SymbolCount; i++ ) {
+ if (pSymbolTable->SectionNumber > 0 &&
+ ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ /*
+ * The name of the Function entry points
+ */
+ if (pSymbolTable->N.Name.Short != 0) {
+ symbol = "";
+ symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+ } else {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ }
+
+ // clear out any leading spaces
+ while (isspace(symbol[0])) symbol.erase(0,1);
+ // if it starts with _ and has an @ then it is a __cdecl
+ // so remove the @ stuff for the export
+ if(symbol[0] == '_') {
+ std::string::size_type posAt = symbol.find('@');
+ if (posAt != std::string::npos) {
+ symbol.erase(posAt);
+ }
+ }
+ if (symbol[0] == '_') symbol.erase(0,1);
+ if (this->ImportFlag) {
+ this->ImportFlag = false;
+ fprintf(this->FileOut,"EXPORTS \n");
+ }
+ /*
+ Check whether it is "Scalar deleting destructor" and
+ "Vector deleting destructor"
+ */
+ const char *scalarPrefix = "??_G";
+ const char *vectorPrefix = "??_E";
+ // original code had a check for
+ // symbol.find("real@") == std::string::npos)
+ // but if this disallows memmber functions with the name real
+ // if scalarPrefix and vectorPrefix are not found then print
+ // the symbol
+ if (symbol.compare(0, 4, scalarPrefix) &&
+ symbol.compare(0, 4, vectorPrefix) )
+ {
+ SectChar =
+ this->
+ SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+ if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+ // Read only (i.e. constants) must be excluded
+ fprintf(this->FileOut, "\t%s \t DATA\n", symbol.c_str());
+ } else {
+ if ( pSymbolTable->Type ||
+ !(SectChar & IMAGE_SCN_MEM_READ)) {
+ fprintf(this->FileOut, "\t%s\n", symbol.c_str());
+ } else {
+ // printf(" strange symbol: %s \n",symbol.c_str());
+ }
+ }
+ }
+ }
+ }
+ else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED &&
+ !pSymbolTable->Type && 0) {
+ /*
+ * The IMPORT global variable entry points
+ */
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ while (isspace(symbol[0])) symbol.erase(0,1);
+ if (symbol[0] == '_') symbol.erase(0,1);
+ if (!this->ImportFlag) {
+ this->ImportFlag = true;
+ fprintf(this->FileOut,"IMPORTS \n");
+ }
+ fprintf(this->FileOut, "\t%s DATA \n", symbol.c_str()+1);
+ }
+ }
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+ }
+private:
+ bool ImportFlag;
+ FILE* FileOut;
+ DWORD_PTR SymbolCount;
+ PIMAGE_SECTION_HEADER SectionHeaders;
+ ObjectHeaderType* ObjectImageHeader;
+ SymbolTableType* SymbolTable;
+};
+
+bool
+DumpFile(const char* filename, FILE *fout)
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase;
+ PIMAGE_DOS_HEADER dosHeader;
+
+ hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(),
+ GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
+ return false;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hFileMapping == 0) {
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+ return false;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if (lpFileBase == 0) {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+ return false;
+ }
+
+ dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+ fprintf(stderr, "File is an executable. I don't dump those.\n");
+ return false;
+ }
+ /* Does it look like a i386 COFF OBJ file??? */
+ else if (
+ ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) ||
+ (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+ && (dosHeader->e_sp == 0)
+ ) {
+ /*
+ * The two tests above aren't what they look like. They're
+ * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+ * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+ */
+ DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL>
+ symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, fout);
+ symbolDumper.DumpObjFile();
+ } else {
+ // check for /bigobj format
+ cmANON_OBJECT_HEADER_BIGOBJ* h =
+ (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase;
+ if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
+ DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
+ symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, fout);
+ symbolDumper.DumpObjFile();
+ } else {
+ printf("unrecognized file format in '%s'\n", filename);
+ return false;
+ }
+ }
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ return true;
+}
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index f117475..bda933b 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -122,35 +122,6 @@ struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
}
};
-template<typename const_iterator_>
-struct Range
-{
- typedef const_iterator_ const_iterator;
- typedef typename std::iterator_traits<const_iterator>::value_type value_type;
- typedef typename std::iterator_traits<const_iterator>::difference_type
- difference_type;
- Range(const_iterator begin_, const_iterator end_)
- : Begin(begin_), End(end_) {}
- const_iterator begin() const { return Begin; }
- const_iterator end() const { return End; }
- bool empty() const { return std::distance(Begin, End) == 0; }
- difference_type size() const { return std::distance(Begin, End); }
- Range& advance(cmIML_INT_intptr_t amount)
- {
- std::advance(Begin, amount);
- return *this;
- }
-
- Range& retreat(cmIML_INT_intptr_t amount)
- {
- std::advance(End, -amount);
- return *this;
- }
-private:
- const_iterator Begin;
- const_iterator End;
-};
-
template<typename FwdIt>
FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
{
@@ -178,17 +149,52 @@ private:
}
+template<typename const_iterator_>
+struct cmRange
+{
+ typedef const_iterator_ const_iterator;
+ typedef typename std::iterator_traits<const_iterator>::value_type value_type;
+ typedef typename std::iterator_traits<const_iterator>::difference_type
+ difference_type;
+ cmRange(const_iterator begin_, const_iterator end_)
+ : Begin(begin_), End(end_) {}
+ const_iterator begin() const { return Begin; }
+ const_iterator end() const { return End; }
+ bool empty() const { return std::distance(Begin, End) == 0; }
+ difference_type size() const { return std::distance(Begin, End); }
+ cmRange& advance(cmIML_INT_intptr_t amount)
+ {
+ std::advance(Begin, amount);
+ return *this;
+ }
+
+ cmRange& retreat(cmIML_INT_intptr_t amount)
+ {
+ std::advance(End, -amount);
+ return *this;
+ }
+private:
+ const_iterator Begin;
+ const_iterator End;
+};
+
+typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
+
+class cmListFileBacktrace;
+typedef
+cmRange<std::vector<cmListFileBacktrace>::const_iterator> cmBacktraceRange;
+
template<typename Iter1, typename Iter2>
-ContainerAlgorithms::Range<Iter1> cmRange(Iter1 begin, Iter2 end)
+cmRange<Iter1> cmMakeRange(Iter1 begin, Iter2 end)
{
- return ContainerAlgorithms::Range<Iter1>(begin, end);
+ return cmRange<Iter1>(begin, end);
}
template<typename Range>
-ContainerAlgorithms::Range<typename Range::const_iterator>
-cmRange(Range const& range)
+cmRange<typename Range::const_iterator>
+cmMakeRange(Range const& range)
{
- return ContainerAlgorithms::Range<typename Range::const_iterator>(
+ return cmRange<typename Range::const_iterator>(
range.begin(), range.end());
}
@@ -350,11 +356,17 @@ typename Range::const_iterator cmFindNot(Range const& r, T const& t)
}
template<typename Range>
-ContainerAlgorithms::Range<typename Range::const_reverse_iterator>
+cmRange<typename Range::const_reverse_iterator>
cmReverseRange(Range const& range)
{
- return ContainerAlgorithms::Range<typename Range::const_reverse_iterator>(
+ return cmRange<typename Range::const_reverse_iterator>(
range.rbegin(), range.rend());
}
+template <class Iter>
+std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it)
+{
+ return std::reverse_iterator<Iter>(it);
+}
+
#endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 72818f5..9f56324 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -13,7 +13,6 @@
#include "cmSystemTools.h"
#include "cmLocale.h"
-#include <cmsys/ios/iostream>
#include <cmsys/Directory.hxx>
#include <cmsys/FStream.hxx>
#include <cm_libarchive.h>
@@ -67,7 +66,7 @@ struct cmArchiveWrite::Callback
{
cmArchiveWrite* self = static_cast<cmArchiveWrite*>(cd);
if(self->Stream.write(static_cast<const char*>(b),
- static_cast<cmsys_ios::streamsize>(n)))
+ static_cast<std::streamsize>(n)))
{
return static_cast<__LA_SSIZE_T>(n);
}
@@ -84,54 +83,55 @@ cmArchiveWrite::cmArchiveWrite(
Stream(os),
Archive(archive_write_new()),
Disk(archive_read_disk_new()),
- Verbose(false)
+ Verbose(false),
+ Format(format)
{
switch (c)
{
case CompressNone:
- if(archive_write_set_compression_none(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_none(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_none: ";
+ this->Error = "archive_write_add_filter_none: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressCompress:
- if(archive_write_set_compression_compress(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_compress(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_compress: ";
+ this->Error = "archive_write_add_filter_compress: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressGZip:
- if(archive_write_set_compression_gzip(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_gzip(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_gzip: ";
+ this->Error = "archive_write_add_filter_gzip: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressBZip2:
- if(archive_write_set_compression_bzip2(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_bzip2(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_bzip2: ";
+ this->Error = "archive_write_add_filter_bzip2: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressLZMA:
- if(archive_write_set_compression_lzma(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_lzma(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_lzma: ";
+ this->Error = "archive_write_add_filter_lzma: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
break;
case CompressXZ:
- if(archive_write_set_compression_xz(this->Archive) != ARCHIVE_OK)
+ if(archive_write_add_filter_xz(this->Archive) != ARCHIVE_OK)
{
- this->Error = "archive_write_set_compression_xz: ";
+ this->Error = "archive_write_add_filter_xz: ";
this->Error += cm_archive_error_string(this->Archive);
return;
}
@@ -176,8 +176,8 @@ cmArchiveWrite::cmArchiveWrite(
//----------------------------------------------------------------------------
cmArchiveWrite::~cmArchiveWrite()
{
- archive_read_finish(this->Disk);
- archive_write_finish(this->Archive);
+ archive_read_free(this->Disk);
+ archive_write_free(this->Archive);
}
//----------------------------------------------------------------------------
@@ -282,6 +282,14 @@ bool cmArchiveWrite::AddFile(const char* file,
archive_entry_acl_clear(e);
archive_entry_xattr_clear(e);
archive_entry_set_fflags(e, 0, 0);
+
+ if (this->Format == "pax" || this->Format == "paxr")
+ {
+ // Sparse files are a GNU tar extension.
+ // Do not use them in standard tar files.
+ archive_entry_sparse_clear(e);
+ }
+
if(archive_write_header(this->Archive, e) != ARCHIVE_OK)
{
this->Error = "archive_write_header: ";
@@ -304,7 +312,7 @@ bool cmArchiveWrite::AddFile(const char* file,
//----------------------------------------------------------------------------
bool cmArchiveWrite::AddData(const char* file, size_t size)
{
- cmsys::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ cmsys::ifstream fin(file, std::ios::in | std::ios::binary);
if(!fin)
{
this->Error = "Error opening \"";
@@ -318,7 +326,7 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
size_t nleft = size;
while(nleft > 0)
{
- typedef cmsys_ios::streamsize ssize_type;
+ typedef std::streamsize ssize_type;
size_t const nnext = nleft > sizeof(buffer)? sizeof(buffer) : nleft;
ssize_type const nnext_s = static_cast<ssize_type>(nnext);
fin.read(buffer, nnext_s);
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 794cb28..e6f515d 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -84,6 +84,7 @@ private:
struct archive* Archive;
struct archive* Disk;
bool Verbose;
+ std::string Format;
std::string Error;
std::string MTime;
};
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 5234538..6ff7c0d 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -11,8 +11,6 @@
============================================================================*/
#include "cmCMakeHostSystemInformationCommand.h"
-#include <cmsys/ios/sstream>
-
// cmCMakeHostSystemInformation
bool cmCMakeHostSystemInformationCommand
::InitialPass(std::vector<std::string> const &args, cmExecutionStatus &)
@@ -107,7 +105,7 @@ bool cmCMakeHostSystemInformationCommand
std::string cmCMakeHostSystemInformationCommand
::ValueToString(size_t value) const
{
- cmsys_ios::stringstream tmp;
+ std::stringstream tmp;
tmp << value;
return tmp.str();
}
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 3c878bf..3ef6d35 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -93,6 +93,22 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
this->SetError("SET failed to set policy.");
return false;
}
+ if(args[1] == "CMP0001" &&
+ (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ {
+ if(!(this->Makefile->GetState()
+ ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+ {
+ // Set it to 2.4 because that is the last version where the
+ // variable had meaning.
+ this->Makefile->AddCacheDefinition
+ ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+ "For backwards compatibility, what version of CMake "
+ "commands and "
+ "syntax should this version of CMake try to support.",
+ cmState::STRING);
+ }
+ }
return true;
}
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
index cf24c13..cbcdd81 100644
--- a/Source/cmCPackPropertiesGenerator.cxx
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -1,13 +1,14 @@
#include "cmCPackPropertiesGenerator.h"
+#include "cmOutputConverter.h"
#include "cmLocalGenerator.h"
cmCPackPropertiesGenerator::cmCPackPropertiesGenerator(
- cmMakefile* mf,
+ cmLocalGenerator* lg,
cmInstalledFile const& installedFile,
std::vector<std::string> const& configurations):
cmScriptGenerator("CPACK_BUILD_CONFIG", configurations),
- Makefile(mf),
+ LG(lg),
InstalledFile(installedFile)
{
this->ActionsPerConfig = true;
@@ -17,7 +18,8 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os,
const std::string& config, Indent const& indent)
{
std::string const& expandedFileName =
- this->InstalledFile.GetNameExpression().Evaluate(this->Makefile, config);
+ this->InstalledFile.GetNameExpression().Evaluate(this->LG->GetMakefile(),
+ config);
cmInstalledFile::PropertyMapType const& properties =
this->InstalledFile.GetProperties();
@@ -29,15 +31,15 @@ void cmCPackPropertiesGenerator::GenerateScriptForConfig(std::ostream& os,
cmInstalledFile::Property const& property = i->second;
os << indent << "set_property(INSTALL " <<
- cmLocalGenerator::EscapeForCMake(expandedFileName) << " PROPERTY " <<
- cmLocalGenerator::EscapeForCMake(name);
+ cmOutputConverter::EscapeForCMake(expandedFileName) << " PROPERTY " <<
+ cmOutputConverter::EscapeForCMake(name);
for(cmInstalledFile::ExpressionVectorType::const_iterator
j = property.ValueExpressions.begin();
j != property.ValueExpressions.end(); ++j)
{
- std::string value = (*j)->Evaluate(this->Makefile, config);
- os << " " << cmLocalGenerator::EscapeForCMake(value);
+ std::string value = (*j)->Evaluate(LG->GetMakefile(), config);
+ os << " " << cmOutputConverter::EscapeForCMake(value);
}
os << ")\n";
diff --git a/Source/cmCPackPropertiesGenerator.h b/Source/cmCPackPropertiesGenerator.h
index 71e2eaa..eec3df0 100644
--- a/Source/cmCPackPropertiesGenerator.h
+++ b/Source/cmCPackPropertiesGenerator.h
@@ -15,6 +15,8 @@
#include "cmScriptGenerator.h"
#include "cmInstalledFile.h"
+class cmLocalGenerator;
+
/** \class cmCPackPropertiesGenerator
* \brief Support class for generating CPackProperties.cmake.
*
@@ -23,7 +25,7 @@ class cmCPackPropertiesGenerator: public cmScriptGenerator
{
public:
cmCPackPropertiesGenerator(
- cmMakefile* mf,
+ cmLocalGenerator* lg,
cmInstalledFile const& installedFile,
std::vector<std::string> const& configurations);
@@ -31,7 +33,7 @@ protected:
virtual void GenerateScriptForConfig(std::ostream& os,
const std::string& config, Indent const& indent);
- cmMakefile* Makefile;
+ cmLocalGenerator* LG;
cmInstalledFile const& InstalledFile;
};
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index c55ea35..7da334e 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -115,7 +115,9 @@ void CCONV cmAddCacheDefinition(void *arg, const char* name,
const char* CCONV cmGetProjectName(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
- return mf->GetProjectName();
+ static std::string name;
+ name = mf->GetProjectName();
+ return name.c_str();
}
const char* CCONV cmGetHomeDirectory(void *arg)
@@ -426,8 +428,7 @@ int CCONV cmExecuteCommand(void *arg, const char *name,
{
// Assume all arguments are quoted.
lff.Arguments.push_back(
- cmListFileArgument(args[i], cmListFileArgument::Quoted,
- "[CMake-Plugin]", 0));
+ cmListFileArgument(args[i], cmListFileArgument::Quoted, 0));
}
cmExecutionStatus status;
return mf->ExecuteCommand(lff,status);
@@ -526,11 +527,9 @@ void * CCONV cmCreateSourceFile(void)
return (void*)new cmCPluginAPISourceFile;
}
-void * CCONV cmCreateNewSourceFile(void *arg)
+void * CCONV cmCreateNewSourceFile(void *)
{
- cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
- sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
return (void*)sf;
}
@@ -630,11 +629,7 @@ const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
{
return sf->FullPath.c_str();
}
- bool chain = false;
- // Ignore chain because old code will not expect it and it is a
- // pain to implement here anyway.
- return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
- chain);
+ return sf->Properties.GetPropertyValue(prop);
}
}
@@ -662,7 +657,7 @@ void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
else if(prop)
{
if(!value) { value = "NOTFOUND"; }
- sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+ sf->Properties.SetProperty(prop, value);
}
}
@@ -801,8 +796,7 @@ void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
// Implement the old SetName method code here.
if(headerFileOnly)
{
- sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
- cmProperty::SOURCE_FILE);
+ sf->Properties.SetProperty("HEADER_FILE_ONLY", "1");
}
sf->SourceName = name;
std::string fname = sf->SourceName;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e3b7a2b..b2ad4a8 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -22,7 +22,6 @@
#include <cmsys/FStream.hxx>
#include "cmDynamicLoader.h"
#include "cmGeneratedFileStream.h"
-#include "cmXMLSafe.h"
#include "cmVersionMacros.h"
#include "cmCTestCommand.h"
#include "cmCTestStartCommand.h"
@@ -156,7 +155,7 @@ std::string cmCTest::CurrentTime()
strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t);
}
cmCTestLog(this, DEBUG, " Current_Time: " << current_time << std::endl);
- return cmXMLSafe(cmCTest::CleanString(current_time)).str();
+ return cmCTest::CleanString(current_time);
}
//----------------------------------------------------------------------
@@ -294,6 +293,7 @@ cmCTest::cmCTest()
this->LabelSummary = true;
this->ParallelLevel = 1;
this->ParallelLevelSetInCli = false;
+ this->TestLoad = 0;
this->SubmitIndex = 0;
this->Failover = false;
this->BatchJobs = false;
@@ -393,6 +393,11 @@ void cmCTest::SetParallelLevel(int level)
this->ParallelLevel = level < 1 ? 1 : level;
}
+void cmCTest::SetTestLoad(unsigned long load)
+{
+ this->TestLoad = load;
+}
+
//----------------------------------------------------------------------------
bool cmCTest::ShouldCompressTestOutput()
{
@@ -514,9 +519,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmGlobalGenerator gg(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
- if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), mf) )
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
+ if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(),
+ mf.get()) )
{
cmCTestOptionalLog(this, DEBUG,
"Cannot find custom configuration file tree" << std::endl, quiet);
@@ -820,6 +826,20 @@ bool cmCTest::UpdateCTestConfiguration()
cmSystemTools::ChangeDirectory(this->BinaryDir);
}
this->TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str());
+ std::string const& testLoad = this->GetCTestConfiguration("TestLoad");
+ if (!testLoad.empty())
+ {
+ unsigned long load;
+ if (cmSystemTools::StringToULong(testLoad.c_str(), &load))
+ {
+ this->SetTestLoad(load);
+ }
+ else
+ {
+ cmCTestLog(this, WARNING, "Invalid value for 'Test Load' : "
+ << testLoad << std::endl);
+ }
+ }
if ( this->ProduceXML )
{
this->CompressXMLFiles = cmSystemTools::IsOn(
@@ -1200,7 +1220,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
char* data;
int length;
- cmCTestLog(this, HANDLER_OUTPUT,
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Each . represents " << tick_len << " bytes of output" << std::endl
<< " " << std::flush);
while(cmsysProcess_WaitForData(cp, &data, &length, 0))
@@ -1216,10 +1236,10 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
while ( output.size() > (tick * tick_len) )
{
tick ++;
- cmCTestLog(this, HANDLER_OUTPUT, "." << std::flush);
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, "." << std::flush);
if ( tick % tick_line_len == 0 && tick > 0 )
{
- cmCTestLog(this, HANDLER_OUTPUT,
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
" Size: "
<< int((double(output.size()) / 1024.0) + 1)
<< "K" << std::endl
@@ -1232,7 +1252,7 @@ int cmCTest::RunMakeCommand(const char* command, std::string& output,
ofs << cmCTestLogWrite(data, length);
}
}
- cmCTestLog(this, OUTPUT, " Size of output: "
+ cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size of output: "
<< int(double(output.size()) / 1024.0) << "K" << std::endl);
cmsysProcess_WaitForExit(cp, 0);
@@ -1477,8 +1497,6 @@ std::string cmCTest::SafeBuildIdField(const std::string& value)
cmSystemTools::ReplaceString(safevalue, replace, "");
}
}
-
- safevalue = cmXMLSafe(safevalue).str();
}
if (safevalue == "")
@@ -1526,9 +1544,8 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
xml.Attribute("Append", "true");
}
xml.Attribute("CompilerName", this->GetCTestConfiguration("Compiler"));
-#ifdef _COMPILER_VERSION
- xml.Attribute("CompilerVersion", _COMPILER_VERSION);
-#endif
+ xml.Attribute("CompilerVersion",
+ this->GetCTestConfiguration("CompilerVersion"));
xml.Attribute("OSName", info.GetOSName());
xml.Attribute("Hostname", info.GetHostname());
xml.Attribute("OSRelease", info.GetOSRelease());
@@ -1547,6 +1564,13 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append)
xml.Attribute("LogicalProcessorsPerPhysical",
info.GetLogicalProcessorsPerPhysical());
xml.Attribute("ProcessorClockFrequency", info.GetProcessorClockFrequency());
+
+ std::string changeId = this->GetCTestConfiguration("ChangeId");
+ if(!changeId.empty())
+ {
+ xml.Attribute("ChangeId", changeId);
+ }
+
this->AddSiteProperties(xml);
}
@@ -2051,6 +2075,21 @@ bool cmCTest::HandleCommandLineArguments(size_t &i,
}
}
+ if(this->CheckArgument(arg, "--test-load") && i < args.size() - 1)
+ {
+ i++;
+ unsigned long load;
+ if (cmSystemTools::StringToULong(args[i].c_str(), &load))
+ {
+ this->SetTestLoad(load);
+ }
+ else
+ {
+ cmCTestLog(this, WARNING,
+ "Invalid value for 'Test Load' : " << args[i] << std::endl);
+ }
+ }
+
if(this->CheckArgument(arg, "--no-compress-output"))
{
this->CompressTestOutput = false;
@@ -3066,6 +3105,7 @@ static const char* cmCTestStringLogType[] =
"DEBUG",
"OUTPUT",
"HANDLER_OUTPUT",
+ "HANDLER_PROGRESS_OUTPUT",
"HANDLER_VERBOSE_OUTPUT",
"WARNING",
"ERROR_MESSAGE",
@@ -3104,6 +3144,11 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg,
{
return;
}
+ if ( logType == cmCTest::HANDLER_PROGRESS_OUTPUT &&
+ ( this->Debug || this->ExtraVerbose ) )
+ {
+ return;
+ }
if ( this->OutputLogFile )
{
bool display = true;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index db3ea10..73c2807 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -161,6 +161,9 @@ public:
int GetParallelLevel() { return this->ParallelLevel; }
void SetParallelLevel(int);
+ unsigned long GetTestLoad() { return this->TestLoad; }
+ void SetTestLoad(unsigned long);
+
/**
* Check if CTest file exists
*/
@@ -379,6 +382,7 @@ public:
DEBUG = 0,
OUTPUT,
HANDLER_OUTPUT,
+ HANDLER_PROGRESS_OUTPUT,
HANDLER_VERBOSE_OUTPUT,
WARNING,
ERROR_MESSAGE,
@@ -499,6 +503,8 @@ private:
int ParallelLevel;
bool ParallelLevelSetInCli;
+ unsigned long TestLoad;
+
int CompatibilityMode;
// information for the --build-and-test options
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 108208e..54209c5 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -161,7 +161,6 @@ bool cmCacheManager::LoadCache(const std::string& path,
// Format is key:type=value
std::string helpString;
CacheEntry e;
- e.Properties.SetCMakeInstance(this->CMakeInstance);
cmSystemTools::GetLineFromStream(fin, buffer);
realbuffer = buffer.c_str();
while(*realbuffer != '0' &&
@@ -323,7 +322,6 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
{
// Create an entry and store the property.
CacheEntry& ne = this->Cache[key];
- ne.Properties.SetCMakeInstance(this->CMakeInstance);
ne.Type = cmState::UNINITIALIZED;
ne.SetProperty(*p, e.Value.c_str());
}
@@ -645,7 +643,6 @@ void cmCacheManager::AddCacheEntry(const std::string& key,
cmState::CacheEntryType type)
{
CacheEntry& e = this->Cache[key];
- e.Properties.SetCMakeInstance(this->CMakeInstance);
if ( value )
{
e.Value = value;
@@ -744,9 +741,7 @@ cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
{
return this->Value.c_str();
}
- bool c = false;
- return
- this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c);
+ return this->Properties.GetPropertyValue(prop);
}
//----------------------------------------------------------------------------
@@ -763,7 +758,7 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
}
else
{
- this->Properties.SetProperty(prop, value, cmProperty::CACHE);
+ this->Properties.SetProperty(prop, value);
}
}
@@ -789,7 +784,7 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
}
else
{
- this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString);
+ this->Properties.AppendProperty(prop, value, asString);
}
}
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index c211111..0e04838 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -498,7 +498,7 @@ int cmCallVisualStudioMacro::CallMacro(
}
}
- if(0 == instances.size())
+ if(instances.empty())
{
// no instances to call
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index bd098a5..14e9e56 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -14,7 +14,7 @@
#include "cmSystemTools.h"
#include "cmMakefile.h"
#include "cmState.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmCommandArgumentLexer.h"
@@ -141,8 +141,9 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
{
std::ostringstream msg;
cmListFileContext lfc;
- lfc.FilePath = this->Makefile->GetLocalGenerator()
- ->Convert(this->FileName, cmLocalGenerator::HOME);
+ cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+ lfc.FilePath = converter.Convert(this->FileName,
+ cmOutputConverter::HOME);
lfc.Line = this->FileLine;
msg << "uninitialized variable \'" << var << "\'";
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index d375ae6..387afc6 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -80,8 +80,6 @@ private:
std::string::size_type InputBufferPos;
std::string InputBuffer;
std::vector<char> OutputBuffer;
- int CurrentLine;
- int Verbose;
void Print(const char* place, const char* str);
void SafePrintMissing(const char* str, int line, int cnt);
@@ -94,12 +92,14 @@ private:
std::vector<char*> Variables;
const cmMakefile* Makefile;
std::string Result;
+ std::string ErrorString;
const char* FileName;
+ long FileLine;
+ int CurrentLine;
+ int Verbose;
bool WarnUninitialized;
bool CheckSystemVars;
- long FileLine;
bool EscapeQuotes;
- std::string ErrorString;
bool NoEscapeMode;
bool ReplaceAtSyntax;
bool RemoveEmpty;
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
new file mode 100644
index 0000000..4840e89
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -0,0 +1,414 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 "cmCommonTargetGenerator.h"
+
+#include "cmComputeLinkInformation.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
+#include "cmLocalCommonGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+
+cmCommonTargetGenerator::cmCommonTargetGenerator(
+ cmOutputConverter::RelativeRoot wd,
+ cmGeneratorTarget* gt
+ )
+ : WorkingDirectory(wd)
+ , GeneratorTarget(gt)
+ , Target(gt->Target)
+ , Makefile(gt->Makefile)
+ , LocalGenerator(static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
+ , GlobalGenerator(static_cast<cmGlobalCommonGenerator*>(
+ gt->LocalGenerator->GetGlobalGenerator()))
+ , ConfigName(LocalGenerator->GetConfigName())
+ , ModuleDefinitionFile(GeneratorTarget->GetModuleDefinitionFile(ConfigName))
+ , FortranModuleDirectoryComputed(false)
+{
+}
+
+cmCommonTargetGenerator::~cmCommonTargetGenerator()
+{
+}
+
+std::string const& cmCommonTargetGenerator::GetConfigName() const
+{
+ return this->ConfigName;
+}
+
+std::string cmCommonTargetGenerator::Convert(
+ std::string const& source,
+ cmLocalGenerator::RelativeRoot relative,
+ cmLocalGenerator::OutputFormat output)
+{
+ return this->LocalGenerator->Convert(source, relative, output);
+}
+
+//----------------------------------------------------------------------------
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+{
+ return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+bool cmCommonTargetGenerator::GetFeatureAsBool(const std::string& feature)
+{
+ return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName);
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFeatureFlags(
+ std::string& flags, const std::string& lang
+ )
+{
+ // Add language-specific flags.
+ this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
+
+ if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
+ {
+ this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+{
+ if(this->ModuleDefinitionFile.empty())
+ {
+ return;
+ }
+
+ // TODO: Create a per-language flag variable.
+ const char* defFileFlag =
+ this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ if(!defFileFlag)
+ {
+ return;
+ }
+
+ // Append the flag and value. Use ConvertToLinkReference to help
+ // vs6's "cl -link" pass it to the linker.
+ std::string flag = defFileFlag;
+ flag += (this->LocalGenerator->ConvertToLinkReference(
+ this->ModuleDefinitionFile));
+ this->LocalGenerator->AppendFlags(flags, flag);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::ComputeFortranModuleDirectory() const
+{
+ std::string mod_dir;
+ const char* target_mod_dir =
+ this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
+ const char* moddir_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
+ if(target_mod_dir && moddir_flag)
+ {
+ // Compute the full path to the module directory.
+ if(cmSystemTools::FileIsFullPath(target_mod_dir))
+ {
+ // Already a full path.
+ mod_dir = target_mod_dir;
+ }
+ else
+ {
+ // Interpret relative to the current output directory.
+ mod_dir = this->Makefile->GetCurrentBinaryDirectory();
+ mod_dir += "/";
+ mod_dir += target_mod_dir;
+ }
+
+ // Make sure the module output directory exists.
+ cmSystemTools::MakeDirectory(mod_dir);
+ }
+ return mod_dir;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFortranModuleDirectory()
+{
+ // Compute the module directory.
+ if(!this->FortranModuleDirectoryComputed)
+ {
+ this->FortranModuleDirectoryComputed = true;
+ this->FortranModuleDirectory = this->ComputeFortranModuleDirectory();
+ }
+
+ // Return the computed directory.
+ return this->FortranModuleDirectory;
+}
+
+//----------------------------------------------------------------------------
+void cmCommonTargetGenerator::AddFortranFlags(std::string& flags)
+{
+ // Enable module output if necessary.
+ if(const char* modout_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
+ {
+ this->LocalGenerator->AppendFlags(flags, modout_flag);
+ }
+
+ // Add a module output directory flag if necessary.
+ std::string mod_dir = this->GetFortranModuleDirectory();
+ if (!mod_dir.empty())
+ {
+ mod_dir = this->Convert(mod_dir,
+ this->WorkingDirectory,
+ cmLocalGenerator::SHELL);
+ }
+ else
+ {
+ mod_dir =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
+ }
+ if (!mod_dir.empty())
+ {
+ const char* moddir_flag =
+ this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
+ std::string modflag = moddir_flag;
+ modflag += mod_dir;
+ this->LocalGenerator->AppendFlags(flags, modflag);
+ }
+
+ // If there is a separate module path flag then duplicate the
+ // include path with it. This compiler does not search the include
+ // path for modules.
+ if(const char* modpath_flag =
+ this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
+ {
+ std::vector<std::string> includes;
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->LocalGenerator->GetIncludeDirectories(includes,
+ this->GeneratorTarget,
+ "C", config);
+ for(std::vector<std::string>::const_iterator idi = includes.begin();
+ idi != includes.end(); ++idi)
+ {
+ std::string flg = modpath_flag;
+ flg += this->Convert(*idi,
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ this->LocalGenerator->AppendFlags(flags, flg);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmCommonTargetGenerator
+::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
+{
+ const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+ cmLocalGenerator::FortranFormat format =
+ this->LocalGenerator->GetFortranFormat(srcfmt);
+ if(format == cmLocalGenerator::FortranFormatNone)
+ {
+ const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
+ format = this->LocalGenerator->GetFortranFormat(tgtfmt);
+ }
+ const char* var = 0;
+ switch (format)
+ {
+ case cmLocalGenerator::FortranFormatFixed:
+ var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
+ case cmLocalGenerator::FortranFormatFree:
+ var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
+ default: break;
+ }
+ if(var)
+ {
+ this->LocalGenerator->AppendFlags(
+ flags, this->Makefile->GetDefinition(var));
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFrameworkFlags(std::string const& l)
+{
+ if(!this->Makefile->IsOn("APPLE"))
+ {
+ return std::string();
+ }
+
+ std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
+ const char* fwSearchFlag =
+ this->Makefile->GetDefinition(fwSearchFlagVar);
+ if(!(fwSearchFlag && *fwSearchFlag))
+ {
+ return std::string();
+ }
+
+ std::set<std::string> emitted;
+#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */
+ emitted.insert("/System/Library/Frameworks");
+#endif
+ std::vector<std::string> includes;
+
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->LocalGenerator->GetIncludeDirectories(includes,
+ this->GeneratorTarget,
+ "C", config);
+ // check all include directories for frameworks as this
+ // will already have added a -F for the framework
+ for(std::vector<std::string>::iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ if(this->Target->NameResolvesToFramework(*i))
+ {
+ std::string frameworkDir = *i;
+ frameworkDir += "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+ emitted.insert(frameworkDir);
+ }
+ }
+
+ std::string flags;
+ const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+ if(cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(cfg))
+ {
+ std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
+ for(std::vector<std::string>::const_iterator i = frameworks.begin();
+ i != frameworks.end(); ++i)
+ {
+ if(emitted.insert(*i).second)
+ {
+ flags += fwSearchFlag;
+ flags += this->LocalGenerator
+ ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL);
+ flags += " ";
+ }
+ }
+ }
+ return flags;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCommonTargetGenerator::GetFlags(const std::string &l)
+{
+ ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
+ if (i == this->FlagsByLanguage.end())
+ {
+ std::string flags;
+ const char *lang = l.c_str();
+
+ // Add language feature flags.
+ this->AddFeatureFlags(flags, lang);
+
+ this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
+ lang, this->ConfigName);
+
+ // Fortran-specific flags computed for this target.
+ if(l == "Fortran")
+ {
+ this->AddFortranFlags(flags);
+ }
+
+ this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
+ lang, this->ConfigName);
+
+ this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
+ lang);
+
+ // Append old-style preprocessor definition flags.
+ this->LocalGenerator->
+ AppendFlags(flags, this->Makefile->GetDefineFlags());
+
+ // Add framework directory flags.
+ this->LocalGenerator->
+ AppendFlags(flags,this->GetFrameworkFlags(l));
+
+ // Add target-specific flags.
+ this->LocalGenerator->AddCompileOptions(flags, this->Target,
+ lang, this->ConfigName);
+
+ ByLanguageMap::value_type entry(l, flags);
+ i = this->FlagsByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetDefines(const std::string &l)
+{
+ ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
+ if (i == this->DefinesByLanguage.end())
+ {
+ std::set<std::string> defines;
+ const char *lang = l.c_str();
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro = this->Target->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
+ this->LocalGenerator->GetConfigName(), l);
+
+ std::string definesString;
+ this->LocalGenerator->JoinDefines(defines, definesString, lang);
+
+ ByLanguageMap::value_type entry(l, definesString);
+ i = this->DefinesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+{
+ ByLanguageMap::iterator i = this->IncludesByLanguage.find(l);
+ if (i == this->IncludesByLanguage.end())
+ {
+ std::string includes;
+ this->AddIncludeFlags(includes, l);
+ ByLanguageMap::value_type entry(l, includes);
+ i = this->IncludesByLanguage.insert(entry).first;
+ }
+ return i->second;
+}
+
+std::vector<std::string>
+cmCommonTargetGenerator::GetLinkedTargetDirectories() const
+{
+ std::vector<std::string> dirs;
+ std::set<cmTarget const*> emitted;
+ if (cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(this->ConfigName))
+ {
+ cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
+ for(cmComputeLinkInformation::ItemVector::const_iterator
+ i = items.begin(); i != items.end(); ++i)
+ {
+ cmTarget const* linkee = i->Target;
+ if(linkee && !linkee->IsImported()
+ // We can ignore the INTERFACE_LIBRARY items because
+ // Target->GetLinkInformation already processed their
+ // link interface and they don't have any output themselves.
+ && linkee->GetType() != cmTarget::INTERFACE_LIBRARY
+ && emitted.insert(linkee).second)
+ {
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(linkee);
+ cmLocalGenerator* lg = gt->GetLocalGenerator();
+ cmMakefile* mf = linkee->GetMakefile();
+ std::string di = mf->GetCurrentBinaryDirectory();
+ di += "/";
+ di += lg->GetTargetDirectory(*linkee);
+ dirs.push_back(di);
+ }
+ }
+ }
+ return dirs;
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
new file mode 100644
index 0000000..0a49e12
--- /dev/null
+++ b/Source/cmCommonTargetGenerator.h
@@ -0,0 +1,95 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 cmCommonTargetGenerator_h
+#define cmCommonTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmLocalGenerator.h"
+
+class cmGeneratorTarget;
+class cmGlobalCommonGenerator;
+class cmLocalCommonGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmTarget;
+
+/** \class cmCommonTargetGenerator
+ * \brief Common infrastructure for Makefile and Ninja per-target generators
+ */
+class cmCommonTargetGenerator
+{
+public:
+ cmCommonTargetGenerator(cmOutputConverter::RelativeRoot wd,
+ cmGeneratorTarget* gt);
+ virtual ~cmCommonTargetGenerator();
+
+ std::string const& GetConfigName() const;
+
+protected:
+
+ // Add language feature flags.
+ void AddFeatureFlags(std::string& flags, const std::string& lang);
+
+ // Feature query methods.
+ const char* GetFeature(const std::string& feature);
+ bool GetFeatureAsBool(const std::string& feature);
+
+ // Helper to add flag for windows .def file.
+ void AddModuleDefinitionFlag(std::string& flags);
+
+ cmOutputConverter::RelativeRoot WorkingDirectory;
+ cmGeneratorTarget* GeneratorTarget;
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalCommonGenerator* LocalGenerator;
+ cmGlobalCommonGenerator* GlobalGenerator;
+ std::string ConfigName;
+
+ // The windows module definition source file (.def), if any.
+ std::string ModuleDefinitionFile;
+
+ // Target-wide Fortran module output directory.
+ bool FortranModuleDirectoryComputed;
+ std::string FortranModuleDirectory;
+ std::string GetFortranModuleDirectory();
+ virtual std::string ComputeFortranModuleDirectory() const;
+
+ // Compute target-specific Fortran language flags.
+ void AddFortranFlags(std::string& flags);
+
+ std::string Convert(std::string const& source,
+ cmLocalGenerator::RelativeRoot relative,
+ cmLocalGenerator::OutputFormat output =
+ cmLocalGenerator::UNCHANGED);
+
+ void AppendFortranFormatFlags(std::string& flags,
+ cmSourceFile const& source);
+
+ // Return the a string with -F flags on apple
+ std::string GetFrameworkFlags(std::string const& l);
+
+ virtual void AddIncludeFlags(std::string& flags,
+ std::string const& lang) = 0;
+
+ typedef std::map<std::string, std::string> ByLanguageMap;
+ std::string GetFlags(const std::string &l);
+ ByLanguageMap FlagsByLanguage;
+ std::string GetDefines(const std::string &l);
+ ByLanguageMap DefinesByLanguage;
+ std::string GetIncludes(std::string const& l);
+ ByLanguageMap IncludesByLanguage;
+
+ std::vector<std::string> GetLinkedTargetDirectories() const;
+};
+
+#endif
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index a2ce946..4dbac4a 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -67,17 +67,17 @@ private:
int Root;
int VisitIndex;
};
- int TarjanWalkId;
std::vector<int> TarjanVisited;
std::vector<int> TarjanComponents;
std::vector<TarjanEntry> TarjanEntries;
+ std::vector<NodeList> Components;
std::stack<int> TarjanStack;
+ int TarjanWalkId;
int TarjanIndex;
void Tarjan();
void TarjanVisit(int i);
// Connected components.
- std::vector<NodeList> Components;
};
#endif
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index abd9877..1b5c9f4 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -12,14 +12,13 @@
#include "cmComputeLinkDepends.h"
#include "cmComputeComponentGraph.h"
+#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmTarget.h"
#include "cmake.h"
#include "cmAlgorithms.h"
-#include <cmsys/stl/algorithm>
-
#include <assert.h>
/*
@@ -173,18 +172,20 @@ items that we know the linker will re-use automatically (shared libs).
//----------------------------------------------------------------------------
cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget const* target, const std::string& config)
+::cmComputeLinkDepends(const cmGeneratorTarget* target,
+ const std::string& config)
{
// Store context information.
this->Target = target;
- this->Makefile = this->Target->GetMakefile();
- this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+ this->Makefile = this->Target->Target->GetMakefile();
+ this->GlobalGenerator =
+ this->Target->GetLocalGenerator()->GetGlobalGenerator();
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
// The configuration being linked.
this->HasConfig = !config.empty();
this->Config = (this->HasConfig)? config : std::string();
- this->LinkType = this->Target->ComputeLinkType(this->Config);
+ this->LinkType = this->Target->Target->ComputeLinkType(this->Config);
// Enable debug mode if requested.
this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
@@ -361,9 +362,11 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
// Follow the item's dependencies.
if(entry.Target)
{
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(entry.Target);
// Follow the target dependencies.
- if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->Target))
+ if(cmLinkInterface const* iface =
+ gtgt->GetLinkInterface(this->Config, this->Target->Target))
{
const bool isIface =
entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -397,7 +400,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
//----------------------------------------------------------------------------
void
cmComputeLinkDepends
-::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
+::FollowSharedDeps(int depender_index, cmLinkInterface const* iface,
bool follow_interface)
{
// Follow dependencies if we have not followed them already.
@@ -460,8 +463,10 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Target items may have their own dependencies.
if(entry.Target)
{
- if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config, this->Target))
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(entry.Target);
+ if(cmLinkInterface const* iface =
+ gtgt->GetLinkInterface(this->Config, this->Target->Target))
{
// Follow public and private dependencies transitively.
this->FollowSharedDeps(index, iface, true);
@@ -551,7 +556,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
- cmTarget::LinkImplementation const* impl =
+ cmLinkImplementation const* impl =
this->Target->GetLinkImplementation(this->Config);
this->AddLinkEntries(-1, impl->Libraries);
for(std::vector<cmLinkItem>::const_iterator
@@ -634,7 +639,7 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
const std::string& name)
{
// Look for a target in the scope of the depender.
- cmTarget const* from = this->Target;
+ cmTarget const* from = this->Target->Target;
if(depender_index >= 0)
{
if(cmTarget const* depender = this->EntryList[depender_index].Target)
@@ -931,8 +936,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
{
if(cmTarget const* target = this->EntryList[*ni].Target)
{
- if(cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config, this->Target))
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(target);
+ if(cmLinkInterface const* iface =
+ gtgt->GetLinkInterface(this->Config, this->Target->Target))
{
if(iface->Multiplicity > count)
{
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 09b9d70..2cbb430 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -22,6 +22,7 @@
class cmComputeComponentGraph;
class cmGlobalGenerator;
class cmMakefile;
+class cmGeneratorTarget;
class cmTarget;
class cmake;
@@ -31,7 +32,8 @@ class cmake;
class cmComputeLinkDepends
{
public:
- cmComputeLinkDepends(cmTarget const* target, const std::string& config);
+ cmComputeLinkDepends(cmGeneratorTarget const* target,
+ const std::string& config);
~cmComputeLinkDepends();
// Basic information about each link item.
@@ -57,18 +59,11 @@ public:
private:
// Context information.
- cmTarget const* Target;
+ cmGeneratorTarget const* Target;
cmMakefile* Makefile;
cmGlobalGenerator const* GlobalGenerator;
cmake* CMakeInstance;
- bool DebugMode;
-
- // Configuration information.
- bool HasConfig;
std::string Config;
- cmTarget::LinkLibraryType LinkType;
-
- // Output information.
EntryVector FinalLinkEntries;
typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
@@ -107,7 +102,7 @@ private:
std::queue<SharedDepEntry> SharedDepQueue;
std::set<int> SharedDepFollowed;
void FollowSharedDeps(int depender_index,
- cmTarget::LinkInterface const* iface,
+ cmLinkInterface const* iface,
bool follow_interface = false);
void QueueSharedDependencies(int depender_index,
std::vector<cmLinkItem> const& deps);
@@ -131,7 +126,7 @@ private:
void OrderLinkEntires();
std::vector<char> ComponentVisited;
std::vector<int> ComponentOrder;
- int ComponentOrderId;
+
struct PendingComponent
{
// The real component id. Needed because the map is indexed by
@@ -158,11 +153,14 @@ private:
// Record of the original link line.
std::vector<int> OriginalEntries;
+ std::set<cmTarget const*> OldWrongConfigItems;
+ void CheckWrongConfigItem(cmLinkItem const& item);
- // Compatibility help.
+ int ComponentOrderId;
+ cmTarget::LinkLibraryType LinkType;
+ bool HasConfig;
+ bool DebugMode;
bool OldLinkDirMode;
- void CheckWrongConfigItem(cmLinkItem const& item);
- std::set<cmTarget const*> OldWrongConfigItems;
};
#endif
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index e6cbe60..4b70e5e 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -14,11 +14,13 @@
#include "cmComputeLinkDepends.h"
#include "cmOrderDirectories.h"
+#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmState.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmMakefile.h"
#include "cmTarget.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
#include "cmAlgorithms.h"
@@ -241,13 +243,14 @@ because this need be done only for shared libraries without soname-s.
//----------------------------------------------------------------------------
cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget const* target, const std::string& config)
+::cmComputeLinkInformation(const cmGeneratorTarget* target,
+ const std::string& config)
{
// Store context information.
this->Target = target;
- this->Makefile = this->Target->GetMakefile();
- this->LocalGenerator = this->Makefile->GetLocalGenerator();
- this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+ this->Makefile = this->Target->Target->GetMakefile();
+ this->GlobalGenerator =
+ this->Target->GetLocalGenerator()->GetGlobalGenerator();
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
// Check whether to recognize OpenBSD-style library versioned names.
@@ -281,14 +284,14 @@ cmComputeLinkInformation
// Check whether we should skip dependencies on shared library files.
this->LinkDependsNoShared =
- this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
+ this->Target->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.
this->LoaderFlag = 0;
if(!this->UseImportLibrary &&
- this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ this->Target->Target->GetType() == cmTarget::MODULE_LIBRARY)
{
std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
loader_flag_var += this->LinkLanguage;
@@ -306,10 +309,10 @@ cmComputeLinkInformation
// Get options needed to specify RPATHs.
this->RuntimeUseChrpath = false;
- if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ if(this->Target->Target->GetType() != cmTarget::STATIC_LIBRARY)
{
const char* tType =
- ((this->Target->GetType() == cmTarget::EXECUTABLE)?
+ ((this->Target->Target->GetType() == cmTarget::EXECUTABLE)?
"EXECUTABLE" : "SHARED_LIBRARY");
std::string rtVar = "CMAKE_";
rtVar += tType;
@@ -322,6 +325,7 @@ cmComputeLinkInformation
this->RuntimeAlways =
(this->Makefile->
GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+
this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
// Get options needed to help find dependent libraries.
@@ -374,9 +378,9 @@ cmComputeLinkInformation
// Add the search path entries requested by the user to path ordering.
this->OrderLinkerSearchPath
- ->AddUserDirectories(this->Target->GetLinkDirectories());
+ ->AddUserDirectories(this->Target->Target->GetLinkDirectories());
this->OrderRuntimeSearchPath
- ->AddUserDirectories(this->Target->GetLinkDirectories());
+ ->AddUserDirectories(this->Target->Target->GetLinkDirectories());
// Set up the implicit link directories.
this->LoadImplicitLinkInfo();
@@ -404,12 +408,13 @@ cmComputeLinkInformation
// order to support such projects we need to add the directories
// containing libraries linked with a full path to the -L path.
this->OldLinkDirMode =
- this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
+ this->Target->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
if(this->OldLinkDirMode)
{
// Construct a mask to not bother with this behavior for link
// directories already specified by the user.
- std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
+ std::vector<std::string> const& dirs =
+ this->Target->Target->GetLinkDirectories();
this->OldLinkDirMask.insert(dirs.begin(), dirs.end());
}
@@ -515,10 +520,12 @@ bool cmComputeLinkInformation::Compute()
// Restore the target link type so the correct system runtime
// libraries are found.
- const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
- if(cmSystemTools::IsOn(lss))
+ const char* lss =
+ this->Target->Target->GetProperty("LINK_SEARCH_END_STATIC");
+ if(lss)
{
- this->SetCurrentLinkType(LinkStatic);
+ this->SetCurrentLinkType(
+ cmSystemTools::IsOn(lss) ? LinkStatic : LinkShared);
}
else
{
@@ -536,10 +543,11 @@ bool cmComputeLinkInformation::Compute()
i != wrongItems.end(); ++i)
{
cmTarget const* tgt = *i;
+ cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
bool implib =
(this->UseImportLibrary &&
(tgt->GetType() == cmTarget::SHARED_LIBRARY));
- std::string lib = tgt->GetFullPath(this->Config , implib, true);
+ std::string lib = gtgt->GetFullPath(this->Config , implib, true);
this->OldLinkDirItems.push_back(lib);
}
}
@@ -565,7 +573,7 @@ bool cmComputeLinkInformation::Compute()
"name."
;
this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->Target->GetBacktrace());
+ this->Target->Target->GetBacktrace());
}
return true;
@@ -575,7 +583,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);
+ cmGeneratorTarget::LinkClosure const* lc =
+ this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
@@ -638,6 +647,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
if(tgt && tgt->IsLinkable())
{
+ cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
// This is a CMake target. Ask the target for its real name.
if(impexe && this->LoaderFlag)
{
@@ -646,7 +656,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// platform. Add it now.
std::string linkItem;
linkItem = this->LoaderFlag;
- std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
+
+ std::string exe = gtgt->GetFullPath(config, this->UseImportLibrary,
true);
linkItem += exe;
this->Items.push_back(Item(linkItem, true, tgt));
@@ -667,7 +678,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
(impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
// Pass the full path to the target file.
- std::string lib = tgt->GetFullPath(config, implib, true);
+ std::string lib = gtgt->GetFullPath(config, implib, true);
if(!this->LinkDependsNoShared ||
tgt->GetType() != cmTarget::SHARED_LIBRARY)
{
@@ -750,13 +761,17 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
return;
}
+ cmGeneratorTarget *gtgt = 0;
+
// Get a full path to the dependent shared library.
// Add it to the runtime path computation so that the target being
// linked will be able to find it.
std::string lib;
if(tgt)
{
- lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
+ gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
+
+ lib = gtgt->GetFullPath(this->Config, this->UseImportLibrary);
this->AddLibraryRuntimeInfo(lib, tgt);
}
else
@@ -781,9 +796,9 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
}
if(order)
{
- if(tgt)
+ if(gtgt)
{
- std::string soName = tgt->GetSOName(this->Config);
+ std::string soName = gtgt->GetSOName(this->Config);
const char* soname = soName.empty()? 0 : soName.c_str();
order->AddRuntimeLibrary(lib, soname);
}
@@ -845,9 +860,11 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
}
// Lookup the starting link type from the target (linked statically?).
- const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+ const char* lss =
+ this->Target->Target->GetProperty("LINK_SEARCH_START_STATIC");
this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
- this->CurrentLinkType = this->StartLinkType;
+ this->CurrentLinkType = LinkUnknown;
+ this->SetCurrentLinkType(this->StartLinkType);
}
//----------------------------------------------------------------------------
@@ -1131,7 +1148,7 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
// Full path libraries should specify a valid library file name.
// See documentation of CMP0008.
std::string generator = this->GlobalGenerator->GetName();
- if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
+ if(this->Target->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
(generator.find("Visual Studio") != generator.npos ||
generator.find("Xcode") != generator.npos))
{
@@ -1212,7 +1229,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
}
// Check the policy for whether we should use the approach below.
- switch (this->Target->GetPolicyStatusCMP0060())
+ switch (this->Target->Target->GetPolicyStatusCMP0060())
{
case cmPolicies::WARN:
if (this->CMP0060Warn)
@@ -1395,7 +1412,8 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
// Add the item using the -framework option.
this->Items.push_back(Item("-framework", false));
- fw = this->LocalGenerator->EscapeForShell(fw);
+ cmOutputConverter converter(this->Makefile->GetStateSnapshot());
+ fw = converter.EscapeForShell(fw);
this->Items.push_back(Item(fw, false));
}
@@ -1521,7 +1539,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
this->OrderLinkerSearchPath->AddLinkLibrary(item);
// Produce any needed message.
- switch(this->Target->GetPolicyStatusCMP0008())
+ switch(this->Target->Target->GetPolicyStatusCMP0008())
{
case cmPolicies::WARN:
{
@@ -1538,7 +1556,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
<< " " << item << "\n"
<< "which is a full-path but not a valid library file name.";
this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->Target->GetBacktrace());
+ this->Target->Target->GetBacktrace());
}
}
case cmPolicies::OLD:
@@ -1556,7 +1574,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
<< " " << item << "\n"
<< "which is a full-path but not a valid library file name.";
this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
+ this->Target->Target->GetBacktrace());
}
break;
}
@@ -1573,7 +1591,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
}
// Enforce policy constraints.
- switch(this->Target->GetPolicyStatusCMP0003())
+ switch(this->Target->Target->GetPolicyStatusCMP0003())
{
case cmPolicies::WARN:
if(!this->CMakeInstance->GetState()
@@ -1584,7 +1602,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
std::ostringstream w;
this->PrintLinkPolicyDiagnosis(w);
this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
- this->Target->GetBacktrace());
+ this->Target->Target->GetBacktrace());
}
case cmPolicies::OLD:
// OLD behavior is to add the paths containing libraries with
@@ -1600,7 +1618,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0003) << "\n";
this->PrintLinkPolicyDiagnosis(e);
this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
+ this->Target->Target->GetBacktrace());
return false;
}
}
@@ -1794,7 +1812,8 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
// Try to get the soname of the library. Only files with this name
// could possibly conflict.
- std::string soName = target->GetSOName(this->Config);
+ cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
+ std::string soName = gtgt->GetSOName(this->Config);
const char* soname = soName.empty()? 0 : soName.c_str();
// Include this library in the runtime path ordering.
@@ -1901,9 +1920,9 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// build tree.
bool linking_for_install =
(for_install ||
- this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
+ this->Target->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
bool use_install_rpath =
- (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+ (outputRuntime && this->Target->Target->HaveInstallTreeRPATH() &&
linking_for_install);
bool use_build_rpath =
(outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
@@ -1911,13 +1930,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
bool use_link_rpath =
outputRuntime && linking_for_install &&
!this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
- this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+ this->Target->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
// Construct the RPATH.
std::set<std::string> emitted;
if(use_install_rpath)
{
- const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+ const char* install_rpath =
+ this->Target->Target->GetProperty("INSTALL_RPATH");
cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
}
if(use_build_rpath || use_link_rpath)
@@ -1989,7 +2009,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// Add runtime paths required by the languages to always be
// present. This is done even when skipping rpath support.
{
- cmTarget::LinkClosure const* lc =
+ cmGeneratorTarget::LinkClosure const* lc =
this->Target->GetLinkClosure(this->Config);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 8847141..8b83574 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -18,9 +18,9 @@
class cmake;
class cmGlobalGenerator;
-class cmLocalGenerator;
class cmMakefile;
class cmTarget;
+class cmGeneratorTarget;
class cmOrderDirectories;
/** \class cmComputeLinkInformation
@@ -29,7 +29,8 @@ class cmOrderDirectories;
class cmComputeLinkInformation
{
public:
- cmComputeLinkInformation(cmTarget const* target, const std::string& config);
+ cmComputeLinkInformation(cmGeneratorTarget const* target,
+ const std::string& config);
~cmComputeLinkInformation();
bool Compute();
@@ -73,16 +74,14 @@ private:
std::set<cmTarget const*> SharedLibrariesLinked;
// Context information.
- cmTarget const* Target;
+ cmGeneratorTarget const* Target;
cmMakefile* Makefile;
- cmLocalGenerator* LocalGenerator;
cmGlobalGenerator* GlobalGenerator;
cmake* CMakeInstance;
// Configuration information.
std::string Config;
std::string LinkLanguage;
- bool LinkDependsNoShared;
// Modes for dealing with dependent shared libraries.
enum SharedDepMode
@@ -93,8 +92,6 @@ private:
SharedDepModeLink // List file on link line
};
- // System info.
- bool UseImportLibrary;
const char* LoaderFlag;
std::string LibLinkFlag;
std::string LibLinkFileFlag;
@@ -102,22 +99,18 @@ private:
std::string RuntimeFlag;
std::string RuntimeSep;
std::string RuntimeAlways;
- bool RuntimeUseChrpath;
- bool NoSONameUsesPath;
- bool LinkWithRuntimePath;
std::string RPathLinkFlag;
SharedDepMode SharedDependencyMode;
+ enum LinkType { LinkUnknown, LinkStatic, LinkShared };
+ void SetCurrentLinkType(LinkType lt);
+
// Link type adjustment.
void ComputeLinkTypeInfo();
- enum LinkType { LinkUnknown, LinkStatic, LinkShared };
LinkType StartLinkType;
LinkType CurrentLinkType;
std::string StaticLinkTypeFlag;
std::string SharedLinkTypeFlag;
- bool LinkTypeEnabled;
- void SetCurrentLinkType(LinkType lt);
- bool ArchivesMayBeShared;
// Link item parsing.
void ComputeItemParserInfo();
@@ -129,7 +122,6 @@ private:
cmsys::RegularExpression ExtractSharedLibraryName;
cmsys::RegularExpression ExtractAnyLibraryName;
std::string SharedRegexString;
- bool OpenBSD;
void AddLinkPrefix(const char* p);
void AddLinkExtension(const char* e, LinkType type);
std::string CreateExtensionRegex(std::vector<std::string> const& exts,
@@ -173,20 +165,27 @@ private:
std::set<std::string> OldLinkDirMask;
std::vector<std::string> OldLinkDirItems;
std::vector<std::string> OldUserFlagItems;
- bool OldLinkDirMode;
-
- // CMP0060 warnings.
- bool CMP0060Warn;
std::set<std::string> CMP0060WarnItems;
-
+ // Dependent library path computation.
+ cmOrderDirectories* OrderDependentRPath;
// Runtime path computation.
cmOrderDirectories* OrderRuntimeSearchPath;
+
+ bool OldLinkDirMode;
+ bool OpenBSD;
+ bool LinkDependsNoShared;
+ bool UseImportLibrary;
+ bool RuntimeUseChrpath;
+ bool NoSONameUsesPath;
+ bool LinkWithRuntimePath;
+ bool LinkTypeEnabled;
+ bool ArchivesMayBeShared;
+ bool CMP0060Warn;
+
void AddLibraryRuntimeInfo(std::string const& fullPath,
cmTarget const* target);
void AddLibraryRuntimeInfo(std::string const& fullPath);
- // Dependent library path computation.
- cmOrderDirectories* OrderDependentRPath;
};
#endif
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 87b47b4..9e37c35 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -147,12 +147,12 @@ bool cmComputeTargetDepends::Compute()
//----------------------------------------------------------------------------
void
-cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t,
+cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
cmTargetDependSet& deps)
{
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmTarget const*, int>::const_iterator tii
+ std::map<cmGeneratorTarget const*, int>::const_iterator tii
= this->TargetIndex.find(t);
assert(tii != this->TargetIndex.end());
int i = tii->second;
@@ -161,7 +161,7 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget const* t,
EdgeList const& nl = this->FinalGraph[i];
for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
- cmTarget const* dep = this->Targets[*ni];
+ cmGeneratorTarget const* dep = this->Targets[*ni];
cmTargetDependSet::iterator di = deps.insert(dep).first;
di->SetType(ni->IsStrong());
}
@@ -180,9 +180,11 @@ void cmComputeTargetDepends::CollectTargets()
ti != targets.end(); ++ti)
{
cmTarget const* target = &ti->second;
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(target);
int index = static_cast<int>(this->Targets.size());
- this->TargetIndex[target] = index;
- this->Targets.push_back(target);
+ this->TargetIndex[gt] = index;
+ this->Targets.push_back(gt);
}
}
}
@@ -204,7 +206,7 @@ void cmComputeTargetDepends::CollectDepends()
void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
{
// Get the depender.
- cmTarget const* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
if (depender->GetType() == cmTarget::INTERFACE_LIBRARY)
{
return;
@@ -216,10 +218,9 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// deal with config-specific dependencies.
{
std::set<std::string> emitted;
- cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(depender);
std::vector<std::string> configs;
- depender->GetMakefile()->GetConfigurations(configs);
+ depender->Makefile->GetConfigurations(configs);
if (configs.empty())
{
configs.push_back("");
@@ -228,7 +229,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
it != configs.end(); ++it)
{
std::vector<cmSourceFile const*> objectFiles;
- gt->GetExternalObjects(objectFiles, *it);
+ depender->GetExternalObjects(objectFiles, *it);
for(std::vector<cmSourceFile const*>::const_iterator
oi = objectFiles.begin(); oi != objectFiles.end(); ++oi)
{
@@ -244,15 +245,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
->IssueMessage(cmake::FATAL_ERROR,
"Only executables and non-OBJECT libraries may "
"reference target objects.",
- depender->GetBacktrace());
+ depender->Target->GetBacktrace());
return;
}
- const_cast<cmTarget*>(depender)->AddUtility(objLib);
+ const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib);
}
}
- cmTarget::LinkImplementation const* impl =
- depender->GetLinkImplementation(*it);
+ cmLinkImplementation const* impl = depender->GetLinkImplementation(*it);
// A target should not depend on itself.
emitted.insert(depender->GetName());
@@ -272,7 +272,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Loop over all utility dependencies.
{
- std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
+ std::set<cmLinkItem> const& tutils = depender->Target->GetUtilityItems();
std::set<std::string> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
@@ -290,13 +290,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
- cmTarget const* dependee,
- const std::string& config,
- std::set<std::string> &emitted)
+ const cmGeneratorTarget* dependee,
+ const std::string& config,
+ std::set<std::string> &emitted)
{
- cmTarget const* depender = this->Targets[depender_index];
- if(cmTarget::LinkInterface const* iface =
- dependee->GetLinkInterface(config, depender))
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
+ if(cmLinkInterface const* iface =
+ dependee->GetLinkInterface(config,
+ depender->Target))
{
for(std::vector<cmLinkItem>::const_iterator
lib = iface->Libraries.begin();
@@ -317,7 +318,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
cmLinkItem const& dependee_name,
std::set<std::string> &emitted)
{
- cmTarget const* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
cmTarget const* dependee = dependee_name.Target;
// Skip targets that will not really be linked. This is probably a
// name conflict between an external library and an executable
@@ -331,16 +332,17 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
if(dependee)
{
- this->AddInterfaceDepends(depender_index, dependee, "", emitted);
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(dependee);
+ this->AddInterfaceDepends(depender_index, gt, "", emitted);
std::vector<std::string> configs;
- depender->GetMakefile()->GetConfigurations(configs);
+ depender->Makefile->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, emitted);
+ this->AddInterfaceDepends(depender_index, gt, *it, emitted);
}
}
}
@@ -351,7 +353,7 @@ void cmComputeTargetDepends::AddTargetDepend(
bool linking)
{
// Get the depender.
- cmTarget const* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
// Check the target's makefile first.
cmTarget const* dependee = dependee_name.Target;
@@ -362,7 +364,7 @@ void cmComputeTargetDepends::AddTargetDepend(
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
bool issueMessage = false;
std::ostringstream e;
- switch(depender->GetPolicyStatusCMP0046())
+ switch(depender->Target->GetPolicyStatusCMP0046())
{
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0046) << "\n";
@@ -383,7 +385,7 @@ void cmComputeTargetDepends::AddTargetDepend(
<< "\" of target \"" << depender->GetName() << "\" does not exist.";
cmListFileBacktrace const* backtrace =
- depender->GetUtilityBacktrace(dependee_name);
+ depender->Target->GetUtilityBacktrace(dependee_name);
if(backtrace)
{
cm->IssueMessage(messageType, e.str(), *backtrace);
@@ -408,27 +410,31 @@ void cmComputeTargetDepends::AddTargetDepend(
if(dependee)
{
- this->AddTargetDepend(depender_index, dependee, linking);
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(dependee);
+ this->AddTargetDepend(depender_index, gt, linking);
}
}
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
- cmTarget const* dependee,
+ const cmGeneratorTarget* dependee,
bool linking)
{
- if(dependee->IsImported() ||
+ if(dependee->Target->IsImported() ||
dependee->GetType() == cmTarget::INTERFACE_LIBRARY)
{
// Skip IMPORTED and INTERFACE targets but follow their utility
// dependencies.
- std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
+ std::set<cmLinkItem> const& utils = dependee->Target->GetUtilityItems();
for(std::set<cmLinkItem>::const_iterator i = utils.begin();
i != utils.end(); ++i)
{
if(cmTarget const* transitive_dependee = i->Target)
{
- this->AddTargetDepend(depender_index, transitive_dependee, false);
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(transitive_dependee);
+ this->AddTargetDepend(depender_index, gt, false);
}
}
}
@@ -436,7 +442,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
{
// Lookup the index for this target. All targets should be known by
// this point.
- std::map<cmTarget const*, int>::const_iterator tii =
+ std::map<cmGeneratorTarget const*, int>::const_iterator tii =
this->TargetIndex.find(dependee);
assert(tii != this->TargetIndex.end());
int dependee_index = tii->second;
@@ -457,13 +463,13 @@ cmComputeTargetDepends::DisplayGraph(Graph const& graph,
for(int depender_index = 0; depender_index < n; ++depender_index)
{
EdgeList const& nl = graph[depender_index];
- cmTarget const* depender = this->Targets[depender_index];
+ cmGeneratorTarget const* depender = this->Targets[depender_index];
fprintf(stderr, "target %d is [%s]\n",
depender_index, depender->GetName().c_str());
for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{
int dependee_index = *ni;
- cmTarget const* dependee = this->Targets[dependee_index];
+ cmGeneratorTarget const* dependee = this->Targets[dependee_index];
fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index,
dependee->GetName().c_str(), ni->IsStrong()? "strong" : "weak");
}
@@ -550,11 +556,11 @@ cmComputeTargetDepends
{
// Get the depender.
int i = *ci;
- cmTarget const* depender = this->Targets[i];
+ cmGeneratorTarget const* depender = this->Targets[i];
// Describe the depender.
e << " \"" << depender->GetName() << "\" of type "
- << cmTarget::GetTargetTypeName(depender->GetType()) << "\n";
+ << cmTarget::GetTargetTypeName(depender->Target->GetType()) << "\n";
// List its dependencies that are inside the component.
EdgeList const& nl = this->InitialGraph[i];
@@ -563,7 +569,7 @@ cmComputeTargetDepends
int j = *ni;
if(cmap[j] == c)
{
- cmTarget const* dependee = this->Targets[j];
+ cmGeneratorTarget const* dependee = this->Targets[j];
e << " depends on \"" << dependee->GetName() << "\""
<< " (" << (ni->IsStrong()? "strong" : "weak") << ")\n";
}
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 902f342..6100d97 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -21,7 +21,7 @@
class cmComputeComponentGraph;
class cmGlobalGenerator;
class cmLinkItem;
-class cmTarget;
+class cmGeneratorTarget;
class cmTargetDependSet;
/** \class cmComputeTargetDepends
@@ -39,9 +39,10 @@ public:
bool Compute();
- std::vector<cmTarget const*> const&
+ std::vector<cmGeneratorTarget const*> const&
GetTargets() const { return this->Targets; }
- void GetTargetDirectDepends(cmTarget const* t, cmTargetDependSet& deps);
+ void GetTargetDirectDepends(cmGeneratorTarget const* t,
+ cmTargetDependSet& deps);
private:
void CollectTargets();
void CollectDepends();
@@ -49,13 +50,14 @@ private:
void AddTargetDepend(int depender_index,
cmLinkItem const& dependee_name,
bool linking);
- void AddTargetDepend(int depender_index, cmTarget const* dependee,
+ void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
bool linking);
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
void AddInterfaceDepends(int depender_index,
cmLinkItem const& dependee_name,
std::set<std::string> &emitted);
- void AddInterfaceDepends(int depender_index, cmTarget const* dependee,
+ void AddInterfaceDepends(int depender_index,
+ cmGeneratorTarget const* dependee,
const std::string& config,
std::set<std::string> &emitted);
cmGlobalGenerator* GlobalGenerator;
@@ -63,8 +65,8 @@ private:
bool NoCycles;
// Collect all targets.
- std::vector<cmTarget const*> Targets;
- std::map<cmTarget const*, int> TargetIndex;
+ std::vector<cmGeneratorTarget const*> Targets;
+ std::map<cmGeneratorTarget const*, int> TargetIndex;
// Represent the target dependency graph. The entry at each
// top-level index corresponds to a depender whose dependencies are
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 61847d4..7874803 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -16,7 +16,8 @@ cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile):
Makefile(makefile),
Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054)),
- Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057))
+ Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057)),
+ Policy64Status(makefile.GetPolicyStatus(cmPolicies::CMP0064))
{
}
@@ -299,11 +300,11 @@ void cmConditionEvaluator::IncrementArguments(cmArgumentList &newArgs,
cmArgumentList::iterator &argP1,
cmArgumentList::iterator &argP2) const
{
- if (argP1 != newArgs.end())
+ if (argP1 != newArgs.end())
{
argP1++;
argP2 = argP1;
- if (argP1 != newArgs.end())
+ if (argP1 != newArgs.end())
{
argP2++;
}
@@ -442,35 +443,35 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
argP1 = arg;
this->IncrementArguments(newArgs,argP1,argP2);
// does a file exist
- if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
{
this->HandlePredicate(
cmSystemTools::FileExists(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a directory with this name exist
- if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
{
this->HandlePredicate(
cmSystemTools::FileIsDirectory(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a symlink with this name exist
- if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
{
this->HandlePredicate(
cmSystemTools::FileIsSymlink(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// is the given path an absolute path ?
- if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
{
this->HandlePredicate(
cmSystemTools::FileIsFullPath(argP1->c_str()),
reducible, arg, newArgs, argP1, argP2);
}
// does a command exist
- if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
{
cmCommand* command =
this->Makefile.GetState()->GetCommand(argP1->c_str());
@@ -493,8 +494,31 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
this->Makefile.FindTargetToUse(argP1->GetValue())?true:false,
reducible, arg, newArgs, argP1, argP2);
}
+ // does a test exist
+ if(this->Policy64Status != cmPolicies::OLD &&
+ this->Policy64Status != cmPolicies::WARN)
+ {
+ if (this->IsKeyword("TEST", *arg) && argP1 != newArgs.end())
+ {
+ const cmTest* haveTest = this->Makefile.GetTest(argP1->c_str());
+ this->HandlePredicate(
+ haveTest?true:false,
+ reducible, arg, newArgs, argP1, argP2);
+ }
+ }
+ else if(this->Policy64Status == cmPolicies::WARN &&
+ this->IsKeyword("TEST", *arg))
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n";
+ e << "TEST will be interpreted as an operator "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
// is a variable defined
- if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
+ if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
{
size_t argP1len = argP1->GetValue().size();
bool bdef = false;
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
index c923d76..c4e2d11 100644
--- a/Source/cmConditionEvaluator.h
+++ b/Source/cmConditionEvaluator.h
@@ -94,6 +94,7 @@ private:
cmPolicies::PolicyStatus Policy12Status;
cmPolicies::PolicyStatus Policy54Status;
cmPolicies::PolicyStatus Policy57Status;
+ cmPolicies::PolicyStatus Policy64Status;
};
#endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index dd276a8..9411555 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -11,7 +11,7 @@
============================================================================*/
#include "cmCoreTryCompile.h"
#include "cmake.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmGlobalGenerator.h"
#include "cmAlgorithms.h"
#include "cmExportTryCompileFileGenerator.h"
@@ -322,7 +322,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
std::string langFlags = "CMAKE_" + *li + "_FLAGS";
const char* flags = this->Makefile->GetDefinition(langFlags);
fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li->c_str(),
- cmLocalGenerator::EscapeForCMake(flags?flags:"").c_str());
+ cmOutputConverter::EscapeForCMake(flags?flags:"").c_str());
fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
" ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str());
}
@@ -355,7 +355,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
const char* exeLinkFlags =
this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n",
- cmLocalGenerator::EscapeForCMake(
+ cmOutputConverter::EscapeForCMake(
exeLinkFlags ? exeLinkFlags : "").c_str());
} break;
}
@@ -379,7 +379,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
if (!targets.empty())
{
std::string fname = "/" + std::string(targetName) + "Targets.cmake";
- cmExportTryCompileFileGenerator tcfg;
+ cmExportTryCompileFileGenerator tcfg(gg);
tcfg.SetExportFile((this->BinaryDirectory + fname).c_str());
tcfg.SetExports(targets);
tcfg.SetConfig(this->Makefile->GetSafeDefinition(
@@ -470,6 +470,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{
fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
}
+ if (const char *lssDef = this->Makefile->GetDefinition(
+ "CMAKE_LINK_SEARCH_START_STATIC"))
+ {
+ fprintf(fout, "set(CMAKE_LINK_SEARCH_START_STATIC \"%s\")\n", lssDef);
+ }
+ if (const char *lssDef = this->Makefile->GetDefinition(
+ "CMAKE_LINK_SEARCH_END_STATIC"))
+ {
+ fprintf(fout, "set(CMAKE_LINK_SEARCH_END_STATIC \"%s\")\n", lssDef);
+ }
/* Put the executable at a known location (for COPY_FILE). */
fprintf(fout, "set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index 74e17b6..6616218 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -46,7 +46,7 @@ std::string cmCryptoHash::HashString(const std::string& input)
//----------------------------------------------------------------------------
std::string cmCryptoHash::HashFile(const std::string& file)
{
- cmsys::ifstream fin(file.c_str(), std::ios::in | cmsys_ios_binary);
+ cmsys::ifstream fin(file.c_str(), std::ios::in | std::ios::binary);
if(!fin)
{
return "";
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
index 96d3547..ad0c7d3 100644
--- a/Source/cmCurl.cxx
+++ b/Source/cmCurl.cxx
@@ -13,7 +13,7 @@
#include "cmSystemTools.h"
#define check_curl_result(result, errstr) \
- if (result != CURLE_OK) \
+ if (result != CURLE_OK && result != CURLE_NOT_BUILT_IN) \
{ \
e += e.empty()? "" : "\n"; \
e += errstr; \
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 015825d..7c37e3b 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -17,7 +17,7 @@
//----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand()
- : Backtrace(NULL)
+ : Backtrace()
{
this->HaveComment = false;
this->EscapeOldStyle = true;
@@ -26,46 +26,6 @@ cmCustomCommand::cmCustomCommand()
}
//----------------------------------------------------------------------------
-cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
- Outputs(r.Outputs),
- Byproducts(r.Byproducts),
- Depends(r.Depends),
- CommandLines(r.CommandLines),
- HaveComment(r.HaveComment),
- Comment(r.Comment),
- WorkingDirectory(r.WorkingDirectory),
- EscapeAllowMakeVars(r.EscapeAllowMakeVars),
- EscapeOldStyle(r.EscapeOldStyle),
- Backtrace(r.Backtrace),
- UsesTerminal(r.UsesTerminal)
-{
-}
-
-//----------------------------------------------------------------------------
-cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r)
-{
- if(this == &r)
- {
- return *this;
- }
-
- this->Outputs = r.Outputs;
- this->Byproducts= r.Byproducts;
- this->Depends = r.Depends;
- this->CommandLines = r.CommandLines;
- this->HaveComment = r.HaveComment;
- this->Comment = r.Comment;
- this->WorkingDirectory = r.WorkingDirectory;
- this->EscapeAllowMakeVars = r.EscapeAllowMakeVars;
- this->EscapeOldStyle = r.EscapeOldStyle;
- this->ImplicitDepends = r.ImplicitDepends;
- this->Backtrace = r.Backtrace;
- this->UsesTerminal = r.UsesTerminal;
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
@@ -77,15 +37,13 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
Byproducts(byproducts),
Depends(depends),
CommandLines(commandLines),
- HaveComment(comment?true:false),
+ Backtrace(),
Comment(comment?comment:""),
WorkingDirectory(workingDirectory?workingDirectory:""),
+ HaveComment(comment?true:false),
EscapeAllowMakeVars(false),
- EscapeOldStyle(true),
- Backtrace(NULL)
+ EscapeOldStyle(true)
{
- this->EscapeOldStyle = true;
- this->EscapeAllowMakeVars = false;
if(mf)
{
this->Backtrace = mf->GetBacktrace();
@@ -93,11 +51,6 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
}
//----------------------------------------------------------------------------
-cmCustomCommand::~cmCustomCommand()
-{
-}
-
-//----------------------------------------------------------------------------
const std::vector<std::string>& cmCustomCommand::GetOutputs() const
{
return this->Outputs;
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 0bfaef2..f9b38c3 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -26,8 +26,6 @@ class cmCustomCommand
public:
/** Default and copy constructors for STL containers. */
cmCustomCommand();
- cmCustomCommand(const cmCustomCommand& r);
- cmCustomCommand& operator=(cmCustomCommand const& r);
/** Main constructor specifies all information for the command. */
cmCustomCommand(cmMakefile const* mf,
@@ -38,8 +36,6 @@ public:
const char* comment,
const char* workingDirectory);
- ~cmCustomCommand();
-
/** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const;
@@ -93,13 +89,13 @@ private:
std::vector<std::string> Byproducts;
std::vector<std::string> Depends;
cmCustomCommandLines CommandLines;
- bool HaveComment;
+ cmListFileBacktrace Backtrace;
+ ImplicitDependsList ImplicitDepends;
std::string Comment;
std::string WorkingDirectory;
+ bool HaveComment;
bool EscapeAllowMakeVars;
bool EscapeOldStyle;
- cmListFileBacktrace Backtrace;
- ImplicitDependsList ImplicitDepends;
bool UsesTerminal;
};
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index d23f815..7f3b651 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -12,16 +12,17 @@
#include "cmCustomCommandGenerator.h"
#include "cmMakefile.h"
-#include "cmCustomCommand.h"
#include "cmLocalGenerator.h"
+#include "cmCustomCommand.h"
+#include "cmOutputConverter.h"
#include "cmGeneratorExpression.h"
//----------------------------------------------------------------------------
cmCustomCommandGenerator::cmCustomCommandGenerator(
- cmCustomCommand const& cc, const std::string& config, cmMakefile* mf):
- CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
+ cmCustomCommand const& cc, const std::string& config, cmLocalGenerator* lg):
+ CC(cc), Config(config), LG(lg),
OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
- GE(new cmGeneratorExpression(&cc.GetBacktrace())), DependsDone(false)
+ GE(new cmGeneratorExpression(cc.GetBacktrace())), DependsDone(false)
{
}
@@ -41,13 +42,16 @@ unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
std::string const& argv0 = this->CC.GetCommandLines()[c][0];
- cmTarget* target = this->Makefile->FindTargetToUse(argv0);
+ cmGeneratorTarget* target =
+ this->LG->GetMakefile()->FindGeneratorTargetToUse(argv0);
if(target && target->GetType() == cmTarget::EXECUTABLE &&
- (target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING")))
+ (target->Target->IsImported()
+ || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")))
{
return target->GetLocation(this->Config);
}
- return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
+ return this->GE->Parse(argv0)->Evaluate(this->LG->GetMakefile(),
+ this->Config);
}
//----------------------------------------------------------------------------
@@ -87,8 +91,9 @@ 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,
- this->Config);
+ std::string arg =
+ this->GE->Parse(commandLine[j])->Evaluate(this->LG->GetMakefile(),
+ this->Config);
cmd += " ";
if(this->OldStyle)
{
@@ -96,7 +101,8 @@ cmCustomCommandGenerator
}
else
{
- cmd += this->LG->EscapeForShell(arg, this->MakeVars);
+ cmOutputConverter converter(this->LG->GetMakefile()->GetStateSnapshot());
+ cmd += converter.EscapeForShell(arg, this->MakeVars);
}
}
}
@@ -140,7 +146,7 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
= this->GE->Parse(*i);
std::vector<std::string> result;
cmSystemTools::ExpandListArgument(
- cge->Evaluate(this->Makefile, this->Config), result);
+ cge->Evaluate(this->LG->GetMakefile(), this->Config), result);
for (std::vector<std::string>::iterator it = result.begin();
it != result.end(); ++it)
{
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index b4ae014..a637fed 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -15,7 +15,6 @@
#include "cmStandardIncludes.h"
class cmCustomCommand;
-class cmMakefile;
class cmLocalGenerator;
class cmGeneratorExpression;
@@ -23,7 +22,6 @@ class cmCustomCommandGenerator
{
cmCustomCommand const& CC;
std::string Config;
- cmMakefile* Makefile;
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
@@ -33,7 +31,7 @@ class cmCustomCommandGenerator
public:
cmCustomCommandGenerator(cmCustomCommand const& cc,
const std::string& config,
- cmMakefile* mf);
+ cmLocalGenerator* lg);
~cmCustomCommandGenerator();
cmCustomCommand const& GetCC() const { return this->CC; }
unsigned int GetNumberOfCommands() const;
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 2dab169..b06fb5c 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -56,9 +56,9 @@ void cmDefinitions::Raise(const std::string& key,
}
bool cmDefinitions::HasKey(const std::string& key,
- StackConstIter begin, StackConstIter end)
+ StackIter begin, StackIter end)
{
- for (StackConstIter it = begin; it != end; ++it)
+ for (StackIter it = begin; it != end; ++it)
{
MapType::const_iterator i = it->Map.find(key);
if (i != it->Map.end())
@@ -94,12 +94,12 @@ std::vector<std::string> cmDefinitions::UnusedKeys() const
}
//----------------------------------------------------------------------------
-cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin,
- StackConstIter end)
+cmDefinitions cmDefinitions::MakeClosure(StackIter begin,
+ StackIter end)
{
cmDefinitions closure;
std::set<std::string> undefined;
- for (StackConstIter it = begin; it != end; ++it)
+ for (StackIter it = begin; it != end; ++it)
{
// Consider local definitions.
for(MapType::const_iterator mi = it->Map.begin();
@@ -125,12 +125,12 @@ cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin,
//----------------------------------------------------------------------------
std::vector<std::string>
-cmDefinitions::ClosureKeys(StackConstIter begin, StackConstIter end)
+cmDefinitions::ClosureKeys(StackIter begin, StackIter end)
{
std::set<std::string> bound;
std::vector<std::string> defined;
- for (StackConstIter it = begin; it != end; ++it)
+ for (StackIter it = begin; it != end; ++it)
{
defined.reserve(defined.size() + it->Map.size());
for(MapType::const_iterator mi = it->Map.begin();
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 5fdcaab..411867c 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -13,6 +13,9 @@
#define cmDefinitions_h
#include "cmStandardIncludes.h"
+
+#include "cmLinkedTree.h"
+
#if defined(CMAKE_BUILD_WITH_CMAKE)
#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
#include <unordered_map>
@@ -32,26 +35,26 @@
*/
class cmDefinitions
{
- typedef std::list<cmDefinitions>::reverse_iterator StackIter;
- typedef std::list<cmDefinitions>::const_reverse_iterator StackConstIter;
+ typedef cmLinkedTree<cmDefinitions>::iterator StackIter;
public:
static const char* Get(const std::string& key,
StackIter begin, StackIter end);
- static void Raise(const std::string& key, StackIter begin, StackIter end);
+ static void Raise(const std::string& key,
+ StackIter begin, StackIter end);
static bool HasKey(const std::string& key,
- StackConstIter begin, StackConstIter end);
+ StackIter begin, StackIter end);
/** Set (or unset if null) a value associated with a key. */
void Set(const std::string& key, const char* value);
std::vector<std::string> UnusedKeys() const;
- static std::vector<std::string> ClosureKeys(StackConstIter begin,
- StackConstIter end);
+ static std::vector<std::string> ClosureKeys(StackIter begin,
+ StackIter end);
- static cmDefinitions MakeClosure(StackConstIter begin, StackConstIter end);
+ static cmDefinitions MakeClosure(StackIter begin, StackIter end);
private:
// String with existence boolean.
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 1b2586c..856dcd4 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -16,84 +16,15 @@
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
+#include "cmFortranParser.h" /* Interface to parser object. */
#include <cmsys/FStream.hxx>
#include <assert.h>
-#include <stack>
// TODO: Test compiler for the case of the mod file. Some always
// use lower case and some always use upper case. I do not know if any
// use the case from the source code.
//----------------------------------------------------------------------------
-// Information about a single source file.
-class cmDependsFortranSourceInfo
-{
-public:
- // The name of the source file.
- std::string Source;
-
- // Set of provided and required modules.
- std::set<std::string> Provides;
- std::set<std::string> Requires;
-
- // Set of files included in the translation unit.
- std::set<std::string> Includes;
-};
-
-//----------------------------------------------------------------------------
-// Parser methods not included in generated interface.
-
-// Get the current buffer processed by the lexer.
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
-
-// The parser entry point.
-int cmDependsFortran_yyparse(yyscan_t);
-
-//----------------------------------------------------------------------------
-// Define parser object internal structure.
-struct cmDependsFortranFile
-{
- cmDependsFortranFile(FILE* file, YY_BUFFER_STATE buffer,
- const std::string& dir):
- File(file), Buffer(buffer), Directory(dir) {}
- FILE* File;
- YY_BUFFER_STATE Buffer;
- std::string Directory;
-};
-
-struct cmDependsFortranParser_s
-{
- cmDependsFortranParser_s(cmDependsFortran* self,
- std::set<std::string>& ppDefines,
- cmDependsFortranSourceInfo& info);
- ~cmDependsFortranParser_s();
-
- // Pointer back to the main class.
- cmDependsFortran* Self;
-
- // Lexical scanner instance.
- yyscan_t Scanner;
-
- // Stack of open files in the translation unit.
- std::stack<cmDependsFortranFile> FileStack;
-
- // Buffer for string literals.
- std::string TokenString;
-
- // Flag for whether lexer is reading from inside an interface.
- bool InInterface;
-
- int OldStartcond;
- std::set<std::string> PPDefinitions;
- size_t InPPFalseBranch;
- std::stack<bool> SkipToEnd;
-
- // Information about the parsed source.
- cmDependsFortranSourceInfo& Info;
-};
-
-//----------------------------------------------------------------------------
class cmDependsFortranInternals
{
public:
@@ -105,18 +36,18 @@ public:
TargetRequiresMap TargetRequires;
// Information about each object file.
- typedef std::map<std::string, cmDependsFortranSourceInfo> ObjectInfoMap;
+ typedef std::map<std::string, cmFortranSourceInfo> ObjectInfoMap;
ObjectInfoMap ObjectInfo;
- cmDependsFortranSourceInfo& CreateObjectInfo(const char* obj,
+ cmFortranSourceInfo& CreateObjectInfo(const char* obj,
const char* src)
{
- std::map<std::string, cmDependsFortranSourceInfo>::iterator i =
+ std::map<std::string, cmFortranSourceInfo>::iterator i =
this->ObjectInfo.find(obj);
if(i == this->ObjectInfo.end())
{
- std::map<std::string, cmDependsFortranSourceInfo>::value_type
- entry(obj, cmDependsFortranSourceInfo());
+ std::map<std::string, cmFortranSourceInfo>::value_type
+ entry(obj, cmFortranSourceInfo());
i = this->ObjectInfo.insert(entry).first;
i->second.Source = src;
}
@@ -126,7 +57,7 @@ public:
//----------------------------------------------------------------------------
cmDependsFortran::cmDependsFortran():
- PPDefinitions(0), Internal(0)
+ Internal(0)
{
}
@@ -159,7 +90,7 @@ cmDependsFortran
{
def = it->substr(0, assignment);
}
- this->PPDefinitions.push_back(def);
+ this->PPDefinitions.insert(def);
}
}
@@ -192,22 +123,18 @@ bool cmDependsFortran::WriteDependencies(
{
const std::string& src = *it;
// Get the information object for this source.
- cmDependsFortranSourceInfo& info =
+ cmFortranSourceInfo& 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());
-
- // 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 info by reference,
+ // so we may look into the resulting objects later.
+ cmFortranParser parser(this->IncludePath, this->PPDefinitions, info);
// Push on the starting file.
- cmDependsFortranParser_FilePush(&parser, src.c_str());
+ cmFortranParser_FilePush(&parser, src.c_str());
// Parse the translation unit.
- if(cmDependsFortran_yyparse(parser.Scanner) != 0)
+ if(cmFortran_yyparse(parser.Scanner) != 0)
{
// Failed to parse the file. Report failure to write dependencies.
okay = false;
@@ -227,14 +154,10 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
const char* stamp_dir = this->TargetDirectory.c_str();
// Get the directory in which module files will be created.
- const char* mod_dir;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- if(const char* target_mod_dir =
- mf->GetDefinition("CMAKE_Fortran_TARGET_MODULE_DIR"))
- {
- mod_dir = target_mod_dir;
- }
- else
+ std::string mod_dir =
+ mf->GetSafeDefinition("CMAKE_Fortran_TARGET_MODULE_DIR");
+ if (mod_dir.empty())
{
mod_dir =
this->LocalGenerator->GetMakefile()->GetCurrentBinaryDirectory();
@@ -318,7 +241,7 @@ void cmDependsFortran::LocateModules()
for(ObjectInfoMap::const_iterator infoI = objInfo.begin();
infoI != objInfo.end(); ++infoI)
{
- cmDependsFortranSourceInfo const& info = infoI->second;
+ cmFortranSourceInfo const& info = infoI->second;
// Include this module in the set provided by this target.
this->Internal->TargetProvides.insert(info.Provides.begin(),
info.Provides.end());
@@ -428,8 +351,9 @@ void cmDependsFortran::ConsiderModule(const char* name,
bool
cmDependsFortran
::WriteDependenciesReal(const char *obj,
- cmDependsFortranSourceInfo const& info,
- const char* mod_dir, const char* stamp_dir,
+ cmFortranSourceInfo const& info,
+ std::string const& mod_dir,
+ const char* stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends)
{
@@ -701,7 +625,7 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
// is later used for longer sequences it should be re-written using an
// efficient string search algorithm such as Boyer-Moore.
static
-bool cmDependsFortranStreamContainsSequence(std::istream& ifs,
+bool cmFortranStreamContainsSequence(std::istream& ifs,
const char* seq, int len)
{
assert(len > 0);
@@ -734,7 +658,7 @@ bool cmDependsFortranStreamContainsSequence(std::istream& ifs,
//----------------------------------------------------------------------------
// Helper function to compare the remaining content in two streams.
-static bool cmDependsFortranStreamsDiffer(std::istream& ifs1,
+static bool cmFortranStreamsDiffer(std::istream& ifs1,
std::istream& ifs2)
{
// Compare the remaining content.
@@ -837,7 +761,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char seq[1] = {'\n'};
const int seqlen = 1;
- if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
{
// The module is of unexpected format. Assume it is different.
std::cerr << compilerId << " fortran module " << modFile
@@ -845,7 +769,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
return true;
}
- if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
{
// The stamp must differ if the sequence is not contained.
return true;
@@ -857,7 +781,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
const char seq[2] = {'\n', '\0'};
const int seqlen = 2;
- if(!cmDependsFortranStreamContainsSequence(finModFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finModFile, seq, seqlen))
{
// The module is of unexpected format. Assume it is different.
std::cerr << compilerId << " fortran module " << modFile
@@ -865,7 +789,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
return true;
}
- if(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ if(!cmFortranStreamContainsSequence(finStampFile, seq, seqlen))
{
// The stamp must differ if the sequence is not contained.
return true;
@@ -875,7 +799,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
// Compare the remaining content. If no compiler id matched above,
// including the case none was given, this will compare the whole
// content.
- if(!cmDependsFortranStreamsDiffer(finModFile, finStampFile))
+ if(!cmFortranStreamsDiffer(finModFile, finStampFile))
{
return false;
}
@@ -883,396 +807,3 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
// The modules are different.
return true;
}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortran::FindIncludeFile(const char* dir,
- const char* includeName,
- std::string& fileName)
-{
- // If the file is a full path, include it directly.
- if(cmSystemTools::FileIsFullPath(includeName))
- {
- fileName = includeName;
- return cmSystemTools::FileExists(fileName.c_str(), true);
- }
- else
- {
- // Check for the file in the directory containing the including
- // file.
- std::string fullName = dir;
- fullName += "/";
- fullName += includeName;
- if(cmSystemTools::FileExists(fullName.c_str(), true))
- {
- fileName = fullName;
- return true;
- }
-
- // Search the include path for the file.
- for(std::vector<std::string>::const_iterator i =
- this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
- {
- fullName = *i;
- fullName += "/";
- fullName += includeName;
- if(cmSystemTools::FileExists(fullName.c_str(), true))
- {
- fileName = fullName;
- return true;
- }
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s
-::cmDependsFortranParser_s(cmDependsFortran* self,
- std::set<std::string>& ppDefines,
- cmDependsFortranSourceInfo& info):
- Self(self), PPDefinitions(ppDefines), Info(info)
-{
- this->InInterface = 0;
- this->InPPFalseBranch = 0;
-
- // Initialize the lexical scanner.
- cmDependsFortran_yylex_init(&this->Scanner);
- cmDependsFortran_yyset_extra(this, this->Scanner);
-
- // Create a dummy buffer that is never read but is the fallback
- // buffer when the last file is popped off the stack.
- YY_BUFFER_STATE buffer =
- cmDependsFortran_yy_create_buffer(0, 4, this->Scanner);
- cmDependsFortran_yy_switch_to_buffer(buffer, this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-cmDependsFortranParser_s::~cmDependsFortranParser_s()
-{
- cmDependsFortran_yylex_destroy(this->Scanner);
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
- const char* fname)
-{
- // Open the new file and push it onto the stack. Save the old
- // buffer with it on the stack.
- if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb"))
- {
- YY_BUFFER_STATE current =
- cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
- std::string dir = cmSystemTools::GetParentDirectory(fname);
- cmDependsFortranFile f(file, current, dir);
- YY_BUFFER_STATE buffer =
- cmDependsFortran_yy_create_buffer(0, 16384, parser->Scanner);
- cmDependsFortran_yy_switch_to_buffer(buffer, parser->Scanner);
- parser->FileStack.push(f);
- return 1;
- }
- else
- {
- return 0;
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser)
-{
- // Pop one file off the stack and close it. Switch the lexer back
- // to the next one on the stack.
- if(parser->FileStack.empty())
- {
- return 0;
- }
- else
- {
- cmDependsFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
- fclose(f.File);
- YY_BUFFER_STATE current =
- cmDependsFortranLexer_GetCurrentBuffer(parser->Scanner);
- cmDependsFortran_yy_delete_buffer(current, parser->Scanner);
- cmDependsFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
- return 1;
- }
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
- char* buffer, size_t bufferSize)
-{
- // Read from the file on top of the stack. If the stack is empty,
- // the end of the translation unit has been reached.
- if(!parser->FileStack.empty())
- {
- FILE* file = parser->FileStack.top().File;
- return (int)fread(buffer, 1, bufferSize, file);
- }
- return 0;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser)
-{
- parser->TokenString = "";
-}
-
-//----------------------------------------------------------------------------
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser)
-{
- return parser->TokenString.c_str();
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
- char c)
-{
- parser->TokenString += c;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
- bool in)
-{
- if(parser->InPPFalseBranch)
- {
- return;
- }
-
- parser->InInterface = in;
-}
-
-//----------------------------------------------------------------------------
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser)
-{
- return parser->InInterface;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
- int arg)
-{
- parser->OldStartcond = arg;
-}
-
-//----------------------------------------------------------------------------
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser)
-{
- return parser->OldStartcond;
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_Error(cmDependsFortranParser*, const char*)
-{
- // If there is a parser error just ignore it. The source will not
- // compile and the user will edit it. Then dependencies will have
- // to be regenerated anyway.
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
- const char* name)
-{
- if(!parser->InPPFalseBranch)
- {
- parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
- const char* name)
-{
- if(parser->InPPFalseBranch)
- {
- return;
- }
-
- // If processing an include statement there must be an open file.
- assert(!parser->FileStack.empty());
-
- // Get the directory containing the source in which the include
- // statement appears. This is always the first search location for
- // Fortran include files.
- std::string dir = parser->FileStack.top().Directory;
-
- // Find the included file. If it cannot be found just ignore the
- // problem because either the source will not compile or the user
- // does not care about depending on this included source.
- std::string fullName;
- if(parser->Self->FindIncludeFile(dir.c_str(), name, fullName))
- {
- // Found the included file. Save it in the set of included files.
- parser->Info.Includes.insert(fullName);
-
- // Parse it immediately to translate the source inline.
- cmDependsFortranParser_FilePush(parser, fullName.c_str());
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
- const char* name)
-{
- if(!parser->InPPFalseBranch && !parser->InInterface)
- {
- parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
- const char* macro)
-{
- if(!parser->InPPFalseBranch)
- {
- parser->PPDefinitions.insert(macro);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
- const char* macro)
-{
- if(!parser->InPPFalseBranch)
- {
- std::set<std::string>::iterator match;
- match = parser->PPDefinitions.find(macro);
- if(match != parser->PPDefinitions.end())
- {
- parser->PPDefinitions.erase(match);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
- const char* macro)
-{
- // A new PP branch has been opened
- parser->SkipToEnd.push(false);
-
- if (parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch++;
- }
- else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
- {
- parser->InPPFalseBranch=1;
- }
- else
- {
- parser->SkipToEnd.top() = true;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
- const char* macro)
-{
- // A new PP branch has been opened
- parser->SkipToEnd.push(false);
-
- if (parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch++;
- }
- else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
- {
- parser->InPPFalseBranch = 1;
- }
- else
- {
- // ignore other branches
- parser->SkipToEnd.top() = true;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser)
-{
- /* Note: The current parser is _not_ able to get statements like
- * #if 0
- * #if 1
- * #if MYSMBOL
- * #if defined(MYSYMBOL)
- * #if defined(MYSYMBOL) && ...
- * right. The same for #elif. Thus in
- * #if SYMBOL_1
- * ..
- * #elif SYMBOL_2
- * ...
- * ...
- * #elif SYMBOL_N
- * ..
- * #else
- * ..
- * #endif
- * _all_ N+1 branches are considered. If you got something like this
- * #if defined(MYSYMBOL)
- * #if !defined(MYSYMBOL)
- * use
- * #ifdef MYSYMBOL
- * #ifndef MYSYMBOL
- * instead.
- */
-
- // A new PP branch has been opened
- // Never skip! See note above.
- parser->SkipToEnd.push(false);
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser)
-{
- /* Note: There are parser limitations. See the note at
- * cmDependsFortranParser_RuleIf(..)
- */
-
- // Always taken unless an #ifdef or #ifndef-branch has been taken
- // already. If the second condition isn't meet already
- // (parser->InPPFalseBranch == 0) correct it.
- if(!parser->SkipToEnd.empty() &&
- parser->SkipToEnd.top() && !parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch = 1;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser)
-{
- // if the parent branch is false do nothing!
- if(parser->InPPFalseBranch > 1)
- {
- return;
- }
-
- // parser->InPPFalseBranch is either 0 or 1. We change it depending on
- // parser->SkipToEnd.top()
- if(!parser->SkipToEnd.empty() &&
- parser->SkipToEnd.top())
- {
- parser->InPPFalseBranch = 1;
- }
- else
- {
- parser->InPPFalseBranch = 0;
- }
-}
-
-//----------------------------------------------------------------------------
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser)
-{
- if(!parser->SkipToEnd.empty())
- {
- parser->SkipToEnd.pop();
- }
-
- // #endif doesn't know if there was a "#else" in before, so it
- // always decreases InPPFalseBranch
- if(parser->InPPFalseBranch)
- {
- parser->InPPFalseBranch--;
- }
-}
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index cb40796..a8a4013 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -9,13 +9,13 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef cmDependsFortran_h
-#define cmDependsFortran_h
+#ifndef cmFortran_h
+#define cmFortran_h
#include "cmDepends.h"
class cmDependsFortranInternals;
-class cmDependsFortranSourceInfo;
+class cmFortranSourceInfo;
/** \class cmDependsFortran
* \brief Dependency scanner for Fortran object files.
@@ -46,12 +46,6 @@ public:
static bool ModulesDiffer(const char* modFile, const char* stampFile,
const char* compilerId);
- /** Method to find an included file in the include path. Fortran
- always searches the directory containing the including source
- first. */
- bool FindIncludeFile(const char* dir, const char* includeName,
- std::string& fileName);
-
protected:
// Finalize the dependency information for the target.
virtual bool Finalize(std::ostream& makeDepends,
@@ -71,15 +65,16 @@ protected:
// Actually write the depenencies to the streams.
bool WriteDependenciesReal(const char *obj,
- cmDependsFortranSourceInfo const& info,
- const char* mod_dir, const char* stamp_dir,
+ cmFortranSourceInfo const& info,
+ std::string const& mod_dir,
+ const char* stamp_dir,
std::ostream& makeDepends,
std::ostream& internalDepends);
// The source file from which to start scanning.
std::string SourceFile;
- std::vector<std::string> PPDefinitions;
+ std::set<std::string> PPDefinitions;
// Internal implementation details.
cmDependsFortranInternals* Internal;
diff --git a/Source/cmDependsFortranParser.h b/Source/cmDependsFortranParser.h
deleted file mode 100644
index 399c3c8..0000000
--- a/Source/cmDependsFortranParser.h
+++ /dev/null
@@ -1,96 +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 cmDependsFortranParser_h
-#define cmDependsFortranParser_h
-
-#include <stddef.h> /* size_t */
-
-/* Forward declare parser object type. */
-typedef struct cmDependsFortranParser_s cmDependsFortranParser;
-
-/* Functions to enter/exit #include'd files in order. */
-bool cmDependsFortranParser_FilePush(cmDependsFortranParser* parser,
- const char* fname);
-bool cmDependsFortranParser_FilePop(cmDependsFortranParser* parser);
-
-/* Callbacks for lexer. */
-int cmDependsFortranParser_Input(cmDependsFortranParser* parser,
- char* buffer, size_t bufferSize);
-
-
-void cmDependsFortranParser_StringStart(cmDependsFortranParser* parser);
-const char* cmDependsFortranParser_StringEnd(cmDependsFortranParser* parser);
-void cmDependsFortranParser_StringAppend(cmDependsFortranParser* parser,
- char c);
-
-void cmDependsFortranParser_SetInInterface(cmDependsFortranParser* parser,
- bool is_in);
-bool cmDependsFortranParser_GetInInterface(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetInPPFalseBranch(cmDependsFortranParser* parser,
- bool is_in);
-bool cmDependsFortranParser_GetInPPFalseBranch(cmDependsFortranParser* parser);
-
-
-void cmDependsFortranParser_SetOldStartcond(cmDependsFortranParser* parser,
- int arg);
-int cmDependsFortranParser_GetOldStartcond(cmDependsFortranParser* parser);
-
-/* Callbacks for parser. */
-void cmDependsFortranParser_Error(cmDependsFortranParser* parser,
- const char* message);
-void cmDependsFortranParser_RuleUse(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleInclude(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleModule(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleDefine(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleUndef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIfdef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIfndef(cmDependsFortranParser* parser,
- const char* name);
-void cmDependsFortranParser_RuleIf(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser);
-void cmDependsFortranParser_RuleEndif(cmDependsFortranParser* parser);
-
-/* Define the parser stack element type. */
-typedef union cmDependsFortran_yystype_u cmDependsFortran_yystype;
-union cmDependsFortran_yystype_u
-{
- char* string;
-};
-
-/* Setup the proper yylex interface. */
-#define YY_EXTRA_TYPE cmDependsFortranParser*
-#define YY_DECL \
-int cmDependsFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
-#define YYSTYPE cmDependsFortran_yystype
-#define YYSTYPE_IS_DECLARED 1
-#if !defined(cmDependsFortranLexer_cxx)
-# include "cmDependsFortranLexer.h"
-#endif
-#if !defined(cmDependsFortranLexer_cxx)
-#if !defined(cmDependsFortranParser_cxx)
-# undef YY_EXTRA_TYPE
-# undef YY_DECL
-# undef YYSTYPE
-# undef YYSTYPE_IS_DECLARED
-#endif
-#endif
-
-#endif
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index 8854c36..b6c5fde 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -13,7 +13,6 @@
#define _cmDocumentation_h
#include "cmStandardIncludes.h"
-#include "cmProperty.h"
#include "cmDocumentationFormatter.h"
#include "cmDocumentationSection.h"
#include "cmake.h"
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index e021d0b..41785c2 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -156,7 +156,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
verbose = false;
}
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
// if the command does not start with a quote, then
// try to find the program, and if the program can not be
// found use system to run the command as it must be a built in
@@ -219,7 +219,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
return false;
}
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
if(dir)
{
cmsysProcess_SetWorkingDirectory(cp, dir);
@@ -305,7 +305,7 @@ bool cmExecProgramCommand::RunCommand(const char* command,
}
if(!msg.empty())
{
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
// Old Windows process execution printed this info.
msg += "\n\nfor command: ";
msg += command;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index bf18deb..fed0dbc 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -18,7 +18,7 @@
//----------------------------------------------------------------------------
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
- : Backtrace(NULL)
+ : Backtrace()
{
this->Makefile = 0;
this->ExportSet = 0;
@@ -27,6 +27,7 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator()
//----------------------------------------------------------------------------
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
+ std::vector<cmGeneratorTarget*> allTargets;
{
std::string expectedTargets;
std::string sep;
@@ -36,10 +37,11 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
tei = targets.begin();
tei != targets.end(); ++tei)
{
- cmTarget *te = this->Makefile->FindTargetToUse(*tei);
- expectedTargets += sep + this->Namespace + te->GetExportName();
+ cmGeneratorTarget *te = this->Makefile
+ ->FindGeneratorTargetToUse(*tei);
+ expectedTargets += sep + this->Namespace + te->Target->GetExportName();
sep = " ";
- if(this->ExportedTargets.insert(te).second)
+ if(this->ExportedTargets.insert(te->Target).second)
{
this->Exports.push_back(te);
}
@@ -63,11 +65,12 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
std::vector<std::string> missingTargets;
// Create all the imported targets.
- for(std::vector<cmTarget*>::const_iterator
+ for(std::vector<cmGeneratorTarget*>::const_iterator
tei = this->Exports.begin();
tei != this->Exports.end(); ++tei)
{
- cmTarget* te = *tei;
+ cmGeneratorTarget* gte = *tei;
+ cmTarget* te = gte->Target;
this->GenerateImportTargetCode(os, te);
te->AppendBuildInterfaceIncludes();
@@ -103,7 +106,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
}
- this->PopulateCompatibleInterfaceProperties(te, properties);
+ this->PopulateCompatibleInterfaceProperties(gte, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
@@ -129,12 +132,12 @@ cmExportBuildFileGenerator
std::string const& suffix,
std::vector<std::string> &missingTargets)
{
- for(std::vector<cmTarget*>::const_iterator
+ for(std::vector<cmGeneratorTarget*>::const_iterator
tei = this->Exports.begin();
tei != this->Exports.end(); ++tei)
{
// Collect import properties for this target.
- cmTarget* target = *tei;
+ cmGeneratorTarget* target = *tei;
ImportPropertyMap properties;
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
@@ -147,10 +150,12 @@ cmExportBuildFileGenerator
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportDetailProperties(config, suffix,
- target, properties, missingTargets);
+ target,
+ properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
- cmGeneratorExpression::BuildInterface,
- target, properties, missingTargets);
+ cmGeneratorExpression::BuildInterface,
+ target,
+ properties, missingTargets);
}
// TOOD: PUBLIC_HEADER_LOCATION
@@ -160,7 +165,8 @@ cmExportBuildFileGenerator
// properties);
// Generate code in the export file.
- this->GenerateImportPropertyCode(os, config, target, properties);
+ this->GenerateImportPropertyCode(os, config, target->Target,
+ properties);
}
}
}
@@ -176,17 +182,18 @@ void
cmExportBuildFileGenerator
::SetImportLocationProperty(const std::string& config,
std::string const& suffix,
- cmTarget* target, ImportPropertyMap& properties)
+ cmGeneratorTarget* target,
+ ImportPropertyMap& properties)
{
// Get the makefile in which to lookup target information.
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Makefile;
// Add the main target file.
{
std::string prop = "IMPORTED_LOCATION";
prop += suffix;
std::string value;
- if(target->IsAppBundleOnApple())
+ if(target->Target->IsAppBundleOnApple())
{
value = target->GetFullPath(config, false);
}
@@ -204,13 +211,13 @@ cmExportBuildFileGenerator
// Add the import library for windows DLLs.
if(dll_platform &&
(target->GetType() == cmTarget::SHARED_LIBRARY ||
- target->IsExecutableWithExports()) &&
+ target->Target->IsExecutableWithExports()) &&
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
{
std::string prop = "IMPORTED_IMPLIB";
prop += suffix;
std::string value = target->GetFullPath(config, true);
- target->GetImplibGNUtoMS(value, value,
+ target->Target->GetImplibGNUtoMS(value, value,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}");
properties[prop] = value;
}
@@ -326,12 +333,12 @@ cmExportBuildFileGenerator
}
std::string
-cmExportBuildFileGenerator::InstallNameDir(cmTarget* target,
+cmExportBuildFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string& config)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 8b5694c..ff3d2e1 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -68,17 +68,18 @@ protected:
/** Fill in properties indicating built file locations. */
void SetImportLocationProperty(const std::string& config,
std::string const& suffix,
- cmTarget* target,
+ cmGeneratorTarget* target,
ImportPropertyMap& properties);
- std::string InstallNameDir(cmTarget* target, const std::string& config);
+ std::string InstallNameDir(cmGeneratorTarget* target,
+ const std::string& config);
std::vector<std::string>
FindNamespaces(cmMakefile* mf, const std::string& name);
std::vector<std::string> Targets;
cmExportSet *ExportSet;
- std::vector<cmTarget*> Exports;
+ std::vector<cmGeneratorTarget*> Exports;
cmMakefile* Makefile;
cmListFileBacktrace Backtrace;
};
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 43d26f9..96ea77b 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -177,6 +177,12 @@ bool cmExportCommand
this->SetError(e.str());
return false;
}
+ if (target->GetType() == cmTarget::UTILITY)
+ {
+ this->SetError("given custom target \"" + *currentTarget
+ + "\" which may not be exported.");
+ return false;
+ }
}
else
{
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index a51fb2a..9a7d73f 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -23,12 +23,28 @@
#include "cmVersion.h"
#include "cmComputeLinkInformation.h"
#include "cmAlgorithms.h"
+#include "cmOutputConverter.h"
#include <cmsys/auto_ptr.hxx>
#include <cmsys/FStream.hxx>
#include <assert.h>
//----------------------------------------------------------------------------
+static std::string cmExportFileGeneratorEscape(std::string const& str)
+{
+ // Escape a property value for writing into a .cmake file.
+ std::string result = cmOutputConverter::EscapeForCMake(str);
+ // Un-escape variable references generated by our own export code.
+ cmSystemTools::ReplaceString(result,
+ "\\${_IMPORT_PREFIX}",
+ "${_IMPORT_PREFIX}");
+ cmSystemTools::ReplaceString(result,
+ "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}",
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ return result;
+}
+
+//----------------------------------------------------------------------------
cmExportFileGenerator::cmExportFileGenerator()
{
this->AppendMode = false;
@@ -509,7 +525,7 @@ void getPropertyContents(cmTarget const* tgt, const std::string& prop,
}
//----------------------------------------------------------------------------
-void getCompatibleInterfaceProperties(cmTarget *target,
+void getCompatibleInterfaceProperties(cmGeneratorTarget *target,
std::set<std::string> &ifaceProperties,
const std::string& config)
{
@@ -517,7 +533,7 @@ void getCompatibleInterfaceProperties(cmTarget *target,
if (!info)
{
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
std::ostringstream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
@@ -552,9 +568,10 @@ void getCompatibleInterfaceProperties(cmTarget *target,
//----------------------------------------------------------------------------
void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
- cmTarget *target,
+ cmGeneratorTarget *gtarget,
ImportPropertyMap &properties)
{
+ cmTarget *target = gtarget->Target;
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
target, properties);
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
@@ -575,7 +592,7 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
- getCompatibleInterfaceProperties(target, ifaceProperties, "");
+ getCompatibleInterfaceProperties(gtarget, ifaceProperties, "");
std::vector<std::string> configNames;
target->GetMakefile()->GetConfigurations(configNames);
@@ -583,7 +600,7 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
for (std::vector<std::string>::const_iterator ci = configNames.begin();
ci != configNames.end(); ++ci)
{
- getCompatibleInterfaceProperties(target, ifaceProperties, *ci);
+ getCompatibleInterfaceProperties(gtarget, ifaceProperties, *ci);
}
}
@@ -608,7 +625,8 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget const* target,
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
- os << " " << pi->first << " \"" << pi->second << "\"\n";
+ os << " " << pi->first << " "
+ << cmExportFileGeneratorEscape(pi->second) << "\n";
}
os << ")\n\n";
}
@@ -774,12 +792,12 @@ void
cmExportFileGenerator
::SetImportLinkInterface(const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets)
{
// Add the transitive link dependencies for this configuration.
- cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
- target);
+ cmLinkInterface const* iface = target->GetLinkInterface(config,
+ target->Target);
if (!iface)
{
return;
@@ -812,12 +830,14 @@ cmExportFileGenerator
}
const bool newCMP0022Behavior =
- target->GetPolicyStatusCMP0022() != cmPolicies::WARN
- && target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+ target->Target
+ ->GetPolicyStatusCMP0022() != cmPolicies::WARN
+ && target->Target
+ ->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if(newCMP0022Behavior && !this->ExportOld)
{
- cmMakefile *mf = target->GetMakefile();
+ cmMakefile *mf = target->Target->GetMakefile();
std::ostringstream e;
e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, "
"but also has old-style LINK_INTERFACE_LIBRARIES properties "
@@ -837,7 +857,7 @@ cmExportFileGenerator
preprocessRule);
if (!prepro.empty())
{
- this->ResolveTargetsInGeneratorExpressions(prepro, target,
+ this->ResolveTargetsInGeneratorExpressions(prepro, target->Target,
missingTargets,
ReplaceFreeTargets);
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
@@ -849,12 +869,13 @@ void
cmExportFileGenerator
::SetImportDetailProperties(const std::string& config,
std::string const& suffix,
- cmTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget* target,
+ ImportPropertyMap& properties,
std::vector<std::string>& missingTargets
)
{
// Get the makefile in which to lookup target information.
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Makefile;
// Add the soname for unix shared libraries.
if(target->GetType() == cmTarget::SHARED_LIBRARY ||
@@ -887,8 +908,8 @@ cmExportFileGenerator
}
// Add the transitive link dependencies for this configuration.
- if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
- target))
+ if(cmLinkInterface const* iface =
+ target->GetLinkInterface(config, target->Target))
{
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LANGUAGES",
@@ -914,7 +935,7 @@ template <typename T>
void
cmExportFileGenerator
::SetImportLinkProperty(std::string const& suffix,
- cmTarget* target,
+ cmGeneratorTarget* target,
const std::string& propName,
std::vector<T> const& entries,
ImportPropertyMap& properties,
@@ -938,7 +959,7 @@ cmExportFileGenerator
sep = ";";
std::string temp = *li;
- this->AddTargetNamespace(temp, target, missingTargets);
+ this->AddTargetNamespace(temp, target->Target, missingTargets);
link_entries += temp;
}
@@ -1112,7 +1133,8 @@ cmExportFileGenerator
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
- os << " " << pi->first << " \"" << pi->second << "\"\n";
+ os << " " << pi->first << " "
+ << cmExportFileGeneratorEscape(pi->second) << "\n";
}
os << " )\n"
<< "\n";
@@ -1223,7 +1245,7 @@ cmExportFileGenerator
ImportPropertyMap::const_iterator pi = properties.find(*li);
if (pi != properties.end())
{
- os << "\"" << pi->second << "\" ";
+ os << cmExportFileGeneratorEscape(pi->second) << " ";
}
}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index b6f4166..44f779b 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -92,13 +92,15 @@ protected:
// Collect properties with detailed information about targets beyond
// their location on disk.
void SetImportDetailProperties(const std::string& config,
- std::string const& suffix, cmTarget* target,
+ std::string const& suffix,
+ cmGeneratorTarget* target,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
template <typename T>
void SetImportLinkProperty(std::string const& suffix,
- cmTarget* target, const std::string& propName,
+ cmGeneratorTarget* target,
+ const std::string& propName,
std::vector<T> const& entries,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
@@ -130,7 +132,7 @@ protected:
std::vector<std::string> &missingTargets);
void PopulateInterfaceProperty(const std::string& propName, cmTarget *target,
ImportPropertyMap &properties);
- void PopulateCompatibleInterfaceProperties(cmTarget *target,
+ void PopulateCompatibleInterfaceProperties(cmGeneratorTarget *target,
ImportPropertyMap &properties);
void GenerateInterfaceProperties(cmTarget const* target, std::ostream& os,
const ImportPropertyMap &properties);
@@ -148,7 +150,7 @@ protected:
void SetImportLinkInterface(const std::string& config,
std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
enum FreeTargetsReplace {
@@ -198,7 +200,7 @@ private:
virtual void ReplaceInstallPrefix(std::string &input);
- virtual std::string InstallNameDir(cmTarget* target,
+ virtual std::string InstallNameDir(cmGeneratorTarget* target,
const std::string& config) = 0;
};
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 89c6ca2..7ffab0c 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -72,8 +72,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
// Set an _IMPORT_PREFIX variable for import location properties
// to reference if they are relative to the install prefix.
- std::string installPrefix =
- this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ std::string installPrefix = this->IEGen->GetLocalGenerator()
+ ->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
std::string const& expDest = this->IEGen->GetDestination();
if(cmSystemTools::FileIsFullPath(expDest))
{
@@ -193,7 +193,11 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties);
- this->PopulateCompatibleInterfaceProperties(te, properties);
+ cmGeneratorTarget *gtgt = te->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(te);
+
+ this->PopulateCompatibleInterfaceProperties(gtgt, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
@@ -358,12 +362,14 @@ cmExportInstallFileGenerator
if(!properties.empty())
{
// Get the rest of the target details.
+ cmGeneratorTarget *gtgt = te->Target->GetMakefile()
+ ->GetGlobalGenerator()->GetGeneratorTarget(te->Target);
this->SetImportDetailProperties(config, suffix,
- te->Target, properties, missingTargets);
+ gtgt, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::InstallInterface,
- te->Target, properties, missingTargets);
+ gtgt, properties, missingTargets);
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
@@ -396,7 +402,7 @@ cmExportInstallFileGenerator
}
// Get the target to be installed.
- cmTarget* target = itgen->GetTarget();
+ cmTarget* target = itgen->GetTarget()->Target;
// Construct the installed location of the target.
std::string dest = itgen->GetDestination(config);
@@ -540,12 +546,12 @@ cmExportInstallFileGenerator
}
std::string
-cmExportInstallFileGenerator::InstallNameDir(cmTarget* target,
+cmExportInstallFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string&)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 6f86ac9..b06fee5 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -83,7 +83,8 @@ protected:
std::set<std::string>& importedLocations
);
- std::string InstallNameDir(cmTarget* target, const std::string& config);
+ std::string InstallNameDir(cmGeneratorTarget* target,
+ const std::string& config);
cmInstallExportGenerator* IEGen;
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index cb150a7..fde8fb1 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -11,7 +11,6 @@
============================================================================*/
#include "cmExportLibraryDependenciesCommand.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include "cmVersion.h"
@@ -82,15 +81,14 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
// the project.
cmake* cm = this->Makefile->GetCMakeInstance();
cmGlobalGenerator* global = cm->GetGlobalGenerator();
- const std::vector<cmLocalGenerator *>& locals = global->GetLocalGenerators();
+ const std::vector<cmMakefile*>& locals = global->GetMakefiles();
std::map<std::string, std::string> libDepsOld;
std::map<std::string, std::string> libDepsNew;
std::map<std::string, std::string> libTypes;
- for(std::vector<cmLocalGenerator *>::const_iterator i = locals.begin();
+ for(std::vector<cmMakefile*>::const_iterator i = locals.begin();
i != locals.end(); ++i)
{
- const cmLocalGenerator* gen = *i;
- const cmTargets &tgts = gen->GetMakefile()->GetTargets();
+ const cmTargets &tgts = (*i)->GetTargets();
for(cmTargets::const_iterator l = tgts.begin();
l != tgts.end(); ++l)
{
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index eb8d193..ba66531 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -13,9 +13,16 @@
#include "cmExportTryCompileFileGenerator.h"
#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
#include "cmGeneratorExpressionDAGChecker.h"
//----------------------------------------------------------------------------
+cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
+ cmGlobalGenerator* gg)
+{
+ gg->CreateGenerationObjects(cmGlobalGenerator::ImportedOnly);
+}
+
bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
{
std::set<cmTarget const*> emitted;
@@ -99,8 +106,6 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target,
|| i->first.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0
|| i->first.find("INTERFACE_LINK_LIBRARIES") == 0)
{
- const std::string libs = i->second.GetValue();
-
std::string evalResult = this->FindTargets(i->first,
target, emitted);
@@ -118,13 +123,14 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget const* target,
}
}
}
+
std::string
-cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target,
+cmExportTryCompileFileGenerator::InstallNameDir(cmGeneratorTarget* target,
const std::string& config)
{
std::string install_name_dir;
- cmMakefile* mf = target->GetMakefile();
+ cmMakefile* mf = target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
install_name_dir =
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index ec70d81..8838eca 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -9,8 +9,8 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef cmExportInstallFileGenerator_h
-#define cmExportInstallFileGenerator_h
+#ifndef cmExportTryCompileFileGenerator_h
+#define cmExportTryCompileFileGenerator_h
#include "cmExportFileGenerator.h"
@@ -20,6 +20,8 @@ class cmInstallTargetGenerator;
class cmExportTryCompileFileGenerator: public cmExportFileGenerator
{
public:
+ cmExportTryCompileFileGenerator(cmGlobalGenerator* gg);
+
/** Set the list of targets to export. */
void SetExports(const std::vector<cmTarget const*> &exports)
{ this->Exports = exports; }
@@ -43,7 +45,7 @@ protected:
ImportPropertyMap& properties,
std::set<cmTarget const*> &emitted);
- std::string InstallNameDir(cmTarget* target,
+ std::string InstallNameDir(cmGeneratorTarget* target,
const std::string& config);
private:
std::string FindTargets(const std::string& prop, cmTarget const* tgt,
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index e374387..dfd51c7 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -313,7 +313,7 @@ void cmExtraCodeBlocksGenerator
" "<<virtualFolders<<"\n"
" <Build>\n";
- this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());
+ this->AppendTarget(fout, "all", 0, make.c_str(), lgs[0], compiler.c_str());
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
@@ -335,7 +335,7 @@ void cmExtraCodeBlocksGenerator
makefile->GetHomeOutputDirectory())==0)
{
this->AppendTarget(fout, ti->first, 0,
- make.c_str(), makefile, compiler.c_str());
+ make.c_str(), *lg, compiler.c_str());
}
}
break;
@@ -351,7 +351,7 @@ void cmExtraCodeBlocksGenerator
}
this->AppendTarget(fout, ti->first, 0,
- make.c_str(), makefile, compiler.c_str());
+ make.c_str(), *lg, compiler.c_str());
break;
case cmTarget::EXECUTABLE:
case cmTarget::STATIC_LIBRARY:
@@ -360,11 +360,11 @@ void cmExtraCodeBlocksGenerator
case cmTarget::OBJECT_LIBRARY:
{
this->AppendTarget(fout, ti->first, &ti->second,
- make.c_str(), makefile, compiler.c_str());
+ make.c_str(), *lg, compiler.c_str());
std::string fastTarget = ti->first;
fastTarget += "/fast";
this->AppendTarget(fout, fastTarget, &ti->second,
- make.c_str(), makefile, compiler.c_str());
+ make.c_str(), *lg, compiler.c_str());
}
break;
default:
@@ -519,14 +519,16 @@ void cmExtraCodeBlocksGenerator
// Write a dummy file for OBJECT libraries, so C::B can reference some file
std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
- cmMakefile* mf, cmTarget* target) const
+ cmLocalGenerator* lg,
+ cmTarget* target) const
{
+ cmMakefile *mf = lg->GetMakefile();
// this file doesn't seem to be used by C::B in custom makefile mode,
// but we generate a unique file for each OBJECT library so in case
// C::B uses it in some way, the targets don't interfere with each other.
std::string filename = mf->GetCurrentBinaryDirectory();
filename += "/";
- filename += mf->GetLocalGenerator()->GetTargetDirectory(*target);
+ filename += lg->GetTargetDirectory(*target);
filename += "/";
filename += target->GetName();
filename += ".objlib";
@@ -547,9 +549,10 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
const std::string& targetName,
cmTarget* target,
const char* make,
- const cmMakefile* makefile,
+ const cmLocalGenerator* lg,
const char* compiler)
{
+ cmMakefile const* makefile = lg->GetMakefile();
std::string makefileName = makefile->GetCurrentBinaryDirectory();
makefileName += "/Makefile";
@@ -583,12 +586,14 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
std::string location;
if ( target->GetType()==cmTarget::OBJECT_LIBRARY)
{
- location = this->CreateDummyTargetFile(const_cast<cmMakefile*>(makefile),
+ location = this->CreateDummyTargetFile(const_cast<cmLocalGenerator*>(lg),
target);
}
else
{
- location = target->GetLocation(buildType);
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(target);
+ location = gt->GetLocation(buildType);
}
fout<<" <Option output=\"" << location
@@ -604,7 +609,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
// the compilerdefines for this target
std::vector<std::string> cdefs;
- target->GetCompileDefinitions(cdefs, buildType, "C");
+ gtgt->GetCompileDefinitions(cdefs, buildType, "C");
// Expand the list.
for(std::vector<std::string>::const_iterator di = cdefs.begin();
@@ -618,8 +623,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
std::set<std::string> uniqIncludeDirs;
std::vector<std::string> includes;
- target->GetMakefile()->GetLocalGenerator()->
- GetIncludeDirectories(includes, gtgt, "C", buildType);
+ lg->GetIncludeDirectories(includes, gtgt, "C", buildType);
uniqIncludeDirs.insert(includes.begin(), includes.end());
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
index 97da1b8..e5ede9a 100644
--- a/Source/cmExtraCodeBlocksGenerator.h
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -48,7 +48,8 @@ private:
void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename);
- std::string CreateDummyTargetFile(cmMakefile* mf, cmTarget* target) const;
+ std::string CreateDummyTargetFile(cmLocalGenerator* lg,
+ cmTarget* target) const;
std::string GetCBCompilerId(const cmMakefile* mf);
int GetCBTargetType(cmTarget* target);
@@ -58,7 +59,7 @@ private:
const std::string& targetName,
cmTarget* target,
const char* make,
- const cmMakefile* makefile,
+ const cmLocalGenerator* lg,
const char* compiler);
};
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 9705d2b..c2cff14 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -141,24 +141,6 @@ void cmExtraCodeLiteGenerator
return;
}
- // figure out the compiler
- //std::string compiler = this->GetCBCompilerId(mf);
- std::string workspaceSourcePath = mf->GetHomeDirectory();
- std::string workspaceOutputDir = mf->GetHomeOutputDirectory();
- std::vector<std::string> outputFiles = mf->GetOutputFiles();
- std::string projectName = mf->GetProjectName();
- std::string incDirs;
- std::vector<cmValueWithOrigin> incDirsVec =
- mf->GetIncludeDirectoriesEntries();
- std::vector<cmValueWithOrigin>::const_iterator iterInc = incDirsVec.begin();
-
- //std::cout << "GetIncludeDirectories:" << std::endl;
- for(; iterInc != incDirsVec.end(); ++iterInc )
- {
- //std::cout << (*ItStrVec) << std::endl;
- incDirs += iterInc->Value + " ";
- }
-
////////////////////////////////////
fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<CodeLite_Project Name=\"" << mf->GetProjectName()
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index a81e53c..44bf586 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -598,7 +598,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
linkName4 += "/";
linkName4 += cmSystemTools::GetFilenameName(fullPath);
this->AppendLinkedResource(fout, linkName4,
- fullPath, LinkToFile);
+ this->GetEclipsePath(fullPath),
+ LinkToFile);
}
}
}
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index 578e7d3..f83b5cf 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -19,7 +19,6 @@
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"
#include "cmSystemTools.h"
-#include "cmXMLSafe.h"
#include <cmsys/SystemTools.hxx>
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 4e721d4..163a75b 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -21,7 +21,6 @@
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include "cmXMLSafe.h"
#include <cmsys/SystemTools.hxx>
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 4698468..87faf84 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -66,7 +66,7 @@ static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID;
#endif
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
// libcurl doesn't support file:// urls for unicode filenames on Windows.
// Convert string from UTF-8 to ACP if this is a file:// URL.
static std::string fix_file_url_windows(const std::string& url)
@@ -270,7 +270,7 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
this->SetError(error);
return false;
}
- std::string message = cmJoin(cmRange(i, args.end()), std::string());
+ std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
file << message;
file.close();
if(mode)
@@ -906,13 +906,13 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
switch(status)
{
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
g.RecurseThroughSymlinksOff();
break;
case cmPolicies::OLD:
case cmPolicies::WARN:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
g.RecurseThroughSymlinksOn();
break;
}
@@ -1044,6 +1044,8 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
switch (status)
{
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Correct behavior, yay!
break;
@@ -1059,12 +1061,6 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0009));
}
break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- this->SetError("policy CMP0009 error");
- this->Makefile->IssueMessage(cmake::FATAL_ERROR,
- cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0009));
- return false;
}
}
@@ -3160,7 +3156,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
url = fix_file_url_windows(url);
#endif
@@ -3415,7 +3411,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
unsigned long file_size = cmsys::SystemTools::FileLength(filename);
-#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8)
+#if defined(_WIN32) && defined(CMAKE_ENCODING_UTF8)
url = fix_file_url_windows(url);
#endif
@@ -3569,19 +3565,16 @@ void cmFileCommand::AddEvaluationFile(const std::string &inputName,
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression outputGe(&lfbt);
+ cmGeneratorExpression outputGe(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge
= outputGe.Parse(outputExpr);
- cmGeneratorExpression conditionGe(&lfbt);
+ cmGeneratorExpression conditionGe(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge
= conditionGe.Parse(condition);
- this->Makefile->GetGlobalGenerator()->AddEvaluationFile(inputName,
- outputCge,
- this->Makefile,
- conditionCge,
- inputIsContent);
+ this->Makefile->AddEvaluationFile(inputName, outputCge,
+ conditionCge, inputIsContent);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index add06a7..7959ffe 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -170,8 +170,8 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
else
{
this->VariableDocumentation += "one of the ";
- this->VariableDocumentation += cmJoin(cmRange(this->Names).retreat(1),
- ", ");
+ this->VariableDocumentation +=
+ cmJoin(cmMakeRange(this->Names).retreat(1), ", ");
this->VariableDocumentation += " or "
+ this->Names[this->Names.size() - 1] + " libraries be found";
}
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 0a66732..e8d158e 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -11,7 +11,6 @@
============================================================================*/
#include "cmFindLibraryCommand.h"
#include <cmsys/Directory.hxx>
-#include <cmsys/stl/algorithm>
cmFindLibraryCommand::cmFindLibraryCommand()
{
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 68a6558..9b9071d 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1378,7 +1378,7 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
cmFindPackageCommandHoldFile holdFile(fname.c_str());
// Load the file.
- cmsys::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
+ cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
std::string fentry;
if(fin && cmSystemTools::GetLineFromStream(fin, fentry) &&
this->CheckPackageRegistryEntry(fentry, outPaths))
diff --git a/Source/cmDependsFortranLexer.cxx b/Source/cmFortranLexer.cxx
index 1eff1e4..b727f0e 100644
--- a/Source/cmDependsFortranLexer.cxx
+++ b/Source/cmFortranLexer.cxx
@@ -9,9 +9,9 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#line 2 "cmDependsFortranLexer.cxx"
+#line 2 "cmFortranLexer.cxx"
-#line 4 "cmDependsFortranLexer.cxx"
+#line 4 "cmFortranLexer.cxx"
#define YY_INT_ALIGNED short int
@@ -164,7 +164,7 @@ typedef void* yyscan_t;
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE cmDependsFortran_yyrestart(yyin ,yyscanner )
+#define YY_NEW_FILE cmFortran_yyrestart(yyin ,yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
@@ -274,7 +274,7 @@ struct yy_buffer_state
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
- * (via cmDependsFortran_yyrestart()), so that the user can continue scanning by
+ * (via cmFortran_yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
@@ -297,36 +297,36 @@ struct yy_buffer_state
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner );
-static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner );
-static void cmDependsFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmFortran_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmFortran_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER cmDependsFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+#define YY_FLUSH_BUFFER cmFortran_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
-#define yy_new_buffer cmDependsFortran_yy_create_buffer
+#define yy_new_buffer cmFortran_yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
- cmDependsFortran_yyensure_buffer_stack (yyscanner); \
+ cmFortran_yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
@@ -334,9 +334,9 @@ void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
- cmDependsFortran_yyensure_buffer_stack (yyscanner); \
+ cmFortran_yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
@@ -345,7 +345,7 @@ void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
-#define cmDependsFortran_yywrap(n) 1
+#define cmFortran_yywrap(n) 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -622,8 +622,8 @@ static yyconst flex_int16_t yy_chk[547] =
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "cmDependsFortranLexer.in.l"
-#line 2 "cmDependsFortranLexer.in.l"
+#line 1 "cmFortranLexer.in.l"
+#line 2 "cmFortranLexer.in.l"
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
@@ -651,17 +651,17 @@ This file must be translated to C and modified to build everywhere.
Run flex like this:
- flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
+ flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
-Modify cmDependsFortranLexer.cxx:
+Modify cmFortranLexer.cxx:
- remove TABs
- remove "yyscanner" argument from these methods:
- yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
- - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
+ yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+ - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
- remove all YY_BREAK lines occurring right after return statements
- change while ( 1 ) to for(;;)
-Modify cmDependsFortranLexer.h:
+Modify cmFortranLexer.h:
- remove TABs
- remove the yy_init_globals function
- remove the block that includes unistd.h
@@ -671,21 +671,21 @@ Modify cmDependsFortranLexer.h:
#include "cmStandardLexer.h"
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
/* Replace the lexer input function. */
#undef YY_INPUT
#define YY_INPUT(buf, result, max_size) \
- { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
+ { result = cmFortranParser_Input(yyextra, buf, max_size); }
/* Include the set of tokens from the parser. */
-#include "cmDependsFortranParserTokens.h"
+#include "cmFortranParserTokens.h"
/*--------------------------------------------------------------------------*/
-#line 678 "cmDependsFortranLexer.cxx"
+#line 678 "cmFortranLexer.cxx"
#define INITIAL 0
#define free_fmt 1
@@ -741,38 +741,38 @@ struct yyguts_t
static int yy_init_globals (yyscan_t yyscanner );
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
+int cmFortran_yylex_init (yyscan_t* scanner);
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
+int cmFortran_yyget_debug (yyscan_t yyscanner );
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
-void cmDependsFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+void cmFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
-void cmDependsFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+void cmFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
+int cmFortran_yyget_leng (yyscan_t yyscanner );
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
+char *cmFortran_yyget_text (yyscan_t yyscanner );
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -780,9 +780,9 @@ void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
+extern int cmFortran_yywrap (yyscan_t yyscanner );
#endif
#endif
@@ -886,9 +886,9 @@ static int input (yyscan_t yyscanner );
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
+extern int cmFortran_yylex (yyscan_t yyscanner);
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
#endif /* !YY_DECL */
/* Code executed at the beginning of each rule, after yytext and yyleng
@@ -918,10 +918,10 @@ YY_DECL
int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 71 "cmDependsFortranLexer.in.l"
+#line 71 "cmFortranLexer.in.l"
-#line 914 "cmDependsFortranLexer.cxx"
+#line 914 "cmFortranLexer.cxx"
if ( !yyg->yy_init )
{
@@ -941,12 +941,12 @@ YY_DECL
yyout = stdout;
if ( ! YY_CURRENT_BUFFER ) {
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
+ cmFortran_yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
}
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ cmFortran_yy_load_buffer_state(yyscanner );
}
for(;;) /* loops until end-of-file is reached */
@@ -1007,47 +1007,47 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 73 "cmDependsFortranLexer.in.l"
+#line 73 "cmFortranLexer.in.l"
{
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
BEGIN(str_dq);
}
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 79 "cmDependsFortranLexer.in.l"
+#line 79 "cmFortranLexer.in.l"
{
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
BEGIN(str_sq);
}
YY_BREAK
case 3:
-#line 86 "cmDependsFortranLexer.in.l"
+#line 86 "cmFortranLexer.in.l"
case 4:
YY_RULE_SETUP
-#line 86 "cmDependsFortranLexer.in.l"
+#line 86 "cmFortranLexer.in.l"
{
- BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
- yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
+ BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+ yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
return STRING;
}
case 5:
/* rule 5 can match eol */
-#line 93 "cmDependsFortranLexer.in.l"
+#line 93 "cmFortranLexer.in.l"
case 6:
/* rule 6 can match eol */
YY_RULE_SETUP
-#line 93 "cmDependsFortranLexer.in.l"
+#line 93 "cmFortranLexer.in.l"
/* Ignore (continued strings, free fmt) */
YY_BREAK
case 7:
/* rule 7 can match eol */
YY_RULE_SETUP
-#line 95 "cmDependsFortranLexer.in.l"
+#line 95 "cmFortranLexer.in.l"
{
- if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+ if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
; /* Ignore (cont. strings, fixed fmt) */
else
{
@@ -1058,7 +1058,7 @@ YY_RULE_SETUP
case 8:
/* rule 8 can match eol */
YY_RULE_SETUP
-#line 105 "cmDependsFortranLexer.in.l"
+#line 105 "cmFortranLexer.in.l"
{
unput ('\n');
BEGIN(INITIAL);
@@ -1066,25 +1066,25 @@ YY_RULE_SETUP
}
case 9:
YY_RULE_SETUP
-#line 111 "cmDependsFortranLexer.in.l"
+#line 111 "cmFortranLexer.in.l"
{
- cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
+ cmFortranParser_StringAppend(yyextra, yytext[0]);
}
YY_BREAK
case 10:
/* rule 10 can match eol */
YY_RULE_SETUP
-#line 115 "cmDependsFortranLexer.in.l"
+#line 115 "cmFortranLexer.in.l"
{ return EOSTMT; } /* Treat comments like */
case 11:
/* rule 11 can match eol */
YY_RULE_SETUP
-#line 116 "cmDependsFortranLexer.in.l"
+#line 116 "cmFortranLexer.in.l"
{ return EOSTMT; } /* empty lines */
case 12:
/* rule 12 can match eol */
YY_RULE_SETUP
-#line 118 "cmDependsFortranLexer.in.l"
+#line 118 "cmFortranLexer.in.l"
{
yytext[yyleng-1] = 0;
yylvalp->string = strdup(strchr(yytext, '<')+1);
@@ -1092,149 +1092,149 @@ YY_RULE_SETUP
}
case 13:
YY_RULE_SETUP
-#line 123 "cmDependsFortranLexer.in.l"
+#line 123 "cmFortranLexer.in.l"
{ return CPP_INCLUDE; }
case 14:
YY_RULE_SETUP
-#line 124 "cmDependsFortranLexer.in.l"
+#line 124 "cmFortranLexer.in.l"
{ return F90PPR_INCLUDE; }
case 15:
YY_RULE_SETUP
-#line 125 "cmDependsFortranLexer.in.l"
+#line 125 "cmFortranLexer.in.l"
{ return COCO_INCLUDE; }
case 16:
YY_RULE_SETUP
-#line 127 "cmDependsFortranLexer.in.l"
+#line 127 "cmFortranLexer.in.l"
{ return CPP_DEFINE; }
case 17:
YY_RULE_SETUP
-#line 128 "cmDependsFortranLexer.in.l"
+#line 128 "cmFortranLexer.in.l"
{ return F90PPR_DEFINE; }
case 18:
YY_RULE_SETUP
-#line 130 "cmDependsFortranLexer.in.l"
+#line 130 "cmFortranLexer.in.l"
{ return CPP_UNDEF; }
case 19:
YY_RULE_SETUP
-#line 131 "cmDependsFortranLexer.in.l"
+#line 131 "cmFortranLexer.in.l"
{ return F90PPR_UNDEF; }
case 20:
YY_RULE_SETUP
-#line 133 "cmDependsFortranLexer.in.l"
+#line 133 "cmFortranLexer.in.l"
{ return CPP_IFDEF; }
case 21:
YY_RULE_SETUP
-#line 134 "cmDependsFortranLexer.in.l"
+#line 134 "cmFortranLexer.in.l"
{ return CPP_IFNDEF; }
case 22:
YY_RULE_SETUP
-#line 135 "cmDependsFortranLexer.in.l"
+#line 135 "cmFortranLexer.in.l"
{ return CPP_IF; }
case 23:
YY_RULE_SETUP
-#line 136 "cmDependsFortranLexer.in.l"
+#line 136 "cmFortranLexer.in.l"
{ return CPP_ELIF; }
case 24:
YY_RULE_SETUP
-#line 137 "cmDependsFortranLexer.in.l"
+#line 137 "cmFortranLexer.in.l"
{ return CPP_ELSE; }
case 25:
YY_RULE_SETUP
-#line 138 "cmDependsFortranLexer.in.l"
+#line 138 "cmFortranLexer.in.l"
{ return CPP_ENDIF; }
case 26:
YY_RULE_SETUP
-#line 140 "cmDependsFortranLexer.in.l"
+#line 140 "cmFortranLexer.in.l"
{ return F90PPR_IFDEF; }
case 27:
YY_RULE_SETUP
-#line 141 "cmDependsFortranLexer.in.l"
+#line 141 "cmFortranLexer.in.l"
{ return F90PPR_IFNDEF; }
case 28:
YY_RULE_SETUP
-#line 142 "cmDependsFortranLexer.in.l"
+#line 142 "cmFortranLexer.in.l"
{ return F90PPR_IF; }
case 29:
YY_RULE_SETUP
-#line 143 "cmDependsFortranLexer.in.l"
+#line 143 "cmFortranLexer.in.l"
{ return F90PPR_ELIF; }
case 30:
YY_RULE_SETUP
-#line 144 "cmDependsFortranLexer.in.l"
+#line 144 "cmFortranLexer.in.l"
{ return F90PPR_ELSE; }
case 31:
YY_RULE_SETUP
-#line 145 "cmDependsFortranLexer.in.l"
+#line 145 "cmFortranLexer.in.l"
{ return F90PPR_ENDIF; }
/* Line continuations, possible involving comments. */
case 32:
/* rule 32 can match eol */
YY_RULE_SETUP
-#line 148 "cmDependsFortranLexer.in.l"
+#line 148 "cmFortranLexer.in.l"
YY_BREAK
case 33:
/* rule 33 can match eol */
YY_RULE_SETUP
-#line 149 "cmDependsFortranLexer.in.l"
+#line 149 "cmFortranLexer.in.l"
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 151 "cmDependsFortranLexer.in.l"
+#line 151 "cmFortranLexer.in.l"
{ return COMMA; }
case 35:
YY_RULE_SETUP
-#line 153 "cmDependsFortranLexer.in.l"
+#line 153 "cmFortranLexer.in.l"
{ return DCOLON; }
case 36:
/* rule 36 can match eol */
YY_RULE_SETUP
-#line 155 "cmDependsFortranLexer.in.l"
+#line 155 "cmFortranLexer.in.l"
{ return GARBAGE; }
case 37:
YY_RULE_SETUP
-#line 157 "cmDependsFortranLexer.in.l"
+#line 157 "cmFortranLexer.in.l"
{ return ASSIGNMENT_OP; }
case 38:
YY_RULE_SETUP
-#line 159 "cmDependsFortranLexer.in.l"
+#line 159 "cmFortranLexer.in.l"
{
yylvalp->string = strdup(yytext);
return WORD;
}
case 39:
YY_RULE_SETUP
-#line 164 "cmDependsFortranLexer.in.l"
+#line 164 "cmFortranLexer.in.l"
{ return GARBAGE; }
case 40:
/* rule 40 can match eol */
YY_RULE_SETUP
-#line 166 "cmDependsFortranLexer.in.l"
+#line 166 "cmFortranLexer.in.l"
{ return EOSTMT; }
case 41:
YY_RULE_SETUP
-#line 169 "cmDependsFortranLexer.in.l"
+#line 169 "cmFortranLexer.in.l"
/* Ignore */
YY_BREAK
case 42:
/* rule 42 can match eol */
YY_RULE_SETUP
-#line 170 "cmDependsFortranLexer.in.l"
+#line 170 "cmFortranLexer.in.l"
/* Ignore line-endings preceeded by \ */
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 172 "cmDependsFortranLexer.in.l"
+#line 172 "cmFortranLexer.in.l"
{ return *yytext; }
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(free_fmt):
case YY_STATE_EOF(fixed_fmt):
case YY_STATE_EOF(str_sq):
case YY_STATE_EOF(str_dq):
-#line 174 "cmDependsFortranLexer.in.l"
+#line 174 "cmFortranLexer.in.l"
{
- if(!cmDependsFortranParser_FilePop(yyextra) )
+ if(!cmFortranParser_FilePop(yyextra) )
{
return YY_NULL;
}
@@ -1242,10 +1242,10 @@ case YY_STATE_EOF(str_dq):
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 181 "cmDependsFortranLexer.in.l"
+#line 181 "cmFortranLexer.in.l"
ECHO;
YY_BREAK
-#line 1270 "cmDependsFortranLexer.cxx"
+#line 1270 "cmFortranLexer.cxx"
case YY_END_OF_BUFFER:
{
@@ -1261,7 +1261,7 @@ ECHO;
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
- * cmDependsFortran_yylex(). If so, then we have to assure
+ * cmFortran_yylex(). If so, then we have to assure
* consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
@@ -1321,7 +1321,7 @@ ECHO;
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( cmDependsFortran_yywrap(yyscanner ) )
+ if ( cmFortran_yywrap(yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1374,7 +1374,7 @@ ECHO;
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
-} /* end of cmDependsFortran_yylex */
+} /* end of cmFortran_yylex */
/* yy_get_next_buffer - try to read in a new buffer
*
@@ -1453,7 +1453,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- cmDependsFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ cmFortran_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
}
else
/* Can't grow it, we don't own it. */
@@ -1485,7 +1485,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- cmDependsFortran_yyrestart(yyin ,yyscanner);
+ cmFortran_yyrestart(yyin ,yyscanner);
}
else
@@ -1502,7 +1502,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmDependsFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) cmFortran_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
}
@@ -1656,13 +1656,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
/* Reset buffer status. */
- cmDependsFortran_yyrestart(yyin ,yyscanner);
+ cmFortran_yyrestart(yyin ,yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( cmDependsFortran_yywrap(yyscanner ) )
+ if ( cmFortran_yywrap(yyscanner ) )
return EOF;
if ( ! yyg->yy_did_buffer_switch_on_eof )
@@ -1696,34 +1696,34 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @note This function does not reset the start condition to @c INITIAL .
*/
- void cmDependsFortran_yyrestart (FILE * input_file , yyscan_t yyscanner)
+ void cmFortran_yyrestart (FILE * input_file , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! YY_CURRENT_BUFFER ){
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
+ cmFortran_yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- cmDependsFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ cmFortran_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
}
- cmDependsFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ cmFortran_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmFortran_yy_load_buffer_state(yyscanner );
}
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
* @param yyscanner The scanner object.
*/
- void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+ void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* TODO. We should be able to replace this entire function body
* with
- * cmDependsFortran_yypop_buffer_state();
- * cmDependsFortran_yypush_buffer_state(new_buffer);
+ * cmFortran_yypop_buffer_state();
+ * cmFortran_yypush_buffer_state(new_buffer);
*/
- cmDependsFortran_yyensure_buffer_stack (yyscanner);
+ cmFortran_yyensure_buffer_stack (yyscanner);
if ( YY_CURRENT_BUFFER == new_buffer )
return;
@@ -1736,17 +1736,17 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ cmFortran_yy_load_buffer_state(yyscanner );
/* We don't actually know whether we did this switch during
- * EOF (cmDependsFortran_yywrap()) processing, but the only time this flag
- * is looked at is after cmDependsFortran_yywrap() is called, so it's safe
+ * EOF (cmFortran_yywrap()) processing, but the only time this flag
+ * is looked at is after cmFortran_yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yyg->yy_did_buffer_switch_on_eof = 1;
}
-static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner)
+static void cmFortran_yy_load_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
@@ -1761,35 +1761,35 @@ static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the allocated buffer state.
*/
- YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+ YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) cmDependsFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) cmFortran_yyalloc(b->yy_buf_size + 2 ,yyscanner );
if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- cmDependsFortran_yy_init_buffer(b,file ,yyscanner);
+ cmFortran_yy_init_buffer(b,file ,yyscanner);
return b;
}
/** Destroy the buffer.
- * @param b a buffer created with cmDependsFortran_yy_create_buffer()
+ * @param b a buffer created with cmFortran_yy_create_buffer()
* @param yyscanner The scanner object.
*/
- void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -1800,9 +1800,9 @@ static void cmDependsFortran_yy_load_buffer_state (yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- cmDependsFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
+ cmFortran_yyfree((void *) b->yy_ch_buf ,yyscanner );
- cmDependsFortran_yyfree((void *) b ,yyscanner );
+ cmFortran_yyfree((void *) b ,yyscanner );
}
#ifndef __cplusplus
@@ -1811,21 +1811,21 @@ extern int isatty (int );
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
- * such as during a cmDependsFortran_yyrestart() or at EOF.
+ * such as during a cmFortran_yyrestart() or at EOF.
*/
- static void cmDependsFortran_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+ static void cmFortran_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
{
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- cmDependsFortran_yy_flush_buffer(b ,yyscanner);
+ cmFortran_yy_flush_buffer(b ,yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
- /* If b is the current buffer, then cmDependsFortran_yy_init_buffer was _probably_
- * called from cmDependsFortran_yyrestart() or through yy_get_next_buffer.
+ /* If b is the current buffer, then cmFortran_yy_init_buffer was _probably_
+ * called from cmFortran_yyrestart() or through yy_get_next_buffer.
* In that case, we don't want to reset the lineno or column.
*/
if (b != YY_CURRENT_BUFFER){
@@ -1842,7 +1842,7 @@ extern int isatty (int );
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
* @param yyscanner The scanner object.
*/
- void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! b )
@@ -1863,7 +1863,7 @@ extern int isatty (int );
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ cmFortran_yy_load_buffer_state(yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
@@ -1872,15 +1872,15 @@ extern int isatty (int );
* @param new_buffer The new state.
* @param yyscanner The scanner object.
*/
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (new_buffer == NULL)
return;
- cmDependsFortran_yyensure_buffer_stack(yyscanner);
+ cmFortran_yyensure_buffer_stack(yyscanner);
- /* This block is copied from cmDependsFortran_yy_switch_to_buffer. */
+ /* This block is copied from cmFortran_yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
@@ -1894,8 +1894,8 @@ void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- /* copied from cmDependsFortran_yy_switch_to_buffer. */
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ /* copied from cmFortran_yy_switch_to_buffer. */
+ cmFortran_yy_load_buffer_state(yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
@@ -1903,19 +1903,19 @@ void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t
* The next element becomes the new top.
* @param yyscanner The scanner object.
*/
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner)
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!YY_CURRENT_BUFFER)
return;
- cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- cmDependsFortran_yy_load_buffer_state(yyscanner );
+ cmFortran_yy_load_buffer_state(yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
@@ -1923,7 +1923,7 @@ void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner)
/* Allocates the stack if it does not exist.
* Guarantees space for at least one push.
*/
-static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
+static void cmFortran_yyensure_buffer_stack (yyscan_t yyscanner)
{
int num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -1935,11 +1935,11 @@ static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
* immediate realloc on the next call.
*/
num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyalloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
@@ -1954,12 +1954,12 @@ static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
int grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsFortran_yyrealloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmFortran_yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yyensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1973,7 +1973,7 @@ static void cmDependsFortran_yyensure_buffer_stack (yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
@@ -1983,9 +1983,9 @@ YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char * base, yy_size_t size ,
/* They forgot to leave room for the EOB's. */
return 0;
- b = (YY_BUFFER_STATE) cmDependsFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) cmFortran_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_buffer()" );
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
@@ -1997,33 +1997,33 @@ YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char * base, yy_size_t size ,
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- cmDependsFortran_yy_switch_to_buffer(b ,yyscanner );
+ cmFortran_yy_switch_to_buffer(b ,yyscanner );
return b;
}
-/** Setup the input buffer state to scan a string. The next call to cmDependsFortran_yylex() will
+/** Setup the input buffer state to scan a string. The next call to cmFortran_yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
- * cmDependsFortran_yy_scan_bytes() instead.
+ * cmFortran_yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
{
- return cmDependsFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return cmFortran_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
}
-/** Setup the input buffer state to scan the given bytes. The next call to cmDependsFortran_yylex() will
+/** Setup the input buffer state to scan the given bytes. The next call to cmFortran_yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
@@ -2032,18 +2032,18 @@ YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char * yybytes, int _y
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
- buf = (char *) cmDependsFortran_yyalloc(n ,yyscanner );
+ buf = (char *) cmFortran_yyalloc(n ,yyscanner );
if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in cmDependsFortran_yy_scan_bytes()" );
+ YY_FATAL_ERROR( "out of dynamic memory in cmFortran_yy_scan_bytes()" );
for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = cmDependsFortran_yy_scan_buffer(buf,n ,yyscanner);
+ b = cmFortran_yy_scan_buffer(buf,n ,yyscanner);
if ( ! b )
- YY_FATAL_ERROR( "bad buffer in cmDependsFortran_yy_scan_bytes()" );
+ YY_FATAL_ERROR( "bad buffer in cmFortran_yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
@@ -2085,7 +2085,7 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t)
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner)
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyextra;
@@ -2094,7 +2094,7 @@ YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner)
/** Get the current line number.
* @param yyscanner The scanner object.
*/
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner)
+int cmFortran_yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -2107,7 +2107,7 @@ int cmDependsFortran_yyget_lineno (yyscan_t yyscanner)
/** Get the current column number.
* @param yyscanner The scanner object.
*/
-int cmDependsFortran_yyget_column (yyscan_t yyscanner)
+int cmFortran_yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -2120,7 +2120,7 @@ int cmDependsFortran_yyget_column (yyscan_t yyscanner)
/** Get the input stream.
* @param yyscanner The scanner object.
*/
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner)
+FILE *cmFortran_yyget_in (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyin;
@@ -2129,7 +2129,7 @@ FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner)
/** Get the output stream.
* @param yyscanner The scanner object.
*/
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner)
+FILE *cmFortran_yyget_out (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyout;
@@ -2138,7 +2138,7 @@ FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner)
+int cmFortran_yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
@@ -2148,7 +2148,7 @@ int cmDependsFortran_yyget_leng (yyscan_t yyscanner)
* @param yyscanner The scanner object.
*/
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner)
+char *cmFortran_yyget_text (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yytext;
@@ -2158,7 +2158,7 @@ char *cmDependsFortran_yyget_text (yyscan_t yyscanner)
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
*/
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyextra = user_defined ;
@@ -2168,13 +2168,13 @@ void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscan
* @param line_number The line number to set.
* @param yyscanner The scanner object.
*/
-void cmDependsFortran_yyset_lineno (int line_number , yyscan_t yyscanner)
+void cmFortran_yyset_lineno (int line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "cmDependsFortran_yyset_lineno called with no buffer" , yyscanner);
+ yy_fatal_error( "cmFortran_yyset_lineno called with no buffer" , yyscanner);
yylineno = line_number;
}
@@ -2183,13 +2183,13 @@ void cmDependsFortran_yyset_lineno (int line_number , yyscan_t yyscanner)
* @param column_no The column number to set.
* @param yyscanner The scanner object.
*/
-void cmDependsFortran_yyset_column (int column_no , yyscan_t yyscanner)
+void cmFortran_yyset_column (int column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "cmDependsFortran_yyset_column called with no buffer" , yyscanner);
+ yy_fatal_error( "cmFortran_yyset_column called with no buffer" , yyscanner);
yycolumn = column_no;
}
@@ -2198,27 +2198,27 @@ void cmDependsFortran_yyset_column (int column_no , yyscan_t yyscanner)
* input buffer.
* @param in_str A readable stream.
* @param yyscanner The scanner object.
- * @see cmDependsFortran_yy_switch_to_buffer
+ * @see cmFortran_yy_switch_to_buffer
*/
-void cmDependsFortran_yyset_in (FILE * in_str , yyscan_t yyscanner)
+void cmFortran_yyset_in (FILE * in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyin = in_str ;
}
-void cmDependsFortran_yyset_out (FILE * out_str , yyscan_t yyscanner)
+void cmFortran_yyset_out (FILE * out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = out_str ;
}
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner)
+int cmFortran_yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
-void cmDependsFortran_yyset_debug (int bdebug , yyscan_t yyscanner)
+void cmFortran_yyset_debug (int bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = bdebug ;
@@ -2228,12 +2228,12 @@ void cmDependsFortran_yyset_debug (int bdebug , yyscan_t yyscanner)
/* User-visible API */
-/* cmDependsFortran_yylex_init is special because it creates the scanner itself, so it is
+/* cmFortran_yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-int cmDependsFortran_yylex_init(yyscan_t* ptr_yy_globals)
+int cmFortran_yylex_init(yyscan_t* ptr_yy_globals)
{
if (ptr_yy_globals == NULL){
@@ -2241,7 +2241,7 @@ int cmDependsFortran_yylex_init(yyscan_t* ptr_yy_globals)
return 1;
}
- *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
+ *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), NULL );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
@@ -2254,27 +2254,27 @@ int cmDependsFortran_yylex_init(yyscan_t* ptr_yy_globals)
return yy_init_globals ( *ptr_yy_globals );
}
-/* cmDependsFortran_yylex_init_extra has the same functionality as cmDependsFortran_yylex_init, but follows the
+/* cmFortran_yylex_init_extra has the same functionality as cmFortran_yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
* is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to cmDependsFortran_yyalloc in
+ * The user defined value in the first argument will be available to cmFortran_yyalloc in
* the yyextra field.
*/
-int cmDependsFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+int cmFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
- cmDependsFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
+ cmFortran_yyset_extra (yy_user_defined, &dummy_yyguts);
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
- *ptr_yy_globals = (yyscan_t) cmDependsFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+ *ptr_yy_globals = (yyscan_t) cmFortran_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
@@ -2285,7 +2285,7 @@ int cmDependsFortran_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* pt
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
- cmDependsFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
+ cmFortran_yyset_extra (yy_user_defined, *ptr_yy_globals);
return yy_init_globals ( *ptr_yy_globals );
}
@@ -2294,7 +2294,7 @@ static int yy_init_globals (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Initialization is the same as for the non-reentrant scanner.
- * This function is called from cmDependsFortran_yylex_destroy(), so don't allocate here.
+ * This function is called from cmFortran_yylex_destroy(), so don't allocate here.
*/
yyg->yy_buffer_stack = 0;
@@ -2318,37 +2318,37 @@ static int yy_init_globals (yyscan_t yyscanner)
#endif
/* For future reference: Set errno on error, since we are called by
- * cmDependsFortran_yylex_init()
+ * cmFortran_yylex_init()
*/
return 0;
}
-/* cmDependsFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner)
+/* cmFortran_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmFortran_yylex_destroy (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- cmDependsFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ cmFortran_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
- cmDependsFortran_yypop_buffer_state(yyscanner);
+ cmFortran_yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- cmDependsFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ cmFortran_yyfree(yyg->yy_buffer_stack ,yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- cmDependsFortran_yyfree(yyg->yy_start_stack ,yyscanner );
+ cmFortran_yyfree(yyg->yy_start_stack ,yyscanner );
yyg->yy_start_stack = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
- * cmDependsFortran_yylex() is called, initialization will occur. */
+ * cmFortran_yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
/* Destroy the main struct (reentrant only). */
- cmDependsFortran_yyfree ( yyscanner , yyscanner );
+ cmFortran_yyfree ( yyscanner , yyscanner );
return 0;
}
@@ -2376,12 +2376,12 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
}
#endif
-void *cmDependsFortran_yyalloc (yy_size_t size , yyscan_t)
+void *cmFortran_yyalloc (yy_size_t size , yyscan_t)
{
return (void *) malloc( size );
}
-void *cmDependsFortran_yyrealloc (void * ptr, yy_size_t size , yyscan_t)
+void *cmFortran_yyrealloc (void * ptr, yy_size_t size , yyscan_t)
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
@@ -2393,22 +2393,21 @@ void *cmDependsFortran_yyrealloc (void * ptr, yy_size_t size , yyscan_t)
return (void *) realloc( (char *) ptr, size );
}
-void cmDependsFortran_yyfree (void * ptr , yyscan_t)
+void cmFortran_yyfree (void * ptr , yyscan_t)
{
- free( (char *) ptr ); /* see cmDependsFortran_yyrealloc() for (char *) cast */
+ free( (char *) ptr ); /* see cmFortran_yyrealloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"
-#line 181 "cmDependsFortranLexer.in.l"
+#line 181 "cmFortranLexer.in.l"
/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
{
/* Hack into the internal flex-generated scanner to get the buffer. */
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return YY_CURRENT_BUFFER;
}
-
diff --git a/Source/cmDependsFortranLexer.h b/Source/cmFortranLexer.h
index 8e24cfd..c67e332 100644
--- a/Source/cmDependsFortranLexer.h
+++ b/Source/cmFortranLexer.h
@@ -9,9 +9,9 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
-#ifndef cmDependsFortran_yyHEADER_H
-#define cmDependsFortran_yyHEADER_H 1
-#define cmDependsFortran_yyIN_HEADER 1
+#ifndef cmFortran_yyHEADER_H
+#define cmFortran_yyHEADER_H 1
+#define cmFortran_yyIN_HEADER 1
#define YY_INT_ALIGNED short int
@@ -211,25 +211,25 @@ struct yy_buffer_state
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-void cmDependsFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void cmDependsFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void cmDependsFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void cmDependsFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void cmDependsFortran_yypop_buffer_state (yyscan_t yyscanner );
+void cmFortran_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmFortran_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmFortran_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmFortran_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmFortran_yypop_buffer_state (yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE cmDependsFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmFortran_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-void *cmDependsFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *cmDependsFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
+void *cmFortran_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmFortran_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmFortran_yyfree (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
-#define cmDependsFortran_yywrap(n) 1
+#define cmFortran_yywrap(n) 1
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
@@ -247,38 +247,38 @@ void cmDependsFortran_yyfree (void * ,yyscan_t yyscanner );
#define YY_EXTRA_TYPE void *
#endif
-int cmDependsFortran_yylex_init (yyscan_t* scanner);
+int cmFortran_yylex_init (yyscan_t* scanner);
-int cmDependsFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int cmFortran_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int cmDependsFortran_yylex_destroy (yyscan_t yyscanner );
+int cmFortran_yylex_destroy (yyscan_t yyscanner );
-int cmDependsFortran_yyget_debug (yyscan_t yyscanner );
+int cmFortran_yyget_debug (yyscan_t yyscanner );
-void cmDependsFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+void cmFortran_yyset_debug (int debug_flag ,yyscan_t yyscanner );
-YY_EXTRA_TYPE cmDependsFortran_yyget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE cmFortran_yyget_extra (yyscan_t yyscanner );
-void cmDependsFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void cmFortran_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-FILE *cmDependsFortran_yyget_in (yyscan_t yyscanner );
+FILE *cmFortran_yyget_in (yyscan_t yyscanner );
-void cmDependsFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+void cmFortran_yyset_in (FILE * in_str ,yyscan_t yyscanner );
-FILE *cmDependsFortran_yyget_out (yyscan_t yyscanner );
+FILE *cmFortran_yyget_out (yyscan_t yyscanner );
-void cmDependsFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+void cmFortran_yyset_out (FILE * out_str ,yyscan_t yyscanner );
-int cmDependsFortran_yyget_leng (yyscan_t yyscanner );
+int cmFortran_yyget_leng (yyscan_t yyscanner );
-char *cmDependsFortran_yyget_text (yyscan_t yyscanner );
+char *cmFortran_yyget_text (yyscan_t yyscanner );
-int cmDependsFortran_yyget_lineno (yyscan_t yyscanner );
+int cmFortran_yyget_lineno (yyscan_t yyscanner );
-void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
+void cmFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -286,9 +286,9 @@ void cmDependsFortran_yyset_lineno (int line_number ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int cmDependsFortran_yywrap (yyscan_t yyscanner );
+extern "C" int cmFortran_yywrap (yyscan_t yyscanner );
#else
-extern int cmDependsFortran_yywrap (yyscan_t yyscanner );
+extern int cmFortran_yywrap (yyscan_t yyscanner );
#endif
#endif
@@ -325,9 +325,9 @@ static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
-extern int cmDependsFortran_yylex (yyscan_t yyscanner);
+extern int cmFortran_yylex (yyscan_t yyscanner);
-#define YY_DECL int cmDependsFortran_yylex (yyscan_t yyscanner)
+#define YY_DECL int cmFortran_yylex (yyscan_t yyscanner)
#endif /* !YY_DECL */
/* yy_get_previous_state - get the state just before the EOB char was reached */
@@ -344,5 +344,5 @@ extern int cmDependsFortran_yylex (yyscan_t yyscanner);
#undef YY_DECL
#endif
-#undef cmDependsFortran_yyIN_HEADER
-#endif /* cmDependsFortran_yyHEADER_H */
+#undef cmFortran_yyIN_HEADER
+#endif /* cmFortran_yyHEADER_H */
diff --git a/Source/cmDependsFortranLexer.in.l b/Source/cmFortranLexer.in.l
index 0148802..03fa90c 100644
--- a/Source/cmDependsFortranLexer.in.l
+++ b/Source/cmFortranLexer.in.l
@@ -26,18 +26,18 @@ This file must be translated to C and modified to build everywhere.
Run flex like this:
- flex -i --prefix=cmDependsFortran_yy --header-file=cmDependsFortranLexer.h -ocmDependsFortranLexer.cxx cmDependsFortranLexer.in.l
+ flex -i --prefix=cmFortran_yy --header-file=cmFortranLexer.h -ocmFortranLexer.cxx cmFortranLexer.in.l
-Modify cmDependsFortranLexer.cxx:
+Modify cmFortranLexer.cxx:
- remove TABs
- remove use of the 'register' storage class specifier
- remove "yyscanner" argument from these methods:
- yy_fatal_error, cmDependsFortran_yyalloc, cmDependsFortran_yyrealloc, cmDependsFortran_yyfree
- - remove "yyscanner = NULL" from end of cmDependsFortran_yylex_destroy
+ yy_fatal_error, cmFortran_yyalloc, cmFortran_yyrealloc, cmFortran_yyfree
+ - remove "yyscanner = NULL" from end of cmFortran_yylex_destroy
- remove all YY_BREAK lines occurring right after return statements
- change while ( 1 ) to for(;;)
-Modify cmDependsFortranLexer.h:
+Modify cmFortranLexer.h:
- remove TABs
- remove the yy_init_globals function
- remove the block that includes unistd.h
@@ -47,16 +47,16 @@ Modify cmDependsFortranLexer.h:
#include "cmStandardLexer.h"
-#define cmDependsFortranLexer_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
+#define cmFortranLexer_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
/* Replace the lexer input function. */
#undef YY_INPUT
#define YY_INPUT(buf, result, max_size) \
- { result = cmDependsFortranParser_Input(yyextra, buf, max_size); }
+ { result = cmFortranParser_Input(yyextra, buf, max_size); }
/* Include the set of tokens from the parser. */
-#include "cmDependsFortranParserTokens.h"
+#include "cmFortranParserTokens.h"
/*--------------------------------------------------------------------------*/
%}
@@ -72,21 +72,21 @@ Modify cmDependsFortranLexer.h:
%%
\" {
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
BEGIN(str_dq);
}
' {
- cmDependsFortranParser_StringStart(yyextra);
- cmDependsFortranParser_SetOldStartcond(yyextra, YY_START);
+ cmFortranParser_StringStart(yyextra);
+ cmFortranParser_SetOldStartcond(yyextra, YY_START);
BEGIN(str_sq);
}
<str_dq>\" |
<str_sq>' {
- BEGIN(cmDependsFortranParser_GetOldStartcond(yyextra) );
- yylvalp->string = strdup(cmDependsFortranParser_StringEnd(yyextra));
+ BEGIN(cmFortranParser_GetOldStartcond(yyextra) );
+ yylvalp->string = strdup(cmFortranParser_StringEnd(yyextra));
return STRING;
}
@@ -94,7 +94,7 @@ Modify cmDependsFortranLexer.h:
<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
- if (cmDependsFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
+ if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
; /* Ignore (cont. strings, fixed fmt) */
else
{
@@ -110,7 +110,7 @@ Modify cmDependsFortranLexer.h:
}
<str_sq,str_dq>. {
- cmDependsFortranParser_StringAppend(yyextra, yytext[0]);
+ cmFortranParser_StringAppend(yyextra, yytext[0]);
}
!.*\n { return EOSTMT; } /* Treat comments like */
@@ -173,7 +173,7 @@ $[ \t]*endif { return F90PPR_ENDIF; }
. { return *yytext; }
<<EOF>> {
- if(!cmDependsFortranParser_FilePop(yyextra) )
+ if(!cmFortranParser_FilePop(yyextra) )
{
return YY_NULL;
}
@@ -182,7 +182,7 @@ $[ \t]*endif { return F90PPR_ENDIF; }
%%
/*--------------------------------------------------------------------------*/
-YY_BUFFER_STATE cmDependsFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner)
{
/* Hack into the internal flex-generated scanner to get the buffer. */
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
diff --git a/Source/cmDependsFortranParser.cxx b/Source/cmFortranParser.cxx
index 9d51025..0230f02 100644
--- a/Source/cmDependsFortranParser.cxx
+++ b/Source/cmFortranParser.cxx
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 3.0.2. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "3.0.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,23 +58,17 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
-#define yyparse cmDependsFortran_yyparse
-#define yylex cmDependsFortran_yylex
-#define yyerror cmDependsFortran_yyerror
-#define yylval cmDependsFortran_yylval
-#define yychar cmDependsFortran_yychar
-#define yydebug cmDependsFortran_yydebug
-#define yynerrs cmDependsFortran_yynerrs
+#define yyparse cmFortran_yyparse
+#define yylex cmFortran_yylex
+#define yyerror cmFortran_yyerror
+#define yydebug cmFortran_yydebug
+#define yynerrs cmFortran_yynerrs
/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 1 "cmDependsFortranParser.y"
+#line 1 "cmFortranParser.y" /* yacc.c:339 */
/*============================================================================
CMake - Cross Platform Makefile Generator
@@ -103,41 +97,33 @@ This file must be translated to C and modified to build everywhere.
Run bison like this:
- bison --yacc --name-prefix=cmDependsFortran_yy
- --defines=cmDependsFortranParserTokens.h
- -ocmDependsFortranParser.cxx
- cmDependsFortranParser.y
+ bison --yacc --name-prefix=cmFortran_yy
+ --defines=cmFortranParserTokens.h
+ -ocmFortranParser.cxx
+ cmFortranParser.y
-Modify cmDependsFortranParser.cxx:
- - remove TABs
- - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+Modify cmFortranParser.cxx:
+ - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
*/
/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
#include <cmsys/String.h>
-/* Configure the parser to use a lexer object. */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
- cmDependsFortranError(yyscanner, x)
-
/* Forward declare the lexer entry point. */
YY_DECL;
-/* Helper function to forward error callback. */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
+/* Helper function to forward error callback from parser. */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_Error(parser, message);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_Error(parser, message);
}
-static bool cmDependsFortranParserIsKeyword(const char* word,
+static bool cmFortranParserIsKeyword(const char* word,
const char* keyword)
{
return cmsysString_strcasecmp(word, keyword) == 0;
@@ -153,65 +139,71 @@ static bool cmDependsFortranParserIsKeyword(const char* word,
# pragma warning (disable: 4244) /* Conversion to smaller type, data loss. */
#endif
+#line 143 "cmFortranParser.cxx" /* yacc.c:339 */
-/* Line 268 of yacc.c */
-#line 165 "cmDependsFortranParser.cxx"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
-# define YYERROR_VERBOSE 0
+# define YYERROR_VERBOSE 1
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+ by #include "cmFortranParserTokens.h". */
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
#endif
-
-/* Tokens. */
+/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EOSTMT = 258,
- ASSIGNMENT_OP = 259,
- GARBAGE = 260,
- CPP_INCLUDE = 261,
- F90PPR_INCLUDE = 262,
- COCO_INCLUDE = 263,
- F90PPR_DEFINE = 264,
- CPP_DEFINE = 265,
- F90PPR_UNDEF = 266,
- CPP_UNDEF = 267,
- CPP_IFDEF = 268,
- CPP_IFNDEF = 269,
- CPP_IF = 270,
- CPP_ELSE = 271,
- CPP_ELIF = 272,
- CPP_ENDIF = 273,
- F90PPR_IFDEF = 274,
- F90PPR_IFNDEF = 275,
- F90PPR_IF = 276,
- F90PPR_ELSE = 277,
- F90PPR_ELIF = 278,
- F90PPR_ENDIF = 279,
- COMMA = 280,
- DCOLON = 281,
- CPP_TOENDL = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286
- };
+ enum yytokentype
+ {
+ EOSTMT = 258,
+ ASSIGNMENT_OP = 259,
+ GARBAGE = 260,
+ CPP_INCLUDE = 261,
+ F90PPR_INCLUDE = 262,
+ COCO_INCLUDE = 263,
+ F90PPR_DEFINE = 264,
+ CPP_DEFINE = 265,
+ F90PPR_UNDEF = 266,
+ CPP_UNDEF = 267,
+ CPP_IFDEF = 268,
+ CPP_IFNDEF = 269,
+ CPP_IF = 270,
+ CPP_ELSE = 271,
+ CPP_ELIF = 272,
+ CPP_ENDIF = 273,
+ F90PPR_IFDEF = 274,
+ F90PPR_IFNDEF = 275,
+ F90PPR_IF = 276,
+ F90PPR_ELSE = 277,
+ F90PPR_ELIF = 278,
+ F90PPR_ENDIF = 279,
+ COMMA = 280,
+ DCOLON = 281,
+ CPP_TOENDL = 282,
+ UNTERMINATED_STRING = 283,
+ STRING = 284,
+ WORD = 285,
+ CPP_INCLUDE_ANGLE = 286
+ };
#endif
/* Tokens. */
#define EOSTMT 258
@@ -244,34 +236,30 @@ static bool cmDependsFortranParserIsKeyword(const char* word,
#define WORD 285
#define CPP_INCLUDE_ANGLE 286
-
-
-
+/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
{
-
-/* Line 293 of yacc.c */
-#line 89 "cmDependsFortranParser.y"
+#line 81 "cmFortranParser.y" /* yacc.c:355 */
char* string;
-
-
-/* Line 293 of yacc.c */
-#line 269 "cmDependsFortranParser.cxx"
-} YYSTYPE;
+#line 249 "cmFortranParser.cxx" /* yacc.c:355 */
+};
# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
-/* Copy the second part of user declarations. */
+int cmFortran_yyparse (yyscan_t yyscanner);
-/* Line 343 of yacc.c */
-#line 281 "cmDependsFortranParser.cxx"
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 263 "cmFortranParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -285,11 +273,8 @@ typedef unsigned char yytype_uint8;
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
#else
-typedef short int yytype_int8;
+typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
@@ -309,8 +294,7 @@ typedef short int yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# elif ! defined YYSIZE_T
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
@@ -324,38 +308,67 @@ typedef short int yytype_int16;
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
-# define YY_(msgid) msgid
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
#else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
#endif
-/* Identity function, used to suppress warnings about constant conditions. */
-#ifndef lint
-# define YYID(n) (n)
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
-#else
-static int
-YYID (yyi)
- int yyi;
+# define YY_INITIAL_VALUE(Value) Value
#endif
-{
- return yyi;
-}
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
#if ! defined yyoverflow || YYERROR_VERBOSE
@@ -374,9 +387,9 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -386,8 +399,8 @@ YYID (yyi)
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
@@ -411,15 +424,13 @@ YYID (yyi)
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
+# if ! defined free && ! defined EXIT_SUCCESS
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
@@ -463,26 +474,26 @@ union yyalloc
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
- while (YYID (0))
+ while (0)
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
+# define YYCOPY(Dst, Src, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
+ (Dst)[yyi] = (Src)[yyi]; \
} \
- while (YYID (0))
+ while (0)
# endif
# endif
#endif /* !YYCOPY_NEEDED */
@@ -498,17 +509,19 @@ union yyalloc
#define YYNNTS 16
/* YYNRULES -- Number of rules. */
#define YYNRULES 53
-/* YYNRULES -- Number of states. */
+/* YYNSTATES -- Number of states. */
#define YYNSTATES 97
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 286
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -543,52 +556,19 @@ static const yytype_uint8 yytranslate[] =
};
#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
- YYRHS. */
-static const yytype_uint8 yyprhs[] =
-{
- 0, 0, 3, 4, 7, 9, 11, 16, 19, 24,
- 30, 38, 43, 47, 52, 57, 62, 67, 72, 76,
- 80, 84, 88, 93, 97, 99, 101, 103, 105, 107,
- 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,
- 129, 131, 133, 135, 137, 139, 140, 143, 145, 147,
- 149, 151, 153, 155
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yytype_int8 yyrhs[] =
-{
- 33, 0, -1, -1, 33, 34, -1, 36, -1, 35,
- -1, 30, 4, 46, 3, -1, 30, 3, -1, 30,
- 30, 46, 3, -1, 30, 26, 30, 46, 3, -1,
- 30, 25, 30, 26, 30, 46, 3, -1, 30, 29,
- 46, 3, -1, 31, 46, 3, -1, 37, 29, 46,
- 3, -1, 38, 30, 46, 3, -1, 39, 30, 46,
- 3, -1, 40, 30, 46, 3, -1, 41, 30, 46,
- 3, -1, 42, 46, 3, -1, 43, 46, 3, -1,
- 44, 46, 3, -1, 45, 46, 3, -1, 30, 5,
- 46, 3, -1, 5, 46, 3, -1, 3, -1, 1,
- -1, 6, -1, 7, -1, 8, -1, 10, -1, 9,
- -1, 12, -1, 11, -1, 13, -1, 19, -1, 14,
- -1, 20, -1, 15, -1, 21, -1, 17, -1, 23,
- -1, 16, -1, 22, -1, 18, -1, 24, -1, -1,
- 46, 47, -1, 30, -1, 29, -1, 5, -1, 4,
- -1, 26, -1, 25, -1, 28, -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 111, 111, 111, 113, 113, 115, 121, 131, 161,
- 172, 185, 196, 203, 210, 216, 222, 228, 234, 239,
- 244, 249, 254, 258, 259, 260, 265, 265, 265, 266,
- 266, 267, 267, 268, 268, 269, 269, 270, 270, 271,
- 271, 272, 272, 273, 273, 274, 274, 277, 278, 279,
- 280, 281, 282, 283
+ 0, 103, 103, 103, 105, 105, 107, 113, 123, 153,
+ 164, 177, 188, 195, 202, 208, 214, 220, 226, 231,
+ 236, 241, 246, 250, 251, 252, 257, 257, 257, 258,
+ 258, 259, 259, 260, 260, 261, 261, 262, 262, 263,
+ 263, 264, 264, 265, 265, 266, 266, 269, 270, 271,
+ 272, 273, 274, 275
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 1
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@@ -601,13 +581,13 @@ static const char *const yytname[] =
"F90PPR_ENDIF", "COMMA", "DCOLON", "CPP_TOENDL", "UNTERMINATED_STRING",
"STRING", "WORD", "CPP_INCLUDE_ANGLE", "$accept", "code", "stmt",
"assignment_stmt", "keyword_stmt", "include", "define", "undef", "ifdef",
- "ifndef", "if", "elif", "else", "endif", "other", "misc_code", 0
+ "ifndef", "if", "elif", "else", "endif", "other", "misc_code", YY_NULLPTR
};
#endif
# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
- token YYLEX-NUM. */
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
@@ -617,31 +597,35 @@ static const yytype_uint16 yytoknum[] =
};
# endif
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
- 0, 32, 33, 33, 34, 34, 35, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 37, 37, 37, 38,
- 38, 39, 39, 40, 40, 41, 41, 42, 42, 43,
- 43, 44, 44, 45, 45, 46, 46, 47, 47, 47,
- 47, 47, 47, 47
-};
+#define YYPACT_NINF -29
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-29)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
{
- 0, 2, 0, 2, 1, 1, 4, 2, 4, 5,
- 7, 4, 3, 4, 4, 4, 4, 4, 3, 3,
- 3, 3, 4, 3, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 2, 1, 1, 1,
- 1, 1, 1, 1
+ -29, 39, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, 246, -29, -29, -29, -29,
+ -28, -27, -22, -17, -16, -29, -29, -29, -29, 2,
+ -29, -29, -29, -13, -12, -29, -29, 61, -29, -29,
+ -29, -29, -29, 68, 74, 80, 108, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, 114, 120, -24, -29,
+ 126, 154, -29, 160, 166, 172, 200, 206, -29, -29,
+ -29, -29, -29, -29, -9, 212, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, 218, -29
};
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
- means the default is an error. */
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
static const yytype_uint8 yydefact[] =
{
2, 0, 1, 25, 24, 45, 26, 27, 28, 30,
@@ -656,41 +640,23 @@ static const yytype_uint8 yydefact[] =
15, 16, 17, 45, 9, 0, 10
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
-{
- -1, 1, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 65
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
-#define YYPACT_NINF -29
-static const yytype_int16 yypact[] =
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
{
- -29, 39, -29, -29, -29, -29, -29, -29, -29, -29,
-29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, 246, -29, -29, -29, -29,
- -28, -27, -22, -17, -16, -29, -29, -29, -29, 2,
- -29, -29, -29, -13, -12, -29, -29, 61, -29, -29,
- -29, -29, -29, 68, 74, 80, 108, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, 114, 120, -24, -29,
- 126, 154, -29, 160, 166, 172, 200, 206, -29, -29,
- -29, -29, -29, -29, -9, 212, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, 218, -29
+ -29, -29, -29, -29, -26, -29
};
-/* YYPGOTO[NTERM-NUM]. */
-static const yytype_int8 yypgoto[] =
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
{
- -29, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -26, -29
+ -1, 1, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 65
};
-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -1
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
47, 48, 84, 49, 0, 57, 58, 59, 50, 53,
@@ -723,12 +689,6 @@ static const yytype_uint8 yytable[] =
0, 43, 44, 0, 0, 45, 46
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-29))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int8 yycheck[] =
{
26, 29, 26, 30, -1, 3, 4, 5, 30, 35,
@@ -761,8 +721,8 @@ static const yytype_int8 yycheck[] =
-1, 25, 26, -1, -1, 29, 30
};
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 33, 0, 1, 3, 5, 6, 7, 8, 9,
@@ -777,6 +737,29 @@ static const yytype_uint8 yystos[] =
3, 3, 3, 30, 3, 46, 3
};
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 32, 33, 33, 34, 34, 35, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 37, 37, 37, 38,
+ 38, 39, 39, 40, 40, 41, 41, 42, 42, 43,
+ 43, 44, 44, 45, 45, 46, 46, 47, 47, 47,
+ 47, 47, 47, 47
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 4, 2, 4, 5,
+ 7, 4, 3, 4, 4, 4, 4, 4, 3, 3,
+ 3, 3, 4, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 2, 1, 1, 1,
+ 1, 1, 1, 1
+};
+
+
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
@@ -787,84 +770,30 @@ static const yytype_uint8 yystos[] =
#define YYERROR goto yyerrorlab
-/* Like YYERROR except do call yyerror. This remains here temporarily
- to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
-
-#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
-
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \
do \
- if (yychar == YYEMPTY && yylen == 1) \
+ if (yychar == YYEMPTY) \
{ \
yychar = (Token); \
yylval = (Value); \
- YYPOPSTACK (1); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
goto yybackup; \
} \
else \
{ \
- yyerror (YY_("syntax error: cannot back up")); \
+ yyerror (yyscanner, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
-while (YYID (0))
-
+while (0)
+/* Error token number */
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
-/* This macro is provided for backward compatibility. */
-
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments. */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval)
-#endif
/* Enable debugging if requested. */
#if YYDEBUG
@@ -878,7 +807,13 @@ while (YYID (0))
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (YYID (0))
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
@@ -886,42 +821,29 @@ do { \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value); \
+ Type, Value, yyscanner); \
YYFPRINTF (stderr, "\n"); \
} \
-} while (YYID (0))
+} while (0)
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ YYUSE (yyscanner);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
- YYUSE (yyoutput);
# endif
- switch (yytype)
- {
- default:
- break;
- }
+ YYUSE (yytype);
}
@@ -929,24 +851,13 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
| Print this symbol on YYOUTPUT. |
`--------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-#else
static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE const * const yyvaluep;
-#endif
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
{
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
- else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
YYFPRINTF (yyoutput, ")");
}
@@ -955,16 +866,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
| TOP (included). |
`------------------------------------------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
static void
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
-#endif
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -979,36 +882,29 @@ yy_stack_print (yybottom, yytop)
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
-} while (YYID (0))
+} while (0)
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-#else
-static void
-yy_reduce_print (yyvsp, yyrule)
- YYSTYPE *yyvsp;
- int yyrule;
-#endif
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
{
+ unsigned long int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
- unsigned long int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
&(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ , yyscanner);
YYFPRINTF (stderr, "\n");
}
}
@@ -1016,8 +912,8 @@ yy_reduce_print (yyvsp, yyrule)
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
-} while (YYID (0))
+ yy_reduce_print (yyssp, yyvsp, Rule, yyscanner); \
+} while (0)
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -1054,15 +950,8 @@ int yydebug;
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
- const char *yystr;
-#endif
{
YYSIZE_T yylen;
for (yylen = 0; yystr[yylen]; yylen++)
@@ -1078,16 +967,8 @@ yystrlen (yystr)
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
static char *
yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-#endif
{
char *yyd = yydest;
const char *yys = yysrc;
@@ -1160,12 +1041,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULLPTR;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1173,10 +1053,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
int yycount = 0;
/* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
@@ -1225,11 +1101,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
}
}
}
@@ -1249,10 +1127,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
# undef YYCASE_
}
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
if (*yymsg_alloc < yysize)
{
@@ -1289,81 +1169,39 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-#else
static void
-yydestruct (yymsg, yytype, yyvaluep)
- const char *yymsg;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, yyscan_t yyscanner)
{
YYUSE (yyvaluep);
-
+ YYUSE (yyscanner);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
- switch (yytype)
- {
-
- default:
- break;
- }
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
/*----------.
| yyparse. |
`----------*/
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
- || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void)
-#else
int
-yyparse ()
-
-#endif
-#endif
+yyparse (yyscan_t yyscanner)
{
/* The lookahead symbol. */
int yychar;
+
/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
+/* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
+YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
/* Number of syntax errors so far. */
int yynerrs;
@@ -1373,10 +1211,10 @@ YYSTYPE yylval;
int yyerrstatus;
/* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1394,7 +1232,7 @@ YYSTYPE yylval;
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
- int yytoken;
+ int yytoken = 0;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
@@ -1412,9 +1250,8 @@ YYSTYPE yylval;
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1423,14 +1260,6 @@ YYSTYPE yylval;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
- yyssp = yyss;
- yyvsp = yyvs;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1531,7 +1360,7 @@ yybackup:
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
- yychar = YYLEX;
+ yychar = yylex (&yylval, yyscanner);
}
if (yychar <= YYEOF)
@@ -1571,7 +1400,9 @@ yybackup:
yychar = YYEMPTY;
yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate;
@@ -1594,7 +1425,7 @@ yyreduce:
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
- `$$ = $1'.
+ '$$ = $1'.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
@@ -1608,249 +1439,228 @@ yyreduce:
switch (yyn)
{
case 6:
-
-/* Line 1806 of yacc.c */
-#line 116 "cmDependsFortranParser.y"
+#line 108 "cmFortranParser.y" /* yacc.c:1646 */
{
- free((yyvsp[(1) - (4)].string));
+ free((yyvsp[-3].string));
}
+#line 1447 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 7:
-
-/* Line 1806 of yacc.c */
-#line 122 "cmDependsFortranParser.y"
+#line 114 "cmFortranParser.y" /* yacc.c:1646 */
{
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (2)].string), "interface"))
+ if (cmFortranParserIsKeyword((yyvsp[-1].string), "interface"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
}
- free((yyvsp[(1) - (2)].string));
+ free((yyvsp[-1].string));
}
+#line 1461 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 8:
-
-/* Line 1806 of yacc.c */
-#line 132 "cmDependsFortranParser.y"
+#line 124 "cmFortranParser.y" /* yacc.c:1646 */
{
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "use"))
+ if (cmFortranParserIsKeyword((yyvsp[-3].string), "use"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(2) - (4)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
}
- else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "module"))
+ else if (cmFortranParserIsKeyword((yyvsp[-3].string), "module"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleModule(parser, (yyvsp[(2) - (4)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
}
- else if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "interface"))
+ else if (cmFortranParserIsKeyword((yyvsp[-3].string), "interface"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
}
- else if (cmDependsFortranParserIsKeyword((yyvsp[(2) - (4)].string), "interface") &&
- cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "end"))
+ else if (cmFortranParserIsKeyword((yyvsp[-2].string), "interface") &&
+ cmFortranParserIsKeyword((yyvsp[-3].string), "end"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, false);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, false);
}
- free((yyvsp[(1) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ free((yyvsp[-3].string));
+ free((yyvsp[-2].string));
}
+#line 1495 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 9:
-
-/* Line 1806 of yacc.c */
-#line 162 "cmDependsFortranParser.y"
+#line 154 "cmFortranParser.y" /* yacc.c:1646 */
{
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (5)].string), "use"))
+ if (cmFortranParserIsKeyword((yyvsp[-4].string), "use"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(3) - (5)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
}
- free((yyvsp[(1) - (5)].string));
- free((yyvsp[(3) - (5)].string));
+ free((yyvsp[-4].string));
+ free((yyvsp[-2].string));
}
+#line 1510 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 10:
-
-/* Line 1806 of yacc.c */
-#line 173 "cmDependsFortranParser.y"
+#line 165 "cmFortranParser.y" /* yacc.c:1646 */
{
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (7)].string), "use") &&
- cmDependsFortranParserIsKeyword((yyvsp[(3) - (7)].string), "non_intrinsic") )
+ if (cmFortranParserIsKeyword((yyvsp[-6].string), "use") &&
+ cmFortranParserIsKeyword((yyvsp[-4].string), "non_intrinsic") )
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, (yyvsp[(5) - (7)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
}
- free((yyvsp[(1) - (7)].string));
- free((yyvsp[(3) - (7)].string));
- free((yyvsp[(5) - (7)].string));
+ free((yyvsp[-6].string));
+ free((yyvsp[-4].string));
+ free((yyvsp[-2].string));
}
+#line 1527 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 11:
-
-/* Line 1806 of yacc.c */
-#line 186 "cmDependsFortranParser.y"
+#line 178 "cmFortranParser.y" /* yacc.c:1646 */
{
- if (cmDependsFortranParserIsKeyword((yyvsp[(1) - (4)].string), "include"))
+ if (cmFortranParserIsKeyword((yyvsp[-3].string), "include"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
}
- free((yyvsp[(1) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ free((yyvsp[-3].string));
+ free((yyvsp[-2].string));
}
+#line 1542 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 12:
-
-/* Line 1806 of yacc.c */
-#line 197 "cmDependsFortranParser.y"
+#line 189 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(1) - (3)].string));
- free((yyvsp[(1) - (3)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1553 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 13:
-
-/* Line 1806 of yacc.c */
-#line 204 "cmDependsFortranParser.y"
+#line 196 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1564 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 14:
-
-/* Line 1806 of yacc.c */
-#line 211 "cmDependsFortranParser.y"
+#line 203 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleDefine(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1574 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 15:
-
-/* Line 1806 of yacc.c */
-#line 217 "cmDependsFortranParser.y"
+#line 209 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUndef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1584 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 16:
-
-/* Line 1806 of yacc.c */
-#line 223 "cmDependsFortranParser.y"
+#line 215 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfdef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1594 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 17:
-
-/* Line 1806 of yacc.c */
-#line 229 "cmDependsFortranParser.y"
+#line 221 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfndef(parser, (yyvsp[(2) - (4)].string));
- free((yyvsp[(2) - (4)].string));
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
}
+#line 1604 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 18:
-
-/* Line 1806 of yacc.c */
-#line 235 "cmDependsFortranParser.y"
+#line 227 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIf(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIf(parser);
}
+#line 1613 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 19:
-
-/* Line 1806 of yacc.c */
-#line 240 "cmDependsFortranParser.y"
+#line 232 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElif(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElif(parser);
}
+#line 1622 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 20:
-
-/* Line 1806 of yacc.c */
-#line 245 "cmDependsFortranParser.y"
+#line 237 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElse(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElse(parser);
}
+#line 1631 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 21:
-
-/* Line 1806 of yacc.c */
-#line 250 "cmDependsFortranParser.y"
+#line 242 "cmFortranParser.y" /* yacc.c:1646 */
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleEndif(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleEndif(parser);
}
+#line 1640 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 22:
-
-/* Line 1806 of yacc.c */
-#line 255 "cmDependsFortranParser.y"
+#line 247 "cmFortranParser.y" /* yacc.c:1646 */
{
- free((yyvsp[(1) - (4)].string));
+ free((yyvsp[-3].string));
}
+#line 1648 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 47:
-
-/* Line 1806 of yacc.c */
-#line 277 "cmDependsFortranParser.y"
- { free ((yyvsp[(1) - (1)].string)); }
+#line 269 "cmFortranParser.y" /* yacc.c:1646 */
+ { free ((yyvsp[0].string)); }
+#line 1654 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 48:
-
-/* Line 1806 of yacc.c */
-#line 278 "cmDependsFortranParser.y"
- { free ((yyvsp[(1) - (1)].string)); }
+#line 270 "cmFortranParser.y" /* yacc.c:1646 */
+ { free ((yyvsp[0].string)); }
+#line 1660 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
-
-/* Line 1806 of yacc.c */
-#line 1860 "cmDependsFortranParser.cxx"
+#line 1664 "cmFortranParser.cxx" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1872,7 +1682,7 @@ yyreduce:
*++yyvsp = yyval;
- /* Now `shift' the result of the reduction. Determine what state
+ /* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -1887,9 +1697,9 @@ yyreduce:
goto yynewstate;
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
@@ -1900,7 +1710,7 @@ yyerrlab:
{
++yynerrs;
#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
+ yyerror (yyscanner, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
@@ -1927,7 +1737,7 @@ yyerrlab:
yymsgp = yymsg;
}
}
- yyerror (yymsgp);
+ yyerror (yyscanner, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
@@ -1951,7 +1761,7 @@ yyerrlab:
else
{
yydestruct ("Error: discarding",
- yytoken, &yylval);
+ yytoken, &yylval, yyscanner);
yychar = YYEMPTY;
}
}
@@ -1973,7 +1783,7 @@ yyerrorlab:
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
@@ -2009,13 +1819,15 @@ yyerrlab1:
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ yystos[yystate], yyvsp, yyscanner);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
/* Shift the error token. */
@@ -2039,12 +1851,12 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
+ yyerror (yyscanner, YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
@@ -2056,16 +1868,16 @@ yyreturn:
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
+ yytoken, &yylval, yyscanner);
}
- /* Do not reclaim the symbols of the rule which action triggered
+ /* Do not reclaim the symbols of the rule whose action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ yystos[*yyssp], yyvsp, yyscanner);
YYPOPSTACK (1);
}
#ifndef yyoverflow
@@ -2076,13 +1888,8 @@ yyreturn:
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
- /* Make sure YYID is used. */
- return YYID (yyresult);
+ return yyresult;
}
-
-
-
-/* Line 2067 of yacc.c */
-#line 286 "cmDependsFortranParser.y"
+#line 278 "cmFortranParser.y" /* yacc.c:1906 */
/* End of grammar */
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
new file mode 100644
index 0000000..156c38a
--- /dev/null
+++ b/Source/cmFortranParser.h
@@ -0,0 +1,175 @@
+/*============================================================================
+ 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 cmFortranParser_h
+#define cmFortranParser_h
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+# include "cmStandardIncludes.h"
+#endif
+
+#include <stddef.h> /* size_t */
+
+/* Forward declare parser object type. */
+typedef struct cmFortranParser_s cmFortranParser;
+
+/* Functions to enter/exit #include'd files in order. */
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+ const char* fname);
+bool cmFortranParser_FilePop(cmFortranParser* parser);
+
+/* Callbacks for lexer. */
+int cmFortranParser_Input(cmFortranParser* parser,
+ char* buffer, size_t bufferSize);
+
+
+void cmFortranParser_StringStart(cmFortranParser* parser);
+const char* cmFortranParser_StringEnd(cmFortranParser* parser);
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+ char c);
+
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+ bool is_in);
+bool cmFortranParser_GetInInterface(cmFortranParser* parser);
+
+
+void cmFortranParser_SetInPPFalseBranch(cmFortranParser* parser,
+ bool is_in);
+bool cmFortranParser_GetInPPFalseBranch(cmFortranParser* parser);
+
+
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+ int arg);
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
+
+/* Callbacks for parser. */
+void cmFortranParser_Error(cmFortranParser* parser,
+ const char* message);
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+ const char* name);
+void cmFortranParser_RuleIf(cmFortranParser* parser);
+void cmFortranParser_RuleElif(cmFortranParser* parser);
+void cmFortranParser_RuleElse(cmFortranParser* parser);
+void cmFortranParser_RuleEndif(cmFortranParser* parser);
+
+/* Define the parser stack element type. */
+typedef union cmFortran_yystype_u cmFortran_yystype;
+union cmFortran_yystype_u
+{
+ char* string;
+};
+
+/* Setup the proper yylex interface. */
+#define YY_EXTRA_TYPE cmFortranParser*
+#define YY_DECL \
+int cmFortran_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
+#define YYSTYPE cmFortran_yystype
+#define YYSTYPE_IS_DECLARED 1
+#if !defined(cmFortranLexer_cxx)
+# include "cmFortranLexer.h"
+#endif
+#if !defined(cmFortranLexer_cxx)
+#if !defined(cmFortranParser_cxx)
+# undef YY_EXTRA_TYPE
+# undef YY_DECL
+# undef YYSTYPE
+# undef YYSTYPE_IS_DECLARED
+#endif
+#endif
+
+#if !defined(cmFortranLexer_cxx) && !defined(cmFortranParser_cxx)
+#include <stack>
+
+//----------------------------------------------------------------------------
+// Information about a single source file.
+class cmFortranSourceInfo
+{
+public:
+ // The name of the source file.
+ std::string Source;
+
+ // Set of provided and required modules.
+ std::set<std::string> Provides;
+ std::set<std::string> Requires;
+
+ // Set of files included in the translation unit.
+ std::set<std::string> Includes;
+};
+
+//----------------------------------------------------------------------------
+// Parser methods not included in generated interface.
+
+// Get the current buffer processed by the lexer.
+YY_BUFFER_STATE cmFortranLexer_GetCurrentBuffer(yyscan_t yyscanner);
+
+// The parser entry point.
+int cmFortran_yyparse(yyscan_t);
+
+//----------------------------------------------------------------------------
+// Define parser object internal structure.
+struct cmFortranFile
+{
+ cmFortranFile(FILE* file, YY_BUFFER_STATE buffer,
+ const std::string& dir):
+ File(file), Buffer(buffer), Directory(dir) {}
+ FILE* File;
+ YY_BUFFER_STATE Buffer;
+ std::string Directory;
+};
+
+struct cmFortranParser_s
+{
+ cmFortranParser_s(std::vector<std::string> const& includes,
+ std::set<std::string> const& defines,
+ cmFortranSourceInfo& info);
+ ~cmFortranParser_s();
+
+ bool FindIncludeFile(const char* dir, const char* includeName,
+ std::string& fileName);
+
+ // The include file search path.
+ std::vector<std::string> IncludePath;
+
+ // Lexical scanner instance.
+ yyscan_t Scanner;
+
+ // Stack of open files in the translation unit.
+ std::stack<cmFortranFile> FileStack;
+
+ // Buffer for string literals.
+ std::string TokenString;
+
+ // Flag for whether lexer is reading from inside an interface.
+ bool InInterface;
+
+ int OldStartcond;
+ std::set<std::string> PPDefinitions;
+ size_t InPPFalseBranch;
+ std::stack<bool> SkipToEnd;
+
+ // Information about the parsed source.
+ cmFortranSourceInfo& Info;
+};
+#endif
+
+#endif
diff --git a/Source/cmDependsFortranParser.y b/Source/cmFortranParser.y
index a987c13..996bef6 100644
--- a/Source/cmDependsFortranParser.y
+++ b/Source/cmFortranParser.y
@@ -26,42 +26,33 @@ This file must be translated to C and modified to build everywhere.
Run bison like this:
- bison --yacc --name-prefix=cmDependsFortran_yy
- --defines=cmDependsFortranParserTokens.h
- -ocmDependsFortranParser.cxx
- cmDependsFortranParser.y
+ bison --yacc --name-prefix=cmFortran_yy
+ --defines=cmFortranParserTokens.h
+ -ocmFortranParser.cxx
+ cmFortranParser.y
-Modify cmDependsFortranParser.cxx:
- - remove TABs
- - remove use of the 'register' storage class specifier
- - Remove the yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
+Modify cmFortranParser.cxx:
+ - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
*/
/*-------------------------------------------------------------------------*/
-#define cmDependsFortranParser_cxx
-#include "cmDependsFortranParser.h" /* Interface to parser object. */
-#include "cmDependsFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+#define cmFortranParser_cxx
+#include "cmFortranParser.h" /* Interface to parser object. */
+#include "cmFortranParserTokens.h" /* Need YYSTYPE for YY_DECL. */
#include <cmsys/String.h>
-/* Configure the parser to use a lexer object. */
-#define YYPARSE_PARAM yyscanner
-#define YYLEX_PARAM yyscanner
-#define YYERROR_VERBOSE 1
-#define cmDependsFortran_yyerror(x) \
- cmDependsFortranError(yyscanner, x)
-
/* Forward declare the lexer entry point. */
YY_DECL;
-/* Helper function to forward error callback. */
-static void cmDependsFortranError(yyscan_t yyscanner, const char* message)
+/* Helper function to forward error callback from parser. */
+static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_Error(parser, message);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_Error(parser, message);
}
-static bool cmDependsFortranParserIsKeyword(const char* word,
+static bool cmFortranParserIsKeyword(const char* word,
const char* keyword)
{
return cmsysString_strcasecmp(word, keyword) == 0;
@@ -79,7 +70,13 @@ static bool cmDependsFortranParserIsKeyword(const char* word,
%}
/* Generate a reentrant parser object. */
-%pure-parser
+%define api.pure
+
+/* Configure the parser to use a lexer object. */
+%lex-param {yyscan_t yyscanner}
+%parse-param {yyscan_t yyscanner}
+
+%define parse.error verbose
%union {
char* string;
@@ -115,63 +112,63 @@ assignment_stmt: WORD ASSIGNMENT_OP other EOSTMT /* Ignore */
keyword_stmt:
WORD EOSTMT
{
- if (cmDependsFortranParserIsKeyword($1, "interface"))
+ if (cmFortranParserIsKeyword($1, "interface"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
}
free($1);
}
| WORD WORD other EOSTMT
{
- if (cmDependsFortranParserIsKeyword($1, "use"))
+ if (cmFortranParserIsKeyword($1, "use"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $2);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $2);
}
- else if (cmDependsFortranParserIsKeyword($1, "module"))
+ else if (cmFortranParserIsKeyword($1, "module"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleModule(parser, $2);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleModule(parser, $2);
}
- else if (cmDependsFortranParserIsKeyword($1, "interface"))
+ else if (cmFortranParserIsKeyword($1, "interface"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, true);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, true);
}
- else if (cmDependsFortranParserIsKeyword($2, "interface") &&
- cmDependsFortranParserIsKeyword($1, "end"))
+ else if (cmFortranParserIsKeyword($2, "interface") &&
+ cmFortranParserIsKeyword($1, "end"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_SetInInterface(parser, false);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, false);
}
free($1);
free($2);
}
| WORD DCOLON WORD other EOSTMT
{
- if (cmDependsFortranParserIsKeyword($1, "use"))
+ if (cmFortranParserIsKeyword($1, "use"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $3);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $3);
}
free($1);
free($3);
}
| WORD COMMA WORD DCOLON WORD other EOSTMT
{
- if (cmDependsFortranParserIsKeyword($1, "use") &&
- cmDependsFortranParserIsKeyword($3, "non_intrinsic") )
+ if (cmFortranParserIsKeyword($1, "use") &&
+ cmFortranParserIsKeyword($3, "non_intrinsic") )
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUse(parser, $5);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $5);
}
free($1);
free($3);
@@ -179,72 +176,72 @@ keyword_stmt:
}
| WORD STRING other EOSTMT /* Ignore */
{
- if (cmDependsFortranParserIsKeyword($1, "include"))
+ if (cmFortranParserIsKeyword($1, "include"))
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $2);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $2);
}
free($1);
free($2);
}
| CPP_INCLUDE_ANGLE other EOSTMT
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $1);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $1);
free($1);
}
| include STRING other EOSTMT
{
- cmDependsFortranParser* parser =
- cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleInclude(parser, $2);
+ cmFortranParser* parser =
+ cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleInclude(parser, $2);
free($2);
}
| define WORD other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleDefine(parser, $2);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleDefine(parser, $2);
free($2);
}
| undef WORD other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleUndef(parser, $2);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUndef(parser, $2);
free($2);
}
| ifdef WORD other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfdef(parser, $2);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfdef(parser, $2);
free($2);
}
| ifndef WORD other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIfndef(parser, $2);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIfndef(parser, $2);
free($2);
}
| if other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleIf(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleIf(parser);
}
| elif other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElif(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElif(parser);
}
| else other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleElse(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleElse(parser);
}
| endif other EOSTMT
{
- cmDependsFortranParser* parser = cmDependsFortran_yyget_extra(yyscanner);
- cmDependsFortranParser_RuleEndif(parser);
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleEndif(parser);
}
| WORD GARBAGE other EOSTMT /* Ignore */
{
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
new file mode 100644
index 0000000..a09c5459
--- /dev/null
+++ b/Source/cmFortranParserImpl.cxx
@@ -0,0 +1,408 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 "cmFortranParser.h"
+
+#include "cmSystemTools.h"
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_s::FindIncludeFile(const char* dir,
+ const char* includeName,
+ std::string& fileName)
+{
+ // If the file is a full path, include it directly.
+ if(cmSystemTools::FileIsFullPath(includeName))
+ {
+ fileName = includeName;
+ return cmSystemTools::FileExists(fileName.c_str(), true);
+ }
+ else
+ {
+ // Check for the file in the directory containing the including
+ // file.
+ std::string fullName = dir;
+ fullName += "/";
+ fullName += includeName;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ fileName = fullName;
+ return true;
+ }
+
+ // Search the include path for the file.
+ for(std::vector<std::string>::const_iterator i =
+ this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+ {
+ fullName = *i;
+ fullName += "/";
+ fullName += includeName;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ fileName = fullName;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s
+::cmFortranParser_s(std::vector<std::string> const& includes,
+ std::set<std::string> const& defines,
+ cmFortranSourceInfo& info):
+ IncludePath(includes), PPDefinitions(defines), Info(info)
+{
+ this->InInterface = 0;
+ this->InPPFalseBranch = 0;
+
+ // Initialize the lexical scanner.
+ cmFortran_yylex_init(&this->Scanner);
+ cmFortran_yyset_extra(this, this->Scanner);
+
+ // Create a dummy buffer that is never read but is the fallback
+ // buffer when the last file is popped off the stack.
+ YY_BUFFER_STATE buffer =
+ cmFortran_yy_create_buffer(0, 4, this->Scanner);
+ cmFortran_yy_switch_to_buffer(buffer, this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+cmFortranParser_s::~cmFortranParser_s()
+{
+ cmFortran_yylex_destroy(this->Scanner);
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePush(cmFortranParser* parser,
+ const char* fname)
+{
+ // Open the new file and push it onto the stack. Save the old
+ // buffer with it on the stack.
+ if(FILE* file = cmsys::SystemTools::Fopen(fname, "rb"))
+ {
+ YY_BUFFER_STATE current =
+ cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+ std::string dir = cmSystemTools::GetParentDirectory(fname);
+ cmFortranFile f(file, current, dir);
+ YY_BUFFER_STATE buffer =
+ cmFortran_yy_create_buffer(0, 16384, parser->Scanner);
+ cmFortran_yy_switch_to_buffer(buffer, parser->Scanner);
+ parser->FileStack.push(f);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_FilePop(cmFortranParser* parser)
+{
+ // Pop one file off the stack and close it. Switch the lexer back
+ // to the next one on the stack.
+ if(parser->FileStack.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ cmFortranFile f = parser->FileStack.top(); parser->FileStack.pop();
+ fclose(f.File);
+ YY_BUFFER_STATE current =
+ cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+ cmFortran_yy_delete_buffer(current, parser->Scanner);
+ cmFortran_yy_switch_to_buffer(f.Buffer, parser->Scanner);
+ return 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_Input(cmFortranParser* parser,
+ char* buffer, size_t bufferSize)
+{
+ // Read from the file on top of the stack. If the stack is empty,
+ // the end of the translation unit has been reached.
+ if(!parser->FileStack.empty())
+ {
+ FILE* file = parser->FileStack.top().File;
+ return (int)fread(buffer, 1, bufferSize, file);
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringStart(cmFortranParser* parser)
+{
+ parser->TokenString = "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmFortranParser_StringEnd(cmFortranParser* parser)
+{
+ return parser->TokenString.c_str();
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_StringAppend(cmFortranParser* parser,
+ char c)
+{
+ parser->TokenString += c;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetInInterface(cmFortranParser* parser,
+ bool in)
+{
+ if(parser->InPPFalseBranch)
+ {
+ return;
+ }
+
+ parser->InInterface = in;
+}
+
+//----------------------------------------------------------------------------
+bool cmFortranParser_GetInInterface(cmFortranParser* parser)
+{
+ return parser->InInterface;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_SetOldStartcond(cmFortranParser* parser,
+ int arg)
+{
+ parser->OldStartcond = arg;
+}
+
+//----------------------------------------------------------------------------
+int cmFortranParser_GetOldStartcond(cmFortranParser* parser)
+{
+ return parser->OldStartcond;
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_Error(cmFortranParser*, const char*)
+{
+ // If there is a parser error just ignore it. The source will not
+ // compile and the user will edit it. Then dependencies will have
+ // to be regenerated anyway.
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUse(cmFortranParser* parser,
+ const char* name)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ parser->Info.Requires.insert(cmSystemTools::LowerCase(name) );
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleInclude(cmFortranParser* parser,
+ const char* name)
+{
+ if(parser->InPPFalseBranch)
+ {
+ return;
+ }
+
+ // If processing an include statement there must be an open file.
+ assert(!parser->FileStack.empty());
+
+ // Get the directory containing the source in which the include
+ // statement appears. This is always the first search location for
+ // Fortran include files.
+ std::string dir = parser->FileStack.top().Directory;
+
+ // Find the included file. If it cannot be found just ignore the
+ // problem because either the source will not compile or the user
+ // does not care about depending on this included source.
+ std::string fullName;
+ if(parser->FindIncludeFile(dir.c_str(), name, fullName))
+ {
+ // Found the included file. Save it in the set of included files.
+ parser->Info.Includes.insert(fullName);
+
+ // Parse it immediately to translate the source inline.
+ cmFortranParser_FilePush(parser, fullName.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+ const char* name)
+{
+ if(!parser->InPPFalseBranch && !parser->InInterface)
+ {
+ parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleDefine(cmFortranParser* parser,
+ const char* macro)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ parser->PPDefinitions.insert(macro);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleUndef(cmFortranParser* parser,
+ const char* macro)
+{
+ if(!parser->InPPFalseBranch)
+ {
+ std::set<std::string>::iterator match;
+ match = parser->PPDefinitions.find(macro);
+ if(match != parser->PPDefinitions.end())
+ {
+ parser->PPDefinitions.erase(match);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfdef(cmFortranParser* parser,
+ const char* macro)
+{
+ // A new PP branch has been opened
+ parser->SkipToEnd.push(false);
+
+ if (parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch++;
+ }
+ else if(parser->PPDefinitions.find(macro) == parser->PPDefinitions.end())
+ {
+ parser->InPPFalseBranch=1;
+ }
+ else
+ {
+ parser->SkipToEnd.top() = true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIfndef(cmFortranParser* parser,
+ const char* macro)
+{
+ // A new PP branch has been opened
+ parser->SkipToEnd.push(false);
+
+ if (parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch++;
+ }
+ else if(parser->PPDefinitions.find(macro) != parser->PPDefinitions.end())
+ {
+ parser->InPPFalseBranch = 1;
+ }
+ else
+ {
+ // ignore other branches
+ parser->SkipToEnd.top() = true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleIf(cmFortranParser* parser)
+{
+ /* Note: The current parser is _not_ able to get statements like
+ * #if 0
+ * #if 1
+ * #if MYSMBOL
+ * #if defined(MYSYMBOL)
+ * #if defined(MYSYMBOL) && ...
+ * right. The same for #elif. Thus in
+ * #if SYMBOL_1
+ * ..
+ * #elif SYMBOL_2
+ * ...
+ * ...
+ * #elif SYMBOL_N
+ * ..
+ * #else
+ * ..
+ * #endif
+ * _all_ N+1 branches are considered. If you got something like this
+ * #if defined(MYSYMBOL)
+ * #if !defined(MYSYMBOL)
+ * use
+ * #ifdef MYSYMBOL
+ * #ifndef MYSYMBOL
+ * instead.
+ */
+
+ // A new PP branch has been opened
+ // Never skip! See note above.
+ parser->SkipToEnd.push(false);
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElif(cmFortranParser* parser)
+{
+ /* Note: There are parser limitations. See the note at
+ * cmFortranParser_RuleIf(..)
+ */
+
+ // Always taken unless an #ifdef or #ifndef-branch has been taken
+ // already. If the second condition isn't meet already
+ // (parser->InPPFalseBranch == 0) correct it.
+ if(!parser->SkipToEnd.empty() &&
+ parser->SkipToEnd.top() && !parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch = 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleElse(cmFortranParser* parser)
+{
+ // if the parent branch is false do nothing!
+ if(parser->InPPFalseBranch > 1)
+ {
+ return;
+ }
+
+ // parser->InPPFalseBranch is either 0 or 1. We change it depending on
+ // parser->SkipToEnd.top()
+ if(!parser->SkipToEnd.empty() &&
+ parser->SkipToEnd.top())
+ {
+ parser->InPPFalseBranch = 1;
+ }
+ else
+ {
+ parser->InPPFalseBranch = 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFortranParser_RuleEndif(cmFortranParser* parser)
+{
+ if(!parser->SkipToEnd.empty())
+ {
+ parser->SkipToEnd.pop();
+ }
+
+ // #endif doesn't know if there was a "#else" in before, so it
+ // always decreases InPPFalseBranch
+ if(parser->InPPFalseBranch)
+ {
+ parser->InPPFalseBranch--;
+ }
+}
diff --git a/Source/cmDependsFortranParserTokens.h b/Source/cmFortranParserTokens.h
index 941eda0..df1aec3 100644
--- a/Source/cmDependsFortranParserTokens.h
+++ b/Source/cmFortranParserTokens.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 3.0.2. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,43 +30,51 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int cmFortran_yydebug;
+#endif
-/* Tokens. */
+/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EOSTMT = 258,
- ASSIGNMENT_OP = 259,
- GARBAGE = 260,
- CPP_INCLUDE = 261,
- F90PPR_INCLUDE = 262,
- COCO_INCLUDE = 263,
- F90PPR_DEFINE = 264,
- CPP_DEFINE = 265,
- F90PPR_UNDEF = 266,
- CPP_UNDEF = 267,
- CPP_IFDEF = 268,
- CPP_IFNDEF = 269,
- CPP_IF = 270,
- CPP_ELSE = 271,
- CPP_ELIF = 272,
- CPP_ENDIF = 273,
- F90PPR_IFDEF = 274,
- F90PPR_IFNDEF = 275,
- F90PPR_IF = 276,
- F90PPR_ELSE = 277,
- F90PPR_ELIF = 278,
- F90PPR_ENDIF = 279,
- COMMA = 280,
- DCOLON = 281,
- CPP_TOENDL = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286
- };
+ enum yytokentype
+ {
+ EOSTMT = 258,
+ ASSIGNMENT_OP = 259,
+ GARBAGE = 260,
+ CPP_INCLUDE = 261,
+ F90PPR_INCLUDE = 262,
+ COCO_INCLUDE = 263,
+ F90PPR_DEFINE = 264,
+ CPP_DEFINE = 265,
+ F90PPR_UNDEF = 266,
+ CPP_UNDEF = 267,
+ CPP_IFDEF = 268,
+ CPP_IFNDEF = 269,
+ CPP_IF = 270,
+ CPP_ELSE = 271,
+ CPP_ELIF = 272,
+ CPP_ENDIF = 273,
+ F90PPR_IFDEF = 274,
+ F90PPR_IFNDEF = 275,
+ F90PPR_IF = 276,
+ F90PPR_ELSE = 277,
+ F90PPR_ELIF = 278,
+ F90PPR_ENDIF = 279,
+ COMMA = 280,
+ DCOLON = 281,
+ CPP_TOENDL = 282,
+ UNTERMINATED_STRING = 283,
+ STRING = 284,
+ WORD = 285,
+ CPP_INCLUDE_ANGLE = 286
+ };
#endif
/* Tokens. */
#define EOSTMT 258
@@ -99,24 +107,23 @@
#define WORD 285
#define CPP_INCLUDE_ANGLE 286
-
-
-
+/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
+typedef union YYSTYPE YYSTYPE;
+union YYSTYPE
{
-
-/* Line 2068 of yacc.c */
-#line 89 "cmDependsFortranParser.y"
+#line 81 "cmFortranParser.y" /* yacc.c:1909 */
char* string;
-
-
-/* Line 2068 of yacc.c */
-#line 118 "cmDependsFortranParserTokens.h"
-} YYSTYPE;
+#line 120 "cmFortranParserTokens.h" /* yacc.c:1909 */
+};
# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
+
+
+
+int cmFortran_yyparse (yyscan_t yyscanner);
+
+#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 001adb1..c883ad7 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -43,6 +43,7 @@ public:
newC->Args = this->Args;
newC->Functions = this->Functions;
newC->Policies = this->Policies;
+ newC->FilePath = this->FilePath;
return newC;
}
@@ -71,9 +72,9 @@ public:
std::vector<std::string> Args;
std::vector<cmListFileFunction> Functions;
cmPolicies::PolicyMap Policies;
+ std::string FilePath;
};
-
bool cmFunctionHelperCommand::InvokeInitialPass
(const std::vector<cmListFileArgument>& args,
cmExecutionStatus & inStatus)
@@ -93,14 +94,9 @@ bool cmFunctionHelperCommand::InvokeInitialPass
return false;
}
- // we push a scope on the makefile
- cmMakefile::ScopePushPop varScope(this->Makefile);
- cmMakefile::LexicalPushPop lexScope(this->Makefile);
- static_cast<void>(varScope);
-
- // Push a weak policy scope which restores the policies recorded at
- // function creation.
- cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+ cmMakefile::FunctionPushPop functionScope(this->Makefile,
+ this->FilePath,
+ this->Policies);
// set the value of argc
std::ostringstream strStream;
@@ -129,7 +125,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
std::string argvDef = cmJoin(expandedArgs, ";");
std::vector<std::string>::const_iterator eit
= expandedArgs.begin() + (this->Args.size()-1);
- std::string argnDef = cmJoin(cmRange(eit, expandedArgs.end()), ";");
+ std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
this->Makefile->AddDefinition("ARGV", argvDef.c_str());
this->Makefile->MarkVariableAsUsed("ARGV");
this->Makefile->AddDefinition("ARGN", argnDef.c_str());
@@ -145,8 +141,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
{
// The error message should have already included the call stack
// so we do not need to report an error here.
- lexScope.Quiet();
- polScope.Quiet();
+ functionScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -179,19 +174,9 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
cmFunctionHelperCommand *f = new cmFunctionHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ f->FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f->Policies);
- // Set the FilePath on the arguments to match the function since it is
- // not stored and the original values may be freed
- for (unsigned int i = 0; i < f->Functions.size(); ++i)
- {
- for (unsigned int j = 0; j < f->Functions[i].Arguments.size(); ++j)
- {
- f->Functions[i].Arguments[j].FilePath =
- f->Functions[i].FilePath.c_str();
- }
- }
-
std::string newName = "_" + this->Args[0];
mf.GetState()->RenameCommand(this->Args[0], newName);
mf.GetState()->AddCommand(f);
@@ -220,7 +205,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
{
std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
// if the endfunction has arguments then make sure
// they match the ones in the opening function command
if ((expandedArguments.empty() ||
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index a1c405b..80a4f81 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -23,7 +23,7 @@
//----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression(
- cmListFileBacktrace const* backtrace):
+ const cmListFileBacktrace& backtrace):
Backtrace(backtrace)
{
}
@@ -33,9 +33,7 @@ cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(std::string const& input)
{
return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
- new cmCompiledGeneratorExpression(
- this->Backtrace ? *this->Backtrace : cmListFileBacktrace(NULL),
- input));
+ new cmCompiledGeneratorExpression(this->Backtrace, input));
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 11c27fd..cd19bc0 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -42,7 +42,8 @@ class cmGeneratorExpression
{
public:
/** Construct. */
- cmGeneratorExpression(cmListFileBacktrace const* backtrace = NULL);
+ cmGeneratorExpression(
+ cmListFileBacktrace const& backtrace = cmListFileBacktrace());
~cmGeneratorExpression();
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
@@ -71,7 +72,7 @@ private:
cmGeneratorExpression(const cmGeneratorExpression &);
void operator=(const cmGeneratorExpression &);
- cmListFileBacktrace const* Backtrace;
+ cmListFileBacktrace Backtrace;
};
class cmCompiledGeneratorExpression
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index ff8790c..851aacd 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -35,7 +35,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *parent)
: Parent(parent), Target(target), Property(property),
- Content(content), Backtrace(NULL), TransitivePropertiesOnly(false)
+ Content(content), Backtrace(), TransitivePropertiesOnly(false)
{
Initialize();
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index c726995..e4d9f10 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -25,19 +25,18 @@
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
const std::string &input,
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
- cmMakefile *makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent)
: Input(input),
OutputFileExpr(outputFileExpr),
- Makefile(makefile),
Condition(condition),
InputIsContent(inputIsContent)
{
}
//----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg,
+ const std::string& config,
const std::string& lang,
cmCompiledGeneratorExpression* inputExpression,
std::map<std::string, std::string> &outputFiles, mode_t perm)
@@ -45,7 +44,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
std::string rawCondition = this->Condition->GetInput();
if (!rawCondition.empty())
{
- std::string condResult = this->Condition->Evaluate(this->Makefile, config,
+ std::string condResult = this->Condition->Evaluate(lg->GetMakefile(),
+ config,
false, 0, 0, 0, lang);
if (condResult == "0")
{
@@ -56,16 +56,17 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
std::ostringstream e;
e << "Evaluation file condition \"" << rawCondition << "\" did "
"not evaluate to valid content. Got \"" << condResult << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
}
const std::string outputFileName
- = this->OutputFileExpr->Evaluate(this->Makefile, config,
+ = this->OutputFileExpr->Evaluate(lg->GetMakefile(), config,
false, 0, 0, 0, lang);
const std::string outputContent
- = inputExpression->Evaluate(this->Makefile, config,
+ = inputExpression->Evaluate(lg->GetMakefile(),
+ config,
false, 0, 0, 0, lang);
std::map<std::string, std::string>::iterator it
@@ -81,11 +82,11 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
e << "Evaluation file to be written multiple times for different "
"configurations or languages with different content:\n "
<< outputFileName;
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ lg->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- this->Makefile->AddCMakeOutputFile(outputFileName.c_str());
+ lg->GetMakefile()->AddCMakeOutputFile(outputFileName.c_str());
this->Files.push_back(outputFileName);
outputFiles[outputFileName] = outputContent;
@@ -100,18 +101,19 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
//----------------------------------------------------------------------------
void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
- std::string const& config)
+ cmLocalGenerator *lg, std::string const& config)
{
std::vector<std::string> enabledLanguages;
- cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator *gg = lg->GetGlobalGenerator();
gg->GetEnabledLanguages(enabledLanguages);
for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
le != enabledLanguages.end(); ++le)
{
- std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config,
+ std::string name = this->OutputFileExpr->Evaluate(lg->GetMakefile(),
+ config,
false, 0, 0, 0, *le);
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(name);
+ cmSourceFile* sf = lg->GetMakefile()->GetOrCreateSource(name);
sf->SetProperty("GENERATED", "1");
gg->SetFilenameTargetDepends(sf,
@@ -120,7 +122,7 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
}
//----------------------------------------------------------------------------
-void cmGeneratorExpressionEvaluationFile::Generate()
+void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator *lg)
{
mode_t perm = 0;
std::string inputContent;
@@ -130,14 +132,14 @@ void cmGeneratorExpressionEvaluationFile::Generate()
}
else
{
- this->Makefile->AddCMakeDependFile(this->Input.c_str());
+ lg->GetMakefile()->AddCMakeDependFile(this->Input.c_str());
cmSystemTools::GetPermissions(this->Input.c_str(), perm);
cmsys::ifstream fin(this->Input.c_str());
if(!fin)
{
std::ostringstream e;
e << "Evaluation file \"" << this->Input << "\" cannot be read.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ lg->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -152,14 +154,14 @@ void cmGeneratorExpressionEvaluationFile::Generate()
}
cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace();
- cmGeneratorExpression contentGE(&lfbt);
+ cmGeneratorExpression contentGE(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression
= contentGE.Parse(inputContent);
std::map<std::string, std::string> outputFiles;
std::vector<std::string> allConfigs;
- this->Makefile->GetConfigurations(allConfigs);
+ lg->GetMakefile()->GetConfigurations(allConfigs);
if (allConfigs.empty())
{
@@ -167,7 +169,7 @@ void cmGeneratorExpressionEvaluationFile::Generate()
}
std::vector<std::string> enabledLanguages;
- cmGlobalGenerator *gg = this->Makefile->GetGlobalGenerator();
+ cmGlobalGenerator *gg = lg->GetGlobalGenerator();
gg->GetEnabledLanguages(enabledLanguages);
for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
@@ -176,7 +178,7 @@ void cmGeneratorExpressionEvaluationFile::Generate()
for(std::vector<std::string>::const_iterator li = allConfigs.begin();
li != allConfigs.end(); ++li)
{
- this->Generate(*li, *le, inputExpression.get(), outputFiles, perm);
+ this->Generate(lg, *li, *le, inputExpression.get(), outputFiles, perm);
if(cmSystemTools::GetFatalErrorOccured())
{
return;
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 5d8b54c..ad41274 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -18,31 +18,32 @@
#include "cmGeneratorExpression.h"
+class cmLocalGenerator;
+
//----------------------------------------------------------------------------
class cmGeneratorExpressionEvaluationFile
{
public:
cmGeneratorExpressionEvaluationFile(const std::string &input,
cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr,
- cmMakefile *makefile,
cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent);
- void Generate();
+ void Generate(cmLocalGenerator* lg);
std::vector<std::string> GetFiles() const { return this->Files; }
- void CreateOutputFile(std::string const& config);
+ void CreateOutputFile(cmLocalGenerator* lg, std::string const& config);
private:
- void Generate(const std::string& config, const std::string& lang,
- cmCompiledGeneratorExpression* inputExpression,
- std::map<std::string, std::string> &outputFiles, mode_t perm);
+ void Generate(cmLocalGenerator* lg, const std::string& config,
+ const std::string& lang,
+ cmCompiledGeneratorExpression* inputExpression,
+ std::map<std::string, std::string> &outputFiles, mode_t perm);
private:
const std::string Input;
const cmsys::auto_ptr<cmCompiledGeneratorExpression> OutputFileExpr;
- cmMakefile *Makefile;
const cmsys::auto_ptr<cmCompiledGeneratorExpression> Condition;
std::vector<std::string> Files;
const bool InputIsContent;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 293eb41..31b6766 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -21,7 +21,7 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
cmTarget const* headTarget, cmTarget const* currentTarget,
cmGeneratorExpressionDAGChecker *dagChecker)
{
- cmGeneratorExpression ge(&context->Backtrace);
+ cmGeneratorExpression ge(context->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
std::string result = cge->Evaluate(makefile,
@@ -990,6 +990,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
assert(target);
+ cmGeneratorTarget* gtgt =
+ context->Makefile->GetGlobalGenerator()->GetGeneratorTarget(target);
+
if (propertyName == "LINKER_LANGUAGE")
{
if (target->LinkLanguagePropagatesToDependents() &&
@@ -1001,7 +1004,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
"link libraries for a static library");
return std::string();
}
- return target->GetLinkerLanguage(context->Config);
+ return gtgt->GetLinkerLanguage(context->Config);
}
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
@@ -1105,8 +1108,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if(isInterfaceProperty)
{
- if(cmTarget::LinkInterfaceLibraries const* iface =
- target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+ if(cmLinkInterfaceLibraries const* iface =
+ gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true))
{
linkedTargetsContent =
getLinkedTargetsContent(iface->Libraries, target,
@@ -1117,7 +1120,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
else if(!interfacePropertyName.empty())
{
- if(cmTarget::LinkImplementationLibraries const* impl =
+ if(cmLinkImplementationLibraries const* impl =
target->GetLinkImplementationLibraries(context->Config))
{
linkedTargetsContent =
@@ -1135,40 +1138,40 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
return linkedTargetsContent;
}
- if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentBoolProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
- return target->GetLinkInterfaceDependentBoolProperty(
+ return gtgt->GetLinkInterfaceDependentBoolProperty(
propertyName,
context->Config) ? "1" : "0";
}
- if (target->IsLinkInterfaceDependentStringProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentStringProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
- target->GetLinkInterfaceDependentStringProperty(
+ gtgt->GetLinkInterfaceDependentStringProperty(
propertyName,
context->Config);
return propContent ? propContent : "";
}
- if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
- target->GetLinkInterfaceDependentNumberMinProperty(
+ gtgt->GetLinkInterfaceDependentNumberMinProperty(
propertyName,
context->Config);
return propContent ? propContent : "";
}
- if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
- target->GetLinkInterfaceDependentNumberMaxProperty(
+ gtgt->GetLinkInterfaceDependentNumberMaxProperty(
propertyName,
context->Config);
return propContent ? propContent : "";
@@ -1180,22 +1183,22 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (!target->IsImported()
&& dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries())
{
- if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentNumberMinProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
- target->GetLinkInterfaceDependentNumberMinProperty(
+ gtgt->GetLinkInterfaceDependentNumberMinProperty(
propertyName,
context->Config);
return propContent ? propContent : "";
}
- if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config))
+ if (gtgt->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
+ context->Config))
{
context->HadContextSensitiveCondition = true;
const char *propContent =
- target->GetLinkInterfaceDependentNumberMaxProperty(
+ gtgt->GetLinkInterfaceDependentNumberMaxProperty(
propertyName,
context->Config);
return propContent ? propContent : "";
@@ -1369,8 +1372,6 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries();
- std::string result;
-
for (LangMap::const_iterator lit = testedFeatures.begin();
lit != testedFeatures.end(); ++lit)
{
@@ -1556,7 +1557,7 @@ class ArtifactDirTag;
template<typename ArtifactT>
struct TargetFilesystemArtifactResultCreator
{
- static std::string Create(cmTarget* target,
+ static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content);
};
@@ -1565,12 +1566,12 @@ struct TargetFilesystemArtifactResultCreator
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
{
- static std::string Create(cmTarget* target,
+ static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content)
{
// The target soname file (.so.1).
- if(target->IsDLLPlatform())
+ if(target->Target->IsDLLPlatform())
{
::reportError(context, content->GetOriginalExpression(),
"TARGET_SONAME_FILE is not allowed "
@@ -1584,7 +1585,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
"SHARED libraries.");
return std::string();
}
- std::string result = target->GetDirectory(context->Config);
+ std::string result = target->Target->GetDirectory(context->Config);
result += "/";
result += target->GetSOName(context->Config);
return result;
@@ -1595,10 +1596,17 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
{
- static std::string Create(cmTarget* target,
+ static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content)
{
+ if (target->IsImported())
+ {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_PDB_FILE not allowed for IMPORTED targets.");
+ return std::string();
+ }
+
std::string language = target->GetLinkerLanguage(context->Config);
std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
@@ -1610,7 +1618,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
return std::string();
}
- cmTarget::TargetType targetType = target->GetType();
+ cmTarget::TargetType targetType = target->Target->GetType();
if(targetType != cmTarget::SHARED_LIBRARY &&
targetType != cmTarget::MODULE_LIBRARY &&
@@ -1622,7 +1630,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
return std::string();
}
- std::string result = target->GetPDBDirectory(context->Config);
+ std::string result = target->Target->GetPDBDirectory(context->Config);
result += "/";
result += target->GetPDBName(context->Config);
return result;
@@ -1633,12 +1641,12 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
{
- static std::string Create(cmTarget* target,
+ static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content)
{
// The file used to link to the target (.so, .lib, .a).
- if(!target->IsLinkable())
+ if(!target->Target->IsLinkable())
{
::reportError(context, content->GetOriginalExpression(),
"TARGET_LINKER_FILE is allowed only for libraries and "
@@ -1646,7 +1654,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
return std::string();
}
return target->GetFullPath(context->Config,
- target->HasImportLibrary());
+ target->Target->HasImportLibrary());
}
};
@@ -1654,7 +1662,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
template<>
struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
{
- static std::string Create(cmTarget* target,
+ static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *)
{
@@ -1716,7 +1724,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
"Expression syntax not recognized.");
return std::string();
}
- cmTarget* target = context->Makefile->FindTargetToUse(name);
+ cmGeneratorTarget* target =
+ context->Makefile->FindGeneratorTargetToUse(name);
if(!target)
{
::reportError(context, content->GetOriginalExpression(),
@@ -1739,8 +1748,8 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
"be used while evaluating link libraries");
return std::string();
}
- context->DependTargets.insert(target);
- context->AllTargets.insert(target);
+ context->DependTargets.insert(target->Target);
+ context->AllTargets.insert(target->Target);
std::string result =
TargetFilesystemArtifactResultCreator<ArtifactT>::Create(
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index e2b8c45..09387b7 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -24,11 +24,31 @@
#include <queue>
+#include <errno.h>
#include "assert.h"
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmsys/hash_set.hxx>
+#define UNORDERED_SET cmsys::hash_set
+#else
+#define UNORDERED_SET std::set
+#endif
+
+class cmGeneratorTarget::TargetPropertyEntry {
+ static cmLinkImplItem NoLinkImplItem;
+public:
+ TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+ cmLinkImplItem const& item = NoLinkImplItem)
+ : ge(cge), LinkImplItem(item)
+ {}
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+ cmLinkImplItem const& LinkImplItem;
+};
+cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
+
//----------------------------------------------------------------------------
void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
- cmTarget *target, cmake *cm)
+ cmGeneratorTarget const* target, cmake *cm)
{
if(!badObjLib.empty())
{
@@ -42,7 +62,7 @@ void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
e << "but may contain only sources that compile, header files, and "
"other files that would not affect linking of a normal library.";
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
- target->GetBacktrace());
+ target->Target->GetBacktrace());
}
}
@@ -125,14 +145,14 @@ struct TagVisitor
{
DataType& Data;
std::vector<cmSourceFile*> BadObjLibFiles;
- cmTarget *Target;
+ cmGeneratorTarget const* Target;
cmGlobalGenerator *GlobalGenerator;
cmsys::RegularExpression Header;
bool IsObjLib;
- TagVisitor(cmTarget *target, DataType& data)
+ TagVisitor(cmGeneratorTarget const* target, DataType& data)
: Data(data), Target(target),
- GlobalGenerator(target->GetMakefile()->GetGlobalGenerator()),
+ GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator()),
Header(CM_HEADER_REGEX),
IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
{
@@ -219,13 +239,71 @@ struct TagVisitor
}
};
+void CreatePropertyGeneratorExpressions(
+ cmStringRange const& entries,
+ cmBacktraceRange const& backtraces,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+ bool evaluateForBuildsystem = false)
+{
+ std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+ for (std::vector<std::string>::const_iterator it = entries.begin();
+ it != entries.end(); ++it, ++btIt)
+ {
+ cmGeneratorExpression ge(*btIt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+ cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
+ items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+}
+
//----------------------------------------------------------------------------
-cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
- SourceFileFlagsConstructed(false)
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
+ : Target(t),
+ SourceFileFlagsConstructed(false),
+ PolicyWarnedCMP0022(false),
+ DebugIncludesDone(false),
+ DebugCompileOptionsDone(false),
+ DebugCompileFeaturesDone(false),
+ DebugCompileDefinitionsDone(false)
{
this->Makefile = this->Target->GetMakefile();
- this->LocalGenerator = this->Makefile->GetLocalGenerator();
- this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+ this->LocalGenerator = lg;
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+
+ CreatePropertyGeneratorExpressions(
+ t->GetIncludeDirectoriesEntries(),
+ t->GetIncludeDirectoriesBacktraces(),
+ this->IncludeDirectoriesEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileOptionsEntries(),
+ t->GetCompileOptionsBacktraces(),
+ this->CompileOptionsEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileFeaturesEntries(),
+ t->GetCompileFeaturesBacktraces(),
+ this->CompileFeaturesEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetCompileDefinitionsEntries(),
+ t->GetCompileDefinitionsBacktraces(),
+ this->CompileDefinitionsEntries);
+}
+
+cmGeneratorTarget::~cmGeneratorTarget()
+{
+ cmDeleteAll(this->IncludeDirectoriesEntries);
+ cmDeleteAll(this->CompileOptionsEntries);
+ cmDeleteAll(this->CompileFeaturesEntries);
+ cmDeleteAll(this->CompileDefinitionsEntries);
+ cmDeleteAll(this->LinkInformation);
+ this->LinkInformation.clear();
+}
+
+cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const
+{
+ return this->LocalGenerator;
}
//----------------------------------------------------------------------------
@@ -247,6 +325,77 @@ const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
}
//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetOutputName(const std::string& config,
+ bool implib) const
+{
+ // Lookup/compute/cache the output name for this configuration.
+ OutputNameKey key(config, implib);
+ cmGeneratorTarget::OutputNameMapType::iterator i =
+ this->OutputNameMap.find(key);
+ if(i == this->OutputNameMap.end())
+ {
+ // Add empty name in map to detect potential recursion.
+ OutputNameMapType::value_type entry(key, "");
+ i = this->OutputNameMap.insert(entry).first;
+
+ // Compute output name.
+ std::vector<std::string> props;
+ std::string type = this->Target->GetOutputTargetType(implib);
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ if(!type.empty() && !configUpper.empty())
+ {
+ // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
+ props.push_back(type + "_OUTPUT_NAME_" + configUpper);
+ }
+ if(!type.empty())
+ {
+ // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
+ props.push_back(type + "_OUTPUT_NAME");
+ }
+ if(!configUpper.empty())
+ {
+ // OUTPUT_NAME_<CONFIG>
+ props.push_back("OUTPUT_NAME_" + configUpper);
+ // <CONFIG>_OUTPUT_NAME
+ props.push_back(configUpper + "_OUTPUT_NAME");
+ }
+ // OUTPUT_NAME
+ props.push_back("OUTPUT_NAME");
+
+ std::string outName;
+ for(std::vector<std::string>::const_iterator it = props.begin();
+ it != props.end(); ++it)
+ {
+ if (const char* outNameProp = this->Target->GetProperty(*it))
+ {
+ outName = outNameProp;
+ break;
+ }
+ }
+
+ if(outName.empty())
+ {
+ outName = this->GetName();
+ }
+
+ // Now evaluate genex and update the previously-prepared map entry.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
+ i->second = cge->Evaluate(this->Makefile, config);
+ }
+ else if(i->second.empty())
+ {
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
+ this->Target->GetBacktrace());
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
std::vector<cmSourceFile*> const*
cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
{
@@ -294,7 +443,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
{ \
std::vector<cmSourceFile*> sourceFiles; \
this->Target->GetSourceFiles(sourceFiles, config); \
- TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
+ TagVisitor<DATA ## Tag DATATYPE> visitor(this, data); \
for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
si != sourceFiles.end(); ++si) \
{ \
@@ -353,6 +502,34 @@ void cmGeneratorTarget::ComputeObjectMapping()
}
//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetFeature(const std::string& feature,
+ const std::string& config) const
+{
+ if(!config.empty())
+ {
+ std::string featureConfig = feature;
+ featureConfig += "_";
+ featureConfig += cmSystemTools::UpperCase(config);
+ if(const char* value = this->Target->GetProperty(featureConfig))
+ {
+ return value;
+ }
+ }
+ if(const char* value = this->Target->GetProperty(feature))
+ {
+ return value;
+ }
+ return this->LocalGenerator->GetFeature(feature, config);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature,
+ const std::string& config) const
+{
+ return cmSystemTools::IsOn(this->GetFeature(feature, config));
+}
+
+//----------------------------------------------------------------------------
const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
{
this->ComputeObjectMapping();
@@ -486,6 +663,61 @@ void cmGeneratorTarget
}
//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocation(const std::string& config) const
+{
+ static std::string location;
+ if (this->Target->IsImported())
+ {
+ location = this->Target->ImportedGetFullPath(config, false);
+ }
+ else
+ {
+ location = this->GetFullPath(config, false);
+ }
+ return location.c_str();
+}
+
+bool cmGeneratorTarget::IsImported() const
+{
+ return this->Target->IsImported();
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLocationForBuild() const
+{
+ static std::string location;
+ if(this->IsImported())
+ {
+ location = this->Target->ImportedGetFullPath("", false);
+ return location.c_str();
+ }
+
+ // Now handle the deprecated build-time configuration location.
+ location = this->Target->GetDirectory();
+ const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+ if(cfgid && strcmp(cfgid, ".") != 0)
+ {
+ location += "/";
+ location += cfgid;
+ }
+
+ if(this->Target->IsAppBundleOnApple())
+ {
+ std::string macdir = this->BuildMacContentDirectory("", "",
+ false);
+ if(!macdir.empty())
+ {
+ location += "/";
+ location += macdir;
+ }
+ }
+ location += "/";
+ location += this->GetFullName("", false);
+ return location.c_str();
+}
+
+
+//----------------------------------------------------------------------------
bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const
{
@@ -522,7 +754,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
}
std::vector<cmTarget const*> const& deps =
- this->Target->GetLinkImplementationClosure(config);
+ this->GetLinkImplementationClosure(config);
for(std::vector<cmTarget const*>::const_iterator
li = deps.begin(), le = deps.end(); li != le; ++li)
{
@@ -562,6 +794,700 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
//----------------------------------------------------------------------------
std::string
+cmGeneratorTarget::GetCompilePDBName(const std::string& config) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(config);
+ std::string configProp = "COMPILE_PDB_NAME_";
+ configProp += configUpper;
+ const char* config_name = this->Target->GetProperty(configProp);
+ if(config_name && *config_name)
+ {
+ return prefix + config_name + ".pdb";
+ }
+
+ const char* name = this->Target->GetProperty("COMPILE_PDB_NAME");
+ if(name && *name)
+ {
+ return prefix + name + ".pdb";
+ }
+
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
+{
+ std::string dir = this->GetCompilePDBDirectory(config);
+ std::string name = this->GetCompilePDBName(config);
+ if(dir.empty() && !name.empty())
+ {
+ dir = this->Target->GetPDBDirectory(config);
+ }
+ if(!dir.empty())
+ {
+ dir += "/";
+ }
+ return dir + name;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasSOName(const std::string& config) const
+{
+ // soname is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ return ((this->GetType() == cmTarget::SHARED_LIBRARY) &&
+ !this->GetPropertyAsBool("NO_SONAME") &&
+ this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
+{
+ // Only executables and shared libraries can have an rpath and may
+ // need relinking.
+ if(this->GetType() != cmTarget::EXECUTABLE &&
+ this->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ return false;
+ }
+
+ // If there is no install location this target will not be installed
+ // and therefore does not need relinking.
+ if(!this->Target->GetHaveInstallRule())
+ {
+ return false;
+ }
+
+ // If skipping all rpaths completely then no relinking is needed.
+ if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+ {
+ return false;
+ }
+
+ // If building with the install-tree rpath no relinking is needed.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return false;
+ }
+
+ // If chrpath is going to be used no relinking is needed.
+ if(this->IsChrpathUsed(config))
+ {
+ return false;
+ }
+
+ // Check for rpath support on this platform.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+ flagVar += ll;
+ flagVar += "_FLAG";
+ if(!this->Makefile->IsSet(flagVar))
+ {
+ // There is no rpath support on this platform so nothing needs
+ // relinking.
+ return false;
+ }
+ }
+ else
+ {
+ // No linker language is known. This error will be reported by
+ // other code.
+ return false;
+ }
+
+ // 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(config)
+ || this->Target->HaveInstallTreeRPATH();
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
+{
+ // Only certain target types have an rpath.
+ if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->GetType() == cmTarget::MODULE_LIBRARY ||
+ this->GetType() == cmTarget::EXECUTABLE))
+ {
+ return false;
+ }
+
+ // If the target will not be installed we do not need to change its
+ // rpath.
+ if(!this->Target->GetHaveInstallRule())
+ {
+ return false;
+ }
+
+ // Skip chrpath if skipping rpath altogether.
+ if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
+ {
+ return false;
+ }
+
+ // Skip chrpath if it does not need to be changed at install time.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return false;
+ }
+
+ // Allow the user to disable builtin chrpath explicitly.
+ if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
+ {
+ return false;
+ }
+
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ {
+ return true;
+ }
+
+#if defined(CMAKE_USE_ELF_PARSER)
+ // Enable if the rpath flag uses a separator and the target uses ELF
+ // binaries.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+ sepVar += ll;
+ sepVar += "_FLAG_SEP";
+ const char* sep = this->Makefile->GetDefinition(sepVar);
+ if(sep && *sep)
+ {
+ // TODO: Add ELF check to ABI detection and get rid of
+ // CMAKE_EXECUTABLE_FORMAT.
+ if(const char* fmt =
+ this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
+ {
+ return strcmp(fmt, "ELF") == 0;
+ }
+ }
+ }
+#endif
+ static_cast<void>(config);
+ return false;
+}
+
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetSOName(const std::string& config) const
+{
+ if(this->Target->IsImported())
+ {
+ // Lookup the imported soname.
+ if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
+ {
+ if(info->NoSOName)
+ {
+ // The imported library has no builtin soname so the name
+ // searched at runtime will be just the filename.
+ return cmSystemTools::GetFilenameName(info->Location);
+ }
+ else
+ {
+ // Use the soname given if any.
+ if(info->SOName.find("@rpath/") == 0)
+ {
+ return info->SOName.substr(6);
+ }
+ return info->SOName;
+ }
+ }
+ else
+ {
+ return "";
+ }
+ }
+ else
+ {
+ // Compute the soname that will be built.
+ std::string name;
+ std::string soName;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetLibraryNames(name, soName, realName,
+ impName, pdbName, config);
+ return soName;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetAppBundleDirectory(const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath = this->GetFullName(config, false);
+ fpath += ".app";
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsBundleOnApple() const
+{
+ return this->Target->IsFrameworkOnApple()
+ || this->Target->IsAppBundleOnApple()
+ || this->Target->IsCFBundleOnApple();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath;
+ fpath += this->GetOutputName(config, false);
+ fpath += ".";
+ const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION");
+ if (!ext)
+ {
+ if (this->Target->IsXCTestOnApple())
+ {
+ ext = "xctest";
+ }
+ else
+ {
+ ext = "bundle";
+ }
+ }
+ fpath += ext;
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Contents";
+ if(!contentOnly)
+ fpath += "/MacOS";
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
+ bool rootDir) const
+{
+ std::string fpath;
+ fpath += this->GetOutputName(config, false);
+ fpath += ".framework";
+ if(!rootDir && !this->Makefile->PlatformIsAppleIos())
+ {
+ fpath += "/Versions/";
+ fpath += this->Target->GetFrameworkVersion();
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const
+{
+ if(this->Target->IsImported())
+ {
+ return this->Target->GetFullNameImported(config, implib);
+ }
+ else
+ {
+ return this->GetFullNameInternal(config, implib);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetInstallNameDirForBuildTree(
+ const std::string& config) const
+{
+ // If building directly for installation then the build tree install_name
+ // is the same as the install tree.
+ if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
+ {
+ return this->GetInstallNameDirForInstallTree();
+ }
+
+ // Use the build tree directory for the target.
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
+ !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+ !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+ {
+ std::string dir;
+ if(this->Target->MacOSXRpathInstallNameDirDefault())
+ {
+ dir = "@rpath";
+ }
+ else
+ {
+ dir = this->Target->GetDirectory(config);
+ }
+ dir += "/";
+ return dir;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
+{
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ {
+ std::string dir;
+ const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+
+ if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
+ {
+ if(install_name_dir && *install_name_dir)
+ {
+ dir = install_name_dir;
+ dir += "/";
+ }
+ }
+ if(!install_name_dir)
+ {
+ if(this->Target->MacOSXRpathInstallNameDirDefault())
+ {
+ dir = "@rpath/";
+ }
+ }
+ return dir;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+//----------------------------------------------------------------------------
+class cmTargetCollectLinkLanguages
+{
+public:
+ cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
+ const std::string& config,
+ UNORDERED_SET<std::string>& languages,
+ cmTarget const* head):
+ Config(config), Languages(languages), HeadTarget(head),
+ Makefile(target->Target->GetMakefile()), Target(target)
+ { this->Visited.insert(target->Target); }
+
+ void Visit(cmLinkItem const& item)
+ {
+ if(!item.Target)
+ {
+ if(item.find("::") != std::string::npos)
+ {
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ std::stringstream e;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+
+ if(!noMessage)
+ {
+ e << "Target \"" << this->Target->GetName()
+ << "\" links to target \"" << item
+ << "\" but the target was not found. Perhaps a find_package() "
+ "call is missing for an IMPORTED target, or an ALIAS target is "
+ "missing?";
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->Target->Target->GetBacktrace());
+ }
+ }
+ return;
+ }
+ if(!this->Visited.insert(item.Target).second)
+ {
+ return;
+ }
+ cmGeneratorTarget* gtgt =
+ this->Target->GetLocalGenerator()->GetGlobalGenerator()
+ ->GetGeneratorTarget(item.Target);
+ cmLinkInterface const* iface =
+ gtgt->GetLinkInterface(this->Config, this->HeadTarget);
+ if(!iface) { return; }
+
+ for(std::vector<std::string>::const_iterator
+ li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
+ {
+ this->Languages.insert(*li);
+ }
+
+ for(std::vector<cmLinkItem>::const_iterator
+ li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
+ {
+ this->Visit(*li);
+ }
+ }
+private:
+ std::string Config;
+ UNORDERED_SET<std::string>& Languages;
+ cmTarget const* HeadTarget;
+ cmMakefile* Makefile;
+ const cmGeneratorTarget* Target;
+ std::set<cmTarget const*> Visited;
+};
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkClosure const*
+cmGeneratorTarget::GetLinkClosure(const std::string& config) const
+{
+ std::string key(cmSystemTools::UpperCase(config));
+ LinkClosureMapType::iterator
+ i = this->LinkClosureMap.find(key);
+ if(i == this->LinkClosureMap.end())
+ {
+ LinkClosure lc;
+ this->ComputeLinkClosure(config, lc);
+ LinkClosureMapType::value_type entry(key, lc);
+ i = this->LinkClosureMap.insert(entry).first;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+class cmTargetSelectLinker
+{
+ int Preference;
+ cmGeneratorTarget const* Target;
+ cmMakefile* Makefile;
+ cmGlobalGenerator* GG;
+ std::set<std::string> Preferred;
+public:
+ cmTargetSelectLinker(cmGeneratorTarget const* target)
+ : Preference(0), Target(target)
+ {
+ this->Makefile = this->Target->Makefile;
+ this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
+ }
+ void Consider(const char* lang)
+ {
+ int preference = this->GG->GetLinkerPreference(lang);
+ if(preference > this->Preference)
+ {
+ this->Preference = preference;
+ this->Preferred.clear();
+ }
+ if(preference == this->Preference)
+ {
+ this->Preferred.insert(lang);
+ }
+ }
+ std::string Choose()
+ {
+ if(this->Preferred.empty())
+ {
+ return "";
+ }
+ else if(this->Preferred.size() > 1)
+ {
+ std::stringstream e;
+ e << "Target " << this->Target->GetName()
+ << " contains multiple languages with the highest linker preference"
+ << " (" << this->Preference << "):\n";
+ for(std::set<std::string>::const_iterator
+ li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
+ {
+ e << " " << *li << "\n";
+ }
+ e << "Set the LINKER_LANGUAGE property for this target.";
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->Target->GetBacktrace());
+ }
+ return *this->Preferred.begin();
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
+{
+ // Get languages built in this target.
+ UNORDERED_SET<std::string> languages;
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config);
+ assert(impl);
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ languages.insert(*li);
+ }
+
+ // Add interface languages from linked targets.
+ cmTargetCollectLinkLanguages cll(this, config, languages, this->Target);
+ for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
+ li != impl->Libraries.end(); ++li)
+ {
+ cll.Visit(*li);
+ }
+
+ // Store the transitive closure of languages.
+ for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
+ li != languages.end(); ++li)
+ {
+ lc.Languages.push_back(*li);
+ }
+
+ // Choose the language whose linker should be used.
+ if(this->GetProperty("HAS_CXX"))
+ {
+ lc.LinkerLanguage = "CXX";
+ }
+ else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
+ {
+ lc.LinkerLanguage = linkerLang;
+ }
+ else
+ {
+ // Find the language with the highest preference value.
+ cmTargetSelectLinker tsl(this);
+
+ // First select from the languages compiled directly in this target.
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ tsl.Consider(li->c_str());
+ }
+
+ // Now consider languages that propagate from linked targets.
+ for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
+ sit != languages.end(); ++sit)
+ {
+ std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
+ if(this->Makefile->IsOn(propagates))
+ {
+ tsl.Consider(sit->c_str());
+ }
+ }
+
+ lc.LinkerLanguage = tsl.Choose();
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetFullNameComponents(std::string& prefix,
+ std::string& base,
+ std::string& suffix,
+ const std::string& config,
+ bool implib) const
+{
+ this->GetFullNameInternal(config, implib, prefix, base, suffix);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::BuildMacContentDirectory(const std::string& base,
+ const std::string& config,
+ bool contentOnly) const
+{
+ std::string fpath = base;
+ if(this->Target->IsAppBundleOnApple())
+ {
+ fpath += this->GetAppBundleDirectory(config, contentOnly);
+ }
+ if(this->Target->IsFrameworkOnApple())
+ {
+ fpath += this->GetFrameworkDirectory(config, contentOnly);
+ }
+ if(this->Target->IsCFBundleOnApple())
+ {
+ fpath += this->GetCFBundleDirectory(config, contentOnly);
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
+ bool implib) const
+{
+ // Start with the output directory for the target.
+ std::string fpath = this->Target->GetDirectory(config, implib);
+ fpath += "/";
+ bool contentOnly = true;
+ if(this->Target->IsFrameworkOnApple())
+ {
+ // additional files with a framework go into the version specific
+ // directory
+ contentOnly = false;
+ }
+ fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
+ return fpath;
+}
+
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
+ const std::string& config) const
+{
+ // There is no compile information for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ if(this->GetType() > cmTarget::OBJECT_LIBRARY)
+ {
+ std::string msg = "cmTarget::GetCompileInfo called for ";
+ msg += this->GetName();
+ msg += " which has type ";
+ msg += cmTarget::GetTargetTypeName(this->Target->GetType());
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ return 0;
+ }
+
+ // Lookup/compute/cache the compile information for this configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ CompileInfoMapType::const_iterator i =
+ this->CompileInfoMap.find(config_upper);
+ if(i == this->CompileInfoMap.end())
+ {
+ CompileInfo info;
+ this->Target
+ ->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
+ CompileInfoMapType::value_type entry(config_upper, info);
+ i = this->CompileInfoMap.insert(entry).first;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+std::string
cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
{
std::string data;
@@ -611,6 +1537,83 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
}
//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
+ const std::string& config) const
+{
+ const char *prop
+ = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
+ config);
+ if (!prop)
+ {
+ return;
+ }
+ cmGeneratorExpression ge;
+
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GetName(),
+ "AUTOUIC_OPTIONS", 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(prop)
+ ->Evaluate(this->Makefile,
+ config,
+ false,
+ this->Target,
+ &dagChecker),
+ result);
+}
+
+//----------------------------------------------------------------------------
+void processILibs(const std::string& config,
+ cmTarget const* headTarget,
+ cmLinkItem const& item,
+ cmGlobalGenerator* gg,
+ std::vector<cmTarget const*>& tgts,
+ std::set<cmTarget const*>& emitted)
+{
+ if (item.Target && emitted.insert(item.Target).second)
+ {
+ tgts.push_back(item.Target);
+ cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target);
+ if(cmLinkInterfaceLibraries const* iface =
+ gt->GetLinkInterfaceLibraries(config, headTarget, true))
+ {
+ for(std::vector<cmLinkItem>::const_iterator
+ it = iface->Libraries.begin();
+ it != iface->Libraries.end(); ++it)
+ {
+ processILibs(config, headTarget, *it, gg, tgts, emitted);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const std::vector<const cmTarget*>&
+cmGeneratorTarget::GetLinkImplementationClosure(
+ const std::string& config) const
+{
+ LinkImplClosure& tgts =
+ this->LinkImplClosureMap[config];
+ if(!tgts.Done)
+ {
+ tgts.Done = true;
+ std::set<cmTarget const*> emitted;
+
+ cmLinkImplementationLibraries const* impl
+ = this->Target->GetLinkImplementationLibraries(config);
+
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
+ {
+ processILibs(config, this->Target, *it,
+ this->LocalGenerator->GetGlobalGenerator(),
+ tgts , emitted);
+ }
+ }
+ return tgts;
+}
+
+//----------------------------------------------------------------------------
class cmTargetTraceDependencies
{
public:
@@ -647,7 +1650,7 @@ cmTargetTraceDependencies
{
// Convenience.
this->Makefile = this->Target->GetMakefile();
- this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
+ this->GlobalGenerator = target->GetLocalGenerator()->GetGlobalGenerator();
this->CurrentEntry = 0;
// Queue all the source files already specified for the target.
@@ -677,7 +1680,8 @@ cmTargetTraceDependencies
e << "Evaluation output file\n \"" << sf->GetFullPath()
<< "\"\ndepends on the sources of a target it is used in. This "
"is a dependency loop and is not allowed.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->GeneratorTarget
+ ->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second)
@@ -799,7 +1803,8 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
}
// Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(util))
+ if(cmGeneratorTarget* t
+ = this->Makefile->FindGeneratorTargetToUse(util))
{
// If we find the target and the dep was given as a full path,
// then make sure it was not a full path to something else, and
@@ -843,7 +1848,7 @@ cmTargetTraceDependencies
{
// Transform command names that reference targets built in this
// project to corresponding target-level dependencies.
- cmGeneratorExpression ge(&cc.GetBacktrace());
+ cmGeneratorExpression ge(cc.GetBacktrace());
// Add target-level dependencies referenced by generator expressions.
std::set<cmTarget*> targets;
@@ -903,7 +1908,8 @@ void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
const std::string& config,
std::set<std::string>& emitted)
{
- cmCustomCommandGenerator ccg(cc, config, this->Makefile);
+ cmCustomCommandGenerator ccg(cc, config,
+ this->GeneratorTarget->LocalGenerator);
const std::vector<std::string>& depends = ccg.GetDepends();
@@ -952,6 +1958,16 @@ void cmGeneratorTarget::TraceDependencies()
tracer.Trace();
}
+std::string
+cmGeneratorTarget::GetCompilePDBDirectory(const std::string& config) const
+{
+ if(CompileInfo const* info = this->GetCompileInfo(config))
+ {
+ return info->CompilePdbDir;
+ }
+ return "";
+}
+
//----------------------------------------------------------------------------
void cmGeneratorTarget::GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const
@@ -983,7 +1999,7 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
case cmTarget::STATIC_LIBRARY:
{
std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
- if(this->Target->GetFeatureAsBool(
+ if(this->GetFeatureAsBool(
"INTERPROCEDURAL_OPTIMIZATION", config))
{
std::string varIPO = var + "_IPO";
@@ -1005,25 +2021,547 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
}
return "";
}
+//----------------------------------------------------------------------------
+static void processIncludeDirectories(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &includes,
+ UNORDERED_SET<std::string> &uniqueIncludes,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugIncludes,
+ const std::string& language)
+{
+ cmMakefile *mf = tgt->Target->GetMakefile();
+
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ cmLinkImplItem const& item = (*it)->LinkImplItem;
+ std::string const& targetName = item;
+ bool const fromImported = item.Target && item.Target->IsImported();
+ bool const checkCMP0027 = item.FromGenex;
+ std::vector<std::string> entryIncludes;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ config,
+ false,
+ tgt->Target,
+ dagChecker, language),
+ entryIncludes);
+
+ std::string usedIncludes;
+ for(std::vector<std::string>::iterator
+ li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+ {
+ if (fromImported
+ && !cmSystemTools::FileExists(li->c_str()))
+ {
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ if (checkCMP0027)
+ {
+ switch(tgt->Target->GetPolicyStatusCMP0027())
+ {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
+ case cmPolicies::OLD:
+ messageType = cmake::AUTHOR_WARNING;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ e << "Imported target \"" << 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->GetLocalGenerator()->IssueMessage(messageType, e.str());
+ return;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(li->c_str()))
+ {
+ std::ostringstream e;
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ if (!targetName.empty())
+ {
+ e << "Target \"" << targetName << "\" contains relative "
+ "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
+ " \"" << *li << "\"";
+ }
+ else
+ {
+ switch(tgt->Target->GetPolicyStatusCMP0021())
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+ e << "Found relative path while evaluating include directories of "
+ "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
+ }
+ if (!noMessage)
+ {
+ tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return;
+ }
+ }
+ }
+
+ if (!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 (!usedIncludes.empty())
+ {
+ mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used includes for target ")
+ + tgt->GetName() + ":\n"
+ + usedIncludes, (*it)->ge->GetBacktrace());
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+static void AddInterfaceEntries(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& prop,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+{
+ if(cmLinkImplementationLibraries const* impl =
+ thisTarget->Target->GetLinkImplementationLibraries(config))
+ {
+ for (std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin(), end = impl->Libraries.end();
+ it != end; ++it)
+ {
+ if(it->Target)
+ {
+ std::string genex =
+ "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+ cmGeneratorExpression ge(it->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+ cge->SetEvaluateForBuildsystem(true);
+ entries.push_back(
+ new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
+ }
+ }
+ }
+}
//----------------------------------------------------------------------------
std::vector<std::string>
cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
const std::string& lang) const
{
- return this->Target->GetIncludeDirectories(config, lang);
+ std::vector<std::string> includes;
+ UNORDERED_SET<std::string> uniqueIncludes;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "INCLUDE_DIRECTORIES", 0, 0);
+
+ 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->IsConfigured())
+ {
+ this->DebugIncludesDone = true;
+ }
+
+ processIncludeDirectories(this,
+ this->IncludeDirectoriesEntries,
+ includes,
+ uniqueIncludes,
+ &dagChecker,
+ config,
+ debugIncludes,
+ lang);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceIncludeDirectoriesEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_INCLUDE_DIRECTORIES",
+ linkInterfaceIncludeDirectoriesEntries);
+
+ if(this->Makefile->IsOn("APPLE"))
+ {
+ cmLinkImplementationLibraries const* impl =
+ this->Target->GetLinkImplementationLibraries(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin();
+ it != impl->Libraries.end(); ++it)
+ {
+ std::string libDir = cmSystemTools::CollapseFullPath(*it);
+
+ static cmsys::RegularExpression
+ frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+ if(!frameworkCheck.find(libDir))
+ {
+ continue;
+ }
+
+ libDir = frameworkCheck.match(1);
+
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(libDir.c_str());
+ linkInterfaceIncludeDirectoriesEntries
+ .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+ }
+
+ processIncludeDirectories(this,
+ linkInterfaceIncludeDirectoriesEntries,
+ includes,
+ uniqueIncludes,
+ &dagChecker,
+ config,
+ debugIncludes,
+ lang);
+
+ cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+
+ return includes;
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions, const char *logName,
+ std::string const& language)
+{
+ cmMakefile *mf = tgt->Target->GetMakefile();
+
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ std::vector<std::string> entryOptions;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ config,
+ false,
+ tgt->Target,
+ dagChecker,
+ language),
+ entryOptions);
+ std::string usedOptions;
+ for(std::vector<std::string>::iterator
+ li = entryOptions.begin(); li != entryOptions.end(); ++li)
+ {
+ std::string const& opt = *li;
+
+ if(uniqueOptions.insert(opt).second)
+ {
+ options.push_back(opt);
+ if (debugOptions)
+ {
+ usedOptions += " * " + opt + "\n";
+ }
+ }
+ }
+ if (!usedOptions.empty())
+ {
+ mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used compile ") + logName
+ + std::string(" for target ")
+ + tgt->GetName() + ":\n"
+ + usedOptions, (*it)->ge->GetBacktrace());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptions(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions,
+ std::string const& language)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions, "options",
+ language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const
+{
+ UNORDERED_SET<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_OPTIONS", 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugOptions = !this->DebugCompileOptionsDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_OPTIONS")
+ != debugProperties.end();
+
+ if (this->Makefile->IsConfigured())
+ {
+ this->DebugCompileOptionsDone = true;
+ }
+
+ processCompileOptions(this,
+ this->CompileOptionsEntries,
+ result,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugOptions,
+ language);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileOptionsEntries;
+
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_OPTIONS",
+ linkInterfaceCompileOptionsEntries);
+
+ processCompileOptions(this,
+ linkInterfaceCompileOptionsEntries,
+ result,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugOptions,
+ language);
+
+ cmDeleteAll(linkInterfaceCompileOptionsEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileFeatures(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions, "features",
+ std::string());
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result,
+ const std::string& config) const
+{
+ UNORDERED_SET<std::string> uniqueFeatures;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_FEATURES",
+ 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugFeatures = !this->DebugCompileFeaturesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_FEATURES")
+ != debugProperties.end();
+
+ if (this->Makefile->IsConfigured())
+ {
+ this->DebugCompileFeaturesDone = true;
+ }
+
+ processCompileFeatures(this,
+ this->CompileFeaturesEntries,
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileFeaturesEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_FEATURES",
+ linkInterfaceCompileFeaturesEntries);
+
+ processCompileFeatures(this,
+ linkInterfaceCompileFeaturesEntries,
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ cmDeleteAll(linkInterfaceCompileFeaturesEntries);
+}
+
+//----------------------------------------------------------------------------
+static void processCompileDefinitions(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ UNORDERED_SET<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions,
+ std::string const& language)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions,
+ "definitions", language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
+ const std::string& config,
+ const std::string& language) const
+{
+ UNORDERED_SET<std::string> uniqueOptions;
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "COMPILE_DEFINITIONS", 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugDefines = !this->DebugCompileDefinitionsDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_DEFINITIONS")
+ != debugProperties.end();
+
+ if (this->Makefile->IsConfigured())
+ {
+ this->DebugCompileDefinitionsDone = true;
+ }
+
+ processCompileDefinitions(this,
+ this->CompileDefinitionsEntries,
+ list,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugDefines,
+ language);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceCompileDefinitionsEntries;
+ AddInterfaceEntries(
+ this, config, "INTERFACE_COMPILE_DEFINITIONS",
+ linkInterfaceCompileDefinitionsEntries);
+ if (!config.empty())
+ {
+ std::string configPropName = "COMPILE_DEFINITIONS_"
+ + cmSystemTools::UpperCase(config);
+ const char *configProp = this->Target->GetProperty(configPropName);
+ if (configProp)
+ {
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING,
+ e.str());
+ }
+ case cmPolicies::OLD:
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(configProp);
+ linkInterfaceCompileDefinitionsEntries
+ .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+ }
+
+ processCompileDefinitions(this,
+ linkInterfaceCompileDefinitionsEntries,
+ list,
+ uniqueOptions,
+ &dagChecker,
+ config,
+ debugDefines,
+ language);
+
+ cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::GenerateTargetManifest(
+void cmGeneratorTarget::ComputeTargetManifest(
const std::string& config) const
{
if (this->Target->IsImported())
{
return;
}
- cmMakefile* mf = this->Target->GetMakefile();
- cmGlobalGenerator* gg = mf->GetGlobalGenerator();
+ cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
// Get the names.
std::string name;
@@ -1033,14 +2571,13 @@ void cmGeneratorTarget::GenerateTargetManifest(
std::string pdbName;
if(this->GetType() == cmTarget::EXECUTABLE)
{
- this->Target->GetExecutableNames(name, realName, impName, pdbName,
- config);
+ this->GetExecutableNames(name, realName, impName, pdbName, config);
}
else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
this->GetType() == cmTarget::SHARED_LIBRARY ||
this->GetType() == cmTarget::MODULE_LIBRARY)
{
- this->Target->GetLibraryNames(name, soName, realName, impName, pdbName,
+ this->GetLibraryNames(name, soName, realName, impName, pdbName,
config);
}
else
@@ -1058,36 +2595,451 @@ void cmGeneratorTarget::GenerateTargetManifest(
f = dir;
f += "/";
f += name;
- gg->AddToManifest(config, f);
+ gg->AddToManifest(f);
}
if(!soName.empty())
{
f = dir;
f += "/";
f += soName;
- gg->AddToManifest(config, f);
+ gg->AddToManifest(f);
}
if(!realName.empty())
{
f = dir;
f += "/";
f += realName;
- gg->AddToManifest(config, f);
+ gg->AddToManifest(f);
}
if(!pdbName.empty())
{
f = dir;
f += "/";
f += pdbName;
- gg->AddToManifest(config, f);
+ gg->AddToManifest(f);
}
if(!impName.empty())
{
f = this->Target->GetDirectory(config, true);
f += "/";
f += impName;
- gg->AddToManifest(config, f);
+ gg->AddToManifest(f);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullPath(const std::string& config,
+ bool implib, bool realname) const
+{
+ if(this->Target->IsImported())
+ {
+ return this->Target->ImportedGetFullPath(config, implib);
+ }
+ else
+ {
+ return this->NormalGetFullPath(config, implib, realname);
+ }
+}
+
+std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
+ bool implib,
+ bool realname) const
+{
+ std::string fpath = this->Target->GetDirectory(config, implib);
+ fpath += "/";
+ if(this->Target->IsAppBundleOnApple())
+ {
+ fpath = this->BuildMacContentDirectory(fpath, config, false);
+ fpath += "/";
+ }
+
+ // Add the full name of the target.
+ if(implib)
+ {
+ fpath += this->GetFullName(config, true);
+ }
+ else if(realname)
+ {
+ fpath += this->NormalGetRealName(config);
+ }
+ else
+ {
+ fpath += this->GetFullName(config, false);
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::NormalGetRealName(const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->Target->IsImported())
+ {
+ std::string msg = "NormalGetRealName called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ }
+
+ if(this->GetType() == cmTarget::EXECUTABLE)
+ {
+ // Compute the real name that will be built.
+ std::string name;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetExecutableNames(name, realName, impName, pdbName, config);
+ return realName;
+ }
+ else
+ {
+ // Compute the real name that will be built.
+ std::string name;
+ std::string soName;
+ std::string realName;
+ std::string impName;
+ std::string pdbName;
+ this->GetLibraryNames(name, soName, realName,
+ impName, pdbName, config);
+ return realName;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLibraryNames(std::string& name,
+ std::string& soName,
+ std::string& realName,
+ std::string& impName,
+ std::string& pdbName,
+ const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->Target->IsImported())
+ {
+ std::string msg = "GetLibraryNames called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR,
+ msg);
+ return;
+ }
+
+ // Check for library version properties.
+ const char* version = this->GetProperty("VERSION");
+ const char* soversion = this->GetProperty("SOVERSION");
+ if(!this->HasSOName(config) ||
+ this->Target->IsFrameworkOnApple())
+ {
+ // Versioning is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ version = 0;
+ soversion = 0;
+ }
+ if(version && !soversion)
+ {
+ // The soversion must be set if the library version is set. Use
+ // the library version as the soversion.
+ soversion = version;
+ }
+ if(!version && soversion)
+ {
+ // Use the soversion as the library version.
+ version = soversion;
+ }
+
+ // Get the components of the library name.
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // The library name.
+ name = prefix+base+suffix;
+
+ if(this->Target->IsFrameworkOnApple())
+ {
+ realName = prefix;
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ realName += "Versions/";
+ realName += this->Target->GetFrameworkVersion();
+ realName += "/";
+ }
+ realName += base;
+ soName = realName;
+ }
+ else
+ {
+ // The library's soname.
+ this->Target->ComputeVersionedName(soName, prefix, base, suffix,
+ name, soversion);
+
+ // The library's real name on disk.
+ this->Target->ComputeVersionedName(realName, prefix, base, suffix,
+ name, version);
+ }
+
+ // The import library name.
+ if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ impName = this->GetFullNameInternal(config, true);
+ }
+ else
+ {
+ impName = "";
+ }
+
+ // The program database file name.
+ pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetExecutableNames(std::string& name,
+ std::string& realName,
+ std::string& impName,
+ std::string& pdbName,
+ const std::string& config) const
+{
+ // This should not be called for imported targets.
+ // TODO: Split cmTarget into a class hierarchy to get compile-time
+ // enforcement of the limited imported target API.
+ if(this->Target->IsImported())
+ {
+ std::string msg =
+ "GetExecutableNames called on imported target: ";
+ msg += this->GetName();
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ }
+
+ // This versioning is supported only for executables and then only
+ // when the platform supports symbolic links.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* version = 0;
+#else
+ // Check for executable version properties.
+ const char* version = this->GetProperty("VERSION");
+ if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
+ {
+ version = 0;
+ }
+#endif
+
+ // Get the components of the executable name.
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ // The executable name.
+ name = prefix+base+suffix;
+
+ // The executable's real name on disk.
+#if defined(__CYGWIN__)
+ realName = prefix+base;
+#else
+ realName = name;
+#endif
+ if(version)
+ {
+ realName += "-";
+ realName += version;
+ }
+#if defined(__CYGWIN__)
+ realName += suffix;
+#endif
+
+ // The import library name.
+ impName = this->GetFullNameInternal(config, true);
+
+ // The program database file name.
+ pdbName = this->GetPDBName(config);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+ bool implib) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, implib, prefix, base, suffix);
+ return prefix+base+suffix;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
+ bool implib,
+ std::string& outPrefix,
+ std::string& outBase,
+ std::string& outSuffix) const
+{
+ // Use just the target name for non-main target types.
+ if(this->GetType() != cmTarget::STATIC_LIBRARY &&
+ this->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->GetType() != cmTarget::MODULE_LIBRARY &&
+ this->GetType() != cmTarget::EXECUTABLE)
+ {
+ outPrefix = "";
+ outBase = this->GetName();
+ outSuffix = "";
+ return;
+ }
+
+ // Return an empty name for the import library if this platform
+ // does not support import libraries.
+ if(implib &&
+ !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
+ {
+ outPrefix = "";
+ outBase = "";
+ outSuffix = "";
+ return;
+ }
+
+ // The implib option is only allowed for shared libraries, module
+ // libraries, and executables.
+ if(this->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->GetType() != cmTarget::MODULE_LIBRARY &&
+ this->GetType() != cmTarget::EXECUTABLE)
+ {
+ implib = false;
+ }
+
+ // Compute the full name for main target types.
+ const char* targetPrefix = (implib
+ ? this->GetProperty("IMPORT_PREFIX")
+ : this->GetProperty("PREFIX"));
+ const char* targetSuffix = (implib
+ ? this->GetProperty("IMPORT_SUFFIX")
+ : this->GetProperty("SUFFIX"));
+ const char* configPostfix = 0;
+ if(!config.empty())
+ {
+ std::string configProp = cmSystemTools::UpperCase(config);
+ configProp += "_POSTFIX";
+ configPostfix = this->GetProperty(configProp);
+ // Mac application bundles and frameworks have no postfix.
+ if(configPostfix &&
+ (this->Target->IsAppBundleOnApple()
+ || this->Target->IsFrameworkOnApple()))
+ {
+ configPostfix = 0;
+ }
+ }
+ const char* prefixVar = this->Target->GetPrefixVariableInternal(implib);
+ const char* suffixVar = this->Target->GetSuffixVariableInternal(implib);
+
+ // Check for language-specific default prefix and suffix.
+ std::string ll = this->GetLinkerLanguage(config);
+ if(!ll.empty())
+ {
+ if(!targetSuffix && suffixVar && *suffixVar)
+ {
+ std::string langSuff = suffixVar + std::string("_") + ll;
+ targetSuffix = this->Makefile->GetDefinition(langSuff);
+ }
+ if(!targetPrefix && prefixVar && *prefixVar)
+ {
+ std::string langPrefix = prefixVar + std::string("_") + ll;
+ targetPrefix = this->Makefile->GetDefinition(langPrefix);
+ }
+ }
+
+ // if there is no prefix on the target use the cmake definition
+ if(!targetPrefix && prefixVar)
+ {
+ targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
+ }
+ // if there is no suffix on the target use the cmake definition
+ if(!targetSuffix && suffixVar)
+ {
+ targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
+ }
+
+ // frameworks have directory prefix but no suffix
+ std::string fw_prefix;
+ if(this->Target->IsFrameworkOnApple())
+ {
+ fw_prefix = this->GetOutputName(config, false);
+ fw_prefix += ".framework/";
+ targetPrefix = fw_prefix.c_str();
+ targetSuffix = 0;
+ }
+
+ if(this->Target->IsCFBundleOnApple())
+ {
+ fw_prefix = this->GetCFBundleDirectory(config, false);
+ fw_prefix += "/";
+ targetPrefix = fw_prefix.c_str();
+ targetSuffix = 0;
}
+
+ // Begin the final name with the prefix.
+ outPrefix = targetPrefix?targetPrefix:"";
+
+ // Append the target name or property-specified name.
+ outBase += this->GetOutputName(config, implib);
+
+ // Append the per-configuration postfix.
+ outBase += configPostfix?configPostfix:"";
+
+ // Name shared libraries with their version number on some platforms.
+ if(const char* soversion = this->GetProperty("SOVERSION"))
+ {
+ if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
+ this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
+ {
+ outBase += "-";
+ outBase += soversion;
+ }
+ }
+
+ // Append the suffix.
+ outSuffix = targetSuffix?targetSuffix:"";
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetLinkerLanguage(const std::string& config) const
+{
+ return this->GetLinkClosure(config)->LinkerLanguage;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+
+ std::vector<std::string> props;
+ std::string configUpper =
+ cmSystemTools::UpperCase(config);
+ if(!configUpper.empty())
+ {
+ // PDB_NAME_<CONFIG>
+ props.push_back("PDB_NAME_" + configUpper);
+ }
+
+ // PDB_NAME
+ props.push_back("PDB_NAME");
+
+ for(std::vector<std::string>::const_iterator i = props.begin();
+ i != props.end(); ++i)
+ {
+ if(const char* outName = this->GetProperty(*i))
+ {
+ base = outName;
+ break;
+ }
+ }
+ return prefix+base+".pdb";
}
bool cmStrictTargetComparison::operator()(cmTarget const* t1,
@@ -1195,3 +3147,1407 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
}
}
}
+
+//----------------------------------------------------------------------------
+const cmGeneratorTarget::CompatibleInterfacesBase&
+cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
+{
+ cmGeneratorTarget::CompatibleInterfaces& compat =
+ this->CompatibleInterfacesMap[config];
+ if(!compat.Done)
+ {
+ compat.Done = true;
+ compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
+ compat.PropsString.insert("AUTOUIC_OPTIONS");
+ std::vector<cmTarget const*> const& deps =
+ this->GetLinkImplementationClosure(config);
+ for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
+ li != deps.end(); ++li)
+ {
+#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
+ if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
+ { \
+ std::vector<std::string> props; \
+ cmSystemTools::ExpandListArgument(prop, props); \
+ compat.Props##x.insert(props.begin(), props.end()); \
+ }
+ CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
+ CM_READ_COMPATIBLE_INTERFACE(STRING, String)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
+ CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
+#undef CM_READ_COMPATIBLE_INTERFACE
+ }
+ }
+ return compat;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+ || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+ || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+ || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
+ const std::string &p, const std::string& config) const
+{
+ if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
+ || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ {
+ return false;
+ }
+ return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
+}
+
+enum CompatibleType
+{
+ BoolType,
+ StringType,
+ NumberMinType,
+ NumberMaxType
+};
+
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType,
+ PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType, bool *)
+{
+ return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop,
+ const std::string& config,
+ CompatibleType t,
+ const char **)
+{
+ switch(t)
+ {
+ case BoolType:
+ assert(0 && "String compatibility check function called for boolean");
+ return 0;
+ case StringType:
+ return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+ case NumberMinType:
+ return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
+ case NumberMaxType:
+ return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
+ }
+ assert(0 && "Unreachable!");
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmGeneratorTarget const* depender,
+ cmTarget const* dependee,
+ const std::string& propName,
+ std::set<std::string> &emitted,
+ const std::string& config,
+ CompatibleType t,
+ PropertyType *)
+{
+ const char *prop = dependee->GetProperty(propName);
+ if (!prop)
+ {
+ return;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+ std::string pdir =
+ dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
+ pdir += "/Help/prop_tgt/";
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ std::string pname = cmSystemTools::HelpFileName(*pi);
+ std::string pfile = pdir + pname + ".rst";
+ if(cmSystemTools::FileExists(pfile.c_str(), true))
+ {
+ std::ostringstream 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->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(emitted.insert(*pi).second)
+ {
+ getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+ t, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+ }
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2)
+{
+ std::set<std::string> intersect;
+ std::set_intersection(s1.begin(),s1.end(),
+ s2.begin(),s2.end(),
+ std::inserter(intersect,intersect.begin()));
+ if (!intersect.empty())
+ {
+ return *intersect.begin();
+ }
+ return "";
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3);
+}
+
+static std::string intersect(const std::set<std::string> &s1,
+ const std::set<std::string> &s2,
+ const std::set<std::string> &s3,
+ const std::set<std::string> &s4)
+{
+ std::string result;
+ result = intersect(s1, s2);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s3);
+ if (!result.empty())
+ return result;
+ result = intersect(s1, s4);
+ if (!result.empty())
+ return result;
+ return intersect(s2, s3, s4);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::CheckPropertyCompatibility(
+ cmComputeLinkInformation *info, const std::string& config) const
+{
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ std::set<std::string> emittedBools;
+ static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
+ std::set<std::string> emittedStrings;
+ static std::string strString = "COMPATIBLE_INTERFACE_STRING";
+ std::set<std::string> emittedMinNumbers;
+ static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
+ std::set<std::string> emittedMaxNumbers;
+ static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin(); li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+
+ checkPropertyConsistency<bool>(this, li->Target,
+ strBool,
+ emittedBools, config, BoolType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strString,
+ emittedStrings, config,
+ StringType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strNumMin,
+ emittedMinNumbers, config,
+ NumberMinType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ strNumMax,
+ emittedMaxNumbers, config,
+ NumberMaxType, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+
+ std::string prop = intersect(emittedBools,
+ emittedStrings,
+ emittedMinNumbers,
+ emittedMaxNumbers);
+
+ if (!prop.empty())
+ {
+ // Use a sorted std::vector to keep the error message sorted.
+ std::vector<std::string> props;
+ std::set<std::string>::const_iterator i = emittedBools.find(prop);
+ if (i != emittedBools.end())
+ {
+ props.push_back(strBool);
+ }
+ i = emittedStrings.find(prop);
+ if (i != emittedStrings.end())
+ {
+ props.push_back(strString);
+ }
+ i = emittedMinNumbers.find(prop);
+ if (i != emittedMinNumbers.end())
+ {
+ props.push_back(strNumMin);
+ }
+ i = emittedMaxNumbers.find(prop);
+ if (i != emittedMaxNumbers.end())
+ {
+ props.push_back(strNumMax);
+ }
+ std::sort(props.begin(), props.end());
+
+ std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
+ propsString += " and the " + props.back();
+
+ std::ostringstream e;
+ e << "Property \"" << prop << "\" appears in both the "
+ << propsString <<
+ " property in the dependencies of target \"" << this->GetName() <<
+ "\". This is not allowed. A property may only require compatibility "
+ "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
+ "string interpretation, but not a mixture.";
+ this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityType(CompatibleType t)
+{
+ switch(t)
+ {
+ case BoolType:
+ return "Boolean compatibility";
+ case StringType:
+ return "String compatibility";
+ case NumberMaxType:
+ return "Numeric maximum compatibility";
+ case NumberMinType:
+ return "Numeric minimum compatibility";
+ }
+ assert(0 && "Unreachable!");
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string compatibilityAgree(CompatibleType t, bool dominant)
+{
+ switch(t)
+ {
+ case BoolType:
+ case StringType:
+ return dominant ? "(Disagree)\n" : "(Agree)\n";
+ case NumberMaxType:
+ case NumberMinType:
+ return dominant ? "(Dominant)\n" : "(Ignored)\n";
+ }
+ assert(0 && "Unreachable!");
+ return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
+
+//----------------------------------------------------------------------------
+template<>
+bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
+{
+ return tgt->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmTarget const* tgt,
+ const std::string& prop)
+{
+ return tgt->GetProperty(prop);
+}
+
+template<typename PropertyType>
+std::string valueAsString(PropertyType);
+template<>
+std::string valueAsString<bool>(bool value)
+{
+ return value ? "TRUE" : "FALSE";
+}
+template<>
+std::string valueAsString<const char*>(const char* value)
+{
+ return value ? value : "(unset)";
+}
+
+template<typename PropertyType>
+PropertyType impliedValue(PropertyType);
+template<>
+bool impliedValue<bool>(bool)
+{
+ return false;
+}
+template<>
+const char* impliedValue<const char*>(const char*)
+{
+ return "";
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
+ PropertyType rhs,
+ CompatibleType t);
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
+ CompatibleType)
+{
+ return std::make_pair(lhs == rhs, lhs);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentStringProperty(const char *lhs,
+ const char *rhs)
+{
+ const bool b = strcmp(lhs, rhs) == 0;
+ return std::make_pair(b, b ? lhs : 0);
+}
+
+//----------------------------------------------------------------------------
+std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
+ const char *rhs,
+ CompatibleType t)
+{
+ char *pEnd;
+
+ const char* const null_ptr = 0;
+
+ long lnum = strtol(lhs, &pEnd, 0);
+ if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ return std::pair<bool, const char*>(false, null_ptr);
+ }
+
+ long rnum = strtol(rhs, &pEnd, 0);
+ if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
+ {
+ return std::pair<bool, const char*>(false, null_ptr);
+ }
+
+ if (t == NumberMaxType)
+ {
+ return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
+ }
+ else
+ {
+ return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
+ }
+}
+
+//----------------------------------------------------------------------------
+template<>
+std::pair<bool, const char*> consistentProperty(const char *lhs,
+ const char *rhs,
+ CompatibleType t)
+{
+ if (!lhs && !rhs)
+ {
+ return std::make_pair(true, lhs);
+ }
+ if (!lhs)
+ {
+ return std::make_pair(true, rhs);
+ }
+ if (!rhs)
+ {
+ return std::make_pair(true, lhs);
+ }
+
+ const char* const null_ptr = 0;
+
+ switch(t)
+ {
+ case BoolType:
+ assert(0 && "consistentProperty for strings called with BoolType");
+ return std::pair<bool, const char*>(false, null_ptr);
+ case StringType:
+ return consistentStringProperty(lhs, rhs);
+ case NumberMinType:
+ case NumberMaxType:
+ return consistentNumberProperty(lhs, rhs, t);
+ }
+ assert(0 && "Unreachable!");
+ return std::pair<bool, const char*>(false, null_ptr);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
+ const std::string &p,
+ const std::string& config,
+ const char *defaultValue,
+ CompatibleType t,
+ PropertyType *)
+{
+ PropertyType propContent = getTypedProperty<PropertyType>(tgt->Target, p);
+ const bool explicitlySet = tgt->Target->GetProperties()
+ .find(p)
+ != tgt->Target->GetProperties().end();
+ const bool impliedByUse =
+ tgt->Target->IsNullImpliedByLinkLibraries(p);
+ assert((impliedByUse ^ explicitlySet)
+ || (!impliedByUse && !explicitlySet));
+
+ std::vector<cmTarget const*> const& deps =
+ tgt->GetLinkImplementationClosure(config);
+
+ if(deps.empty())
+ {
+ return propContent;
+ }
+ bool propInitialized = explicitlySet;
+
+ std::string report = " * Target \"";
+ report += tgt->GetName();
+ if (explicitlySet)
+ {
+ report += "\" has property content \"";
+ report += valueAsString<PropertyType>(propContent);
+ report += "\"\n";
+ }
+ else if (impliedByUse)
+ {
+ report += "\" property is implied by use.\n";
+ }
+ else
+ {
+ report += "\" property not set.\n";
+ }
+
+ std::string interfaceProperty = "INTERFACE_" + p;
+ for(std::vector<cmTarget const*>::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.
+
+ cmTarget const* theTarget = *li;
+
+ const bool ifaceIsSet = theTarget->GetProperties()
+ .find(interfaceProperty)
+ != theTarget->GetProperties().end();
+ PropertyType ifacePropContent =
+ getTypedProperty<PropertyType>(theTarget,
+ interfaceProperty);
+
+ std::string reportEntry;
+ if (ifaceIsSet)
+ {
+ reportEntry += " * Target \"";
+ reportEntry += theTarget->GetName();
+ reportEntry += "\" property value \"";
+ reportEntry += valueAsString<PropertyType>(ifacePropContent);
+ reportEntry += "\" ";
+ }
+
+ if (explicitlySet)
+ {
+ if (ifaceIsSet)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream e;
+ e << "Property " << p << " on target \""
+ << tgt->GetName() << "\" does\nnot match the "
+ "INTERFACE_" << p << " property requirement\nof "
+ "dependency \"" << theTarget->GetName() << "\".\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ // Explicitly set on target and not set in iface. Can't disagree.
+ continue;
+ }
+ }
+ else if (impliedByUse)
+ {
+ propContent = impliedValue<PropertyType>(propContent);
+
+ if (ifaceIsSet)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream 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 \""
+ << theTarget->GetName() << "\" is in conflict.\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ // Implicitly set on target and not set in iface. Can't disagree.
+ continue;
+ }
+ }
+ else
+ {
+ if (ifaceIsSet)
+ {
+ if (propInitialized)
+ {
+ std::pair<bool, PropertyType> consistent =
+ consistentProperty(propContent,
+ ifacePropContent, t);
+ report += reportEntry;
+ report += compatibilityAgree(t, propContent != consistent.second);
+ if (!consistent.first)
+ {
+ std::ostringstream e;
+ e << "The INTERFACE_" << p << " property of \""
+ << theTarget->GetName() << "\" does\nnot agree with the value "
+ "of " << p << " already determined\nfor \""
+ << tgt->GetName() << "\".\n";
+ cmSystemTools::Error(e.str().c_str());
+ break;
+ }
+ else
+ {
+ propContent = consistent.second;
+ continue;
+ }
+ }
+ else
+ {
+ report += reportEntry + "(Interface set)\n";
+ propContent = ifacePropContent;
+ propInitialized = true;
+ }
+ }
+ else
+ {
+ // Not set. Nothing to agree on.
+ continue;
+ }
+ }
+ }
+
+ tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
+ report, compatibilityType(t));
+ return propContent;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
+ const std::string &p, const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<bool>(this, p, config,
+ "FALSE",
+ BoolType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ StringType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMinProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMinType, 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMaxProperty(
+ const std::string &p,
+ const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty",
+ NumberMaxType, 0);
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmGeneratorTarget::GetLinkInformation(const std::string& config) const
+{
+ // Lookup any existing information for this configuration.
+ std::string key(cmSystemTools::UpperCase(config));
+ cmTargetLinkInformationMap::iterator
+ i = this->LinkInformation.find(key);
+ if(i == this->LinkInformation.end())
+ {
+ // Compute information for this configuration.
+ cmComputeLinkInformation* info =
+ new cmComputeLinkInformation(this, config);
+ 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;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
+ const std::string &result,
+ const std::string &report,
+ const std::string &compatibilityType) const
+{
+ std::vector<std::string> debugProperties;
+ const char *debugProp = this->Target->GetMakefile()
+ ->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ p)
+ != debugProperties.end();
+
+ if (this->Target->GetMakefile()->IsConfigured())
+ {
+ this->DebugCompatiblePropertiesDone[p] = true;
+ }
+ if (!debugOrigin)
+ {
+ return;
+ }
+
+ std::string areport = compatibilityType;
+ areport += std::string(" of property \"") + p + "\" for target \"";
+ areport += std::string(this->GetName());
+ areport += "\" (result: \"";
+ areport += result;
+ areport += "\"):\n" + report;
+
+ this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const
+{
+ for(std::vector<std::string>::const_iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ std::string name = this->Target->CheckCMP0004(*i);
+ if(name == this->GetName() || name.empty())
+ {
+ continue;
+ }
+ items.push_back(cmLinkItem(name, this->Target->FindTargetToLink(name)));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
+ std::string const& value,
+ std::string const& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const
+{
+ cmGeneratorExpression ge;
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+ // The $<LINK_ONLY> expression may be in a link interface to specify private
+ // link dependencies that are otherwise excluded from usage requirements.
+ if(usage_requirements_only)
+ {
+ dagChecker.SetTransitivePropertiesOnly();
+ }
+ std::vector<std::string> libs;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->Makefile,
+ config,
+ false,
+ headTarget,
+ this->Target, &dagChecker), libs);
+ this->LookupLinkItems(libs, items);
+ hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+}
+
+//----------------------------------------------------------------------------
+cmLinkInterface const*
+cmGeneratorTarget::GetLinkInterface(const std::string& config,
+ cmTarget const* head) const
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ return this->GetImportLinkInterface(config, head, false);
+ }
+
+ // Link interfaces are not supported for executables that do not
+ // export symbols.
+ if(this->GetType() == cmTarget::EXECUTABLE &&
+ !this->Target->IsExecutableWithExports())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link interface for this configuration.
+ cmHeadToLinkInterfaceMap& hm =
+ this->GetHeadToLinkInterfaceMap(config);
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->ComputeLinkInterfaceLibraries(
+ config, iface, head, false);
+ }
+ if(!iface.AllDone)
+ {
+ iface.AllDone = true;
+ if(iface.Exists)
+ {
+ this->ComputeLinkInterface(config, iface, head);
+ }
+ }
+
+ return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface &iface,
+ cmTarget const* headTarget) const
+{
+ if(iface.ExplicitLibraries)
+ {
+ if(this->GetType() == cmTarget::SHARED_LIBRARY
+ || this->GetType() == cmTarget::STATIC_LIBRARY
+ || this->GetType() == cmTarget::INTERFACE_LIBRARY)
+ {
+ // Shared libraries may have runtime implementation dependencies
+ // on other shared libraries that are not in the interface.
+ UNORDERED_SET<std::string> emitted;
+ for(std::vector<cmLinkItem>::const_iterator
+ li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
+ {
+ emitted.insert(*li);
+ }
+ if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
+ {
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config);
+ for(std::vector<cmLinkImplItem>::const_iterator
+ li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
+ {
+ if(emitted.insert(*li).second)
+ {
+ if(li->Target)
+ {
+ // This is a runtime dependency on another shared library.
+ if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ iface.SharedDeps.push_back(*li);
+ }
+ }
+ else
+ {
+ // TODO: Recognize shared library file names. Perhaps this
+ // should be moved to cmComputeLinkInformation, but that creates
+ // a chicken-and-egg problem since this list is needed for its
+ // construction.
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ {
+ // The link implementation is the default link interface.
+ cmLinkImplementationLibraries const*
+ impl = this->Target->GetLinkImplementationLibrariesInternal(config,
+ headTarget);
+ iface.ImplementationIsInterface = true;
+ iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+ }
+
+ if(this->Target->LinkLanguagePropagatesToDependents())
+ {
+ // Targets using this archive need its language runtime libraries.
+ if(cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config))
+ {
+ iface.Languages = impl->Languages;
+ }
+ }
+
+ if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ // Construct the property name suffix for this configuration.
+ std::string suffix = "_";
+ if(!config.empty())
+ {
+ suffix += cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ suffix += "NOCONFIG";
+ }
+
+ // How many repetitions are needed if this library has cyclic
+ // dependencies?
+ std::string propName = "LINK_INTERFACE_MULTIPLICITY";
+ propName += suffix;
+ if(const char* config_reps = this->GetProperty(propName))
+ {
+ sscanf(config_reps, "%u", &iface.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &iface.Multiplicity);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const cmLinkInterfaceLibraries *
+cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
+ cmTarget const* head,
+ bool usage_requirements_only) const
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ return this->GetImportLinkInterface(config, head,
+ usage_requirements_only);
+ }
+
+ // Link interfaces are not supported for executables that do not
+ // export symbols.
+ if(this->GetType() == cmTarget::EXECUTABLE &&
+ !this->Target->IsExecutableWithExports())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link interface for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmHeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+ this->GetHeadToLinkInterfaceMap(config));
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[head];
+ if(!iface.LibrariesDone)
+ {
+ iface.LibrariesDone = true;
+ this->ComputeLinkInterfaceLibraries(
+ config, iface, head, usage_requirements_only);
+ }
+
+ return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ComputeLinkInterfaceLibraries(
+ const std::string& config,
+ cmOptionalLinkInterface& iface,
+ cmTarget const* headTarget,
+ bool usage_requirements_only) const
+{
+ // Construct the property name suffix for this configuration.
+ std::string suffix = "_";
+ if(!config.empty())
+ {
+ suffix += cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ suffix += "NOCONFIG";
+ }
+
+ // 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->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+ this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN)
+ {
+ // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
+ linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+ }
+ else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->Target->IsExecutableWithExports())
+ {
+ // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
+ // shared lib or executable.
+
+ // Lookup the per-configuration property.
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ linkIfaceProp += suffix;
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+
+ // If not set, try the generic property.
+ if(!explicitLibraries)
+ {
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp);
+ }
+ }
+
+ if(explicitLibraries &&
+ this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022)
+ {
+ // Compare the explicitly set old link interface properties to the
+ // preferred new link interface property one and warn if different.
+ const char* newExplicitLibraries =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ if (newExplicitLibraries
+ && strcmp(newExplicitLibraries, explicitLibraries) != 0)
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property which differs from its " <<
+ linkIfaceProp << " properties."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newExplicitLibraries << "\n" <<
+ linkIfaceProp << ":\n"
+ " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
+ }
+ }
+
+ // There is no implicit link interface for executables or modules
+ // so if none was explicitly set then there is no link interface.
+ if(!explicitLibraries &&
+ (this->GetType() == cmTarget::EXECUTABLE ||
+ (this->GetType() == cmTarget::MODULE_LIBRARY)))
+ {
+ return;
+ }
+ iface.Exists = true;
+ iface.ExplicitLibraries = explicitLibraries;
+
+ if(explicitLibraries)
+ {
+ // The interface libraries have been explicitly set.
+ this->ExpandLinkItems(linkIfaceProp, explicitLibraries,
+ config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ }
+ else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ // If CMP0022 is NEW then the plain tll signature sets the
+ // INTERFACE_LINK_LIBRARIES, so if we get here then the project
+ // cleared the property explicitly and we should not fall back
+ // to the link implementation.
+ {
+ // The link implementation is the default link interface.
+ cmLinkImplementationLibraries const* impl =
+ this->Target->GetLinkImplementationLibrariesInternal(config,
+ headTarget);
+ iface.Libraries.insert(iface.Libraries.end(),
+ impl->Libraries.begin(), impl->Libraries.end());
+ if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ !this->PolicyWarnedCMP0022 && !usage_requirements_only)
+ {
+ // Compare the link implementation fallback link interface to the
+ // preferred new link interface property and warn if different.
+ std::vector<cmLinkItem> ifaceLibs;
+ static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
+ if(const char* newExplicitLibraries = this->GetProperty(newProp))
+ {
+ bool hadHeadSensitiveConditionDummy = false;
+ this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+ headTarget, usage_requirements_only,
+ ifaceLibs, hadHeadSensitiveConditionDummy);
+ }
+ if (ifaceLibs != iface.Libraries)
+ {
+ std::string oldLibraries = cmJoin(impl->Libraries, ";");
+ std::string newLibraries = cmJoin(ifaceLibs, ";");
+ if(oldLibraries.empty())
+ { oldLibraries = "(empty)"; }
+ if(newLibraries.empty())
+ { newLibraries = "(empty)"; }
+
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+ "Target \"" << this->GetName() << "\" has an "
+ "INTERFACE_LINK_LIBRARIES property. "
+ "This should be preferred as the source of the link interface "
+ "for this library but because CMP0022 is not set CMake is "
+ "ignoring the property and using the link implementation "
+ "as the link interface instead."
+ "\n"
+ "INTERFACE_LINK_LIBRARIES:\n"
+ " " << newLibraries << "\n"
+ "Link implementation:\n"
+ " " << oldLibraries << "\n";
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->PolicyWarnedCMP0022 = true;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const cmLinkInterface *
+cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only) const
+{
+ cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
+ if(!info)
+ {
+ return 0;
+ }
+
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmHeadToLinkInterfaceMap& hm =
+ (usage_requirements_only ?
+ this->GetHeadToLinkInterfaceUsageRequirementsMap(config) :
+ this->GetHeadToLinkInterfaceMap(config));
+
+ // If the link interface does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkInterface& iface = hm[headTarget];
+ if(!iface.AllDone)
+ {
+ iface.AllDone = true;
+ iface.Multiplicity = info->Multiplicity;
+ cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+ this->ExpandLinkItems(info->LibrariesProp, info->Libraries,
+ config,
+ headTarget, usage_requirements_only,
+ iface.Libraries,
+ iface.HadHeadSensitiveCondition);
+ std::vector<std::string> deps;
+ cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+ this->LookupLinkItems(deps, iface.SharedDeps);
+ }
+
+ return &iface;
+}
+
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const
+{
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ return this->LinkInterfaceMap[CONFIG];
+}
+
+cmHeadToLinkInterfaceMap&
+cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
+ const std::string &config) const
+{
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+}
+
+//----------------------------------------------------------------------------
+const cmLinkImplementation *
+cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
+{
+ // There is no link implementation for imported targets.
+ if(this->Target->IsImported())
+ {
+ return 0;
+ }
+
+ cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+ if(!impl.LibrariesDone)
+ {
+ impl.LibrariesDone = true;
+ this->Target->ComputeLinkImplementationLibraries(config, impl,
+ this->Target);
+ }
+ if(!impl.LanguagesDone)
+ {
+ impl.LanguagesDone = true;
+ this->ComputeLinkImplementationLanguages(config, impl);
+ }
+ return &impl;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+ std::vector<cmSourceFile*>& files) const
+{
+ std::vector<std::string> configs;
+ this->Makefile->GetConfigurations(configs);
+ if (configs.empty())
+ {
+ configs.push_back("");
+ }
+
+ std::vector<std::string>::const_iterator it = configs.begin();
+ const std::string& firstConfig = *it;
+ this->Target->GetSourceFiles(files, firstConfig);
+
+ for ( ; it != configs.end(); ++it)
+ {
+ std::vector<cmSourceFile*> configFiles;
+ this->Target->GetSourceFiles(configFiles, *it);
+ if (configFiles != files)
+ {
+ std::string firstConfigFiles;
+ const char* sep = "";
+ for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ firstConfigFiles += sep;
+ firstConfigFiles += (*fi)->GetFullPath();
+ sep = "\n ";
+ }
+
+ std::string thisConfigFiles;
+ sep = "";
+ for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
+ fi != configFiles.end(); ++fi)
+ {
+ thisConfigFiles += sep;
+ thisConfigFiles += (*fi)->GetFullPath();
+ sep = "\n ";
+ }
+ std::ostringstream e;
+ e << "Target \"" << this->GetName()
+ << "\" has source files which vary by "
+ "configuration. This is not supported by the \""
+ << this->GlobalGenerator->GetName()
+ << "\" generator.\n"
+ "Config \"" << firstConfig << "\":\n"
+ " " << firstConfigFiles << "\n"
+ "Config \"" << *it << "\":\n"
+ " " << thisConfigFiles << "\n";
+ this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
+ const std::string& config) const
+{
+ std::vector<cmSourceFile*> sourceFiles;
+ this->GetSourceFiles(sourceFiles, config);
+ for(std::vector<cmSourceFile*>::const_iterator
+ i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
+ {
+ const std::string& lang = (*i)->GetLanguage();
+ if(!lang.empty())
+ {
+ languages.insert(lang);
+ }
+ }
+
+ std::vector<cmGeneratorTarget*> objectLibraries;
+ std::vector<cmSourceFile const*> externalObjects;
+ if (!this->Makefile->IsConfigured())
+ {
+ std::vector<cmTarget*> objectTargets;
+ this->Target->GetObjectLibrariesCMP0026(objectTargets);
+ objectLibraries.reserve(objectTargets.size());
+ for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin();
+ it != objectTargets.end(); ++it)
+ {
+ objectLibraries.push_back(this->GlobalGenerator
+ ->GetGeneratorTarget(*it));
+ }
+ }
+ else
+ {
+ this->GetExternalObjects(externalObjects, config);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ i = externalObjects.begin(); i != externalObjects.end(); ++i)
+ {
+ std::string objLib = (*i)->GetObjectLibrary();
+ if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+ {
+ objectLibraries.push_back(this->GlobalGenerator
+ ->GetGeneratorTarget(tgt));
+ }
+ }
+ }
+ for(std::vector<cmGeneratorTarget*>::const_iterator
+ i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+ {
+ (*i)->GetLanguages(languages, config);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLanguages(
+ const std::string& config,
+ cmOptionalLinkImplementation& impl) const
+{
+ // This target needs runtime libraries for its source languages.
+ std::set<std::string> languages;
+ // Get languages used in our source files.
+ this->GetLanguages(languages, config);
+ // Copy the set of langauges to the link implementation.
+ impl.Languages.insert(impl.Languages.begin(),
+ languages.begin(), languages.end());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
+{
+ if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+ {
+ return false;
+ }
+ if(cmLinkImplementationLibraries const* impl =
+ this->Target->GetLinkImplementationLibraries(config))
+ {
+ return !impl->Libraries.empty();
+ }
+ return false;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index c79aa72..06d9a1f 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -12,7 +12,7 @@
#ifndef cmGeneratorTarget_h
#define cmGeneratorTarget_h
-#include "cmStandardIncludes.h"
+#include "cmLinkItem.h"
class cmCustomCommand;
class cmGlobalGenerator;
@@ -20,11 +20,26 @@ class cmLocalGenerator;
class cmMakefile;
class cmSourceFile;
class cmTarget;
+class cmComputeLinkInformation;
class cmGeneratorTarget
{
public:
- cmGeneratorTarget(cmTarget*);
+ cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg);
+ ~cmGeneratorTarget();
+
+ cmLocalGenerator* GetLocalGenerator() const;
+
+ bool IsImported() const;
+ const char *GetLocation(const std::string& config) const;
+
+ /** Get the location of the target in the build tree with a placeholder
+ referencing the configuration in the native build system. This
+ location is suitable for use as the LOCATION target property. */
+ const char* GetLocationForBuild() const;
+
+ cmComputeLinkInformation*
+ GetLinkInformation(const std::string& config) const;
int GetType() const;
std::string GetName() const;
@@ -67,6 +82,101 @@ public:
void ComputeObjectMapping();
+ const char* GetFeature(const std::string& feature,
+ const std::string& config) const;
+ bool GetFeatureAsBool(const std::string& feature,
+ const std::string& config) const;
+
+ bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const std::string& config) const;
+ bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const std::string& config) const;
+
+ bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
+ const std::string& config) const;
+
+ const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+ const std::string& config) const;
+ const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
+ const std::string& config) const;
+ const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
+ const std::string& config) const;
+
+ cmLinkInterface const* GetLinkInterface(const std::string& config,
+ cmTarget const* headTarget) const;
+ void ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface& iface,
+ cmTarget const* head) const;
+
+ cmLinkInterfaceLibraries const*
+ GetLinkInterfaceLibraries(const std::string& config,
+ cmTarget const* headTarget,
+ bool usage_requirements_only) const;
+
+ void ComputeLinkInterfaceLibraries(const std::string& config,
+ cmOptionalLinkInterface &iface,
+ cmTarget const* head,
+ bool usage_requirements_only) const;
+
+ /** Get the full path to the target according to the settings in its
+ makefile and the configuration type. */
+ std::string GetFullPath(const std::string& config="", bool implib = false,
+ bool realname = false) const;
+ std::string NormalGetFullPath(const std::string& config, bool implib,
+ bool realname) const;
+ std::string NormalGetRealName(const std::string& config) const;
+
+ /** @return the Mac App directory without the base */
+ std::string GetAppBundleDirectory(const std::string& config,
+ bool contentOnly) const;
+
+ /** Return whether this target is an executable Bundle, a framework
+ or CFBundle on Apple. */
+ bool IsBundleOnApple() const;
+
+ /** Get the full name of the target according to the settings in its
+ makefile. */
+ std::string GetFullName(const std::string& config="",
+ bool implib = false) const;
+
+ /** @return the Mac framework directory without the base. */
+ std::string GetFrameworkDirectory(const std::string& config,
+ bool rootDir) const;
+
+ /** @return the Mac CFBundle directory without the base */
+ std::string GetCFBundleDirectory(const std::string& config,
+ bool contentOnly) const;
+
+ /** Return the install name directory for the target in the
+ * build tree. For example: "\@rpath/", "\@loader_path/",
+ * or "/full/path/to/library". */
+ std::string GetInstallNameDirForBuildTree(const std::string& config) const;
+
+ /** Return the install name directory for the target in the
+ * install tree. For example: "\@rpath/" or "\@loader_path/". */
+ std::string GetInstallNameDirForInstallTree() const;
+
+ /** Get the soname of the target. Allowed only for a shared library. */
+ std::string GetSOName(const std::string& config) const;
+
+ void GetFullNameComponents(std::string& prefix,
+ std::string& base, std::string& suffix,
+ const std::string& config="",
+ bool implib = false) const;
+
+ /** Append to @a base the mac content directory and return it. */
+ std::string BuildMacContentDirectory(const std::string& base,
+ const std::string& config = "",
+ bool contentOnly = true) const;
+
+ /** @return the mac content directory for this target. */
+ std::string GetMacContentDirectory(const std::string& config = 0,
+ bool implib = false) const;
+
cmTarget* Target;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
@@ -74,6 +184,39 @@ public:
std::string GetModuleDefinitionFile(const std::string& config) const;
+ /** Link information from the transitive closure of the link
+ implementation and the interfaces of its dependencies. */
+ struct LinkClosure
+ {
+ // The preferred linker language.
+ std::string LinkerLanguage;
+
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+ };
+
+ LinkClosure const* GetLinkClosure(const std::string& config) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+
+ cmLinkImplementation const*
+ GetLinkImplementation(const std::string& config) const;
+
+ void ComputeLinkImplementationLanguages(const std::string& config,
+ cmOptionalLinkImplementation& impl
+ ) const;
+
+ // 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
+ // information to forward these property changes to the targets
+ // until we have per-target object file properties.
+ void GetLanguages(std::set<std::string>& languages,
+ std::string const& config) const;
+
+ bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+
+ bool HaveBuildTreeRPATH(const std::string& config) const;
+
/** Full path with trailing slash to the top-level directory
holding object files for this target. Includes the build
time config name placeholder if needed for the generator. */
@@ -93,11 +236,22 @@ public:
std::vector<std::string> GetIncludeDirectories(
const std::string& config, const std::string& lang) const;
+ void GetCompileOptions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const;
+
+ void GetCompileFeatures(std::vector<std::string> &features,
+ const std::string& config) const;
+
+ void GetCompileDefinitions(std::vector<std::string> &result,
+ const std::string& config,
+ const std::string& language) const;
+
bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const;
/** Add the target output files to the global generator manifest. */
- void GenerateTargetManifest(const std::string& config) const;
+ void ComputeTargetManifest(const std::string& config) const;
/**
* Trace through the source files in this target and add al source files
@@ -105,10 +259,41 @@ public:
*/
void TraceDependencies();
+ /** Get the directory in which to place the target compiler .pdb file.
+ If the configuration name is given then the generator will add its
+ subdirectory for that configuration. Otherwise just the canonical
+ compiler pdb output directory is given. */
+ std::string GetCompilePDBDirectory(const std::string& config = "") const;
+
/** Get sources that must be built before the given source. */
std::vector<cmSourceFile*> const*
GetSourceDepends(cmSourceFile const* sf) const;
+ /** Get the name of the pdb file for the target. */
+ std::string GetPDBName(const std::string& config="") const;
+
+ /** Whether this library has soname enabled and platform supports it. */
+ bool HasSOName(const std::string& config) const;
+
+ struct CompileInfo
+ {
+ std::string CompilePdbDir;
+ };
+
+ CompileInfo const* GetCompileInfo(const std::string& config) const;
+
+ typedef std::map<std::string, CompileInfo> CompileInfoMapType;
+ mutable CompileInfoMapType CompileInfoMap;
+
+ /** Get the name of the compiler pdb file for the target. */
+ std::string GetCompilePDBName(const std::string& config="") const;
+
+ /** Get the path for the MSVC /Fd option for this target. */
+ std::string GetCompilePDBPath(const std::string& config="") const;
+
+ // Get the target base name.
+ std::string GetOutputName(const std::string& config, bool implib) const;
+
/**
* Flags for a given source file as used in this target. Typically assigned
* via SET_TARGET_PROPERTIES when the property is a list of source files.
@@ -130,6 +315,33 @@ public:
SourceFileType Type;
const char* MacFolder; // location inside Mac content folders
};
+ void GetAutoUicOptions(std::vector<std::string> &result,
+ const std::string& config) const;
+
+ /** Get the names of the executable needed to generate a build rule
+ that takes into account executable version numbers. This should
+ be called only on an executable target. */
+ void GetExecutableNames(std::string& name, std::string& realName,
+ std::string& impName, std::string& pdbName,
+ const std::string& config) const;
+
+ /** Get the names of the library needed to generate a build rule
+ that takes into account shared library version numbers. This
+ should be called only on a library target. */
+ void GetLibraryNames(std::string& name, std::string& soName,
+ std::string& realName, std::string& impName,
+ std::string& pdbName, const std::string& config) const;
+
+ /**
+ * Compute whether this target must be relinked before installing.
+ */
+ bool NeedRelinkBeforeInstall(const std::string& config) const;
+
+ /** Return true if builtin chrpath will work for this target */
+ bool IsChrpathUsed(const std::string& config) const;
+
+ ///! Return the preferred linker language for this target
+ std::string GetLinkerLanguage(const std::string& config = "") const;
struct SourceFileFlags
GetTargetSourceFileFlags(const cmSourceFile* sf) const;
@@ -145,12 +357,18 @@ public:
std::vector<cmSourceFile const*> XamlSources;
};
+ void ReportPropertyOrigin(const std::string &p,
+ const std::string &result,
+ const std::string &report,
+ const std::string &compatibilityType) const;
+
+ class TargetPropertyEntry;
+
private:
friend class cmTargetTraceDependencies;
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
SourceEntriesType SourceEntries;
-
mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName;
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
@@ -159,8 +377,91 @@ private:
mutable bool SourceFileFlagsConstructed;
mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
+ mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
+
+ std::string GetFullNameInternal(const std::string& config,
+ bool implib) const;
+ void GetFullNameInternal(const std::string& config, bool implib,
+ std::string& outPrefix, std::string& outBase,
+ std::string& outSuffix) const;
+
+ typedef std::map<std::string, LinkClosure> LinkClosureMapType;
+ mutable LinkClosureMapType LinkClosureMap;
+
+ struct CompatibleInterfacesBase
+ {
+ std::set<std::string> PropsBool;
+ std::set<std::string> PropsString;
+ std::set<std::string> PropsNumberMax;
+ std::set<std::string> PropsNumberMin;
+ };
+ CompatibleInterfacesBase const&
+ GetCompatibleInterfaces(std::string const& config) const;
+
+ struct CompatibleInterfaces: public CompatibleInterfacesBase
+ {
+ CompatibleInterfaces(): Done(false) {}
+ bool Done;
+ };
+ mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
+
+ typedef std::map<std::string, cmComputeLinkInformation*>
+ cmTargetLinkInformationMap;
+ mutable cmTargetLinkInformationMap LinkInformation;
+
+ void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const std::string& config) const;
+
cmGeneratorTarget(cmGeneratorTarget const&);
void operator=(cmGeneratorTarget const&);
+
+ struct LinkImplClosure: public std::vector<cmTarget const*>
+ {
+ LinkImplClosure(): Done(false) {}
+ bool Done;
+ };
+ mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
+
+ typedef std::map<std::string, cmHeadToLinkInterfaceMap>
+ LinkInterfaceMapType;
+ mutable LinkInterfaceMapType LinkInterfaceMap;
+ mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
+
+ cmHeadToLinkInterfaceMap&
+ GetHeadToLinkInterfaceMap(std::string const& config) const;
+ cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
+ std::string const& config) const;
+
+ cmLinkInterface const*
+ GetImportLinkInterface(const std::string& config, cmTarget const* head,
+ bool usage_requirements_only) const;
+
+ std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
+ std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+ std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
+ std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+
+ void ExpandLinkItems(std::string const& prop, std::string const& value,
+ std::string const& config, cmTarget const* headTarget,
+ bool usage_requirements_only,
+ std::vector<cmLinkItem>& items,
+ bool& hadHeadSensitiveCondition) const;
+ void LookupLinkItems(std::vector<std::string> const& names,
+ std::vector<cmLinkItem>& items) const;
+
+ typedef std::pair<std::string, bool> OutputNameKey;
+ typedef std::map<OutputNameKey, std::string> OutputNameMapType;
+ mutable OutputNameMapType OutputNameMap;
+ mutable bool PolicyWarnedCMP0022;
+ mutable bool DebugIncludesDone;
+ mutable bool DebugCompileOptionsDone;
+ mutable bool DebugCompileFeaturesDone;
+ mutable bool DebugCompileDefinitionsDone;
+
+public:
+ std::vector<cmTarget const*> const&
+ GetLinkImplementationClosure(const std::string& config) const;
+
};
struct cmStrictTargetComparison {
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index 76803c1..248ce59 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -32,17 +32,18 @@ bool cmGetCMakePropertyCommand
if ( args[1] == "VARIABLES" )
{
- int cacheonly = 0;
- std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly);
- if (!vars.empty())
+ if (const char* varsProp = this->Makefile->GetProperty("VARIABLES"))
{
- output = cmJoin(vars, ";");
+ output = varsProp;
}
}
else if ( args[1] == "MACROS" )
{
output.clear();
- this->Makefile->GetListOfMacros(output);
+ if (const char* macrosProp = this->Makefile->GetProperty("MACROS"))
+ {
+ output = macrosProp;
+ }
}
else if ( args[1] == "COMPONENTS" )
{
@@ -52,9 +53,11 @@ bool cmGetCMakePropertyCommand
}
else
{
- const char *prop =
- this->Makefile->GetState()
- ->GetGlobalProperty(args[1]);
+ const char *prop = 0;
+ if (!args[1].empty())
+ {
+ prop = this->Makefile->GetState()->GetGlobalProperty(args[1]);
+ }
if (prop)
{
output = prop;
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 4fe3318..2558876 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -26,7 +26,6 @@ bool cmGetDirectoryPropertyCommand
std::vector<std::string>::const_iterator i = args.begin();
std::string variable = *i;
++i;
- std::string output = "";
// get the directory argument if there is one
cmMakefile *dir = this->Makefile;
@@ -52,10 +51,8 @@ bool cmGetDirectoryPropertyCommand
sd = cmSystemTools::CollapseFullPath(sd);
// lookup the makefile from the directory name
- cmLocalGenerator *lg =
- this->Makefile->GetGlobalGenerator()->
- FindLocalGenerator(sd);
- if (!lg)
+ dir = this->Makefile->GetGlobalGenerator()->FindMakefile(sd);
+ if (!dir)
{
this->SetError
("DIRECTORY argument provided but requested directory not found. "
@@ -63,7 +60,6 @@ bool cmGetDirectoryPropertyCommand
"it is valid but has not been processed yet.");
return false;
}
- dir = lg->GetMakefile();
++i;
}
@@ -79,18 +75,45 @@ bool cmGetDirectoryPropertyCommand
"providing the name of the variable to get.");
return false;
}
- output = dir->GetSafeDefinition(*i);
+ std::string output = dir->GetSafeDefinition(*i);
this->Makefile->AddDefinition(variable, output.c_str());
return true;
}
- const char *prop = dir->GetProperty(*i);
+ const char *prop = 0;
+ if (!i->empty())
+ {
+ if (*i == "DEFINITIONS")
+ {
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0059))
+ {
+ case cmPolicies::WARN:
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+ case cmPolicies::OLD:
+ this->StoreResult(variable,
+ this->Makefile->GetDefineFlagsCMP0059());
+ return true;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+ prop = dir->GetProperty(*i);
+ }
+ this->StoreResult(variable, prop);
+ return true;
+}
+
+void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
+ const char* prop)
+{
if (prop)
{
this->Makefile->AddDefinition(variable, prop);
- return true;
+ return;
}
this->Makefile->AddDefinition(variable, "");
- return true;
}
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index 6c5750a..f418886 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -40,8 +40,9 @@ public:
virtual std::string GetName() const { return "get_directory_property";}
cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand);
-};
-
+private:
+ void StoreResult(const std::string& variable, const char* prop);
+};
#endif
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 67f9f2d..0f56c8e 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -24,7 +24,7 @@ bool cmGetFilenameComponentCommand
// Check and see if the value has been stored in the cache
// already, if so use that value
- if(args.size() == 4 && args[3] == "CACHE")
+ if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
{
const char* cacheValue = this->Makefile->GetDefinition(args[0]);
if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue))
@@ -93,11 +93,23 @@ bool cmGetFilenameComponentCommand
else if (args[2] == "ABSOLUTE" ||
args[2] == "REALPATH")
{
+ // If the path given is relative, evaluate it relative to the
+ // current source directory unless the user passes a different
+ // base directory.
+ std::string baseDir = this->Makefile->GetCurrentSourceDirectory();
+ for(unsigned int i=3; i < args.size(); ++i)
+ {
+ if(args[i] == "BASE_DIR")
+ {
+ ++i;
+ if(i < args.size())
+ {
+ baseDir = args[i];
+ }
+ }
+ }
// Collapse the path to its simplest form.
- // If the path given is relative evaluate it relative to the
- // current source directory.
- result = cmSystemTools::CollapseFullPath(
- filename, this->Makefile->GetCurrentSourceDirectory());
+ result = cmSystemTools::CollapseFullPath(filename, baseDir);
if(args[2] == "REALPATH")
{
// Resolve symlinks if possible
@@ -111,7 +123,7 @@ bool cmGetFilenameComponentCommand
return false;
}
- if(args.size() == 4 && args[3] == "CACHE")
+ if(args.size() >= 4 && args[args.size() - 1] == "CACHE")
{
if(!programArgs.empty() && !storeArgs.empty())
{
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 250bd35..4c42f53 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -142,8 +142,7 @@ bool cmGetPropertyCommand
{
// Lookup brief documentation.
std::string output;
- if(cmPropertyDefinition* def =
- this->Makefile->GetState()->
+ if(cmPropertyDefinition const* def = this->Makefile->GetState()->
GetPropertyDefinition(this->PropertyName, scope))
{
output = def->GetShortDescription();
@@ -158,8 +157,7 @@ bool cmGetPropertyCommand
{
// Lookup full documentation.
std::string output;
- if(cmPropertyDefinition* def =
- this->Makefile->GetState()->
+ if(cmPropertyDefinition const* def = this->Makefile->GetState()->
GetPropertyDefinition(this->PropertyName, scope))
{
output = def->GetFullDescription();
@@ -264,13 +262,8 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
dir = cmSystemTools::CollapseFullPath(dir);
// Lookup the generator.
- if(cmLocalGenerator* lg =
- (this->Makefile->GetGlobalGenerator()->FindLocalGenerator(dir)))
- {
- // Use the makefile for the directory found.
- mf = lg->GetMakefile();
- }
- else
+ mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ if (!mf)
{
// Could not find the directory.
this->SetError
@@ -281,6 +274,22 @@ bool cmGetPropertyCommand::HandleDirectoryMode()
}
}
+ if (this->PropertyName == "DEFINITIONS")
+ {
+ switch(mf->GetPolicyStatus(cmPolicies::CMP0059))
+ {
+ case cmPolicies::WARN:
+ mf->IssueMessage(cmake::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0059));
+ case cmPolicies::OLD:
+ return this->StoreResult(mf->GetDefineFlagsCMP0059());
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ break;
+ }
+ }
+
// Get the property.
return this->StoreResult(mf->GetProperty(this->PropertyName));
}
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 7667a85..46daa34 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -38,7 +38,11 @@ bool cmGetSourceFilePropertyCommand
this->Makefile->AddDefinition(var, sf->GetLanguage().c_str());
return true;
}
- const char *prop = sf->GetPropertyForUser(args[2]);
+ const char *prop = 0;
+ if (!args[2].empty())
+ {
+ prop = sf->GetPropertyForUser(args[2]);
+ }
if (prop)
{
this->Makefile->AddDefinition(var, prop);
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 315e851..ca40bd0 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -40,7 +40,11 @@ bool cmGetTargetPropertyCommand
else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
{
cmTarget& target = *tgt;
- const char* prop_cstr = target.GetProperty(args[2], this->Makefile);
+ const char* prop_cstr = 0;
+ if (!args[2].empty())
+ {
+ prop_cstr = target.GetProperty(args[2], this->Makefile);
+ }
if(prop_cstr)
{
prop = prop_cstr;
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index b3df4c3..bf34589 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -29,7 +29,11 @@ bool cmGetTestPropertyCommand
cmTest *test = this->Makefile->GetTest(testName);
if (test)
{
- const char *prop = test->GetProperty(args[1]);
+ const char *prop = 0;
+ if (!args[1].empty())
+ {
+ prop = test->GetProperty(args[1]);
+ }
if (prop)
{
this->Makefile->AddDefinition(var, prop);
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 01e2011..846b6e2 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -21,23 +21,24 @@
std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
-cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmTarget *target)
- : Target(target)
+cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target)
+ : Target(target->Target)
+ , GeneratorTarget(target)
, LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
- target->GetMakefile()->GetLocalGenerator()))
- , Makefile(target->GetMakefile())
- , TargetGroup(DetermineIfTargetGroup(target))
+ target->GetLocalGenerator()))
+ , Makefile(target->Target->GetMakefile())
+ , TargetGroup(DetermineIfTargetGroup(target->Target))
, DynamicDownload(false)
{
- this->RelBuildFilePath = this->GetRelBuildFilePath(target);
+ this->RelBuildFilePath = this->GetRelBuildFilePath(target->Target);
this->RelOutputFileName =
this->RelBuildFilePath + this->Target->GetName() + ".a";
this->RelBuildFileName = this->RelBuildFilePath;
- this->RelBuildFileName += this->GetBuildFileName(target);
+ this->RelBuildFileName += this->GetBuildFileName(target->Target);
- std::string absPathToRoot = this->GetAbsPathToRoot(target);
+ std::string absPathToRoot = this->GetAbsPathToRoot(target->Target);
absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
@@ -127,7 +128,8 @@ void cmGhsMultiTargetGenerator::Generate()
{
config = "RELEASE";
}
- const std::string language(this->Target->GetLinkerLanguage(config));
+ const std::string language(
+ this->GeneratorTarget->GetLinkerLanguage(config));
config = cmSystemTools::UpperCase(config);
this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
if (this->DynamicDownload)
@@ -328,7 +330,8 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
const std::string &config, const std::string &language)
{
std::vector<std::string> compileDefinitions;
- this->Target->GetCompileDefinitions(compileDefinitions, config, language);
+ this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
+ config, language);
for (std::vector<std::string>::const_iterator cdI =
compileDefinitions.begin();
cdI != compileDefinitions.end(); ++cdI)
@@ -341,7 +344,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
const std::string &language)
{
std::vector<std::string> includes =
- this->Target->GetIncludeDirectories(config, language);
+ this->GeneratorTarget->GetIncludeDirectories(config, language);
for (std::vector<std::string>::const_iterator includes_i = includes.begin();
includes_i != includes.end(); ++includes_i)
{
@@ -354,11 +357,11 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries()
{
// library directories
cmTargetDependSet tds =
- this->GetGlobalGenerator()->GetTargetDirectDepends(*this->Target);
+ this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
++tdsI)
{
- const cmTarget *tg(*tdsI);
+ const cmTarget *tg = (*tdsI)->Target;
*this->GetFolderBuildStreams() << " -L\"" << GetAbsBuildFilePath(tg)
<< "\"" << std::endl;
}
@@ -373,7 +376,6 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries()
cmTarget *tg(GetGlobalGenerator()->FindTarget(libName));
if (NULL != tg)
{
- cmGhsMultiTargetGenerator gmtg(tg);
libName = tg->GetName() + ".a";
}
*this->GetFolderBuildStreams() << " -l\"" << libName << "\""
@@ -557,7 +559,7 @@ bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
{
bool output;
std::vector<std::string> options;
- this->Target->GetCompileOptions(options, config, language);
+ this->GeneratorTarget->GetCompileOptions(options, config, language);
output =
options.end() == std::find(options.begin(), options.end(), "-kernel");
return output;
@@ -586,7 +588,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
{
std::vector<std::string> options;
bool output = false;
- this->Target->GetCompileOptions(options, config, language);
+ this->GeneratorTarget->GetCompileOptions(options, config, language);
for (std::vector<std::string>::const_iterator options_i = options.begin();
options_i != options.end(); ++options_i)
{
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index 8e81db8..c29a31e 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -27,7 +27,7 @@ class cmCustomCommand;
class cmGhsMultiTargetGenerator
{
public:
- cmGhsMultiTargetGenerator(cmTarget *target);
+ cmGhsMultiTargetGenerator(cmGeneratorTarget* target);
virtual ~cmGhsMultiTargetGenerator();
@@ -100,6 +100,7 @@ private:
const std::string &language);
cmTarget *Target;
+ cmGeneratorTarget* GeneratorTarget;
cmLocalGhsMultiGenerator *LocalGenerator;
cmMakefile *Makefile;
std::string AbsBuildFilePath;
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 87665a0..40e8d29 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -44,10 +44,10 @@ void cmGlobalBorlandMakefileGenerator
///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
- cmLocalGenerator* parent, cmState::Snapshot snapshot)
+ cmMakefile *mf)
{
cmLocalUnixMakefileGenerator3* lg =
- new cmLocalUnixMakefileGenerator3(this, parent, snapshot);
+ new cmLocalUnixMakefileGenerator3(this, mf);
lg->SetMakefileVariableSize(32);
lg->SetMakeCommandEscapeTargetTwice(true);
lg->SetBorlandMakeCurlyHack(true);
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 2ec510d..b59c86d 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -36,8 +36,7 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
* Try to determine system information such as shared library
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
new file mode 100644
index 0000000..dc8e5a7
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 "cmGlobalCommonGenerator.h"
+
+cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm):
+ cmGlobalGenerator(cm)
+{
+}
+
+cmGlobalCommonGenerator::~cmGlobalCommonGenerator()
+{
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
new file mode 100644
index 0000000..7bb0e55
--- /dev/null
+++ b/Source/cmGlobalCommonGenerator.h
@@ -0,0 +1,27 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 cmGlobalCommonGenerator_h
+#define cmGlobalCommonGenerator_h
+
+#include "cmGlobalGenerator.h"
+
+/** \class cmGlobalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja global generators.
+ */
+class cmGlobalCommonGenerator : public cmGlobalGenerator
+{
+public:
+ cmGlobalCommonGenerator(cmake* cm);
+ ~cmGlobalCommonGenerator();
+};
+
+#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cd05c54..ec36d2a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -14,6 +14,20 @@
#if defined(_MSC_VER) && _MSC_VER >= 1800
# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
#endif
+typedef struct {
+ ULONG dwOSVersionInfoSize;
+ ULONG dwMajorVersion;
+ ULONG dwMinorVersion;
+ ULONG dwBuildNumber;
+ ULONG dwPlatformId;
+ WCHAR szCSDVersion[128];
+ USHORT wServicePackMajor;
+ USHORT wServicePackMinor;
+ USHORT wSuiteMask;
+ UCHAR wProductType;
+ UCHAR wReserved;
+} CMRTL_OSVERSIONINFOEXW;
+
#endif
#include "cmGlobalGenerator.h"
@@ -30,10 +44,10 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGeneratorExpression.h"
-#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmExportBuildFileGenerator.h"
#include "cmCPackPropertiesGenerator.h"
#include "cmAlgorithms.h"
+#include "cmInstallGenerator.h"
#include <cmsys/Directory.hxx>
#include <cmsys/FStream.hxx>
@@ -70,7 +84,7 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
this->TryCompileTimeout = 0;
this->ExtraGenerator = 0;
- this->CurrentLocalGenerator = 0;
+ this->CurrentMakefile = 0;
this->TryCompileOuterMakefile = 0;
}
@@ -87,18 +101,16 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
{
return true;
}
- else
- {
- std::ostringstream e;
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "does not support platform specification, but platform\n"
- " " << p << "\n"
- "was specified.";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
- }
+
+ std::ostringstream e;
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support platform specification, but platform\n"
+ " " << p << "\n"
+ "was specified.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
}
bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
@@ -108,18 +120,15 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
{
return true;
}
- else
- {
- std::ostringstream e;
- e <<
- "Generator\n"
- " " << this->GetName() << "\n"
- "does not support toolset specification, but toolset\n"
- " " << ts << "\n"
- "was specified.";
- mf->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
- }
+ std::ostringstream e;
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support toolset specification, but toolset\n"
+ " " << ts << "\n"
+ "was specified.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
}
std::string cmGlobalGenerator::SelectMakeProgram(
@@ -437,23 +446,45 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
if (!mf->GetDefinition("CMAKE_SYSTEM"))
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- /* Windows version number data. */
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(osvi));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ CMRTL_OSVERSIONINFOEXW osviex;
+ ZeroMemory(&osviex, sizeof(osviex));
+ osviex.dwOSVersionInfoSize = sizeof(osviex);
+
+ typedef LONG (FAR WINAPI *cmRtlGetVersion)(CMRTL_OSVERSIONINFOEXW*);
+ cmRtlGetVersion rtlGetVersion = reinterpret_cast<cmRtlGetVersion>(
+ GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"));
+ if (rtlGetVersion && rtlGetVersion(&osviex) == 0)
+ {
+ std::ostringstream windowsVersionString;
+ windowsVersionString << osviex.dwMajorVersion << "."
+ << osviex.dwMinorVersion << "."
+ << osviex.dwBuildNumber;
+ windowsVersionString.str();
+ mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
+ windowsVersionString.str().c_str());
+ }
+ else
+ {
+ // RtlGetVersion failed, so use the deprecated GetVersionEx function.
+ /* Windows version number data. */
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
# pragma warning (push)
# pragma warning (disable:4996)
#endif
- GetVersionEx (&osvi);
+ GetVersionEx (&osvi);
#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx
# pragma warning (pop)
#endif
- std::ostringstream windowsVersionString;
- windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
- windowsVersionString.str();
- mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
- windowsVersionString.str().c_str());
+ std::ostringstream windowsVersionString;
+ windowsVersionString << osvi.dwMajorVersion << "."
+ << osvi.dwMinorVersion;
+ windowsVersionString.str();
+ mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
+ windowsVersionString.str().c_str());
+ }
#endif
// Read the DetermineSystem file
std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
@@ -569,6 +600,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
cmSystemTools::Error("Could not find cmake module file: ",
determineCompiler.c_str());
}
+ if (cmSystemTools::GetFatalErrorOccured())
+ {
+ return;
+ }
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
// So the global generator can specify that in this variable
@@ -1092,37 +1127,52 @@ void cmGlobalGenerator::Configure()
this->FirstTimeProgress = 0.0f;
this->ClearGeneratorMembers();
- // start with this directory
- cmLocalGenerator *lg = this->MakeLocalGenerator();
+ cmMakefile* dirMf =
+ new cmMakefile(this, this->GetCMakeInstance()->GetCurrentSnapshot());
+ this->Makefiles.push_back(dirMf);
+ cmLocalGenerator *lg = this->CreateLocalGenerator(dirMf);
this->LocalGenerators.push_back(lg);
// set the Start directories
- lg->GetMakefile()->SetCurrentSourceDirectory
+ dirMf->SetCurrentSourceDirectory
(this->CMakeInstance->GetHomeDirectory());
- lg->GetMakefile()->SetCurrentBinaryDirectory
+ dirMf->SetCurrentBinaryDirectory
(this->CMakeInstance->GetHomeOutputDirectory());
this->BinaryDirectories.insert(
this->CMakeInstance->GetHomeOutputDirectory());
// now do it
- lg->Configure();
+ dirMf->Configure();
+ dirMf->EnforceDirectoryLevelRules();
+
+ // Put a copy of each global target in every directory.
+ cmTargets globalTargets;
+ this->CreateDefaultGlobalTargets(&globalTargets);
+
+ for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
+ {
+ cmMakefile* mf = this->Makefiles[i];
+ cmTargets* targets = &(mf->GetTargets());
+ cmTargets::iterator tit;
+ for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
+ {
+ (*targets)[tit->first] = tit->second;
+ (*targets)[tit->first].SetMakefile(mf);
+ }
+ }
// update the cache entry for the number of local generators, this is used
// for progress
char num[100];
- sprintf(num,"%d",static_cast<int>(this->LocalGenerators.size()));
+ sprintf(num,"%d",static_cast<int>(this->Makefiles.size()));
this->GetCMakeInstance()->AddCacheEntry
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
+ ("CMAKE_NUMBER_OF_MAKEFILES", num,
"number of local generators", cmState::INTERNAL);
// check for link libraries and include directories containing "NOTFOUND"
// and for infinite loops
- this->CheckLocalGenerators();
-
- // at this point this->LocalGenerators has been filled,
- // so create the map from project name to vector of local generators
- this->FillProjectMap();
+ this->CheckTargetProperties();
if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
{
@@ -1151,6 +1201,13 @@ void cmGlobalGenerator::Configure()
}
}
+void cmGlobalGenerator::CreateGenerationObjects(TargetTypes targetTypes)
+{
+ cmDeleteAll(this->GeneratorTargets);
+ this->GeneratorTargets.clear();
+ this->CreateGeneratorTargets(targetTypes);
+}
+
cmExportBuildFileGenerator*
cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
{
@@ -1186,7 +1243,7 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
return false;
}
-void cmGlobalGenerator::DoGenerate()
+bool cmGlobalGenerator::Compute()
{
// Some generators track files replaced during the Generate.
// Start with an empty vector:
@@ -1195,19 +1252,19 @@ void cmGlobalGenerator::DoGenerate()
// clear targets to issue warning CMP0042 for
this->CMP0042WarnTargets.clear();
- this->Generate();
-}
-
-void cmGlobalGenerator::Generate()
-{
// Check whether this generator is allowed to run.
if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
{
- return;
+ return false;
}
-
this->FinalizeTargetCompileInfo();
+ this->CreateGenerationObjects();
+
+ // at this point this->LocalGenerators has been filled,
+ // so create the map from project name to vector of local generators
+ this->FillProjectMap();
+
#ifdef CMAKE_BUILD_WITH_CMAKE
// Iterate through all targets and set up automoc for those which have
// the AUTOMOC, AUTOUIC or AUTORCC property set
@@ -1215,22 +1272,11 @@ void cmGlobalGenerator::Generate()
this->CreateQtAutoGeneratorsTargets(autogens);
#endif
- // For each existing cmLocalGenerator
unsigned int i;
- // Put a copy of each global target in every directory.
- cmTargets globalTargets;
- this->CreateDefaultGlobalTargets(&globalTargets);
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
- cmTargets* targets = &(mf->GetTargets());
- cmTargets::iterator tit;
- for ( tit = globalTargets.begin(); tit != globalTargets.end(); ++ tit )
- {
- (*targets)[tit->first] = tit->second;
- (*targets)[tit->first].SetMakefile(mf);
- }
+ this->LocalGenerators[i]->ComputeObjectMaxPath();
}
// Add generator specific helper commands
@@ -1239,8 +1285,7 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->AddHelperCommands();
}
- // Create per-target generator information.
- this->CreateGeneratorTargets();
+ this->InitGeneratorTargets();
#ifdef CMAKE_BUILD_WITH_CMAKE
for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
@@ -1250,6 +1295,24 @@ void cmGlobalGenerator::Generate()
}
#endif
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
+ std::vector<cmInstallGenerator*>& gens = mf->GetInstallGenerators();
+ for (std::vector<cmInstallGenerator*>::const_iterator git = gens.begin();
+ git != gens.end(); ++git)
+ {
+ (*git)->Compute(this->LocalGenerators[i]);
+ }
+ }
+
+ return true;
+}
+
+void cmGlobalGenerator::Generate()
+{
+ unsigned int i;
+
// Trace the dependencies, after that no custom commands should be added
// because their dependencies might not be handled correctly
for (i = 0; i < this->LocalGenerators.size(); ++i)
@@ -1262,11 +1325,9 @@ void cmGlobalGenerator::Generate()
// Compute the manifest of main targets generated.
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->LocalGenerators[i]->GenerateTargetManifest();
+ this->LocalGenerators[i]->ComputeTargetManifest();
}
- this->ProcessEvaluationFiles();
-
// Compute the inter-target dependencies.
if(!this->ComputeTargetDepends())
{
@@ -1275,13 +1336,19 @@ void cmGlobalGenerator::Generate()
// Create a map from local generator to the complete set of targets
// it builds by default.
- this->FillLocalGeneratorToTargetMap();
+ this->InitializeProgressMarks();
+
+ this->ProcessEvaluationFiles();
+
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->LocalGenerators[i]->ComputeHomeRelativeOutputPath();
+ }
// Generate project files
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
- this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
+ this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile());
this->LocalGenerators[i]->Generate();
if(!this->LocalGenerators[i]->GetMakefile()->IsOn(
"CMAKE_SKIP_INSTALL_RULES"))
@@ -1293,7 +1360,7 @@ void cmGlobalGenerator::Generate()
(static_cast<float>(i)+1.0f)/
static_cast<float>(this->LocalGenerators.size()));
}
- this->SetCurrentLocalGenerator(0);
+ this->SetCurrentMakefile(0);
if(!this->GenerateCPackPropertiesFile())
{
@@ -1350,9 +1417,9 @@ bool cmGlobalGenerator::ComputeTargetDepends()
{
return false;
}
- std::vector<cmTarget const*> const& targets = ctd.GetTargets();
- for(std::vector<cmTarget const*>::const_iterator ti = targets.begin();
- ti != targets.end(); ++ti)
+ std::vector<cmGeneratorTarget const*> const& targets = ctd.GetTargets();
+ for(std::vector<cmGeneratorTarget const*>::const_iterator ti
+ = targets.begin(); ti != targets.end(); ++ti)
{
ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
}
@@ -1372,6 +1439,10 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
for(cmTargets::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
+ if (ti->second.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ continue;
+ }
targetNames.push_back(ti->second.GetName());
}
for(std::vector<std::string>::iterator ti = targetNames.begin();
@@ -1391,7 +1462,8 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
&& !target.IsImported())
{
cmQtAutoGenerators autogen;
- if(autogen.InitializeAutogenTarget(&target))
+ if(autogen.InitializeAutogenTarget(this->LocalGenerators[i],
+ &target))
{
autogens.push_back(std::make_pair(autogen, &target));
}
@@ -1408,18 +1480,24 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
void cmGlobalGenerator::FinalizeTargetCompileInfo()
{
// Construct per-target generator information.
- for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+ for(unsigned int i=0; i < this->Makefiles.size(); ++i)
{
- cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
+ cmMakefile *mf = this->Makefiles[i];
- const std::vector<cmValueWithOrigin> noconfig_compile_definitions =
+ const cmStringRange noconfig_compile_definitions =
mf->GetCompileDefinitionsEntries();
+ const cmBacktraceRange noconfig_compile_definitions_bts =
+ mf->GetCompileDefinitionsBacktraces();
cmTargets& targets = mf->GetTargets();
for(cmTargets::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
cmTarget* t = &ti->second;
+ if (t->GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ continue;
+ }
t->AppendBuildInterfaceIncludes();
@@ -1428,11 +1506,13 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
continue;
}
- for (std::vector<cmValueWithOrigin>::const_iterator it
+ cmBacktraceRange::const_iterator btIt
+ = noconfig_compile_definitions_bts.begin();
+ for (cmStringRange::const_iterator it
= noconfig_compile_definitions.begin();
- it != noconfig_compile_definitions.end(); ++it)
+ it != noconfig_compile_definitions.end(); ++it, ++btIt)
{
- t->InsertCompileDefinition(*it);
+ t->InsertCompileDefinition(*it, *btIt);
}
cmPolicies::PolicyStatus polSt
@@ -1456,25 +1536,29 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
+void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes,
+ cmLocalGenerator *lg)
{
cmGeneratorTargetsType generatorTargets;
- cmTargets& targets = mf->GetTargets();
- for(cmTargets::iterator ti = targets.begin();
- ti != targets.end(); ++ti)
+ cmMakefile* mf = lg->GetMakefile();
+ if (targetTypes == AllTargets)
{
- cmTarget* t = &ti->second;
- cmGeneratorTarget* gt = new cmGeneratorTarget(t);
- this->ComputeTargetObjectDirectory(gt);
- this->GeneratorTargets[t] = gt;
- generatorTargets[t] = gt;
+ cmTargets& targets = mf->GetTargets();
+ for(cmTargets::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ cmTarget* t = &ti->second;
+ cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
+ this->GeneratorTargets[t] = gt;
+ generatorTargets[t] = gt;
+ }
}
for(std::vector<cmTarget*>::const_iterator
j = mf->GetOwnedImportedTargets().begin();
j != mf->GetOwnedImportedTargets().end(); ++j)
{
- cmGeneratorTarget* gt = new cmGeneratorTarget(*j);
+ cmGeneratorTarget* gt = new cmGeneratorTarget(*j, lg);
this->GeneratorTargets[*j] = gt;
generatorTargets[*j] = gt;
}
@@ -1482,12 +1566,25 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::CreateGeneratorTargets()
+void cmGlobalGenerator::InitGeneratorTargets()
+{
+ for(cmGeneratorTargetsType::iterator ti =
+ this->GeneratorTargets.begin(); ti != this->GeneratorTargets.end(); ++ti)
+ {
+ if (!ti->second->Target->IsImported())
+ {
+ this->ComputeTargetObjectDirectory(ti->second);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
{
// Construct per-target generator information.
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
{
- this->CreateGeneratorTargets(this->LocalGenerators[i]->GetMakefile());
+ this->CreateGeneratorTargets(targetTypes, this->LocalGenerators[i]);
}
}
@@ -1498,12 +1595,12 @@ void cmGlobalGenerator::ClearGeneratorMembers()
cmDeleteAll(this->GeneratorTargets);
this->GeneratorTargets.clear();
- cmDeleteAll(this->EvaluationFiles);
- this->EvaluationFiles.clear();
-
cmDeleteAll(this->BuildExportSets);
this->BuildExportSets.clear();
+ cmDeleteAll(this->Makefiles);
+ this->Makefiles.clear();
+
cmDeleteAll(this->LocalGenerators);
this->LocalGenerators.clear();
@@ -1511,7 +1608,6 @@ void cmGlobalGenerator::ClearGeneratorMembers()
this->TargetDependencies.clear();
this->TotalTargets.clear();
this->ImportedTargets.clear();
- this->LocalGeneratorToTargetMap.clear();
this->ProjectMap.clear();
this->RuleHashes.clear();
this->DirectoryContentMap.clear();
@@ -1537,17 +1633,17 @@ void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
{
}
-void cmGlobalGenerator::CheckLocalGenerators()
+void cmGlobalGenerator::CheckTargetProperties()
{
std::map<std::string, std::string> notFoundMap;
// std::set<std::string> notFoundMap;
// after it is all done do a ConfigureFinalPass
cmState* state = this->GetCMakeInstance()->GetState();
- for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ for (unsigned int i = 0; i < this->Makefiles.size(); ++i)
{
- this->LocalGenerators[i]->ConfigureFinalPass();
+ this->Makefiles[i]->ConfigureFinalPass();
cmTargets &targets =
- this->LocalGenerators[i]->GetMakefile()->GetTargets();
+ this->Makefiles[i]->GetTargets();
for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++)
{
@@ -1572,8 +1668,7 @@ void cmGlobalGenerator::CheckLocalGenerators()
text += "\n linked by target \"";
text += l->second.GetName();
text += "\" in directory ";
- text+=this->LocalGenerators[i]->GetMakefile()
- ->GetCurrentSourceDirectory();
+ text+=this->Makefiles[i]->GetCurrentSourceDirectory();
notFoundMap[varName] = text;
}
}
@@ -1602,15 +1697,14 @@ void cmGlobalGenerator::CheckLocalGenerators()
}
std::string text = notFoundMap[varName];
text += "\n used as include directory in directory ";
- text += this->LocalGenerators[i]
- ->GetMakefile()->GetCurrentSourceDirectory();
+ text += this->Makefiles[i]->GetCurrentSourceDirectory();
notFoundMap[varName] = text;
}
}
}
this->CMakeInstance->UpdateProgress
("Configuring", 0.9f+0.1f*(static_cast<float>(i)+1.0f)/
- static_cast<float>(this->LocalGenerators.size()));
+ static_cast<float>(this->Makefiles.size()));
}
if(!notFoundMap.empty())
@@ -1644,9 +1738,9 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir,
// take the bulk of the time, so try and guess some progress
// by getting closer and closer to 100 without actually getting there.
if (!this->CMakeInstance->GetState()->GetInitializedCacheValue
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"))
+ ("CMAKE_NUMBER_OF_MAKEFILES"))
{
- // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+ // If CMAKE_NUMBER_OF_MAKEFILES is not set
// we are in the first time progress and we have no
// idea how long it will be. So, just move 1/10th of the way
// there each time, and don't go over 95%
@@ -1834,19 +1928,19 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
+void cmGlobalGenerator::AddMakefile(cmMakefile *mf)
{
- this->LocalGenerators.push_back(lg);
+ this->Makefiles.push_back(mf);
// update progress
// estimate how many lg there will be
const char *numGenC =
this->CMakeInstance->GetState()->GetInitializedCacheValue
- ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
+ ("CMAKE_NUMBER_OF_MAKEFILES");
if (!numGenC)
{
- // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set
+ // If CMAKE_NUMBER_OF_MAKEFILES is not set
// we are in the first time progress and we have no
// idea how long it will be. So, just move half way
// there each time, and don't go over 95%
@@ -1861,7 +1955,7 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
}
int numGen = atoi(numGenC);
- float prog = 0.9f*static_cast<float>(this->LocalGenerators.size())/
+ float prog = 0.9f*static_cast<float>(this->Makefiles.size())/
static_cast<float>(numGen);
if (prog > 0.9f)
{
@@ -1870,6 +1964,12 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
this->CMakeInstance->UpdateProgress("Configuring", prog);
}
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
+{
+ this->LocalGenerators.push_back(lg);
+}
+
void cmGlobalGenerator::AddInstallComponent(const char* component)
{
if(component && *component)
@@ -1883,23 +1983,10 @@ void cmGlobalGenerator::EnableInstallTarget()
this->InstallTargetEnabled = true;
}
-cmLocalGenerator *
-cmGlobalGenerator::MakeLocalGenerator(cmState::Snapshot snapshot,
- cmLocalGenerator *parent)
-{
- if (!snapshot.IsValid())
- {
- snapshot = this->CMakeInstance->GetCurrentSnapshot();
- }
-
- return this->CreateLocalGenerator(parent, snapshot);
-}
-
cmLocalGenerator*
-cmGlobalGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalGenerator(this, parent, snapshot);
+ return new cmLocalGenerator(this, mf);
}
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
@@ -1938,41 +2025,51 @@ void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
}
}
-bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
- cmLocalGenerator* gen) const
+bool cmGlobalGenerator::IsExcluded(cmState::Snapshot const& rootSnp,
+ cmState::Snapshot const& snp_) const
{
- if(!gen || gen == root)
+ cmState::Snapshot snp = snp_;
+ while (snp.IsValid())
{
- // No directory excludes itself.
- return false;
- }
+ if(snp == rootSnp)
+ {
+ // No directory excludes itself.
+ return false;
+ }
- if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
- {
- // This directory is excluded from its parent.
- return true;
+ if(snp.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ // This directory is excluded from its parent.
+ return true;
+ }
+ snp = snp.GetBuildsystemDirectoryParent();
}
+ return false;
+}
+
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
+ cmLocalGenerator* gen) const
+{
+ assert(gen);
- // This directory is included in its parent. Check whether the
- // parent is excluded.
- return this->IsExcluded(root, gen->GetParent());
+ cmState::Snapshot rootSnp = root->GetStateSnapshot();
+ cmState::Snapshot snp = gen->GetStateSnapshot();
+
+ return this->IsExcluded(rootSnp, snp);
}
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
- cmTarget const& target) const
+ cmGeneratorTarget* target) const
{
- if(target.GetType() == cmTarget::INTERFACE_LIBRARY
- || target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ if(target->GetType() == cmTarget::INTERFACE_LIBRARY
+ || target->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
// This target is excluded from its directory.
return true;
}
- else
- {
- // This target is included in its directory. Check whether the
- // directory is excluded.
- return this->IsExcluded(root, target.GetMakefile()->GetLocalGenerator());
- }
+ // This target is included in its directory. Check whether the
+ // directory is excluded.
+ return this->IsExcluded(root, target->GetLocalGenerator());
}
void
@@ -1999,65 +2096,37 @@ void cmGlobalGenerator::FillProjectMap()
for(i = 0; i < this->LocalGenerators.size(); ++i)
{
// for each local generator add all projects
- cmLocalGenerator *lg = this->LocalGenerators[i];
+ cmState::Snapshot snp = this->LocalGenerators[i]->GetStateSnapshot();
std::string name;
do
{
- if (name != lg->GetMakefile()->GetProjectName())
+ std::string snpProjName = snp.GetProjectName();
+ if (name != snpProjName)
{
- name = lg->GetMakefile()->GetProjectName();
+ name = snpProjName;
this->ProjectMap[name].push_back(this->LocalGenerators[i]);
}
- lg = lg->GetParent();
+ snp = snp.GetBuildsystemDirectoryParent();
}
- while (lg);
+ while (snp.IsValid());
}
}
-
-// Build a map that contains a the set of targets used by each local
-// generator directory level.
-void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
+cmMakefile*
+cmGlobalGenerator::FindMakefile(const std::string& start_dir) const
{
- this->LocalGeneratorToTargetMap.clear();
- // Loop over all targets in all local generators.
- for(std::vector<cmLocalGenerator*>::const_iterator
- lgi = this->LocalGenerators.begin();
- lgi != this->LocalGenerators.end(); ++lgi)
+ for(std::vector<cmMakefile*>::const_iterator it =
+ this->Makefiles.begin(); it != this->Makefiles.end(); ++it)
{
- cmLocalGenerator* lg = *lgi;
- cmMakefile* mf = lg->GetMakefile();
- cmTargets const& targets = mf->GetTargets();
- for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
+ std::string sd = (*it)->GetCurrentSourceDirectory();
+ if (sd == start_dir)
{
- cmTarget const& target = t->second;
-
- // Consider the directory containing the target and all its
- // parents until something excludes the target.
- for(cmLocalGenerator* clg = lg; clg && !this->IsExcluded(clg, target);
- clg = clg->GetParent())
- {
- // This local generator includes the target.
- std::set<cmTarget const*>& targetSet =
- this->LocalGeneratorToTargetMap[clg];
- targetSet.insert(&target);
-
- // Add dependencies of the included target. An excluded
- // target may still be included if it is a dependency of a
- // non-excluded target.
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
- for(TargetDependSet::const_iterator ti = tgtdeps.begin();
- ti != tgtdeps.end(); ++ti)
- {
- cmTarget const* ttt = *ti;
- targetSet.insert(ttt);
- }
- }
+ return *it;
}
}
+ return 0;
}
-
///! Find a local generator by its startdirectory
cmLocalGenerator*
cmGlobalGenerator::FindLocalGenerator(const std::string& start_dir) const
@@ -2144,7 +2213,7 @@ inline std::string removeQuotes(const std::string& s)
void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
{
- cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+ cmMakefile* mf = this->Makefiles[0];
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
// CPack
@@ -2443,7 +2512,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
{
// Package
cmTarget target;
- target.GetProperties().SetCMakeInstance(this->CMakeInstance);
target.SetType(cmTarget::GLOBAL_TARGET, name);
target.SetProperty("EXCLUDE_FROM_ALL","TRUE");
@@ -2513,9 +2581,9 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const std::string&,
//----------------------------------------------------------------------------
cmGlobalGenerator::TargetDependSet const&
-cmGlobalGenerator::GetTargetDirectDepends(cmTarget const& target)
+cmGlobalGenerator::GetTargetDirectDepends(cmGeneratorTarget const* target)
{
- return this->TargetDependencies[&target];
+ return this->TargetDependencies[target];
}
void cmGlobalGenerator::AddTarget(cmTarget* t)
@@ -2615,9 +2683,10 @@ void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
continue;
}
// put the target in the set of original targets
- originalTargets.insert(target);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+ originalTargets.insert(gt);
// Get the set of targets that depend on target
- this->AddTargetDepends(target, projectTargets);
+ this->AddTargetDepends(gt, projectTargets);
}
}
}
@@ -2630,7 +2699,7 @@ bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target) const
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddTargetDepends(cmTarget const* target,
+void cmGlobalGenerator::AddTargetDepends(cmGeneratorTarget const* target,
TargetDependSet& projectTargets)
{
// add the target itself
@@ -2638,23 +2707,18 @@ void cmGlobalGenerator::AddTargetDepends(cmTarget const* target,
{
// This is the first time we have encountered the target.
// Recursively follow its dependencies.
- TargetDependSet const& ts = this->GetTargetDirectDepends(*target);
+ TargetDependSet const& ts = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i)
{
- cmTarget const* dtarget = *i;
- this->AddTargetDepends(dtarget, projectTargets);
+ this->AddTargetDepends(*i, projectTargets);
}
}
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddToManifest(const std::string& config,
- std::string const& f)
+void cmGlobalGenerator::AddToManifest(std::string const& f)
{
- // Add to the main manifest for this configuration.
- this->TargetManifest[config].insert(f);
-
// Add to the content listing for the file's directory.
std::string dir = cmSystemTools::GetFilenamePath(f);
std::string file = cmSystemTools::GetFilenameName(f);
@@ -2722,9 +2786,9 @@ cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
}
// Shorten the output name (in expected use case).
- cmLocalGenerator* lg = this->GetLocalGenerators()[0];
- std::string fname = lg->Convert(outputs[0],
- cmLocalGenerator::HOME_OUTPUT);
+ cmOutputConverter converter(this->GetMakefiles()[0]->GetStateSnapshot());
+ std::string fname = converter.Convert(
+ outputs[0], cmLocalGenerator::HOME_OUTPUT);
// Associate the hash with this output.
this->RuleHashes[fname] = hash;
@@ -2974,61 +3038,21 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const {
void cmGlobalGenerator::CreateEvaluationSourceFiles(
std::string const& config) const
{
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- (*li)->CreateOutputFile(config);
+ this->LocalGenerators[i]->CreateEvaluationFileOutputs(config);
}
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr,
- cmMakefile *makefile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent)
-{
- this->EvaluationFiles.push_back(
- new cmGeneratorExpressionEvaluationFile(inputFile, outputExpr,
- makefile, condition,
- inputIsContent));
-}
-
-//----------------------------------------------------------------------------
void cmGlobalGenerator::ProcessEvaluationFiles()
{
std::vector<std::string> generatedFiles;
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
{
- (*li)->Generate();
- if (cmSystemTools::GetFatalErrorOccured())
- {
- return;
- }
- std::vector<std::string> files = (*li)->GetFiles();
- std::sort(files.begin(), files.end());
-
- std::vector<std::string> intersection;
- std::set_intersection(files.begin(), files.end(),
- generatedFiles.begin(), generatedFiles.end(),
- std::back_inserter(intersection));
- if (!intersection.empty())
- {
- cmSystemTools::Error("Files to be generated by multiple different "
- "commands: ", cmWrap('"', intersection, '"', " ").c_str());
- return;
- }
-
- generatedFiles.insert(generatedFiles.end(),
- files.begin(), files.end());
- std::vector<std::string>::iterator newIt =
- generatedFiles.end() - files.size();
- std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end());
+ this->LocalGenerators[i]->ProcessEvaluationFiles(generatedFiles);
}
}
@@ -3045,7 +3069,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
cmake::InstalledFilesMap const& installedFiles =
this->CMakeInstance->GetInstalledFiles();
- cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+ cmLocalGenerator* lg = this->LocalGenerators[0];
+ cmMakefile* mf = lg->GetMakefile();
std::vector<std::string> configs;
std::string config = mf->GetConfigurations(configs, false);
@@ -3067,7 +3092,7 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
cmInstalledFile const& installedFile = i->second;
cmCPackPropertiesGenerator cpackPropertiesGenerator(
- mf, installedFile, configs);
+ lg, installedFile, configs);
cpackPropertiesGenerator.Generate(file, config, configs);
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 979e971..9fc2d45 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -34,7 +34,6 @@
class cmake;
class cmGeneratorTarget;
-class cmGeneratorExpressionEvaluationFile;
class cmMakefile;
class cmLocalGenerator;
class cmExternalMakefileProjectGenerator;
@@ -57,9 +56,8 @@ public:
cmGlobalGenerator(cmake* cm);
virtual ~cmGlobalGenerator();
- cmLocalGenerator* MakeLocalGenerator(
- cmState::Snapshot snapshot = cmState::Snapshot(),
- cmLocalGenerator* parent = 0);
+ virtual cmLocalGenerator*
+ CreateLocalGenerator(cmMakefile* mf);
///! Get the name for this generator
virtual std::string GetName() const { return "Generic"; }
@@ -86,12 +84,21 @@ public:
*/
virtual void Configure();
+ virtual bool Compute();
+
+ enum TargetTypes {
+ AllTargets,
+ ImportedOnly
+ };
+
+ void CreateGenerationObjects(TargetTypes targetTypes = AllTargets);
+
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
* requests that they Generate.
*/
- void DoGenerate();
+ virtual void Generate();
/**
* Set/Get and Clear the enabled languages.
@@ -165,15 +172,20 @@ public:
cmake *GetCMakeInstance() const { return this->CMakeInstance; }
void SetConfiguredFilesPath(cmGlobalGenerator* gen);
+ const std::vector<cmMakefile*>& GetMakefiles() const {
+ return this->Makefiles;}
const std::vector<cmLocalGenerator *>& GetLocalGenerators() const {
return this->LocalGenerators;}
- cmLocalGenerator* GetCurrentLocalGenerator()
- {return this->CurrentLocalGenerator;}
+ cmMakefile* GetCurrentMakefile() const
+ {
+ return this->CurrentMakefile;
+ }
- void SetCurrentLocalGenerator(cmLocalGenerator* lg)
- {this->CurrentLocalGenerator = lg;}
+ void SetCurrentMakefile(cmMakefile* mf)
+ {this->CurrentMakefile = mf;}
+ void AddMakefile(cmMakefile *mf);
void AddLocalGenerator(cmLocalGenerator *lg);
///! Set an generator for an "external makefile based project"
@@ -190,7 +202,7 @@ public:
cmExportSetMap& GetExportSets() {return this->ExportSets;}
/** Add a file to the manifest of generated targets for a configuration. */
- void AddToManifest(const std::string& config, std::string const& f);
+ void AddToManifest(std::string const& f);
void EnableInstallTarget();
@@ -229,7 +241,7 @@ public:
#if defined(_WIN32) && !defined(__CYGWIN__)
/** Is this the Visual Studio 6 generator? */
- virtual bool IsForVS6() const { return false; }
+ bool IsForVS6() const { return this->GetName() == "Visual Studio 6"; }
#endif
///! Find a target by name by searching the local generators.
@@ -243,6 +255,7 @@ public:
that is a framework. */
bool NameResolvesToFramework(const std::string& libname) const;
+ cmMakefile* FindMakefile(const std::string& start_dir) const;
///! Find a local generator by its startdirectory
cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const;
@@ -254,11 +267,6 @@ public:
const std::string& suffix,
std::string& dir);
- /** Get the manifest of all targets that will be built for each
- configuration. This is valid during generation only. */
- cmTargetManifest const& GetTargetManifest() const
- { return this->TargetManifest; }
-
/** Get the content of a directory. Directory listings are cached
and re-loaded from disk only when modified. During the generation
step the content will include the target files to be built even if
@@ -290,11 +298,17 @@ public:
// what targets does the specified target depend on directly
// via a target_link_libraries or add_dependencies
- TargetDependSet const& GetTargetDirectDepends(cmTarget const& target);
+ TargetDependSet const& GetTargetDirectDepends(
+ const cmGeneratorTarget* target);
/** Get per-target generator information. */
cmGeneratorTarget* GetGeneratorTarget(cmTarget const*) const;
+ void AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt)
+ {
+ this->GeneratorTargets[t] = gt;
+ }
+
const std::map<std::string, std::vector<cmLocalGenerator*> >& GetProjectMap()
const {return this->ProjectMap;}
@@ -310,8 +324,6 @@ public:
{
return this->BinaryDirectories.insert(dir).second;
}
- /** Supported systems creates a GUID for the given name */
- virtual void CreateGUID(const std::string&) {}
/** Return true if the generated build tree may contain multiple builds.
i.e. "Can I build Debug and Release in the same tree?" */
@@ -324,12 +336,6 @@ public:
static std::string EscapeJSON(const std::string& s);
- void AddEvaluationFile(const std::string &inputFile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
- cmMakefile *makefile,
- cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
- bool inputIsContent);
-
void ProcessEvaluationFiles();
std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
@@ -359,8 +365,6 @@ public:
std::string MakeSilentFlag;
protected:
- virtual void Generate();
-
typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend
// information, and also collect all the targets
@@ -368,11 +372,13 @@ protected:
TargetDependSet& originalTargets,
cmLocalGenerator* root, GeneratorVector const&);
bool IsRootOnlyTarget(cmTarget* target) const;
- void AddTargetDepends(cmTarget const* target,
+ void AddTargetDepends(const cmGeneratorTarget* target,
TargetDependSet& projectTargets);
void SetLanguageEnabledFlag(const std::string& l, cmMakefile* mf);
void SetLanguageEnabledMaps(const std::string& l, cmMakefile* mf);
void FillExtensionToLanguageMap(const std::string& l, cmMakefile* mf);
+ virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
virtual bool ComputeTargetDepends();
@@ -388,42 +394,34 @@ protected:
// Fill the ProjectMap, this must be called after LocalGenerators
// has been populated.
void FillProjectMap();
- void CheckLocalGenerators();
+ void CheckTargetProperties();
+ bool IsExcluded(cmState::Snapshot const& root,
+ cmState::Snapshot const& snp) const;
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
- bool IsExcluded(cmLocalGenerator* root, cmTarget const& target) const;
- void FillLocalGeneratorToTargetMap();
+ bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+ virtual void InitializeProgressMarks() {}
void CreateDefaultGlobalTargets(cmTargets* targets);
cmTarget CreateGlobalTarget(const std::string& name, const char* message,
const cmCustomCommandLines* commandLines,
std::vector<std::string> depends, const char* workingDir,
bool uses_terminal);
- bool NeedSymbolicMark;
- bool UseLinkScript;
- bool ForceUnixPaths;
- bool ToolSupportsColor;
std::string FindMakeProgramFile;
std::string ConfiguredFilesPath;
cmake *CMakeInstance;
+ std::vector<cmMakefile*> Makefiles;
std::vector<cmLocalGenerator *> LocalGenerators;
- cmLocalGenerator* CurrentLocalGenerator;
+ cmMakefile* CurrentMakefile;
// map from project name to vector of local generators in that project
std::map<std::string, std::vector<cmLocalGenerator*> > ProjectMap;
- std::map<cmLocalGenerator*, std::set<cmTarget const*> >
- LocalGeneratorToTargetMap;
// Set of named installation components requested by the project.
std::set<std::string> InstallComponents;
- bool InstallTargetEnabled;
// Sets of named target exports
cmExportSetMap ExportSets;
std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
- // Manifest of all targets that will be built for each configuration.
- // This is computed just before local generators generate.
- cmTargetManifest TargetManifest;
-
// All targets in the entire project.
#if defined(CMAKE_BUILD_WITH_CMAKE)
#ifdef CMake_HAVE_CXX11_UNORDERED_MAP
@@ -437,18 +435,12 @@ protected:
TargetMap TotalTargets;
TargetMap AliasTargets;
TargetMap ImportedTargets;
- std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
const char* GetPredefinedTargetsFolder();
virtual bool UseFolderProperty();
private:
- ///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
-
cmMakefile* TryCompileOuterMakefile;
- float FirstTimeProgress;
// If you add a new map here, make sure it is copied
// in EnableLanguagesFromGenerator
std::map<std::string, bool> IgnoreExtensions;
@@ -472,8 +464,6 @@ private:
virtual void ForceLinkerLanguages();
- virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
- const char* envVar) const;
void CheckCompilerIdCompatibility(cmMakefile* mf,
std::string const& lang) const;
@@ -483,14 +473,15 @@ private:
std::vector<std::string> FilesReplacedDuringGenerate;
// Store computed inter-target dependencies.
- typedef std::map<cmTarget const*, TargetDependSet> TargetDependMap;
+ typedef std::map<cmGeneratorTarget const*, TargetDependSet> TargetDependMap;
TargetDependMap TargetDependencies;
// Per-target generator information.
cmGeneratorTargetsType GeneratorTargets;
friend class cmake;
- void CreateGeneratorTargets(cmMakefile* mf);
- void CreateGeneratorTargets();
+ void CreateGeneratorTargets(TargetTypes targetTypes, cmLocalGenerator* lg);
+ void InitGeneratorTargets();
+ void CreateGeneratorTargets(TargetTypes targetTypes);
void ClearGeneratorMembers();
@@ -521,6 +512,14 @@ private:
// Pool of file locks
cmFileLockPool FileLockPool;
#endif
+
+protected:
+ float FirstTimeProgress;
+ bool NeedSymbolicMark;
+ bool UseLinkScript;
+ bool ForceUnixPaths;
+ bool ToolSupportsColor;
+ bool InstallTargetEnabled;
};
#endif
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index f764418..6dde1e3 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -33,10 +33,9 @@ cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
}
cmLocalGenerator *
-cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalGhsMultiGenerator(this, parent, snapshot);
+ return new cmLocalGhsMultiGenerator(this, mf);
}
void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry)
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index f1a3ed7..8f88d4f 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -31,8 +31,7 @@ public:
{ return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>(); }
///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/// @return the name of this generator.
static std::string GetActualName() { return "Green Hills MULTI"; }
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index 50e7053..3f33f91 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -36,18 +36,6 @@ void cmGlobalJOMMakefileGenerator
// pick a default
mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
- if(!(cmSystemTools::GetEnv("INCLUDE") &&
- cmSystemTools::GetEnv("LIB"))
- )
- {
- std::string message = "To use the JOM generator, cmake must be run "
- "from a shell that can use the compiler cl from the command line. "
- "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
- "these must be set for the cl compiler to work. ";
- mf->IssueMessage(cmake::WARNING,
- message);
- }
-
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
@@ -58,3 +46,19 @@ void cmGlobalJOMMakefileGenerator
entry.Name = cmGlobalJOMMakefileGenerator::GetActualName();
entry.Brief = "Generates JOM makefiles.";
}
+
+//----------------------------------------------------------------------------
+void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+ std::string const& lang,
+ const char* envVar) const
+{
+ if(lang == "CXX" || lang == "C")
+ {
+ os <<
+ "To use the JOM generator with Visual C++, cmake must be run from a "
+ "shell that can use the compiler cl from the command line. This "
+ "environment is unable to invoke the cl compiler. To fix this problem, "
+ "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+ }
+ this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
+}
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index 2185b23..1869fed 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -42,6 +42,9 @@ public:
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+private:
+ void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
};
#endif
diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx
index 98557cc..138ddbb 100644
--- a/Source/cmGlobalKdevelopGenerator.cxx
+++ b/Source/cmGlobalKdevelopGenerator.cxx
@@ -70,13 +70,13 @@ void cmGlobalKdevelopGenerator::Generate()
lg!=lgs.end(); lg++)
{
cmMakefile* makefile=(*lg)->GetMakefile();
- cmTargets& targets=makefile->GetTargets();
- for (cmTargets::iterator ti = targets.begin();
+ cmGeneratorTargetsType const& targets = makefile->GetGeneratorTargets();
+ for (cmGeneratorTargetsType::const_iterator ti = targets.begin();
ti != targets.end(); ti++)
{
- if (ti->second.GetType()==cmTarget::EXECUTABLE)
+ if (ti->second->GetType()==cmTarget::EXECUTABLE)
{
- executable = ti->second.GetLocation("");
+ executable = ti->second->GetLocation("");
break;
}
}
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index a84923b..9a6f3ba 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -62,19 +62,19 @@ void cmGlobalMSYSMakefileGenerator
locations.push_back("c:/mingw/bin");
std::string tgcc = cmSystemTools::FindProgram("gcc", locations);
std::string gcc = "gcc.exe";
- if(tgcc.size())
+ if(!tgcc.empty())
{
gcc = tgcc;
}
std::string tgxx = cmSystemTools::FindProgram("g++", locations);
std::string gxx = "g++.exe";
- if(tgxx.size())
+ if(!tgxx.empty())
{
gxx = tgxx;
}
std::string trc = cmSystemTools::FindProgram("windres", locations);
std::string rc = "windres.exe";
- if(trc.size())
+ if(!trc.empty())
{
rc = trc;
}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 4219c34..7c570a6 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -36,18 +36,6 @@ void cmGlobalNMakeMakefileGenerator
// pick a default
mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
- if(!(cmSystemTools::GetEnv("INCLUDE") &&
- cmSystemTools::GetEnv("LIB"))
- )
- {
- std::string message = "To use the NMake generator, cmake must be run "
- "from a shell that can use the compiler cl from the command line. "
- "This environment does not contain INCLUDE, LIB, or LIBPATH, and "
- "these must be set for the cl compiler to work. ";
- mf->IssueMessage(cmake::WARNING,
- message);
- }
-
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
@@ -58,3 +46,19 @@ void cmGlobalNMakeMakefileGenerator
entry.Name = cmGlobalNMakeMakefileGenerator::GetActualName();
entry.Brief = "Generates NMake makefiles.";
}
+
+//----------------------------------------------------------------------------
+void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(std::ostream& os,
+ std::string const& lang,
+ const char* envVar) const
+{
+ if(lang == "CXX" || lang == "C")
+ {
+ os <<
+ "To use the NMake generator with Visual C++, cmake must be run from a "
+ "shell that can use the compiler cl from the command line. This "
+ "environment is unable to invoke the cl compiler. To fix this problem, "
+ "run cmake from the Visual Studio Command Prompt (vcvarsall.bat).\n";
+ }
+ this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar);
+}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index dd72c49..3c8375a 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -40,6 +40,9 @@ public:
*/
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile *, bool optional);
+private:
+ void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
+ const char* envVar) const;
};
#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 103d75a..120bb03 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -505,7 +505,7 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
- : cmGlobalGenerator(cm)
+ : cmGlobalCommonGenerator(cm)
, BuildFileStream(0)
, RulesFileStream(0)
, CompileCommandsStream(0)
@@ -528,10 +528,9 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
// Virtual public methods.
cmLocalGenerator*
-cmGlobalNinjaGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalNinjaGenerator(this, parent, snapshot);
+ return new cmLocalNinjaGenerator(this, mf);
}
void cmGlobalNinjaGenerator
@@ -547,6 +546,18 @@ void cmGlobalNinjaGenerator
// Source/cmake.cxx
void cmGlobalNinjaGenerator::Generate()
{
+ // Check minimum Ninja version.
+ if (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ CurrentNinjaVersion().c_str(),
+ RequiredNinjaVersion().c_str()))
+ {
+ std::ostringstream msg;
+ msg << "The detected version of Ninja (" << this->CurrentNinjaVersion();
+ msg << ") is less than the version of Ninja required by CMake (";
+ msg << this->RequiredNinjaVersion() << ").";
+ this->GetCMakeInstance()->IssueMessage(cmake::FATAL_ERROR, msg.str());
+ return;
+ }
this->OpenBuildFileStream();
this->OpenRulesFileStream();
@@ -910,10 +921,12 @@ cmGlobalNinjaGenerator
case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::MODULE_LIBRARY:
+ {
+ cmGeneratorTarget *gtgt = this->GetGeneratorTarget(target);
outputs.push_back(ng->ConvertToNinjaPath(
- target->GetFullPath(configName, false, realname)));
+ gtgt->GetFullPath(configName, false, realname)));
break;
-
+ }
case cmTarget::OBJECT_LIBRARY:
case cmTarget::UTILITY: {
std::string path = ng->ConvertToNinjaPath(
@@ -949,8 +962,8 @@ cmGlobalNinjaGenerator
std::set<std::string> const& utils = target->GetUtilities();
std::copy(utils.begin(), utils.end(), std::back_inserter(outputs));
} else {
- cmTargetDependSet const& targetDeps =
- this->GetTargetDirectDepends(*target);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+ cmTargetDependSet const& targetDeps = this->GetTargetDirectDepends(gt);
for (cmTargetDependSet::const_iterator i = targetDeps.begin();
i != targetDeps.end(); ++i)
{
@@ -958,7 +971,7 @@ cmGlobalNinjaGenerator
{
continue;
}
- this->AppendTargetOutputs(*i, outputs);
+ this->AppendTargetOutputs((*i)->Target, outputs);
}
}
}
@@ -1051,23 +1064,21 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
{
knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
}
- }
- knownDependencies.insert( "CMakeCache.txt" );
-
- for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
- li = this->EvaluationFiles.begin();
- li != this->EvaluationFiles.end();
- ++li)
- {
- //get all the files created by generator expressions and convert them
- //to ninja paths
- std::vector<std::string> files = (*li)->GetFiles();
- typedef std::vector<std::string>::const_iterator vect_it;
- for(vect_it j = files.begin(); j != files.end(); ++j)
+ std::vector<cmGeneratorExpressionEvaluationFile*> const& ef =
+ (*i)->GetMakefile()->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin(); li != ef.end(); ++li)
{
- knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
+ //get all the files created by generator expressions and convert them
+ //to ninja paths
+ std::vector<std::string> evaluationFiles = (*li)->GetFiles();
+ for(vect_it j = evaluationFiles.begin(); j != evaluationFiles.end(); ++j)
+ {
+ knownDependencies.insert( ng->ConvertToNinjaPath( *j ) );
+ }
}
}
+ knownDependencies.insert( "CMakeCache.txt" );
for(TargetAliasMap::const_iterator i= this->TargetAliases.begin();
i != this->TargetAliases.end();
@@ -1256,7 +1267,7 @@ std::string cmGlobalNinjaGenerator::ninjaCmd() const
return "ninja";
}
-std::string cmGlobalNinjaGenerator::ninjaVersion() const
+std::string cmGlobalNinjaGenerator::CurrentNinjaVersion() const
{
std::string version;
std::string command = ninjaCmd() + " --version";
@@ -1264,13 +1275,14 @@ std::string cmGlobalNinjaGenerator::ninjaVersion() const
&version, 0, 0, 0,
cmSystemTools::OUTPUT_NONE);
- return version;
+ return cmSystemTools::TrimWhitespace(version);
}
bool cmGlobalNinjaGenerator::SupportsConsolePool() const
{
return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
- ninjaVersion().c_str(), "1.5") == false;
+ CurrentNinjaVersion().c_str(),
+ RequiredNinjaVersionForConsolePool().c_str()) == false;
}
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index ffd1cdc..d204a50 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -13,7 +13,7 @@
#ifndef cmGlobalNinjaGenerator_h
# define cmGlobalNinjaGenerator_h
-# include "cmGlobalGenerator.h"
+# include "cmGlobalCommonGenerator.h"
# include "cmGlobalGeneratorFactory.h"
# include "cmNinjaTypes.h"
@@ -42,7 +42,7 @@ class cmGeneratorTarget;
* - We extensively use Ninja variable overloading system to minimize the
* number of generated rules.
*/
-class cmGlobalNinjaGenerator : public cmGlobalGenerator
+class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator
{
public:
/// The default name of Ninja's build file. Typically: build.ninja.
@@ -162,33 +162,24 @@ public:
public:
cmGlobalNinjaGenerator(cmake* cm);
- /// Convenience method for creating an instance of this class.
static cmGlobalGeneratorFactory* NewFactory() {
return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); }
- /// Destructor.
virtual ~cmGlobalNinjaGenerator() { }
- /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
- virtual cmLocalGenerator* CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
- /// Overloaded methods. @see cmGlobalGenerator::GetName().
virtual std::string GetName() const {
return cmGlobalNinjaGenerator::GetActualName(); }
- /// @return the name of this generator.
static std::string GetActualName() { return "Ninja"; }
- /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
static void GetDocumentation(cmDocumentationEntry& entry);
- /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
virtual void EnableLanguage(std::vector<std::string>const& languages,
cmMakefile* mf,
bool optional);
- /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
virtual void GenerateBuildCommand(
std::vector<std::string>& makeCommand,
const std::string& makeProgram,
@@ -289,7 +280,7 @@ public:
const std::vector<cmLocalGenerator*>& GetLocalGenerators() const {
return LocalGenerators; }
- bool IsExcluded(cmLocalGenerator* root, cmTarget& target) {
+ bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) {
return cmGlobalGenerator::IsExcluded(root, target); }
int GetRuleCmdLength(const std::string& name) {
@@ -299,17 +290,16 @@ public:
virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
- std::string ninjaVersion() const;
-
+ std::string CurrentNinjaVersion() const;
+ // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
+ static std::string RequiredNinjaVersion() { return "1.3"; }
+ static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
bool SupportsConsolePool() const;
protected:
- /// Overloaded methods. @see cmGlobalGenerator::Generate()
virtual void Generate();
- /// Overloaded methods.
- /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const { return true; }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4fe52dd..cf4fd69 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -21,7 +21,7 @@
#include "cmAlgorithms.h"
cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
- : cmGlobalGenerator(cm)
+ : cmGlobalCommonGenerator(cm)
{
// This type of makefile always requires unix style paths
this->ForceUnixPaths = true;
@@ -59,11 +59,10 @@ void cmGlobalUnixMakefileGenerator3
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalUnixMakefileGenerator3(this, parent, snapshot);
+ return new cmLocalUnixMakefileGenerator3(this, mf);
}
//----------------------------------------------------------------------------
@@ -482,8 +481,8 @@ cmGlobalUnixMakefileGenerator3
// Add this to the list of depends rules in this directory.
if((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
(!check_relink ||
- gtarget->Target
- ->NeedRelinkBeforeInstall(lg->ConfigurationName)))
+ gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName())))
{
std::string tname = lg->GetRelativeTargetDirectory(*gtarget->Target);
tname += "/";
@@ -495,12 +494,12 @@ cmGlobalUnixMakefileGenerator3
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
- for(std::vector<cmLocalGenerator*>::iterator sdi =
- lg->GetChildren().begin(); sdi != lg->GetChildren().end(); ++sdi)
+ std::vector<cmState::Snapshot> children
+ = lg->GetMakefile()->GetStateSnapshot().GetChildren();
+ for(std::vector<cmState::Snapshot>::const_iterator
+ ci = children.begin(); ci != children.end(); ++ci)
{
- cmLocalUnixMakefileGenerator3* slg =
- static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
- std::string subdir = slg->GetMakefile()->GetCurrentBinaryDirectory();
+ std::string subdir = ci->GetDirectory().GetCurrentBinary();
subdir += "/";
subdir += pass;
depends.push_back(subdir);
@@ -529,7 +528,7 @@ cmGlobalUnixMakefileGenerator3
cmLocalUnixMakefileGenerator3* lg)
{
// Only subdirectories need these rules.
- if(lg->IsRootMakefile())
+ if(lg->GetMakefile()->IsRootMakefile())
{
return;
}
@@ -578,16 +577,20 @@ void cmGlobalUnixMakefileGenerator3
makeOptions.begin(), makeOptions.end());
if (!targetName.empty())
{
+ cmMakefile* mf;
cmLocalUnixMakefileGenerator3 *lg;
if (!this->LocalGenerators.empty())
{
lg = static_cast<cmLocalUnixMakefileGenerator3 *>
(this->LocalGenerators[0]);
+ mf = lg->GetMakefile();
}
else
{
+ cmState::Snapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
+ mf = new cmMakefile(this, snapshot);
lg = static_cast<cmLocalUnixMakefileGenerator3 *>
- (this->MakeLocalGenerator());
+ (this->CreateLocalGenerator(mf));
// set the Start directories
lg->GetMakefile()->SetCurrentSourceDirectory
(this->CMakeInstance->GetHomeDirectory());
@@ -606,6 +609,7 @@ void cmGlobalUnixMakefileGenerator3
if (this->LocalGenerators.empty())
{
delete lg;
+ delete mf;
}
}
}
@@ -691,8 +695,8 @@ cmGlobalUnixMakefileGenerator3
// Add a local name for the rule to relink the target before
// installation.
- if(gtarget->Target
- ->NeedRelinkBeforeInstall(lg->ConfigurationName))
+ if(gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName()))
{
makeTargetName = lg->GetRelativeTargetDirectory(*gtarget->Target);
makeTargetName += "/preinstall";
@@ -801,15 +805,27 @@ cmGlobalUnixMakefileGenerator3
}
progress.Arg = progressArg.str();
}
- lg->AppendEcho(commands, "Built target " + name,
- cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
- this->AppendGlobalTargetDepends(depends,*gtarget->Target);
+ bool targetMessages = true;
+ if (const char* tgtMsg = this->GetCMakeInstance()
+ ->GetState()
+ ->GetGlobalProperty("TARGET_MESSAGES"))
+ {
+ targetMessages = cmSystemTools::IsOn(tgtMsg);
+ }
+
+ if (targetMessages)
+ {
+ lg->AppendEcho(commands, "Built target " + name,
+ cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+ }
+
+ this->AppendGlobalTargetDepends(depends, gtarget);
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName, depends, commands, true);
// add the all/all dependency
- if(!this->IsExcluded(this->LocalGenerators[0], *gtarget->Target))
+ if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
{
depends.clear();
depends.push_back(localName);
@@ -830,9 +846,9 @@ cmGlobalUnixMakefileGenerator3
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
//
- std::set<cmTarget const*> emitted;
+ std::set<cmGeneratorTarget const*> emitted;
progCmd << " "
- << this->CountProgressMarksInTarget(gtarget->Target, emitted);
+ << this->CountProgressMarksInTarget(gtarget, emitted);
commands.push_back(progCmd.str());
}
std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
@@ -864,8 +880,8 @@ cmGlobalUnixMakefileGenerator3
name, depends, commands, true);
// Add rules to prepare the target for installation.
- if(gtarget->Target
- ->NeedRelinkBeforeInstall(lg->ConfigurationName))
+ if(gtarget
+ ->NeedRelinkBeforeInstall(lg->GetConfigName()))
{
localName = lg->GetRelativeTargetDirectory(*gtarget->Target);
localName += "/preinstall";
@@ -877,7 +893,7 @@ cmGlobalUnixMakefileGenerator3
"Pre-install relink rule for target.",
localName, depends, commands, true);
- if(!this->IsExcluded(this->LocalGenerators[0], *gtarget->Target))
+ if(!this->IsExcluded(this->LocalGenerators[0], gtarget))
{
depends.clear();
depends.push_back(localName);
@@ -905,17 +921,71 @@ cmGlobalUnixMakefileGenerator3
}
}
+// Build a map that contains a the set of targets used by each local
+// generator directory level.
+void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
+{
+ this->DirectoryTargetsMap.clear();
+ // Loop over all targets in all local generators.
+ for(std::vector<cmLocalGenerator*>::const_iterator
+ lgi = this->LocalGenerators.begin();
+ lgi != this->LocalGenerators.end(); ++lgi)
+ {
+ cmLocalGenerator* lg = *lgi;
+ cmMakefile* mf = lg->GetMakefile();
+ cmTargets const& targets = mf->GetTargets();
+ for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ cmTarget const& target = t->second;
+
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+
+ cmLocalGenerator* tlg = gt->GetLocalGenerator();
+
+ if(gt->GetType() == cmTarget::INTERFACE_LIBRARY
+ || gt->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ continue;
+ }
+
+ cmState::Snapshot csnp = lg->GetStateSnapshot();
+ cmState::Snapshot tsnp = tlg->GetStateSnapshot();
+
+ // Consider the directory containing the target and all its
+ // parents until something excludes the target.
+ for( ; csnp.IsValid() && !this->IsExcluded(csnp, tsnp);
+ csnp = csnp.GetBuildsystemDirectoryParent())
+ {
+ // This local generator includes the target.
+ std::set<cmGeneratorTarget const*>& targetSet =
+ this->DirectoryTargetsMap[csnp];
+ targetSet.insert(gt);
+
+ // Add dependencies of the included target. An excluded
+ // target may still be included if it is a dependency of a
+ // non-excluded target.
+ TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(gt);
+ for(TargetDependSet::const_iterator ti = tgtdeps.begin();
+ ti != tgtdeps.end(); ++ti)
+ {
+ targetSet.insert(*ti);
+ }
+ }
+ }
+ }
+}
+
//----------------------------------------------------------------------------
size_t
cmGlobalUnixMakefileGenerator3
-::CountProgressMarksInTarget(cmTarget const* target,
- std::set<cmTarget const*>& emitted)
+::CountProgressMarksInTarget(cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& emitted)
{
size_t count = 0;
if(emitted.insert(target).second)
{
- count = this->ProgressMap[target].Marks.size();
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ count = this->ProgressMap[target->Target].Marks.size();
+ TargetDependSet const& depends = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
@@ -935,10 +1005,10 @@ cmGlobalUnixMakefileGenerator3
::CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg)
{
size_t count = 0;
- std::set<cmTarget const*> emitted;
- std::set<cmTarget const*> const& targets
- = this->LocalGeneratorToTargetMap[lg];
- for(std::set<cmTarget const*>::const_iterator t = targets.begin();
+ std::set<cmGeneratorTarget const*> emitted;
+ std::set<cmGeneratorTarget const*> const& targets
+ = this->DirectoryTargetsMap[lg->GetStateSnapshot()];
+ for(std::set<cmGeneratorTarget const*>::const_iterator t = targets.begin();
t != targets.end(); ++t)
{
count += this->CountProgressMarksInTarget(*t, emitted);
@@ -987,22 +1057,21 @@ cmGlobalUnixMakefileGenerator3::TargetProgress
void
cmGlobalUnixMakefileGenerator3
::AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target)
+ cmGeneratorTarget* target)
{
TargetDependSet const& depends_set = this->GetTargetDirectDepends(target);
for(TargetDependSet::const_iterator i = depends_set.begin();
i != depends_set.end(); ++i)
{
// Create the target-level dependency.
- cmTarget const* dep = *i;
+ cmGeneratorTarget const* dep = *i;
if (dep->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
cmLocalUnixMakefileGenerator3* lg3 =
- static_cast<cmLocalUnixMakefileGenerator3*>
- (dep->GetMakefile()->GetLocalGenerator());
- std::string tgtName = lg3->GetRelativeTargetDirectory(*dep);
+ static_cast<cmLocalUnixMakefileGenerator3*>(dep->GetLocalGenerator());
+ std::string tgtName = lg3->GetRelativeTargetDirectory(*(*dep).Target);
tgtName += "/all";
depends.push_back(tgtName);
}
@@ -1034,7 +1103,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
// for the passed in makefile or if this is the top Makefile wripte out
// the targets
- if (lg2 == lg || lg->IsRootMakefile())
+ if (lg2 == lg || lg->GetMakefile()->IsRootMakefile())
{
// for each target Generate the rule files for each target.
cmTargets& targets = lg2->GetMakefile()->GetTargets();
@@ -1080,7 +1149,8 @@ bool cmGlobalUnixMakefileGenerator3
::NeedRequiresStep(cmTarget const& target)
{
std::set<std::string> languages;
- target.GetLanguages(languages,
+ cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&target);
+ gtgt->GetLanguages(languages,
target.GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for(std::set<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index a639ff0..5f39c79 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -12,7 +12,7 @@
#ifndef cmGlobalUnixMakefileGenerator3_h
#define cmGlobalUnixMakefileGenerator3_h
-#include "cmGlobalGenerator.h"
+#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
class cmGeneratedFileStream;
@@ -51,7 +51,7 @@ class cmLocalUnixMakefileGenerator3;
*/
-class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator
+class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
{
public:
cmGlobalUnixMakefileGenerator3(cmake* cm);
@@ -67,9 +67,7 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- ///! Create a local generator appropriate to this Global Generator3
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
* Try to determine system information such as shared library
@@ -153,7 +151,7 @@ protected:
cmLocalUnixMakefileGenerator3* lg);
void AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target);
+ cmGeneratorTarget* target);
// does this generator need a requires step for any of its targets
bool NeedRequiresStep(cmTarget const&);
@@ -198,14 +196,19 @@ protected:
cmStrictTargetComparison> ProgressMapType;
ProgressMapType ProgressMap;
- size_t CountProgressMarksInTarget(cmTarget const* target,
- std::set<cmTarget const*>& emitted);
+ size_t CountProgressMarksInTarget(cmGeneratorTarget const* target,
+ std::set<cmGeneratorTarget const*>& emitted);
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
cmGeneratedFileStream *CommandDatabase;
private:
virtual const char* GetBuildIgnoreErrorsFlag() const { return "-i"; }
virtual std::string GetEditCacheCommand() const;
+
+ std::map<cmState::Snapshot,
+ std::set<cmGeneratorTarget const*>,
+ cmState::Snapshot::StrictWeakOrder> DirectoryTargetsMap;
+ virtual void InitializeProgressMarks();
};
#endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 4e8ada4..44d632d 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -306,17 +306,25 @@ void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalVisualStudio10Generator(this, parent, snapshot);
+ return new cmLocalVisualStudio10Generator(this, mf);
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio10Generator::Generate()
+bool cmGlobalVisualStudio10Generator::Compute()
{
+ if (!cmGlobalVisualStudio8Generator::Compute())
+ {
+ return false;
+ }
this->LongestSource = LongestSourcePath();
+ return true;
+}
+
+void cmGlobalVisualStudio10Generator::Generate()
+{
this->cmGlobalVisualStudio8Generator::Generate();
if(this->LongestSource.Length > 0)
{
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 74d5022..8de7b09 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -45,9 +45,10 @@ public:
std::vector<std::string> const& makeOptions = std::vector<std::string>()
);
+ virtual bool Compute();
+
///! create the correct local generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
* Try to determine system information such as shared library
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 632141a..df49948 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -173,10 +173,9 @@ cmGlobalVisualStudio6Generator::GenerateBuildCommand(
///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *
-cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmGlobalVisualStudio6Generator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalVisualStudio6Generator(this, parent, snapshot);
+ return new cmLocalVisualStudio6Generator(this, mf);
}
@@ -224,7 +223,7 @@ void cmGlobalVisualStudio6Generator
tt = orderedProjectTargets.begin();
tt != orderedProjectTargets.end(); ++tt)
{
- cmTarget const* target = *tt;
+ cmTarget const* target = (*tt)->Target;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
@@ -255,7 +254,7 @@ void cmGlobalVisualStudio6Generator
::OutputDSWFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
- if(generators.size() == 0)
+ if(generators.empty())
{
return;
}
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 2460158..e9b24ea 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -39,8 +39,7 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
/**
* Try to determine system information such as shared library
@@ -85,8 +84,6 @@ public:
virtual void FindMakeProgram(cmMakefile*);
- virtual bool IsForVS6() const { return true; }
-
protected:
virtual void Generate();
virtual const char* GetIDEVersion() { return "6.0"; }
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 1ab4c9c..607642c 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -212,7 +212,7 @@ cmGlobalVisualStudio71Generator
{
const char* name = di->c_str();
std::string guid = this->GetGUID(name);
- if(guid.size() == 0)
+ if(guid.empty())
{
std::string m = "Target: ";
m += target.GetName();
@@ -250,7 +250,7 @@ void cmGlobalVisualStudio71Generator
std::set<std::string>::const_iterator it;
for(it = depends.begin(); it != depends.end(); ++it)
{
- if(it->size() > 0)
+ if(!it->empty())
{
fout << "\t\t{"
<< this->GetGUID(it->c_str())
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 4dd54d0..0175062 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratedFileStream.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
+#include "cmUuid.h"
#include "cmake.h"
#include <cmsys/Encoding.hxx>
@@ -278,12 +279,11 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
}
///! Create a local generator appropriate to this Global Generator
-cmLocalGenerator *
-cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator(
+ cmMakefile* mf)
{
cmLocalVisualStudio7Generator *lg =
- new cmLocalVisualStudio7Generator(this, parent, snapshot);
+ new cmLocalVisualStudio7Generator(this, mf);
return lg;
}
@@ -358,7 +358,7 @@ void cmGlobalVisualStudio7Generator
::OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
- if(generators.size() == 0)
+ if(generators.empty())
{
return;
}
@@ -401,7 +401,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget const* target = *tt;
+ cmTarget const* target = (*tt)->Target;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
@@ -441,7 +441,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget const* target = *tt;
+ cmTarget const* target = (*tt)->Target;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
@@ -513,8 +513,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
cumulativePath = cumulativePath + "/" + *iter;
}
-
- this->CreateGUID(cumulativePath.c_str());
}
if (!cumulativePath.empty())
@@ -535,7 +533,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
for(OrderedTargetDependSet::const_iterator tt =
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
- cmTarget const* target = *tt;
+ cmTarget const* target = (*tt)->Target;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
@@ -737,7 +735,7 @@ cmGlobalVisualStudio7Generator
{
const char* name = di->c_str();
std::string guid = this->GetGUID(name);
- if(guid.size() == 0)
+ if(guid.empty())
{
std::string m = "Target: ";
m += target.GetName();
@@ -815,14 +813,15 @@ void cmGlobalVisualStudio7Generator
{
bool extensibilityGlobalsOverridden = false;
bool extensibilityAddInsOverridden = false;
- const cmPropertyMap& props = root->GetMakefile()->GetProperties();
- for(cmPropertyMap::const_iterator itProp = props.begin();
- itProp != props.end(); ++itProp)
+ const std::vector<std::string> propKeys =
+ root->GetMakefile()->GetPropertyKeys();
+ for(std::vector<std::string>::const_iterator it = propKeys.begin();
+ it != propKeys.end(); ++it)
{
- if(itProp->first.find("VS_GLOBAL_SECTION_") == 0)
+ if(it->find("VS_GLOBAL_SECTION_") == 0)
{
std::string sectionType;
- std::string name = itProp->first.substr(18);
+ std::string name = it->substr(18);
if(name.find("PRE_") == 0)
{
name = name.substr(4);
@@ -843,8 +842,9 @@ void cmGlobalVisualStudio7Generator
extensibilityAddInsOverridden = true;
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
std::vector<std::string> keyValuePairs;
- cmSystemTools::ExpandListArgument(itProp->second.GetValue(),
- keyValuePairs);
+ cmSystemTools::ExpandListArgument(
+ root->GetMakefile()->GetProperty(it->c_str()),
+ keyValuePairs);
for(std::vector<std::string>::const_iterator itPair =
keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair)
{
@@ -899,7 +899,6 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target)
fname += ".vcproj";
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
- this->CreateGUID(pname.c_str());
std::string guid = this->GetGUID(pname.c_str());
fout <<
@@ -943,41 +942,29 @@ cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget const* target)
return pname;
}
-std::string cmGlobalVisualStudio7Generator::GetGUID(const std::string& name)
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio7Generator::GetGUID(std::string const& name)
{
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
- const char* storedGUID =
- this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
- if(storedGUID)
+ std::string const& guidStoreName = name + "_GUID_CMAKE";
+ if (const char* storedGUID =
+ this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
{
return std::string(storedGUID);
}
- cmSystemTools::Error("Unknown Target referenced : ",
- name.c_str());
- return "";
-}
+ // Compute a GUID that is deterministic but unique to the build tree.
+ std::string input = this->CMakeInstance->GetState()->GetBinaryDirectory();
+ input += "|";
+ input += name;
+ cmUuid uuidGenerator;
-void cmGlobalVisualStudio7Generator::CreateGUID(const std::string& name)
-{
- std::string guidStoreName = name;
- guidStoreName += "_GUID_CMAKE";
- if(this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()))
- {
- return;
- }
- std::string ret;
- UUID uid;
- unsigned short *uidstr;
- UuidCreate(&uid);
- UuidToStringW(&uid,&uidstr);
- ret = cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(uidstr));
- RpcStringFreeW(&uidstr);
- ret = cmSystemTools::UpperCase(ret);
- this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
- ret.c_str(), "Stored GUID",
- cmState::INTERNAL);
+ std::vector<unsigned char> uuidNamespace;
+ uuidGenerator.StringToBinary(
+ "ee30c4be-5192-4fb0-b335-722a2dffe760", uuidNamespace);
+
+ std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
+
+ return cmSystemTools::UpperCase(guid);
}
//----------------------------------------------------------------------------
@@ -1039,12 +1026,13 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
{
return activeConfigs;
}
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
// inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
for(std::vector<std::string>::const_iterator i = configs.begin();
i != configs.end(); ++i)
{
const char* propertyValue =
- target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
+ gt->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
if(cmSystemTools::IsOff(propertyValue))
{
activeConfigs.insert(*i);
@@ -1058,12 +1046,12 @@ cmGlobalVisualStudio7Generator
::IsDependedOn(OrderedTargetDependSet const& projectTargets,
cmTarget const* targetIn)
{
+ cmGeneratorTarget* gtIn = this->GetGeneratorTarget(targetIn);
for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
l != projectTargets.end(); ++l)
{
- cmTarget const& target = **l;
- TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
- if(tgtdeps.count(targetIn))
+ TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(*l);
+ if(tgtdeps.count(gtIn))
{
return true;
}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index c98d269..35575d1 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -43,8 +43,7 @@ public:
std::string const& GetPlatformName() const;
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile* mf);
virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
@@ -80,9 +79,8 @@ public:
*/
virtual void OutputSLNFile();
- ///! Create a GUID or get an existing one.
- void CreateGUID(const std::string& name);
- std::string GetGUID(const std::string& name);
+ ///! Lookup a stored GUID or compute one deterministically.
+ std::string GetGUID(std::string const& name);
/** Append the subdirectory for the given configuration. */
virtual void AppendDirectoryForConfig(const std::string& prefix,
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index a3ebc61..28f0425 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -185,7 +185,6 @@ void cmGlobalVisualStudio8Generator
void cmGlobalVisualStudio8Generator::Configure()
{
this->cmGlobalVisualStudio7Generator::Configure();
- this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
}
//----------------------------------------------------------------------------
@@ -256,6 +255,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
no_working_directory, no_depends,
noCommandLines);
+ cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
+ mf->AddGeneratorTarget(tgt, gt);
+
// Organize in the "predefined targets" folder:
//
if (this->UseFolderProperty())
@@ -310,14 +312,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
cmCustomCommandLine commandLine;
commandLine.push_back(cmSystemTools::GetCMakeCommand());
std::string argH = "-H";
- argH += lg->Convert(mf->GetHomeDirectory(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED, true);
+ argH += mf->GetHomeDirectory();
commandLine.push_back(argH);
std::string argB = "-B";
- argB += lg->Convert(mf->GetHomeOutputDirectory(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED, true);
+ argB += mf->GetHomeOutputDirectory();
commandLine.push_back(argB);
commandLine.push_back("--check-stamp-list");
commandLine.push_back(stampList.c_str());
@@ -350,8 +348,13 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudio8Generator::Generate()
+bool cmGlobalVisualStudio8Generator::Compute()
{
+ if (!cmGlobalVisualStudio7Generator::Compute())
+ {
+ return false;
+ }
+
if(this->AddCheckTarget())
{
// All targets depend on the build-system check target.
@@ -365,9 +368,7 @@ void cmGlobalVisualStudio8Generator::Generate()
}
}
}
-
- // Now perform the main generation.
- this->cmGlobalVisualStudio7Generator::Generate();
+ return true;
}
//----------------------------------------------------------------------------
@@ -446,7 +447,8 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
void cmGlobalVisualStudio8Generator::WriteProjectDepends(
std::ostream& fout, const std::string&, const char*, cmTarget const& t)
{
- TargetDependSet const& unordered = this->GetTargetDirectDepends(t);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(&t);
+ TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
OrderedTargetDependSet depends(unordered);
for(OrderedTargetDependSet::const_iterator i = depends.begin();
i != depends.end(); ++i)
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index cc02b78..1c61103 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -67,7 +67,7 @@ public:
return !this->WindowsCEVersion.empty(); }
protected:
- virtual void Generate();
+ virtual bool Compute();
virtual const char* GetIDEVersion() { return "8.0"; }
virtual std::string FindDevEnvCommand();
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 585d19a..2bf04b4 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -13,12 +13,14 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmCallVisualStudioMacro.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmTarget.h"
#include <cmsys/Encoding.hxx>
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm)
@@ -62,8 +64,13 @@ std::string cmGlobalVisualStudioGenerator::GetRegistryBase(
}
//----------------------------------------------------------------------------
-void cmGlobalVisualStudioGenerator::Generate()
+bool cmGlobalVisualStudioGenerator::Compute()
{
+ if (!cmGlobalGenerator::Compute())
+ {
+ return false;
+ }
+
// Add a special target that depends on ALL projects for easy build
// of one configuration only.
const char* no_working_dir = 0;
@@ -74,7 +81,7 @@ void cmGlobalVisualStudioGenerator::Generate()
{
std::vector<cmLocalGenerator*>& gen = it->second;
// add the ALL_BUILD to the first local generator of each project
- if(gen.size())
+ if(!gen.empty())
{
// Use no actual command lines so that the target itself is not
// considered always out of date.
@@ -84,6 +91,9 @@ void cmGlobalVisualStudioGenerator::Generate()
no_depends, no_commands, false,
"Build all projects");
+ cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
+ allBuild->GetMakefile()->AddGeneratorTarget(allBuild, gt);
+
#if 0
// Can't activate this code because we want ALL_BUILD
// selected as the default "startup project" when first
@@ -102,13 +112,19 @@ void cmGlobalVisualStudioGenerator::Generate()
for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
i != gen.end(); ++i)
{
- cmTargets& targets = (*i)->GetMakefile()->GetTargets();
- for(cmTargets::iterator t = targets.begin();
+ cmGeneratorTargetsType targets =
+ (*i)->GetMakefile()->GetGeneratorTargets();
+ for(cmGeneratorTargetsType::iterator t = targets.begin();
t != targets.end(); ++t)
{
+ if (t->second->GetType() == cmTarget::GLOBAL_TARGET
+ || t->first->IsImported())
+ {
+ continue;
+ }
if(!this->IsExcluded(gen[0], t->second))
{
- allBuild->AddUtility(t->second.GetName());
+ allBuild->AddUtility(t->second->GetName());
}
}
}
@@ -128,9 +144,7 @@ void cmGlobalVisualStudioGenerator::Generate()
static_cast<cmLocalVisualStudioGenerator*>(*lgi);
lg->AddCMakeListsRules();
}
-
- // Run all the local generators.
- this->cmGlobalGenerator::Generate();
+ return true;
}
//----------------------------------------------------------------------------
@@ -251,7 +265,7 @@ cmGlobalVisualStudioGenerator
{
std::vector<std::string> filenames;
this->GetFilesReplacedDuringGenerate(filenames);
- if (filenames.size() > 0)
+ if (!filenames.empty())
{
// Convert vector to semi-colon delimited string of filenames:
std::string projects;
@@ -299,13 +313,14 @@ void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget const* target,
{
if(linked.insert(target).second)
{
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+ TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
if(di->IsLink())
{
- this->FillLinkClosure(*di, linked);
+ this->FillLinkClosure((*di)->Target, linked);
}
}
}
@@ -338,13 +353,14 @@ void cmGlobalVisualStudioGenerator::FollowLinkDepends(
{
// Static library targets do not list their link dependencies so
// we must follow them transitively now.
- TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(target);
+ TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
if(di->IsLink())
{
- this->FollowLinkDepends(*di, linked);
+ this->FollowLinkDepends((*di)->Target, linked);
}
}
}
@@ -413,7 +429,8 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
target.GetType() != cmTarget::MODULE_LIBRARY &&
target.GetType() != cmTarget::EXECUTABLE);
- TargetDependSet const& depends = this->GetTargetDirectDepends(target);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+ TargetDependSet const& depends = this->GetTargetDirectDepends(gt);
// Collect implicit link dependencies (target_link_libraries).
// Static libraries cannot depend on their link implementation
@@ -427,7 +444,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
cmTargetDepend dep = *di;
if(dep.IsLink())
{
- this->FollowLinkDepends(dep, linkDepends);
+ this->FollowLinkDepends(dep->Target, linkDepends);
}
}
}
@@ -440,7 +457,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
cmTargetDepend dep = *di;
if(dep.IsUtil())
{
- this->FollowLinkDepends(dep, utilDepends);
+ this->FollowLinkDepends(dep->Target, utilDepends);
}
}
@@ -819,17 +836,19 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
bool
cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
{
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
+
// check to see if this is a fortran build
std::set<std::string> languages;
{
// Issue diagnostic if the source files depend on the config.
std::vector<cmSourceFile*> sources;
- if (!target.GetConfigCommonSourceFiles(sources))
+ if (!gt->GetConfigCommonSourceFiles(sources))
{
return false;
}
}
- target.GetLanguages(languages, "");
+ gt->GetLanguages(languages, "");
if(languages.size() == 1)
{
if(*languages.begin() == "Fortran")
@@ -843,7 +862,7 @@ cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
//----------------------------------------------------------------------------
bool
cmGlobalVisualStudioGenerator::TargetCompare
-::operator()(cmTarget const* l, cmTarget const* r) const
+::operator()(cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
// Make sure ALL_BUILD is first so it is the default active project.
if(r->GetName() == "ALL_BUILD")
@@ -868,7 +887,13 @@ cmGlobalVisualStudioGenerator::OrderedTargetDependSet
cmGlobalVisualStudioGenerator::OrderedTargetDependSet
::OrderedTargetDependSet(TargetSet const& targets)
{
- this->insert(targets.begin(), targets.end());
+ for (TargetSet::const_iterator it = targets.begin();
+ it != targets.end(); ++it)
+ {
+ cmGeneratorTarget* gt =
+ (*it)->GetMakefile()->GetGlobalGenerator()->GetGeneratorTarget(*it);
+ this->insert(gt);
+ }
}
std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
@@ -887,3 +912,71 @@ std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
}
return tmp;
}
+
+void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
+ cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
+ std::string const& configName)
+{
+ std::vector<std::string> outputs;
+ std::string deffile = gt->ObjectDirectory;
+ deffile += "/exportall.def";
+ outputs.push_back(deffile);
+ std::vector<std::string> empty;
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources, configName);
+ std::map<cmSourceFile const*, std::string> mapping;
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ mapping[*it];
+ }
+ gt->LocalGenerator->
+ ComputeObjectFilenames(mapping, gt);
+ std::string obj_dir = gt->ObjectDirectory;
+ std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
+ cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
+ cmCustomCommandLine cmdl;
+ cmdl.push_back(cmakeCommand);
+ cmdl.push_back("-E");
+ cmdl.push_back("__create_def");
+ cmdl.push_back(deffile);
+ std::string obj_dir_expanded = obj_dir;
+ cmSystemTools::ReplaceString(obj_dir_expanded,
+ this->GetCMakeCFGIntDir(),
+ configName.c_str());
+ std::string objs_file = obj_dir_expanded;
+ cmSystemTools::MakeDirectory(objs_file.c_str());
+ objs_file += "/objects.txt";
+ cmdl.push_back(objs_file);
+ cmGeneratedFileStream fout(objs_file.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("could not open ", objs_file.c_str());
+ return;
+ }
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ // Find the object file name corresponding to this source file.
+ std::map<cmSourceFile const*, std::string>::const_iterator
+ map_it = mapping.find(*it);
+ // It must exist because we populated the mapping just above.
+ assert(!map_it->second.empty());
+ std::string objFile = obj_dir + map_it->second;
+ // replace $(ConfigurationName) in the object names
+ cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+ configName.c_str());
+ if(cmHasLiteralSuffix(objFile, ".obj"))
+ {
+ fout << objFile << "\n";
+ }
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(cmdl);
+ cmCustomCommand command(gt->Target->GetMakefile(),
+ outputs, empty, empty,
+ commandLines,
+ "Auto build dll exports",
+ ".");
+ commands.push_back(command);
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 69b4564..64440ad 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -91,7 +91,8 @@ public:
class TargetSet: public std::set<cmTarget const*> {};
struct TargetCompare
{
- bool operator()(cmTarget const* l, cmTarget const* r) const;
+ bool operator()(cmGeneratorTarget const* l,
+ cmGeneratorTarget const* r) const;
};
class OrderedTargetDependSet;
@@ -102,8 +103,12 @@ public:
const std::string& config) const;
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+ void AddSymbolExportCommand(
+ cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
+ std::string const& configName);
protected:
- virtual void Generate();
+ virtual bool Compute();
// Does this VS version link targets to each other if there are
// dependencies in the SLN file? This was done for VS versions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7464e90..33babec 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -371,15 +371,19 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
//----------------------------------------------------------------------------
///! Create a local generator appropriate to this Global Generator
cmLocalGenerator *
-cmGlobalXCodeGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
+cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalXCodeGenerator(this, parent, snapshot);
+ return new cmLocalXCodeGenerator(this, mf);
}
//----------------------------------------------------------------------------
-void cmGlobalXCodeGenerator::Generate()
+bool cmGlobalXCodeGenerator::Compute()
{
+ if (!cmGlobalGenerator::Compute())
+ {
+ return false;
+ }
+
std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
// make sure extra targets are added before calling
// the parent generate which will call trace depends
@@ -390,11 +394,17 @@ void cmGlobalXCodeGenerator::Generate()
// add ALL_BUILD, INSTALL, etc
this->AddExtraTargets(root, it->second);
}
+ return true;
+}
+
+void cmGlobalXCodeGenerator::Generate()
+{
this->cmGlobalGenerator::Generate();
if(cmSystemTools::GetErrorOccuredFlag())
{
return;
}
+ std::map<std::string, std::vector<cmLocalGenerator*> >::iterator it;
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
cmLocalGenerator* root = it->second[0];
@@ -449,10 +459,12 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
// Add ALL_BUILD
const char* no_working_directory = 0;
std::vector<std::string> no_depends;
- mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
+ cmTarget* allbuild = mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
no_working_directory,
"echo", "Build all projects");
- cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+
+ cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
+ mf->AddGeneratorTarget(allbuild, allBuildGt);
// Refer to the main build configuration file for easy editing.
std::string listfile = mf->GetCurrentSourceDirectory();
@@ -481,9 +493,13 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
std::string file = this->ConvertToRelativeForMake(
this->CurrentReRunCMakeMakefile.c_str());
cmSystemTools::ReplaceString(file, "\\ ", " ");
- mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true, no_depends,
+ cmTarget* check = mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET,
+ true, no_depends,
no_working_directory,
"make", "-f", file.c_str());
+
+ cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
+ mf->AddGeneratorTarget(check, checkGt);
}
// now make the allbuild depend on all the non-utility targets
@@ -502,6 +518,11 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
{
cmTarget& target = l->second;
+ if (target.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ continue;
+ }
+
if (regenerate && (l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
{
target.AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
@@ -750,7 +771,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
sf->GetProperty("COMPILE_DEFINITIONS"), true);
if (!flagsBuild.IsEmpty())
{
- if (flags.size())
+ if (!flags.empty())
{
flags += ' ';
}
@@ -843,6 +864,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
{
sourcecode += ".c.objc";
}
+ else if (ext == "swift")
+ {
+ sourcecode += ".swift";
+ }
else if(ext == "plist")
{
sourcecode += ".text.plist";
@@ -1098,7 +1123,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
// organize the sources
std::vector<cmSourceFile*> classes;
- if (!cmtarget.GetConfigCommonSourceFiles(classes))
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
{
return false;
}
@@ -1352,12 +1377,13 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
return;
}
- std::string llang = cmtarget.GetLinkerLanguage("NOCONFIG");
+ cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&cmtarget);
+ std::string llang = gtgt->GetLinkerLanguage("NOCONFIG");
if(llang.empty()) { return; }
// If the language is compiled as a source trust Xcode to link with it.
- cmTarget::LinkImplementation const* impl =
- cmtarget.GetLinkImplementation("NOCONFIG");
+ cmLinkImplementation const* impl =
+ gtgt->GetLinkImplementation("NOCONFIG");
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
@@ -1478,7 +1504,8 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
}
std::vector<cmSourceFile*> classes;
- if (!cmtarget.GetConfigCommonSourceFiles(classes))
+ cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
{
return;
}
@@ -1664,7 +1691,7 @@ void cmGlobalXCodeGenerator
for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+ cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
if(ccg.GetNumberOfCommands() > 0)
{
const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -1690,7 +1717,7 @@ void cmGlobalXCodeGenerator
for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+ cmCustomCommandGenerator ccg(*i, configName, this->CurrentLocalGenerator);
if(ccg.GetNumberOfCommands() > 0)
{
makefileStream << "\n";
@@ -1778,7 +1805,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// Compute the compilation flags for each language.
std::set<std::string> languages;
- target.GetLanguages(languages, configName);
+ cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
+ gtgt->GetLanguages(languages, configName);
std::map<std::string, std::string> cflags;
for (std::set<std::string>::iterator li = languages.begin();
li != languages.end(); ++li)
@@ -1800,7 +1828,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
AddCompileOptions(flags, &target, lang, configName);
}
- std::string llang = target.GetLinkerLanguage(configName);
+ std::string llang = gtgt->GetLinkerLanguage(configName);
if(binary && llang.empty())
{
cmSystemTools::Error
@@ -1826,9 +1854,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
// Add the export symbol definition for shared library objects.
this->AppendDefines(ppDefs, exportMacro);
}
- cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName, "C");
+ gtgt->GetCompileDefinitions(targetDefines, configName, "C");
this->AppendDefines(ppDefs, targetDefines);
buildSettings->AddAttribute
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
@@ -1847,7 +1874,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{
extraLinkOptionsVar = "CMAKE_MODULE_LINKER_FLAGS";
}
- if(extraLinkOptionsVar.size())
+ if(!extraLinkOptionsVar.empty())
{
this->CurrentLocalGenerator
->AddConfigVariableFlags(extraLinkOptions,
@@ -1916,11 +1943,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string pnprefix;
std::string pnbase;
std::string pnsuffix;
- target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
+ gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
const char* version = target.GetProperty("VERSION");
const char* soversion = target.GetProperty("SOVERSION");
- if(!target.HasSOName(configName) || target.IsFrameworkOnApple())
+ if(!gtgt->HasSOName(configName) || target.IsFrameworkOnApple())
{
version = 0;
soversion = 0;
@@ -2178,7 +2205,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
}
// Add framework search paths needed for linking.
- if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
+ if(cmComputeLinkInformation* cli = gtgt->GetLinkInformation(configName))
{
std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
@@ -2307,7 +2334,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
if(target.GetType() == cmTarget::SHARED_LIBRARY)
{
// Get the install_name directory for the build tree.
- install_name_dir = target.GetInstallNameDirForBuildTree(configName);
+ install_name_dir = gtgt->GetInstallNameDirForBuildTree(configName);
// Xcode doesn't create the correct install_name in some cases.
// That is, if the INSTALL_PATH is empty, or if we have versioning
// of dylib libraries, we want to specify the install_name.
@@ -2321,7 +2348,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
install_name += install_name_dir;
install_name += "/";
}
- install_name += target.GetSOName(configName);
+ install_name += gtgt->GetSOName(configName);
if((realName != soName) || install_name_dir.empty())
{
@@ -2334,7 +2361,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(install_name_dir.c_str()));
// Create the LD_RUNPATH_SEARCH_PATHS
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
if(pcli)
{
std::string search_paths;
@@ -2530,7 +2557,8 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
if(cmtarget.GetType() == cmTarget::UTILITY)
{
std::vector<cmSourceFile*> sources;
- if (!cmtarget.GetConfigCommonSourceFiles(sources))
+ cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+ if (!gtgt->GetConfigCommonSourceFiles(sources))
{
return 0;
}
@@ -2587,7 +2615,7 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
config->SetComment(configVector[i].c_str());
config->AddAttribute("buildSettings", buildSettings);
}
- if(configVector.size())
+ if(!configVector.empty())
{
configlist->AddAttribute("defaultConfigurationName",
this->CreateString(configVector[0].c_str()));
@@ -2718,7 +2746,8 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
}
else
{
- fullName = cmtarget.GetFullName(defConfig.c_str());
+ cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&cmtarget);
+ fullName = gtgt->GetFullName(defConfig.c_str());
}
fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
fileRef->AddAttribute("refType", this->CreateString("0"));
@@ -2895,10 +2924,11 @@ void cmGlobalXCodeGenerator
}
// Add dependencies on other CMake targets.
- TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
+ cmGeneratorTarget* gt = this->GetGeneratorTarget(cmtarget);
+ TargetDependSet const& deps = this->GetTargetDirectDepends(gt);
for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
{
- if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
+ if(cmXCodeObject* dptarget = this->FindXCodeTarget((*i)->Target))
{
this->AddDependTarget(target, dptarget);
}
@@ -2939,7 +2969,8 @@ void cmGlobalXCodeGenerator
}
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
+ cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget);
+ cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
if(!pcli)
{
continue;
@@ -3055,7 +3086,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
}
std::vector<cmSourceFile*> classes;
- if (!cmtarget.GetConfigCommonSourceFiles(classes))
+ cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+ if (!gtgt->GetConfigCommonSourceFiles(classes))
{
return false;
}
@@ -3593,6 +3625,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
{
cmXCodeObject* target = *i;
cmTarget* t =target->GetTarget();
+ cmGeneratorTarget *gt = this->GetGeneratorTarget(t);
if(t->GetType() == cmTarget::EXECUTABLE ||
// Nope - no post-build for OBJECT_LIRBRARY
@@ -3610,7 +3643,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
t->GetType() == cmTarget::SHARED_LIBRARY ||
t->GetType() == cmTarget::MODULE_LIBRARY)
{
- std::string tfull = t->GetFullPath(configName);
+ std::string tfull = gt->GetFullPath(configName);
std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
// Add this target to the post-build phases of its dependencies.
@@ -3661,7 +3694,7 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::string universalFile = universal;
universalFile += *arch;
universalFile += "/";
- universalFile += t->GetFullName(configName);
+ universalFile += gt->GetFullName(configName);
makefileStream << "\t/bin/rm -f "
<<
this->ConvertToRelativeForMake(universalFile.c_str())
@@ -3804,33 +3837,13 @@ void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
{
- if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
- else
- {
- std::string ret =
- this->CurrentLocalGenerator->
- ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
- return cmSystemTools::ConvertToOutputPath(ret.c_str());
- }
+ return cmSystemTools::ConvertToOutputPath(p);
}
//----------------------------------------------------------------------------
std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
{
- if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
- else
- {
- std::string ret =
- this->CurrentLocalGenerator->
- ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
- return cmSystemTools::ConvertToOutputPath(ret.c_str());
- }
+ return cmSystemTools::ConvertToOutputPath(p);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index c36e4af..102c036 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -41,8 +41,7 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
///! Create a local generator appropriate to this Global Generator
- virtual cmLocalGenerator *CreateLocalGenerator(cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ virtual cmLocalGenerator *CreateLocalGenerator(cmMakefile *mf);
/**
* Try to determine system information such as shared library
@@ -88,6 +87,7 @@ public:
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
void AppendFlag(std::string& flags, std::string const& flag);
protected:
+ virtual bool Compute();
virtual void Generate();
private:
cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 7f4c4c9..2023697 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -48,6 +48,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
,GraphName("GG")
,GraphHeader("node [\n fontsize = \"12\"\n];")
,GraphNodePrefix("node")
+,LocalGenerators(localGenerators)
,GenerateForExecutables(true)
,GenerateForStaticLibs(true)
,GenerateForSharedLibs(true)
@@ -55,7 +56,6 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
,GenerateForExternals(true)
,GeneratePerTarget(true)
,GenerateDependers(true)
-,LocalGenerators(localGenerators)
,HaveTargetsAndLibs(false)
{
}
@@ -68,8 +68,9 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmGlobalGenerator ggi(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(ggi.MakeLocalGenerator());
- cmMakefile *mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(
+ new cmMakefile(&ggi, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator(mf.get()));
const char* inFileName = settingsFileName;
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index a7acd0e..64de684 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -69,14 +69,6 @@ protected:
std::string GraphHeader;
std::string GraphNodePrefix;
- bool GenerateForExecutables;
- bool GenerateForStaticLibs;
- bool GenerateForSharedLibs;
- bool GenerateForModuleLibs;
- bool GenerateForExternals;
- bool GeneratePerTarget;
- bool GenerateDependers;
-
std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
const std::vector<cmLocalGenerator*>& LocalGenerators;
@@ -85,6 +77,13 @@ protected:
// maps from the actual target names to node names in dot:
std::map<std::string, std::string> TargetNamesNodes;
+ bool GenerateForExecutables;
+ bool GenerateForStaticLibs;
+ bool GenerateForSharedLibs;
+ bool GenerateForModuleLibs;
+ bool GenerateForExternals;
+ bool GeneratePerTarget;
+ bool GenerateDependers;
bool HaveTargetsAndLibs;
};
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 3551f83..20448c1 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -27,7 +27,7 @@ static std::string cmIfCommandError(
i != args.end(); ++i)
{
err += " ";
- err += cmLocalGenerator::EscapeForCMake(i->GetValue());
+ err += cmOutputConverter::EscapeForCMake(i->GetValue());
}
err += "\n";
return err;
@@ -92,10 +92,6 @@ IsFunctionBlocked(const cmListFileFunction& lff,
}
else
{
- // Place this call on the call stack.
- cmMakefileCall stack_manager(&mf, this->Functions[c], status);
- static_cast<void>(stack_manager);
-
// if trace is enabled, print the evaluated "elseif" statement
if(mf.GetCMakeInstance()->GetTrace())
{
@@ -119,7 +115,8 @@ IsFunctionBlocked(const cmListFileFunction& lff,
{
std::string err = cmIfCommandError(expandedArguments);
err += errorString;
- mf.IssueMessage(messType, err);
+ cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]);
+ mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
if (messType == cmake::FATAL_ERROR)
{
cmSystemTools::SetFatalErrorOccured();
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index b94ad25..8890e2b 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -125,6 +125,7 @@ bool cmIncludeCommand
return false;
}
}
+ gg->CreateGenerationObjects();
gg->GenerateImportFile(fname_abs);
}
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 899b088..333c2ff 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -27,7 +27,8 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
- return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
+ return new cmInstallTargetGenerator(target.GetName(),
+ args.GetDestination().c_str(),
impLib, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
message,
@@ -41,7 +42,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(mf);
- return new cmInstallFilesGenerator(mf,
+ return new cmInstallFilesGenerator(
absFiles, args.GetDestination().c_str(),
programs, args.GetPermissions().c_str(),
args.GetConfigurations(), args.GetComponent().c_str(),
@@ -752,6 +753,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
installsPublicHeader = installsPublicHeader || publicHeaderGenerator != 0;
installsResource = installsResource || resourceGenerator;
+ if (installsArchive || installsRuntime || installsFramework
+ || installsLibrary || installsBundle)
+ {
+ target.SetHaveInstallRule(true);
+ }
+
this->Makefile->AddInstallGenerator(archiveGenerator);
this->Makefile->AddInstallGenerator(libraryGenerator);
this->Makefile->AddInstallGenerator(runtimeGenerator);
@@ -1399,7 +1406,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
ica.GetDestination().c_str(),
ica.GetPermissions().c_str(), ica.GetConfigurations(),
ica.GetComponent().c_str(), message, fname.c_str(),
- name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
+ name_space.GetCString(), exportOld.IsEnabled());
this->Makefile->AddInstallGenerator(exportGenerator);
return true;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 7f6aa4d..97b9405 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -34,15 +34,14 @@ cmInstallExportGenerator::cmInstallExportGenerator(
const char* component,
MessageLevel message,
const char* filename, const char* name_space,
- bool exportOld,
- cmMakefile* mf)
+ bool exportOld)
:cmInstallGenerator(destination, configurations, component, message)
,ExportSet(exportSet)
,FilePermissions(file_permissions)
,FileName(filename)
,Namespace(name_space)
,ExportOld(exportOld)
- ,Makefile(mf)
+ ,LocalGenerator(0)
{
this->EFGen = new cmExportInstallFileGenerator(this);
exportSet->AddInstallation(this);
@@ -54,12 +53,18 @@ cmInstallExportGenerator::~cmInstallExportGenerator()
delete this->EFGen;
}
+void cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+}
+
//----------------------------------------------------------------------------
void cmInstallExportGenerator::ComputeTempDir()
{
// Choose a temporary directory in which to generate the import
// files to be installed.
- this->TempDir = this->Makefile->GetCurrentBinaryDirectory();
+ this->TempDir =
+ this->LocalGenerator->GetMakefile()->GetCurrentBinaryDirectory();
this->TempDir += cmake::GetCMakeFilesDirectory();
this->TempDir += "/Export";
if(this->Destination.empty())
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 3e078f2..885ed05 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -32,12 +32,14 @@ public:
const char* component,
MessageLevel message,
const char* filename, const char* name_space,
- bool exportOld, cmMakefile* mf);
+ bool exportOld);
~cmInstallExportGenerator();
cmExportSet* GetExportSet() {return this->ExportSet;}
- cmMakefile* GetMakefile() const { return this->Makefile; }
+ void Compute(cmLocalGenerator* lg);
+
+ cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
const std::string& GetNamespace() const { return this->Namespace; }
@@ -57,7 +59,7 @@ protected:
std::string FileName;
std::string Namespace;
bool ExportOld;
- cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
std::string TempDir;
std::string MainImportFile;
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 508c373..68557bd 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -128,7 +128,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
- new cmInstallFilesGenerator(this->Makefile, this->Files,
+ new cmInstallFilesGenerator(this->Files,
destination.c_str(), false,
no_permissions, no_configurations,
no_component.c_str(), message, no_rename));
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 28c27c2..c18b174 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -14,11 +14,11 @@
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
+#include "cmLocalGenerator.h"
//----------------------------------------------------------------------------
cmInstallFilesGenerator
-::cmInstallFilesGenerator(cmMakefile* mf,
- std::vector<std::string> const& files,
+::cmInstallFilesGenerator(std::vector<std::string> const& files,
const char* dest, bool programs,
const char* file_permissions,
std::vector<std::string> const& configurations,
@@ -27,10 +27,12 @@ cmInstallFilesGenerator
const char* rename,
bool optional):
cmInstallGenerator(dest, configurations, component, message),
- Makefile(mf),
- Files(files), Programs(programs),
+ LocalGenerator(0),
+ Files(files),
FilePermissions(file_permissions),
- Rename(rename), Optional(optional)
+ Rename(rename),
+ Programs(programs),
+ Optional(optional)
{
// We need per-config actions if any files have generator expressions.
for(std::vector<std::string>::const_iterator i = files.begin();
@@ -49,6 +51,11 @@ cmInstallFilesGenerator
{
}
+void cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+}
+
//----------------------------------------------------------------------------
void cmInstallFilesGenerator::AddFilesInstallRule(
std::ostream& os, Indent const& indent,
@@ -92,8 +99,8 @@ void cmInstallFilesGenerator::GenerateScriptForConfig(std::ostream& os,
i != this->Files.end(); ++i)
{
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
- cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config),
- files);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(
+ this->LocalGenerator->GetMakefile(), config), files);
}
this->AddFilesInstallRule(os, indent, files);
}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 0dbd712..00b3a79 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -14,16 +14,13 @@
#include "cmInstallGenerator.h"
-class cmMakefile;
-
/** \class cmInstallFilesGenerator
* \brief Generate file installation rules.
*/
class cmInstallFilesGenerator: public cmInstallGenerator
{
public:
- cmInstallFilesGenerator(cmMakefile* mf,
- std::vector<std::string> const& files,
+ cmInstallFilesGenerator(std::vector<std::string> const& files,
const char* dest, bool programs,
const char* file_permissions,
std::vector<std::string> const& configurations,
@@ -33,6 +30,8 @@ public:
bool optional = false);
virtual ~cmInstallFilesGenerator();
+ void Compute(cmLocalGenerator* lg);
+
protected:
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
virtual void GenerateScriptForConfig(std::ostream& os,
@@ -41,11 +40,11 @@ protected:
void AddFilesInstallRule(std::ostream& os, Indent const& indent,
std::vector<std::string> const& files);
- cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
std::vector<std::string> Files;
- bool Programs;
std::string FilePermissions;
std::string Rename;
+ bool Programs;
bool Optional;
};
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index c4191e4..b8e5b53 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -62,6 +62,8 @@ public:
/** Select message level from CMAKE_INSTALL_MESSAGE or 'never'. */
static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
+ virtual void Compute(cmLocalGenerator*) {}
+
protected:
virtual void GenerateScript(std::ostream& os);
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index be8096c..e6fbe88 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -91,7 +91,7 @@ void cmInstallProgramsCommand::FinalPass()
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(this->Makefile);
this->Makefile->AddInstallGenerator(
- new cmInstallFilesGenerator(this->Makefile, this->Files,
+ new cmInstallFilesGenerator(this->Files,
destination.c_str(), true,
no_permissions, no_configurations,
no_component.c_str(), message, no_rename));
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 082a78c..30cf175 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -16,24 +16,30 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
+#include "cmGeneratorTarget.h"
#include <assert.h>
//----------------------------------------------------------------------------
cmInstallTargetGenerator
-::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
+::cmInstallTargetGenerator(const std::string& targetName,
+ const char* dest, bool implib,
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
MessageLevel message,
bool optional):
- cmInstallGenerator(dest, configurations, component, message), Target(&t),
- ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
+ cmInstallGenerator(dest, configurations, component, message),
+ TargetName(targetName),
+ Target(0),
+ FilePermissions(file_permissions),
+ ImportLibrary(implib),
+ Optional(optional)
{
this->ActionsPerConfig = true;
this->NamelinkMode = NamelinkModeNone;
- this->Target->SetHaveInstallRule(true);
}
//----------------------------------------------------------------------------
@@ -69,13 +75,15 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string fromDirConfig;
if(this->Target->NeedRelinkBeforeInstall(config))
{
- fromDirConfig = this->Target->GetMakefile()->GetCurrentBinaryDirectory();
+ fromDirConfig =
+ this->Target->Target->GetMakefile()->GetCurrentBinaryDirectory();
fromDirConfig += cmake::GetCMakeFilesDirectory();
fromDirConfig += "/CMakeRelink.dir/";
}
else
{
- fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+ fromDirConfig =
+ this->Target->Target->GetDirectory(config, this->ImportLibrary);
fromDirConfig += "/";
}
std::string toDir =
@@ -86,7 +94,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::vector<std::string> filesFrom;
std::vector<std::string> filesTo;
std::string literal_args;
- cmTarget::TargetType targetType = this->Target->GetType();
+ cmTarget::TargetType targetType =
+ static_cast<cmTarget::TargetType>(this->Target->GetType());
cmInstallType type = cmInstallType();
switch(targetType)
{
@@ -103,7 +112,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
case cmTarget::UNKNOWN_LIBRARY:
- this->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
+ this->Target->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
"cmInstallTargetGenerator created with non-installable target.");
return;
}
@@ -126,7 +135,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
filesFrom.push_back(from1);
filesTo.push_back(to1);
std::string targetNameImportLib;
- if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ if(this->Target->Target->GetImplibGNUtoMS(targetNameImport,
targetNameImportLib))
{
filesFrom.push_back(fromDirConfig + targetNameImportLib);
@@ -142,7 +151,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string to1 = toDir + targetName;
// Handle OSX Bundles.
- if(this->Target->IsAppBundleOnApple())
+ if(this->Target->Target->IsAppBundleOnApple())
{
// Install the whole app bundle directory.
type = cmInstallType_DIRECTORY;
@@ -176,7 +185,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ this->Target->GetLibraryNames(targetName, targetNameSO,
+ targetNameReal,
targetNameImport, targetNamePDB,
config);
if(this->ImportLibrary)
@@ -189,7 +199,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
filesFrom.push_back(from1);
filesTo.push_back(to1);
std::string targetNameImportLib;
- if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ if(this->Target->Target->GetImplibGNUtoMS(targetNameImport,
targetNameImportLib))
{
filesFrom.push_back(fromDirConfig + targetNameImportLib);
@@ -199,7 +209,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// An import library looks like a static library.
type = cmInstallType_STATIC_LIBRARY;
}
- else if(this->Target->IsFrameworkOnApple())
+ else if(this->Target->Target->IsFrameworkOnApple())
{
// There is a bug in cmInstallCommand if this fails.
assert(this->NamelinkMode == NamelinkModeNone);
@@ -217,7 +227,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
filesFrom.push_back(from1);
filesTo.push_back(to1);
}
- else if(this->Target->IsCFBundleOnApple())
+ else if(this->Target->Target->IsCFBundleOnApple())
{
// Install the whole app bundle directory.
type = cmInstallType_DIRECTORY;
@@ -341,7 +351,7 @@ cmInstallTargetGenerator::GetDestination(std::string const& config) const
{
cmGeneratorExpression ge;
return ge.Parse(this->Destination)
- ->Evaluate(this->Target->GetMakefile(), config);
+ ->Evaluate(this->Target->Target->GetMakefile(), config);
}
//----------------------------------------------------------------------------
@@ -350,7 +360,7 @@ cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const
{
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
return
- cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
+ cmInstallTargetGenerator::GetInstallFilename(this->Target->Target, config,
nameType);
}
@@ -362,13 +372,16 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
{
std::string fname;
// Compute the name of the library.
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
if(target->GetType() == cmTarget::EXECUTABLE)
{
std::string targetName;
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- target->GetExecutableNames(targetName, targetNameReal,
+ gtgt->GetExecutableNames(targetName, targetNameReal,
targetNameImport, targetNamePDB,
config);
if(nameType == NameImplib)
@@ -398,7 +411,7 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ gtgt->GetLibraryNames(targetName, targetNameSO, targetNameReal,
targetNameImport, targetNamePDB, config);
if(nameType == NameImplib)
{
@@ -429,6 +442,12 @@ cmInstallTargetGenerator::GetInstallFilename(cmTarget const* target,
return fname;
}
+void cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->Target = lg->GetGlobalGenerator()->GetGeneratorTarget(
+ lg->GetMakefile()->FindTarget(this->TargetName));
+}
+
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
@@ -531,8 +550,8 @@ cmInstallTargetGenerator
}
// Fix the install_name settings in installed binaries.
- std::string installNameTool =
- this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+ std::string installNameTool = this->Target->Target->GetMakefile()
+ ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
if(installNameTool.empty())
{
@@ -557,11 +576,14 @@ cmInstallTargetGenerator
continue;
}
+ cmGeneratorTarget *gtgt = tgt->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(tgt);
// If the build tree and install tree use different path
// components of the install_name field then we need to create a
// mapping to be applied after installation.
- std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
- std::string for_install = tgt->GetInstallNameDirForInstallTree();
+ std::string for_build = gtgt->GetInstallNameDirForBuildTree(config);
+ std::string for_install = gtgt->GetInstallNameDirForInstallTree();
if(for_build != for_install)
{
// The directory portions differ. Append the filename to
@@ -590,7 +612,7 @@ cmInstallTargetGenerator
std::string for_install =
this->Target->GetInstallNameDirForInstallTree();
- if(this->Target->IsFrameworkOnApple() && for_install.empty())
+ if(this->Target->Target->IsFrameworkOnApple() && for_install.empty())
{
// Frameworks seem to have an id corresponding to their own full
// path.
@@ -604,7 +626,7 @@ cmInstallTargetGenerator
{
// Prepare to refer to the install-tree install_name.
new_id = for_install;
- new_id += this->GetInstallFilename(this->Target, config, NameSO);
+ new_id += this->GetInstallFilename(this->Target->Target, config, NameSO);
}
}
@@ -641,9 +663,9 @@ cmInstallTargetGenerator
{
return;
}
-
// Skip if on Apple
- if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ if(this->Target->Target->GetMakefile()
+ ->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
return;
}
@@ -688,7 +710,7 @@ cmInstallTargetGenerator
return;
}
- cmMakefile* mf = this->Target->GetMakefile();
+ cmMakefile* mf = this->Target->Target->GetMakefile();
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{
@@ -800,20 +822,20 @@ cmInstallTargetGenerator::AddStripRule(std::ostream& os,
}
// Don't handle OSX Bundles.
- if(this->Target->GetMakefile()->IsOn("APPLE") &&
- this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
+ if(this->Target->Target->GetMakefile()->IsOn("APPLE") &&
+ this->Target->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
{
return;
}
- if(! this->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
+ if(! this->Target->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
{
return;
}
os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n";
os << indent << " execute_process(COMMAND \""
- << this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
+ << this->Target->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
<< "\" \"" << toDestDirPath << "\")\n";
os << indent << "endif()\n";
}
@@ -832,13 +854,13 @@ cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
// Perform post-installation processing on the file depending
// on its type.
- if(!this->Target->GetMakefile()->IsOn("APPLE"))
+ if(!this->Target->Target->GetMakefile()->IsOn("APPLE"))
{
return;
}
std::string ranlib =
- this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
+ this->Target->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
if(ranlib.empty())
{
return;
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 075c8a4..a8f4a75 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -13,8 +13,9 @@
#define cmInstallTargetGenerator_h
#include "cmInstallGenerator.h"
-#include "cmTarget.h"
-#include "cmGeneratorTarget.h"
+
+class cmTarget;
+class cmGeneratorTarget;
/** \class cmInstallTargetGenerator
* \brief Generate target installation rules.
@@ -23,7 +24,7 @@ class cmInstallTargetGenerator: public cmInstallGenerator
{
public:
cmInstallTargetGenerator(
- cmTarget& t, const char* dest, bool implib,
+ std::string const& targetName, const char* dest, bool implib,
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
@@ -57,7 +58,10 @@ public:
const std::string& config,
NameType nameType = NameNormal);
- cmTarget* GetTarget() const { return this->Target; }
+ void Compute(cmLocalGenerator* lg);
+
+ cmGeneratorTarget* GetTarget() const { return this->Target; }
+
bool IsImportLibrary() const { return this->ImportLibrary; }
std::string GetDestination(std::string const& config) const;
@@ -99,12 +103,12 @@ protected:
void AddRanlibRule(std::ostream& os, Indent const& indent,
const std::string& toDestDirPath);
- cmTarget* Target;
- bool ImportLibrary;
+ std::string TargetName;
+ cmGeneratorTarget* Target;
std::string FilePermissions;
- bool Optional;
NamelinkModeType NamelinkMode;
- cmGeneratorTarget* GeneratorTarget;
+ bool ImportLibrary;
+ bool Optional;
};
#endif
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 8c52b48..fa5e815 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -44,7 +44,7 @@ cmInstalledFile::Property::~Property()
void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(&backtrace);
+ cmGeneratorExpression ge(backtrace);
this->Name = name;
this->NameExpression = ge.Parse(name).release();
@@ -81,7 +81,7 @@ void cmInstalledFile::AppendProperty(cmMakefile const* mf,
const std::string& prop, const char* value, bool /*asString*/)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
- cmGeneratorExpression ge(&backtrace);
+ cmGeneratorExpression ge(backtrace);
Property& property = this->Properties[prop];
property.ValueExpressions.push_back(ge.Parse(value).release());
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index f486bf7..b6c0072 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -65,5 +65,5 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir)
unixPath = tmp;
}
}
- this->Makefile->AddLinkDirectory(unixPath);
+ this->Makefile->AppendProperty("LINK_DIRECTORIES", unixPath.c_str());
}
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
new file mode 100644
index 0000000..10dd465
--- /dev/null
+++ b/Source/cmLinkItem.h
@@ -0,0 +1,121 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2015 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 cmLinkItem_h
+#define cmLinkItem_h
+
+#include "cmListFileCache.h"
+
+class cmTarget;
+
+// Basic information about each link item.
+class cmLinkItem: public std::string
+{
+ typedef std::string std_string;
+public:
+ cmLinkItem(): std_string(), Target(0) {}
+ cmLinkItem(const std_string& n,
+ cmTarget const* t): std_string(n), Target(t) {}
+ cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
+ cmTarget const* Target;
+};
+
+class cmLinkImplItem: public cmLinkItem
+{
+public:
+ cmLinkImplItem(): cmLinkItem(), Backtrace(), FromGenex(false) {}
+ cmLinkImplItem(std::string const& n,
+ cmTarget const* t,
+ cmListFileBacktrace const& bt,
+ bool fromGenex):
+ cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
+ cmLinkImplItem(cmLinkImplItem const& r):
+ cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
+ cmListFileBacktrace Backtrace;
+ bool FromGenex;
+};
+
+/** The link implementation specifies the direct library
+ dependencies needed by the object files of the target. */
+struct cmLinkImplementationLibraries
+{
+ // Libraries linked directly in this configuration.
+ std::vector<cmLinkImplItem> Libraries;
+
+ // Libraries linked directly in other configurations.
+ // Needed only for OLD behavior of CMP0003.
+ std::vector<cmLinkItem> WrongConfigLibraries;
+};
+
+struct cmLinkInterfaceLibraries
+{
+ // Libraries listed in the interface.
+ std::vector<cmLinkItem> Libraries;
+};
+
+struct cmLinkInterface: public cmLinkInterfaceLibraries
+{
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+
+ // Shared library dependencies needed for linking on some platforms.
+ std::vector<cmLinkItem> SharedDeps;
+
+ // Number of repetitions of a strongly connected component of two
+ // or more static libraries.
+ int Multiplicity;
+
+ // Libraries listed for other configurations.
+ // Needed only for OLD behavior of CMP0003.
+ std::vector<cmLinkItem> WrongConfigLibraries;
+
+ bool ImplementationIsInterface;
+
+ cmLinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
+};
+
+struct cmOptionalLinkInterface: public cmLinkInterface
+{
+ cmOptionalLinkInterface():
+ LibrariesDone(false), AllDone(false),
+ Exists(false), HadHeadSensitiveCondition(false),
+ ExplicitLibraries(0) {}
+ bool LibrariesDone;
+ bool AllDone;
+ bool Exists;
+ bool HadHeadSensitiveCondition;
+ const char* ExplicitLibraries;
+};
+
+struct cmHeadToLinkInterfaceMap:
+ public std::map<cmTarget const*, cmOptionalLinkInterface>
+{
+};
+
+struct cmLinkImplementation: public cmLinkImplementationLibraries
+{
+ // Languages whose runtime libraries must be linked.
+ std::vector<std::string> Languages;
+};
+
+// Cache link implementation computation from each configuration.
+struct cmOptionalLinkImplementation: public cmLinkImplementation
+{
+ cmOptionalLinkImplementation():
+ LibrariesDone(false), LanguagesDone(false),
+ HadHeadSensitiveCondition(false) {}
+ bool LibrariesDone;
+ bool LanguagesDone;
+ bool HadHeadSensitiveCondition;
+};
+
+#endif
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
new file mode 100644
index 0000000..721a246
--- /dev/null
+++ b/Source/cmLinkedTree.h
@@ -0,0 +1,195 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 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 cmLinkedTree_h
+#define cmLinkedTree_h
+
+#include "cmStandardIncludes.h"
+
+#include <assert.h>
+
+/**
+ @brief A adaptor for traversing a tree structure in a vector
+
+ This class is not intended to be wholly generic like a standard library
+ container adaptor. Mostly it exists to facilitate code sharing for the
+ needs of the cmState. For example, the Truncate() method is a specific
+ requirement of the cmState.
+
+ An empty cmLinkedTree provides a Root() method, and an Extend() method,
+ each of which return iterators. A Tree can be built up by extending
+ from the root, and then extending from any other iterator.
+
+ An iterator resulting from this tree construction can be
+ forward-only-iterated toward the root. Extending the tree never
+ invalidates existing iterators.
+ */
+template<typename T>
+class cmLinkedTree
+{
+ typedef typename std::vector<T>::size_type PositionType;
+ typedef T* PointerType;
+ typedef T& ReferenceType;
+public:
+ class iterator : public std::iterator<std::forward_iterator_tag, T>
+ {
+ friend class cmLinkedTree;
+ cmLinkedTree* Tree;
+
+ // The Position is always 'one past the end'.
+ PositionType Position;
+
+ iterator(cmLinkedTree* tree, PositionType pos)
+ : Tree(tree), Position(pos)
+ {
+
+ }
+
+ public:
+ iterator()
+ : Tree(0), Position(0)
+ {
+
+ }
+
+ void operator++()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ this->Position = this->Tree->UpPositions[this->Position - 1];
+ }
+
+ PointerType operator->() const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ PointerType operator->()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetPointer(this->Position - 1);
+ }
+
+ ReferenceType operator*() const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetReference(this->Position - 1);
+ }
+
+ ReferenceType operator*()
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Position <= this->Tree->Data.size());
+ assert(this->Position > 0);
+ return this->Tree->GetReference(this->Position - 1);
+ }
+
+ bool operator==(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ assert(this->Tree == other.Tree);
+ return this->Position == other.Position;
+ }
+
+ bool operator!=(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree->UpPositions.size() == this->Tree->Data.size());
+ return !(*this == other);
+ }
+
+ bool IsValid() const
+ {
+ if (!this->Tree)
+ {
+ return false;
+ }
+ return this->Position <= this->Tree->Data.size();
+ }
+
+ bool StrictWeakOrdered(iterator other) const
+ {
+ assert(this->Tree);
+ assert(this->Tree == other.Tree);
+ return this->Position < other.Position;
+ }
+ };
+
+ iterator Root() const
+ {
+ return iterator(const_cast<cmLinkedTree*>(this), 0);
+ }
+
+ iterator Extend(iterator it)
+ {
+ return Extend_impl(it, T());
+ }
+
+ iterator Extend(iterator it, T t)
+ {
+ return Extend_impl(it, t);
+ }
+
+ iterator Truncate()
+ {
+ assert(this->UpPositions.size() > 0);
+ this->UpPositions.erase(this->UpPositions.begin() + 1,
+ this->UpPositions.end());
+ assert(this->Data.size() > 0);
+ this->Data.erase(this->Data.begin() + 1, this->Data.end());
+ return iterator(this, 1);
+ }
+
+ void Clear()
+ {
+ this->UpPositions.clear();
+ this->Data.clear();
+ }
+
+private:
+ T& GetReference(PositionType pos)
+ {
+ return this->Data[pos];
+ }
+
+ T* GetPointer(PositionType pos)
+ {
+ return &this->Data[pos];
+ }
+
+ iterator Extend_impl(iterator it, T t)
+ {
+ assert(this->UpPositions.size() == this->Data.size());
+ assert(it.Position <= this->UpPositions.size());
+ this->UpPositions.push_back(it.Position);
+ this->Data.push_back(t);
+ return iterator(this, this->UpPositions.size());
+ }
+
+ std::vector<T> Data;
+ std::vector<PositionType> UpPositions;
+};
+
+#endif
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index f96b4a8..6041fb7 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -247,7 +247,7 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
{
listString += ";";
}
- listString += cmJoin(cmRange(args).advance(2), ";");
+ listString += cmJoin(cmMakeRange(args).advance(2), ";");
this->Makefile->AddDefinition(listName, listString.c_str());
return true;
@@ -361,9 +361,9 @@ bool cmListCommand
std::vector<std::string>::const_iterator remBegin = remove.begin();
std::vector<std::string>::const_iterator argsEnd =
- cmRemoveMatching(varArgsExpanded, cmRange(remBegin, remEnd));
+ cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
- std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
this->Makefile->AddDefinition(listName, value.c_str());
return true;
}
@@ -421,7 +421,7 @@ bool cmListCommand
cmRemoveDuplicates(varArgsExpanded);
std::vector<std::string>::const_iterator argsBegin =
varArgsExpanded.begin();
- std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
this->Makefile->AddDefinition(listName, value.c_str());
return true;
@@ -509,9 +509,9 @@ bool cmListCommand::HandleRemoveAtCommand(
std::vector<size_t>::const_iterator remBegin = removed.begin();
std::vector<std::string>::const_iterator argsEnd =
- cmRemoveIndices(varArgsExpanded, cmRange(remBegin, remEnd));
+ cmRemoveIndices(varArgsExpanded, cmMakeRange(remBegin, remEnd));
std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
- std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";");
+ std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
this->Makefile->AddDefinition(listName, value.c_str());
return true;
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 2756cd2..bff2986 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -234,8 +234,7 @@ bool cmListFile::ParseFile(const char* filename,
{
cmListFileFunction project;
project.Name = "PROJECT";
- cmListFileArgument prj("Project", cmListFileArgument::Unquoted,
- filename, 0);
+ cmListFileArgument prj("Project", cmListFileArgument::Unquoted, 0);
project.Arguments.push_back(prj);
this->Functions.insert(this->Functions.begin(),project);
}
@@ -252,7 +251,6 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
{
// Inintialize a new function call.
this->Function = cmListFileFunction();
- this->Function.FilePath = this->FileName;
this->Function.Name = name;
this->Function.Line = line;
@@ -375,7 +373,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim)
{
- cmListFileArgument a(token->text, delim, this->FileName, token->line);
+ cmListFileArgument a(token->text, delim, token->line);
this->Function.Arguments.push_back(a);
if(this->Separation == SeparationOkay)
{
@@ -400,50 +398,50 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
}
}
-void cmListFileBacktrace::Append(cmListFileContext const& context)
+void cmListFileBacktrace::PrintTitle(std::ostream& out) const
{
- this->push_back(context);
-}
-
-//----------------------------------------------------------------------------
-void cmListFileBacktrace::MakeRelative()
-{
- if (this->Relative)
+ if (!this->Snapshot.IsValid())
{
return;
}
- for (cmListFileBacktrace::iterator i = this->begin();
- i != this->end(); ++i)
- {
- i->FilePath = this->LocalGenerator->Convert(i->FilePath,
- cmLocalGenerator::HOME);
- }
- this->Relative = true;
+ cmOutputConverter converter(this->Snapshot);
+ cmListFileContext lfc =
+ cmListFileContext::FromCommandContext(
+ this->Context, this->Snapshot.GetExecutionListFile());
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+ out << (lfc.Line ? " at " : " in ") << lfc;
}
-void cmListFileBacktrace::PrintTitle(std::ostream& out)
+void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
{
- if (this->empty())
+ if (!this->Snapshot.IsValid())
{
return;
}
- out << (this->front().Line ? " at " : " in ") << this->front();
-}
-
-void cmListFileBacktrace::PrintCallStack(std::ostream& out)
-{
- if (size() <= 1)
+ cmState::Snapshot parent = this->Snapshot.GetCallStackParent();
+ if (!parent.IsValid() || parent.GetExecutionListFile().empty())
{
return;
}
- const_iterator i = this->begin() + 1;
+ cmOutputConverter converter(this->Snapshot);
+ std::string commandName = this->Snapshot.GetEntryPointCommand();
+ long commandLine = this->Snapshot.GetEntryPointLine();
+
out << "Call Stack (most recent call first):\n";
- while(i != this->end())
+ while(parent.IsValid())
{
- cmListFileContext const& lfc = *i;
+ cmListFileContext lfc;
+ lfc.Name = commandName;
+ lfc.Line = commandLine;
+
+ lfc.FilePath = converter.Convert(parent.GetExecutionListFile(),
+ cmOutputConverter::HOME);
out << " " << lfc << "\n";
- ++i;
+
+ commandName = parent.GetEntryPointCommand();
+ commandLine = parent.GetEntryPointLine();
+ parent = parent.GetCallStackParent();
}
}
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 4a1d181..0afd7f5 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -14,7 +14,7 @@
#include "cmStandardIncludes.h"
-class cmLocalGenerator;
+#include "cmState.h"
/** \class cmListFileCache
* \brief A class to cache list file contents.
@@ -25,6 +25,13 @@ class cmLocalGenerator;
class cmMakefile;
+struct cmCommandContext
+{
+ std::string Name;
+ long Line;
+ cmCommandContext(): Name(), Line(0) {}
+};
+
struct cmListFileArgument
{
enum Delimiter
@@ -33,12 +40,11 @@ struct cmListFileArgument
Quoted,
Bracket
};
- cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {}
- cmListFileArgument(const cmListFileArgument& r):
- Value(r.Value), Delim(r.Delim), FilePath(r.FilePath), Line(r.Line) {}
- cmListFileArgument(const std::string& v, Delimiter d, const char* file,
- long line): Value(v), Delim(d),
- FilePath(file), Line(line) {}
+ cmListFileArgument(): Value(), Delim(Unquoted), Line(0) {}
+ cmListFileArgument(const cmListFileArgument& r)
+ : Value(r.Value), Delim(r.Delim), Line(r.Line) {}
+ cmListFileArgument(const std::string& v, Delimiter d, long line)
+ : Value(v), Delim(d), Line(line) {}
bool operator == (const cmListFileArgument& r) const
{
return (this->Value == r.Value) && (this->Delim == r.Delim);
@@ -49,7 +55,6 @@ struct cmListFileArgument
}
std::string Value;
Delimiter Delim;
- const char* FilePath;
long Line;
};
@@ -59,6 +64,16 @@ struct cmListFileContext
std::string FilePath;
long Line;
cmListFileContext(): Name(), FilePath(), Line(0) {}
+
+ static cmListFileContext FromCommandContext(cmCommandContext const& lfcc,
+ std::string const& fileName)
+ {
+ cmListFileContext lfc;
+ lfc.FilePath = fileName;
+ lfc.Line = lfcc.Line;
+ lfc.Name = lfcc.Name;
+ return lfc;
+ }
};
std::ostream& operator<<(std::ostream&, cmListFileContext const&);
@@ -66,29 +81,25 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
-struct cmListFileFunction: public cmListFileContext
+struct cmListFileFunction: public cmCommandContext
{
std::vector<cmListFileArgument> Arguments;
};
-class cmListFileBacktrace: private std::vector<cmListFileContext>
+class cmListFileBacktrace
{
public:
- cmListFileBacktrace(cmLocalGenerator* localGen)
- : LocalGenerator(localGen)
- , Relative(localGen ? false : true)
+ cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(),
+ cmCommandContext const& cc = cmCommandContext())
+ : Context(cc), Snapshot(snapshot)
{
}
- void Append(cmListFileContext const& context);
-
- void MakeRelative();
-
- void PrintTitle(std::ostream& out);
- void PrintCallStack(std::ostream& out);
+ void PrintTitle(std::ostream& out) const;
+ void PrintCallStack(std::ostream& out) const;
private:
- cmLocalGenerator* LocalGenerator;
- bool Relative;
+ cmCommandContext Context;
+ cmState::Snapshot Snapshot;
};
struct cmListFile
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
new file mode 100644
index 0000000..5a18e2f
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -0,0 +1,39 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 "cmLocalCommonGenerator.h"
+
+#include "cmMakefile.h"
+
+cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf):
+ cmLocalGenerator(gg, mf)
+{
+}
+
+cmLocalCommonGenerator::~cmLocalCommonGenerator()
+{
+}
+
+void cmLocalCommonGenerator::SetConfigName()
+{
+ // Store the configuration name that will be generated.
+ if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
+ {
+ // Use the build type given by the user.
+ this->ConfigName = config;
+ }
+ else
+ {
+ // No configuration type given.
+ this->ConfigName = "";
+ }
+}
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
new file mode 100644
index 0000000..6b4b1cd
--- /dev/null
+++ b/Source/cmLocalCommonGenerator.h
@@ -0,0 +1,37 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2015 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 cmLocalCommonGenerator_h
+#define cmLocalCommonGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmCommonTargetGenerator;
+
+/** \class cmLocalCommonGenerator
+ * \brief Common infrastructure for Makefile and Ninja local generators.
+ */
+class cmLocalCommonGenerator: public cmLocalGenerator
+{
+public:
+ cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
+ ~cmLocalCommonGenerator();
+
+ std::string const& GetConfigName() { return this->ConfigName; }
+
+protected:
+ void SetConfigName();
+ std::string ConfigName;
+
+ friend class cmCommonTargetGenerator;
+};
+
+#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index eb6b871..b360c22 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h"
#include "cmInstallFilesGenerator.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmMakefile.h"
@@ -32,8 +33,6 @@
# include <cmsys/MD5.h>
#endif
-#include <cmsys/System.h>
-
#include <ctype.h> // for isalpha
#include <assert.h>
@@ -44,23 +43,14 @@
#endif
cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : StateSnapshot(snapshot)
+ cmMakefile* makefile)
+ : cmOutputConverter(makefile->GetStateSnapshot()),
+ StateSnapshot(makefile->GetStateSnapshot())
{
- assert(snapshot.IsValid());
this->GlobalGenerator = gg;
- this->Parent = parent;
- if (parent)
- {
- parent->AddChild(this);
- }
- this->Makefile = new cmMakefile(this);
+ this->Makefile = makefile;
- this->LinkScriptShell = false;
- this->UseRelativePaths = false;
- this->Configured = false;
this->EmitUniversalBinaryFlags = true;
this->BackwardsCompatibility = 0;
this->BackwardsCompatibilityFinal = false;
@@ -68,82 +58,22 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
cmLocalGenerator::~cmLocalGenerator()
{
- delete this->Makefile;
}
-bool cmLocalGenerator::IsRootMakefile() const
+void cmLocalGenerator::IssueMessage(cmake::MessageType t,
+ std::string const& text) const
{
- return !this->StateSnapshot.GetParent().IsValid();
-}
+ cmListFileContext lfc;
+ lfc.FilePath = this->StateSnapshot.GetDirectory().GetCurrentSource();
+ lfc.FilePath += "/CMakeLists.txt";
-//----------------------------------------------------------------------------
-class cmLocalGeneratorCurrent
-{
- cmGlobalGenerator* GG;
- cmLocalGenerator* LG;
- cmState::Snapshot Snapshot;
-public:
- cmLocalGeneratorCurrent(cmLocalGenerator* lg)
- {
- this->GG = lg->GetGlobalGenerator();
- this->LG = this->GG->GetCurrentLocalGenerator();
- this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
- this->GG->GetCMakeInstance()->SetCurrentSnapshot(lg->GetStateSnapshot());
- this->GG->SetCurrentLocalGenerator(lg);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- this->GG->GetFileLockPool().PushFileScope();
-#endif
- }
- ~cmLocalGeneratorCurrent()
+ if(!this->GlobalGenerator->GetCMakeInstance()->GetIsInTryCompile())
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- this->GG->GetFileLockPool().PopFileScope();
-#endif
- this->GG->SetCurrentLocalGenerator(this->LG);
- this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmLocalGenerator::HOME);
}
-};
-
-//----------------------------------------------------------------------------
-void cmLocalGenerator::Configure()
-{
- // Manage the global generator's current local generator.
- cmLocalGeneratorCurrent clg(this);
- static_cast<void>(clg);
-
- // make sure the CMakeFiles dir is there
- std::string filesDir = this->StateSnapshot.GetCurrentBinaryDirectory();
- filesDir += cmake::GetCMakeFilesDirectory();
- cmSystemTools::MakeDirectory(filesDir.c_str());
-
- std::string currentStart = this->StateSnapshot.GetCurrentSourceDirectory();
- currentStart += "/CMakeLists.txt";
- assert(cmSystemTools::FileExists(currentStart.c_str(), true));
- this->Makefile->ProcessBuildsystemFile(currentStart.c_str());
-
- // at the end of the ReadListFile handle any old style subdirs
- // first get all the subdirectories
- std::vector<cmLocalGenerator *> subdirs = this->GetChildren();
-
- // for each subdir recurse
- std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
- for (; sdi != subdirs.end(); ++sdi)
- {
- if (!(*sdi)->Configured)
- {
- this->Makefile->ConfigureSubDirectory(*sdi);
- }
- }
-
- this->Makefile->AddCMakeDependFilesFromUser();
-
- // Check whether relative paths should be used for optionally
- // relative paths.
- this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
-
- this->ComputeObjectMaxPath();
-
- this->Configured = true;
+ lfc.Line = 0;
+ this->GlobalGenerator->GetCMakeInstance()->IssueMessage(t, text, lfc);
}
//----------------------------------------------------------------------------
@@ -171,7 +101,7 @@ void cmLocalGenerator::ComputeObjectMaxPath()
w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
<< ", which is less than the minimum of 128. "
<< "The value will be ignored.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
}
else
@@ -180,17 +110,12 @@ void cmLocalGenerator::ComputeObjectMaxPath()
w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen
<< "\", which fails to parse as a positive integer. "
<< "The value will be ignored.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
}
}
this->ObjectMaxPathViolations.clear();
}
-void cmLocalGenerator::ConfigureFinalPass()
-{
- this->Makefile->ConfigureFinalPass();
-}
-
void cmLocalGenerator::TraceDependencies()
{
std::vector<std::string> configs;
@@ -230,7 +155,8 @@ void cmLocalGenerator::GenerateTestFiles()
const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
- std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+ std::string file =
+ this->StateSnapshot.GetDirectory().GetCurrentBinary();
file += "/";
file += "CTestTestfile.cmake";
@@ -239,9 +165,11 @@ void cmLocalGenerator::GenerateTestFiles()
fout << "# CMake generated Testfile for " << std::endl
<< "# Source directory: "
- << this->StateSnapshot.GetCurrentSourceDirectory() << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << std::endl
<< "# Build directory: "
- << this->StateSnapshot.GetCurrentBinaryDirectory() << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+ << std::endl
<< "# " << std::endl
<< "# This file includes the relevant testing commands "
<< "required for " << std::endl
@@ -261,20 +189,66 @@ void cmLocalGenerator::GenerateTestFiles()
for(std::vector<cmTestGenerator*>::const_iterator gi = testers.begin();
gi != testers.end(); ++gi)
{
+ (*gi)->Compute(this);
(*gi)->Generate(fout, config, configurationTypes);
}
- if (!this->Children.empty())
+ size_t i;
+ std::vector<cmState::Snapshot> children
+ = this->Makefile->GetStateSnapshot().GetChildren();
+ for(i = 0; i < children.size(); ++i)
+ {
+ // TODO: Use add_subdirectory instead?
+ fout << "subdirs(";
+ std::string outP = children[i].GetDirectory().GetCurrentBinary();
+ fout << this->Convert(outP,START_OUTPUT);
+ fout << ")" << std::endl;
+ }
+}
+
+void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
+{
+ std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+ this->Makefile->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin(); li != ef.end(); ++li)
+ {
+ (*li)->CreateOutputFile(this, config);
+ }
+}
+
+void cmLocalGenerator::ProcessEvaluationFiles(
+ std::vector<std::string>& generatedFiles)
+{
+ std::vector<cmGeneratorExpressionEvaluationFile*> ef =
+ this->Makefile->GetEvaluationFiles();
+ for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
+ li = ef.begin();
+ li != ef.end();
+ ++li)
{
- size_t i;
- for(i = 0; i < this->Children.size(); ++i)
+ (*li)->Generate(this);
+ if (cmSystemTools::GetFatalErrorOccured())
+ {
+ return;
+ }
+ std::vector<std::string> files = (*li)->GetFiles();
+ std::sort(files.begin(), files.end());
+
+ std::vector<std::string> intersection;
+ std::set_intersection(files.begin(), files.end(),
+ generatedFiles.begin(), generatedFiles.end(),
+ std::back_inserter(intersection));
+ if (!intersection.empty())
{
- // TODO: Use add_subdirectory instead?
- fout << "subdirs(";
- std::string outP =
- this->Children[i]->GetMakefile()->GetCurrentBinaryDirectory();
- fout << this->Convert(outP,START_OUTPUT);
- fout << ")" << std::endl;
+ cmSystemTools::Error("Files to be generated by multiple different "
+ "commands: ", cmWrap('"', intersection, '"', " ").c_str());
+ return;
}
+
+ generatedFiles.insert(generatedFiles.end(), files.begin(), files.end());
+ std::vector<std::string>::iterator newIt =
+ generatedFiles.end() - files.size();
+ std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end());
}
}
@@ -355,7 +329,8 @@ void cmLocalGenerator::GenerateInstallRules()
}
// Create the install script file.
- std::string file = this->StateSnapshot.GetCurrentBinaryDirectory();
+ std::string file =
+ this->StateSnapshot.GetDirectory().GetCurrentBinary();
std::string homedir = this->GetState()->GetBinaryDirectory();
int toplevel_install = 0;
if (file == homedir)
@@ -368,7 +343,7 @@ void cmLocalGenerator::GenerateInstallRules()
// Write the header.
fout << "# Install script for directory: "
- << this->StateSnapshot.GetCurrentSourceDirectory()
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
<< std::endl << std::endl;
fout << "# Set the install prefix" << std::endl
<< "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
@@ -432,16 +407,18 @@ void cmLocalGenerator::GenerateInstallRules()
this->GenerateTargetInstallRules(fout, config, configurationTypes);
// Include install scripts from subdirectories.
- if(!this->Children.empty())
+ std::vector<cmState::Snapshot> children
+ = this->Makefile->GetStateSnapshot().GetChildren();
+ if(!children.empty())
{
fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n";
fout << " # Include the install script for each subdirectory.\n";
- for(std::vector<cmLocalGenerator*>::const_iterator
- ci = this->Children.begin(); ci != this->Children.end(); ++ci)
+ for(std::vector<cmState::Snapshot>::const_iterator
+ ci = children.begin(); ci != children.end(); ++ci)
{
- if(!(*ci)->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ if(!ci->GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
- std::string odir = (*ci)->GetMakefile()->GetCurrentBinaryDirectory();
+ std::string odir = ci->GetDirectory().GetCurrentBinary();
cmSystemTools::ConvertToUnixSlashes(odir);
fout << " include(\"" << odir
<< "/cmake_install.cmake\")" << std::endl;
@@ -470,7 +447,7 @@ void cmLocalGenerator::GenerateInstallRules()
}
//----------------------------------------------------------------------------
-void cmLocalGenerator::GenerateTargetManifest()
+void cmLocalGenerator::ComputeTargetManifest()
{
// Collect the set of configuration types.
std::vector<std::string> configNames;
@@ -498,7 +475,7 @@ void cmLocalGenerator::GenerateTargetManifest()
ci != configNames.end(); ++ci)
{
const char* config = ci->c_str();
- target.GenerateTargetManifest(config);
+ target.ComputeTargetManifest(config);
}
}
}
@@ -513,225 +490,6 @@ cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
return this->StateSnapshot;
}
-void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
- const std::string& lang,
- cmSourceFile& source,
- cmGeneratorTarget& target)
-{
- std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname));
- objectDir = this->Convert(objectDir,START_OUTPUT,SHELL);
- std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL);
- std::string sourceFile =
- this->Convert(source.GetFullPath(),START_OUTPUT,SHELL,true);
- std::string varString = "CMAKE_";
- varString += lang;
- varString += "_COMPILE_OBJECT";
- std::vector<std::string> rules;
- rules.push_back(this->Makefile->GetRequiredDefinition(varString));
- varString = "CMAKE_";
- varString += lang;
- varString += "_FLAGS";
- std::string flags;
- flags += this->Makefile->GetSafeDefinition(varString);
- flags += " ";
- {
- std::vector<std::string> includes;
- this->GetIncludeDirectories(includes, &target, lang);
- flags += this->GetIncludeFlags(includes, &target, lang);
- }
- flags += this->Makefile->GetDefineFlags();
-
- // Construct the command lines.
- cmCustomCommandLines commandLines;
- std::vector<std::string> commands;
- cmSystemTools::ExpandList(rules, commands);
- cmLocalGenerator::RuleVariables vars;
- vars.Language = lang.c_str();
- vars.Source = sourceFile.c_str();
- vars.Object = objectFile.c_str();
- vars.ObjectDir = objectDir.c_str();
- vars.Flags = flags.c_str();
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- // Expand the full command line string.
- this->ExpandRuleVariables(*i, vars);
-
- // Parse the string to get the custom command line.
- cmCustomCommandLine commandLine;
- std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str());
- commandLine.insert(commandLine.end(), cmd.begin(), cmd.end());
-
- // Store this command line.
- commandLines.push_back(commandLine);
- }
-
- // Check for extra object-file dependencies.
- std::vector<std::string> depends;
- const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
- if(additionalDeps)
- {
- cmSystemTools::ExpandListArgument(additionalDeps, depends);
- }
-
- // Generate a meaningful comment for the command.
- std::string comment = "Building ";
- comment += lang;
- comment += " object ";
- comment += this->Convert(ofname, START_OUTPUT);
-
- // Add the custom command to build the object file.
- this->Makefile->AddCustomCommandToOutput(
- ofname,
- depends,
- source.GetFullPath(),
- commandLines,
- comment.c_str(),
- this->StateSnapshot.GetCurrentBinaryDirectory()
- );
-}
-
-void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
- cmGeneratorTarget& target)
-{
- std::string objs;
- std::vector<std::string> objVector;
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- // Add all the sources outputs to the depends of the target
- std::vector<cmSourceFile*> classes;
- target.GetSourceFiles(classes, config);
- for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
- i != classes.end(); ++i)
- {
- cmSourceFile* sf = *i;
- if(!sf->GetCustomCommand() &&
- !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
- !sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
- {
- std::string dir_max;
- dir_max += this->StateSnapshot.GetCurrentBinaryDirectory();
- dir_max += "/";
- std::string obj = this->GetObjectFileNameWithoutTarget(*sf, dir_max);
- if(!obj.empty())
- {
- std::string ofname = this->StateSnapshot.GetCurrentBinaryDirectory();
- ofname += "/";
- ofname += obj;
- objVector.push_back(ofname);
- this->AddCustomCommandToCreateObject(ofname.c_str(),
- llang, *(*i), target);
- objs += this->Convert(ofname,START_OUTPUT,SHELL);
- objs += " ";
- }
- }
- }
- std::string createRule = target.GetCreateRuleVariable(llang, config);
- bool useWatcomQuote = this->Makefile->IsOn(createRule+"_USE_WATCOM_QUOTE");
- std::string targetName = target.Target->GetFullName();
- // Executable :
- // Shared Library:
- // Static Library:
- // Shared Module:
- std::string linkLibs; // should be set
- std::string frameworkPath;
- std::string linkPath;
- std::string flags; // should be set
- std::string linkFlags; // should be set
- this->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
- &target, useWatcomQuote);
- linkLibs = frameworkPath + linkPath + linkLibs;
- cmLocalGenerator::RuleVariables vars;
- vars.Language = llang.c_str();
- vars.Objects = objs.c_str();
- vars.ObjectDir = ".";
- vars.Target = targetName.c_str();
- vars.LinkLibraries = linkLibs.c_str();
- vars.Flags = flags.c_str();
- vars.LinkFlags = linkFlags.c_str();
-
- std::string langFlags;
- this->AddLanguageFlags(langFlags, llang, "");
- this->AddArchitectureFlags(langFlags, &target, llang, "");
- vars.LanguageCompileFlags = langFlags.c_str();
-
- cmCustomCommandLines commandLines;
- std::vector<std::string> rules;
- rules.push_back(this->Makefile->GetRequiredDefinition(createRule));
- std::vector<std::string> commands;
- cmSystemTools::ExpandList(rules, commands);
- for(std::vector<std::string>::iterator i = commands.begin();
- i != commands.end(); ++i)
- {
- // Expand the full command line string.
- this->ExpandRuleVariables(*i, vars);
- // Parse the string to get the custom command line.
- cmCustomCommandLine commandLine;
- std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str());
- commandLine.insert(commandLine.end(), cmd.begin(), cmd.end());
-
- // Store this command line.
- commandLines.push_back(commandLine);
- }
- std::string targetFullPath = target.Target->GetFullPath();
- // Generate a meaningful comment for the command.
- std::string comment = "Linking ";
- comment += llang;
- comment += " target ";
- comment += this->Convert(targetFullPath, START_OUTPUT);
- this->Makefile->AddCustomCommandToOutput(
- targetFullPath,
- objVector,
- "",
- commandLines,
- comment.c_str(),
- this->StateSnapshot.GetCurrentBinaryDirectory()
- );
- this->Makefile->GetSource(targetFullPath);
- target.Target->AddSource(targetFullPath);
-}
-
-
-void cmLocalGenerator
-::CreateCustomTargetsAndCommands(std::set<std::string> const& lang)
-{
- cmGeneratorTargetsType tgts = this->Makefile->GetGeneratorTargets();
- for(cmGeneratorTargetsType::iterator l = tgts.begin();
- l != tgts.end(); l++)
- {
- if (l->first->IsImported())
- {
- continue;
- }
- cmGeneratorTarget& target = *l->second;
- switch(target.GetType())
- {
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::EXECUTABLE:
- {
- std::string llang = target.Target->GetLinkerLanguage();
- if(llang.empty())
- {
- cmSystemTools::Error
- ("CMake can not determine linker language for target: ",
- target.Target->GetName().c_str());
- return;
- }
- // if the language is not in the set lang then create custom
- // commands to build the target
- if(lang.count(llang) == 0)
- {
- this->AddBuildTargetRule(llang, target);
- }
- }
- break;
- default:
- break;
- }
- }
-}
-
// List of variables that are replaced when
// rules are expanced. These variables are
// replaced in the form <var> with GetSafeDefinition(var).
@@ -835,6 +593,10 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
{
return replaceValues.Defines;
}
+ if(replaceValues.Includes && variable == "INCLUDES")
+ {
+ return replaceValues.Includes;
+ }
if(replaceValues.TargetPDB )
{
if(variable == "TARGET_PDB")
@@ -1169,56 +931,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
//----------------------------------------------------------------------------
std::string
-cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote,
- std::string const& result,
- OutputFormat format)
-{
- // If this is a windows shell, the result has a space, and the path
- // already exists, we can use a short-path to reference it without a
- // space.
- if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
- cmSystemTools::FileExists(remote.c_str()))
- {
- std::string tmp;
- if(cmSystemTools::GetShortPath(remote, tmp))
- {
- return this->Convert(tmp, NONE, format, true);
- }
- }
-
- // Otherwise, leave it unchanged.
- return result;
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote,
- RelativeRoot local,
- OutputFormat format)
-{
- // Perform standard conversion.
- std::string result = this->Convert(remote, local, format, true);
-
- // Consider short-path.
- return this->ConvertToOutputForExistingCommon(remote, result, format);
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
- const std::string& local,
- OutputFormat format)
-{
- // Perform standard conversion.
- std::string result = this->Convert(remote, local, format, true);
-
- // Consider short-path.
- const char* remotePath = this->GetRelativeRootPath(remote);
- return this->ConvertToOutputForExistingCommon(remotePath, result, format);
-}
-
-//----------------------------------------------------------------------------
-std::string
cmLocalGenerator::ConvertToIncludeReference(std::string const& path,
OutputFormat format,
bool forceFullPaths)
@@ -1316,8 +1028,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
{
includeFlags << fwSearchFlag;
}
- includeFlags << this->Convert(frameworkDir, START_OUTPUT,
- shellFormat, true)
+ includeFlags << this->ConvertToOutputFormat(frameworkDir, shellFormat)
<< " ";
}
continue;
@@ -1365,7 +1076,8 @@ void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
const std::string& lang)
{
std::vector<std::string> targetDefines;
- target->GetCompileDefinitions(targetDefines, config, lang);
+ cmGeneratorTarget* gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
+ gtgt->GetCompileDefinitions(targetDefines, config, lang);
this->AppendDefines(defines, targetDefines);
}
@@ -1376,6 +1088,10 @@ void cmLocalGenerator::AddCompileOptions(
)
{
std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX";
+
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(target);
+
if(const char* langFlagRegexStr =
this->Makefile->GetDefinition(langFlagRegexVar))
{
@@ -1386,7 +1102,7 @@ void cmLocalGenerator::AddCompileOptions(
{
cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
}
- target->GetCompileOptions(opts, config, lang);
+ gtgt->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
@@ -1407,7 +1123,7 @@ void cmLocalGenerator::AddCompileOptions(
this->AppendFlags(flags, targetFlags);
}
std::vector<std::string> opts;
- target->GetCompileOptions(opts, config, lang);
+ gtgt->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
@@ -1416,7 +1132,7 @@ void cmLocalGenerator::AddCompileOptions(
}
}
std::vector<std::string> features;
- target->GetCompileFeatures(features, config);
+ gtgt->GetCompileFeatures(features, config);
for(std::vector<std::string>::const_iterator it = features.begin();
it != features.end(); ++it)
{
@@ -1446,7 +1162,7 @@ void cmLocalGenerator::AddCompileOptions(
"higher \"" << it->first << "_STANDARD\" \"" << standard << "\". "
"This is not permitted. The COMPILE_FEATURES may not both depend on "
"and be depended on by the link implementation." << std::endl;
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
}
@@ -1459,7 +1175,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
const std::string& lang,
const std::string& config,
bool stripImplicitInclDirs
- )
+ ) const
{
// Need to decide whether to automatically include the source and
// binary directories at the beginning of the include path.
@@ -1485,20 +1201,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
// Store the automatic include paths.
if(includeBinaryDir)
{
- if(emitted.find(
- this->StateSnapshot.GetCurrentBinaryDirectory()) == emitted.end())
+ std::string binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ if(emitted.find(binDir) == emitted.end())
{
- dirs.push_back(this->StateSnapshot.GetCurrentBinaryDirectory());
- emitted.insert(this->StateSnapshot.GetCurrentBinaryDirectory());
+ dirs.push_back(binDir);
+ emitted.insert(binDir);
}
}
if(includeSourceDir)
{
- if(emitted.find(
- this->StateSnapshot.GetCurrentSourceDirectory()) == emitted.end())
+ std::string srcDir = this->StateSnapshot.GetDirectory().GetCurrentSource();
+ if(emitted.find(srcDir) == emitted.end())
{
- dirs.push_back(this->StateSnapshot.GetCurrentSourceDirectory());
- emitted.insert(this->StateSnapshot.GetCurrentSourceDirectory());
+ dirs.push_back(srcDir);
+ emitted.insert(srcDir);
}
}
@@ -1684,7 +1400,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
linkFlags += this->Makefile->GetSafeDefinition(build);
linkFlags += " ";
}
- std::string linkLanguage = target->Target->GetLinkerLanguage(buildType);
+ std::string linkLanguage = target->GetLinkerLanguage(buildType);
if(linkLanguage.empty())
{
cmSystemTools::Error
@@ -1799,7 +1515,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
bool escapeAllowMakeVars = !forResponseFile;
std::ostringstream fout;
std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config);
+ cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
if(!pcli)
{
return;
@@ -2030,7 +1746,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
}
// Look for a CMake target with the given name.
- if(cmTarget* target = this->Makefile->FindTargetToUse(name))
+ if(cmGeneratorTarget* target =
+ this->Makefile->FindGeneratorTargetToUse(name))
{
// make sure it is not just a coincidence that the target name
// found is part of the inName
@@ -2099,7 +1816,7 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
// Treat the name as relative to the source directory in which it
// was given.
- dep = this->StateSnapshot.GetCurrentSourceDirectory();
+ dep = this->StateSnapshot.GetDirectory().GetCurrentSource();
dep += "/";
dep += inName;
return true;
@@ -2170,7 +1887,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target,
"dialect \"" << lang << standardProp << "\" "
<< (ext ? "(with compiler extensions)" : "") << ", but CMake "
"does not know the compile flags to use to enable it.";
- this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
}
else
{
@@ -2214,7 +1931,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget const* target,
std::string e =
"CMAKE_" + lang + "_STANDARD_DEFAULT is set to invalid value '" +
std::string(defaultStd) + "'";
- this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, e);
+ this->IssueMessage(cmake::INTERNAL_ERROR, e);
return;
}
@@ -2389,7 +2106,9 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags,
return;
}
- if (target->GetLinkInterfaceDependentBoolProperty(
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(target);
+ if (gtgt->GetLinkInterfaceDependentBoolProperty(
"POSITION_INDEPENDENT_CODE",
config))
{
@@ -2430,7 +2149,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
<< flagsVar << " was removed.\n"
<< cmPolicies::GetPolicyWarning(cmPolicies::CMP0018);
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
// fall through to OLD behaviour
}
case cmPolicies::OLD:
@@ -2644,6 +2363,30 @@ void cmLocalGenerator::AppendFeatureOptions(
}
//----------------------------------------------------------------------------
+const char* cmLocalGenerator::GetFeature(const std::string& feature,
+ const std::string& config)
+{
+ std::string featureName = feature;
+ // TODO: Define accumulation policy for features (prepend, append, replace).
+ // Currently we always replace.
+ if(!config.empty())
+ {
+ featureName += "_";
+ featureName += cmSystemTools::UpperCase(config);
+ }
+ cmState::Snapshot snp = this->StateSnapshot;
+ while(snp.IsValid())
+ {
+ if(const char* value = snp.GetDirectory().GetProperty(featureName))
+ {
+ return value;
+ }
+ snp = snp.GetBuildsystemDirectoryParent();
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
std::string
cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
const char* default_comment)
@@ -2675,250 +2418,18 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
}
//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(
- const std::string& remote)
-{
- return this->Convert(remote, START_OUTPUT, SHELL, true);
-}
-
-//----------------------------------------------------------------------------
-const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot)
-{
- switch (relroot)
- {
- case HOME: return this->GetState()->GetSourceDirectory();
- case START: return this->StateSnapshot.GetCurrentSourceDirectory();
- case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory();
- case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory();
- default: break;
- }
- return 0;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(const std::string& source,
- RelativeRoot relative,
- OutputFormat output,
- bool optional)
-{
- // Convert the path to a relative path.
- std::string result = source;
-
- if (!optional || this->UseRelativePaths)
- {
- switch (relative)
- {
- case HOME:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(
- this->GetState()->GetSourceDirectoryComponents(), result);
- break;
- case START:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(
- this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result);
- break;
- case HOME_OUTPUT:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(
- this->GetState()->GetBinaryDirectoryComponents(), result);
- break;
- case START_OUTPUT:
- //result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->ConvertToRelativePath(
- this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result);
- break;
- case FULL:
- result = cmSystemTools::CollapseFullPath(result);
- break;
- case NONE:
- break;
- }
- }
- return this->ConvertToOutputFormat(result, output);
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source,
- OutputFormat output)
-{
- std::string result = source;
- // Convert it to an output path.
- if (output == MAKERULE)
- {
- result = cmSystemTools::ConvertToOutputPath(result.c_str());
- }
- else if(output == SHELL || output == WATCOMQUOTE)
- {
- // For the MSYS shell convert drive letters to posix paths, so
- // that c:/some/path becomes /c/some/path. This is needed to
- // avoid problems with the shell path translation.
- if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
- {
- if(result.size() > 2 && result[1] == ':')
- {
- result[1] = result[0];
- result[0] = '/';
- }
- }
- if(this->GetState()->UseWindowsShell())
- {
- std::replace(result.begin(), result.end(), '/', '\\');
- }
- result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
- }
- else if(output == RESPONSE)
- {
- result = this->EscapeForShell(result, false, false, false);
- }
- return result;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::Convert(RelativeRoot remote,
- const std::string& local,
- OutputFormat output,
- bool optional)
-{
- const char* remotePath = this->GetRelativeRootPath(remote);
-
- // The relative root must have a path (i.e. not FULL or NONE)
- assert(remotePath != 0);
-
- if(!local.empty() && (!optional || this->UseRelativePaths))
- {
- std::vector<std::string> components;
- cmSystemTools::SplitPath(local, components);
- std::string result = this->ConvertToRelativePath(components, remotePath);
- return this->ConvertToOutputFormat(result, output);
- }
- else
- {
- return this->ConvertToOutputFormat(remotePath, output);
- }
-}
-
-//----------------------------------------------------------------------------
-static bool cmLocalGeneratorNotAbove(const char* a, const char* b)
-{
- return (cmSystemTools::ComparePath(a, b) ||
- cmSystemTools::IsSubDirectory(a, b));
-}
-
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
- const std::string& in_remote,
- bool force)
-{
- // The path should never be quoted.
- assert(in_remote[0] != '\"');
-
- // The local path should never have a trailing slash.
- assert(!local.empty() && !(local[local.size()-1] == ""));
-
- // If the path is already relative then just return the path.
- if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
- {
- return in_remote;
- }
-
- if(!force)
- {
- // Skip conversion if the path and local are not both in the source
- // or both in the binary tree.
- std::string local_path = cmSystemTools::JoinPath(local);
- if(!((cmLocalGeneratorNotAbove(local_path.c_str(),
- this->StateSnapshot.GetRelativePathTopBinary()) &&
- cmLocalGeneratorNotAbove(in_remote.c_str(),
- this->StateSnapshot.GetRelativePathTopBinary())) ||
- (cmLocalGeneratorNotAbove(local_path.c_str(),
- this->StateSnapshot.GetRelativePathTopSource()) &&
- cmLocalGeneratorNotAbove(in_remote.c_str(),
- this->StateSnapshot.GetRelativePathTopSource()))))
- {
- return in_remote;
- }
- }
-
- // Identify the longest shared path component between the remote
- // path and the local path.
- std::vector<std::string> remote;
- cmSystemTools::SplitPath(in_remote, remote);
- unsigned int common=0;
- while(common < remote.size() &&
- common < local.size() &&
- cmSystemTools::ComparePath(remote[common],
- local[common]))
- {
- ++common;
- }
-
- // If no part of the path is in common then return the full path.
- if(common == 0)
- {
- return in_remote;
- }
-
- // If the entire path is in common then just return a ".".
- if(common == remote.size() &&
- common == local.size())
- {
- return ".";
- }
-
- // If the entire path is in common except for a trailing slash then
- // just return a "./".
- if(common+1 == remote.size() &&
- remote[common].empty() &&
- common == local.size())
- {
- return "./";
- }
-
- // Construct the relative path.
- std::string relative;
-
- // First add enough ../ to get up to the level of the shared portion
- // of the path. Leave off the trailing slash. Note that the last
- // component of local will never be empty because local should never
- // have a trailing slash.
- for(unsigned int i=common; i < local.size(); ++i)
- {
- relative += "..";
- if(i < local.size()-1)
- {
- relative += "/";
- }
- }
-
- // Now add the portion of the destination path that is not included
- // in the shared portion of the path. Add a slash the first time
- // only if there was already something in the path. If there was a
- // trailing slash in the input then the last iteration of the loop
- // will add a slash followed by an empty string which will preserve
- // the trailing slash in the output.
-
- if(!relative.empty() && !remote.empty())
- {
- relative += "/";
- }
- relative += cmJoin(cmRange(remote).advance(common), "/");
-
- // Finally return the path.
- return relative;
-}
-
-//----------------------------------------------------------------------------
class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
{
public:
- cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
+ cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
+ const char* dest, bool implib):
cmInstallTargetGenerator(
t, dest, implib, "", std::vector<std::string>(), "Unspecified",
- cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
- false) {}
+ cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()),
+ false)
+ {
+ this->Compute(lg);
+ }
};
//----------------------------------------------------------------------------
@@ -2967,7 +2478,7 @@ cmLocalGenerator
{
// Use a target install generator.
cmInstallTargetGeneratorLocal
- g(l->second, destination.c_str(), false);
+ g(this, l->first, destination.c_str(), false);
g.Generate(os, config, configurationTypes);
}
break;
@@ -2978,18 +2489,18 @@ cmLocalGenerator
// to the normal destination and the DLL to the runtime
// destination.
cmInstallTargetGeneratorLocal
- g1(l->second, destination.c_str(), true);
+ g1(this, l->first, destination.c_str(), true);
g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user.
destination = l->second.GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
cmInstallTargetGeneratorLocal
- g2(l->second, destination.c_str(), false);
+ g2(this, l->first, destination.c_str(), false);
g2.Generate(os, config, configurationTypes);
#else
// Use a target install generator.
cmInstallTargetGeneratorLocal
- g(l->second, destination.c_str(), false);
+ g(this, l->first, destination.c_str(), false);
g.Generate(os, config, configurationTypes);
#endif
}
@@ -3151,7 +2662,7 @@ cmLocalGenerator
<< " " << ssin << "\n"
<< "cannot be safely placed under this directory. "
<< "The build may not work correctly.";
- this->Makefile->IssueMessage(cmake::WARNING, m.str());
+ this->IssueMessage(cmake::WARNING, m.str());
}
}
#else
@@ -3195,11 +2706,6 @@ bool cmLocalGenerator::IsNMake() const
return this->GetState()->UseNMake();
}
-void cmLocalGenerator::SetConfiguredCMP0014(bool configured)
-{
- this->Configured = configured;
-}
-
//----------------------------------------------------------------------------
std::string
cmLocalGenerator
@@ -3308,150 +2814,6 @@ cmLocalGenerator
}
//----------------------------------------------------------------------------
-static bool cmLocalGeneratorIsShellOperator(const std::string& str)
-{
- static std::set<std::string> shellOperators;
- if(shellOperators.empty())
- {
- shellOperators.insert("<");
- shellOperators.insert(">");
- shellOperators.insert("<<");
- shellOperators.insert(">>");
- shellOperators.insert("|");
- shellOperators.insert("||");
- shellOperators.insert("&&");
- shellOperators.insert("&>");
- shellOperators.insert("1>");
- shellOperators.insert("2>");
- shellOperators.insert("2>&1");
- shellOperators.insert("1>&2");
- }
- return shellOperators.count(str) > 0;
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForShell(const std::string& str,
- bool makeVars,
- bool forEcho,
- bool useWatcomQuote)
-{
- // Do not escape shell operators.
- if(cmLocalGeneratorIsShellOperator(str))
- {
- return str;
- }
-
- // Compute the flags for the target shell environment.
- int flags = 0;
- if(this->GetState()->UseWindowsVSIDE())
- {
- flags |= cmsysSystem_Shell_Flag_VSIDE;
- }
- else if(!this->LinkScriptShell)
- {
- flags |= cmsysSystem_Shell_Flag_Make;
- }
- if(makeVars)
- {
- flags |= cmsysSystem_Shell_Flag_AllowMakeVariables;
- }
- if(forEcho)
- {
- flags |= cmsysSystem_Shell_Flag_EchoWindows;
- }
- if(useWatcomQuote)
- {
- flags |= cmsysSystem_Shell_Flag_WatcomQuote;
- }
- if(this->GetState()->UseWatcomWMake())
- {
- flags |= cmsysSystem_Shell_Flag_WatcomWMake;
- }
- if(this->GetState()->UseMinGWMake())
- {
- flags |= cmsysSystem_Shell_Flag_MinGWMake;
- }
- if(this->GetState()->UseNMake())
- {
- flags |= cmsysSystem_Shell_Flag_NMake;
- }
-
- // Compute the buffer size needed.
- int size = (this->GetState()->UseWindowsShell() ?
- cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
- cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags));
-
- // Compute the shell argument itself.
- std::vector<char> arg(size);
- if(this->GetState()->UseWindowsShell())
- {
- cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
- }
- else
- {
- cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
- }
- return std::string(&arg[0]);
-}
-
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::EscapeForCMake(const std::string& str)
-{
- // Always double-quote the argument to take care of most escapes.
- std::string result = "\"";
- for(const char* c = str.c_str(); *c; ++c)
- {
- if(*c == '"')
- {
- // Escape the double quote to avoid ending the argument.
- result += "\\\"";
- }
- else if(*c == '$')
- {
- // Escape the dollar to avoid expanding variables.
- result += "\\$";
- }
- else if(*c == '\\')
- {
- // Escape the backslash to avoid other escapes.
- result += "\\\\";
- }
- else
- {
- // Other characters will be parsed correctly.
- result += *c;
- }
- }
- result += "\"";
- return result;
-}
-
-//----------------------------------------------------------------------------
-cmLocalGenerator::FortranFormat
-cmLocalGenerator::GetFortranFormat(const char* value)
-{
- FortranFormat format = FortranFormatNone;
- if(value && *value)
- {
- std::vector<std::string> fmt;
- cmSystemTools::ExpandListArgument(value, fmt);
- for(std::vector<std::string>::iterator fi = fmt.begin();
- fi != fmt.end(); ++fi)
- {
- if(*fi == "FIXED")
- {
- format = FortranFormatFixed;
- }
- if(*fi == "FREE")
- {
- format = FortranFormatFree;
- }
- }
- }
- return format;
-}
-
-//----------------------------------------------------------------------------
std::string
cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
{
@@ -3481,7 +2843,7 @@ cmIML_INT_uint64_t cmLocalGenerator::GetBackwardsCompatibility()
}
}
this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch);
- this->BackwardsCompatibilityFinal = this->Configured;
+ this->BackwardsCompatibilityFinal = this->Makefile->IsConfigured();
}
return this->BackwardsCompatibility;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 32b17f5..b051e5d 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -14,6 +14,8 @@
#include "cmStandardIncludes.h"
#include "cmState.h"
+#include "cmake.h"
+#include "cmOutputConverter.h"
class cmMakefile;
class cmGlobalGenerator;
@@ -31,26 +33,18 @@ class cmCustomCommandGenerator;
* platforms. This class should never be constructed directly. A
* GlobalGenerator will create it and invoke the appropriate commands on it.
*/
-class cmLocalGenerator
+class cmLocalGenerator : public cmOutputConverter
{
public:
- cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
virtual ~cmLocalGenerator();
- /// @return whether we are processing the top CMakeLists.txt file.
- bool IsRootMakefile() const;
-
/**
* Generate the makefile for this directory.
*/
virtual void Generate() {}
- /**
- * Process the CMakeLists files for this directory to fill in the
- * Makefile ivar
- */
- virtual void Configure();
+ virtual void ComputeHomeRelativeOutputPath() {}
/**
* Calls TraceVSDependencies() on all targets of this generator.
@@ -60,11 +54,6 @@ public:
virtual void AddHelperCommands() {}
/**
- * Perform any final calculations prior to generation
- */
- void ConfigureFinalPass();
-
- /**
* Generate the install rules files in this directory.
*/
void GenerateInstallRules();
@@ -77,7 +66,7 @@ public:
/**
* Generate a manifest of target files that will be built.
*/
- void GenerateTargetManifest();
+ void ComputeTargetManifest();
///! Get the makefile for this generator
cmMakefile *GetMakefile() {
@@ -96,52 +85,6 @@ public:
cmState* GetState() const;
cmState::Snapshot GetStateSnapshot() const;
- /**
- * Convert something to something else. This is a centralized conversion
- * routine used by the generators to handle relative paths and the like.
- * The flags determine what is actually done.
- *
- * relative: treat the argument as a directory and convert it to make it
- * relative or full or unchanged. If relative (HOME, START etc) then that
- * specifies what it should be relative to.
- *
- * output: make the result suitable for output to a...
- *
- * optional: should any relative path operation be controlled by the rel
- * path setting
- */
- enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
- enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
- std::string ConvertToOutputFormat(const std::string& source,
- OutputFormat output);
- std::string Convert(const std::string& remote, RelativeRoot local,
- OutputFormat output = UNCHANGED,
- bool optional = false);
- std::string Convert(RelativeRoot remote, const std::string& local,
- OutputFormat output = UNCHANGED,
- bool optional = false);
-
- /**
- * Get path for the specified relative root.
- */
- const char* GetRelativeRootPath(RelativeRoot relroot);
-
- /**
- * Convert the given path to an output path that is optionally
- * relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToOptionallyRelativeOutputPath(const std::string& remote);
-
- ///! set/get the parent generator
- cmLocalGenerator* GetParent() const {return this->Parent;}
-
- ///! set/get the children
- void AddChild(cmLocalGenerator* g) { this->Children.push_back(g); }
- std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }
-
-
void AddArchitectureFlags(std::string& flags,
cmGeneratorTarget const* target,
const std::string&lang, const std::string& config);
@@ -194,6 +137,9 @@ public:
void AppendFeatureOptions(std::string& flags, const std::string& lang,
const char* feature);
+ const char* GetFeature(const std::string& feature,
+ const std::string& config);
+
/** \brief Get absolute path to dependency \a name
*
* Translate a dependency as given in CMake code to the name to
@@ -209,17 +155,6 @@ public:
bool GetRealDependency(const std::string& name, const std::string& config,
std::string& dep);
- ///! for existing files convert to output path and short path if spaces
- std::string ConvertToOutputForExisting(const std::string& remote,
- RelativeRoot local = START_OUTPUT,
- OutputFormat format = SHELL);
-
- /** For existing path identified by RelativeRoot convert to output
- path and short path if spaces. */
- std::string ConvertToOutputForExisting(RelativeRoot remote,
- const std::string& local = "",
- OutputFormat format = SHELL);
-
virtual std::string ConvertToIncludeReference(std::string const& path,
OutputFormat format = SHELL,
bool forceFullPaths = false);
@@ -239,7 +174,7 @@ public:
cmGeneratorTarget* target,
const std::string& lang = "C",
const std::string& config = "",
- bool stripImplicitInclDirs = true);
+ bool stripImplicitInclDirs = true) const;
void AddCompileOptions(std::string& flags, cmTarget* target,
const std::string& lang, const std::string& config);
void AddCompileDefinitions(std::set<std::string>& defines,
@@ -286,45 +221,12 @@ public:
const char* LinkFlags;
const char* LanguageCompileFlags;
const char* Defines;
+ const char* Includes;
const char* RuleLauncher;
const char* DependencyFile;
const char* FilterPrefix;
};
- /** Set whether to treat conversions to SHELL as a link script shell. */
- void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; }
-
- /** Escape the given string to be used as a command line argument in
- the native build system shell. Optionally allow the build
- system to replace make variable references. Optionally adjust
- escapes for the special case of passing to the native echo
- command. */
- std::string EscapeForShell(const std::string& str, bool makeVars = false,
- bool forEcho = false,
- bool useWatcomQuote = false);
-
- /** Escape the given string as an argument in a CMake script. */
- static std::string EscapeForCMake(const std::string& str);
-
- enum FortranFormat
- {
- FortranFormatNone,
- FortranFormatFixed,
- FortranFormatFree
- };
- FortranFormat GetFortranFormat(const char* value);
-
- /**
- * Convert the given remote path to a relative path with respect to
- * the given local path. The local path must be given in component
- * form (see SystemTools::SplitPath) without a trailing slash. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToRelativePath(const std::vector<std::string>& local,
- const std::string& remote,
- bool force=false);
-
/**
* Get the relative path from the generator output directory to a
* per-target support directory.
@@ -392,8 +294,12 @@ public:
bool IsMinGWMake() const;
bool IsNMake() const;
- void SetConfiguredCMP0014(bool configured);
+ void IssueMessage(cmake::MessageType t, std::string const& text) const;
+ void CreateEvaluationFileOutputs(const std::string& config);
+ void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
+
+ void ComputeObjectMaxPath();
protected:
///! put all the libraries for a target on into the given stream
void OutputLinkLibraries(std::string& linkLibraries,
@@ -415,23 +321,6 @@ protected:
void InsertRuleLauncher(std::string& s, cmTarget* target,
const std::string& prop);
-
- /** Convert a target to a utility target for unsupported
- * languages of a generator */
- void AddBuildTargetRule(const std::string& llang,
- cmGeneratorTarget& target);
- ///! add a custom command to build a .o file that is part of a target
- void AddCustomCommandToCreateObject(const char* ofname,
- const std::string& lang,
- cmSourceFile& source,
- cmGeneratorTarget& target);
- // Create Custom Targets and commands for unsupported languages
- // The set passed in should contain the languages supported by the
- // generator directly. Any targets containing files that are not
- // of the types listed will be compiled as custom commands and added
- // to a custom target.
- void CreateCustomTargetsAndCommands(std::set<std::string> const&);
-
// Handle old-style install rules stored in the targets.
void GenerateTargetInstallRules(
std::ostream& os, const std::string& config,
@@ -439,7 +328,6 @@ protected:
std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
std::string const& dir_max);
- void ComputeObjectMaxPath();
virtual std::string ConvertToLinkReference(std::string const& lib,
OutputFormat format = SHELL);
@@ -451,17 +339,12 @@ protected:
cmMakefile *Makefile;
cmState::Snapshot StateSnapshot;
cmGlobalGenerator *GlobalGenerator;
- cmLocalGenerator* Parent;
- std::vector<cmLocalGenerator*> Children;
std::map<std::string, std::string> UniqueObjectNamesMap;
std::string::size_type ObjectPathMax;
std::set<std::string> ObjectMaxPathViolations;
std::set<cmTarget const*> WarnCMP0063;
- bool LinkScriptShell;
- bool UseRelativePaths;
- bool Configured;
bool EmitUniversalBinaryFlags;
// Hack for ExpandRuleVariable until object-oriented version is
@@ -471,10 +354,6 @@ protected:
cmIML_INT_uint64_t BackwardsCompatibility;
bool BackwardsCompatibilityFinal;
private:
- std::string ConvertToOutputForExistingCommon(const std::string& remote,
- std::string const& result,
- OutputFormat format);
-
void AddSharedFlags(std::string& flags, const std::string& lang,
bool shared);
bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 870b9b9..bac989f 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -17,9 +17,8 @@
#include "cmGeneratedFileStream.h"
cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : cmLocalGenerator(gg, parent, snapshot)
+ cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
{
}
@@ -37,7 +36,7 @@ void cmLocalGhsMultiGenerator::Generate()
{
continue;
}
- cmGhsMultiTargetGenerator tg(l->second->Target);
+ cmGhsMultiTargetGenerator tg(l->second);
tg.Generate();
}
}
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
index f52ef39..b6a9a33 100644
--- a/Source/cmLocalGhsMultiGenerator.h
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -25,8 +25,7 @@ class cmGeneratedFileStream;
class cmLocalGhsMultiGenerator : public cmLocalGenerator
{
public:
- cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalGhsMultiGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalGhsMultiGenerator();
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c08c91f..7525bf2 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -23,10 +23,8 @@
#include <assert.h>
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : cmLocalGenerator(gg, parent, snapshot)
- , ConfigName("")
+ cmMakefile* mf)
+ : cmLocalCommonGenerator(gg, mf)
, HomeRelativeOutputPath("")
{
this->TargetImplib = "$TARGET_IMPLIB";
@@ -41,6 +39,15 @@ cmLocalNinjaGenerator::~cmLocalNinjaGenerator()
void cmLocalNinjaGenerator::Generate()
{
+ // Compute the path to use when referencing the current output
+ // directory from the top output directory.
+ this->HomeRelativeOutputPath =
+ this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+ if(this->HomeRelativeOutputPath == ".")
+ {
+ this->HomeRelativeOutputPath = "";
+ }
+
this->SetConfigName();
this->WriteProcessedMakefile(this->GetBuildFileStream());
@@ -49,7 +56,7 @@ void cmLocalNinjaGenerator::Generate()
#endif
// We do that only once for the top CMakeLists.txt file.
- if(this->IsRootMakefile())
+ if(this->Makefile->IsRootMakefile())
{
this->WriteBuildFileTop();
@@ -82,7 +89,7 @@ void cmLocalNinjaGenerator::Generate()
// Add the target to "all" if required.
if (!this->GetGlobalNinjaGenerator()->IsExcluded(
this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
- *t->second->Target))
+ t->second))
this->GetGlobalNinjaGenerator()->AddDependencyToAll(t->second->Target);
delete tg;
}
@@ -91,25 +98,6 @@ void cmLocalNinjaGenerator::Generate()
this->WriteCustomCommandBuildStatements();
}
-// Implemented in:
-// cmLocalUnixMakefileGenerator3.
-// Used in:
-// Source/cmMakefile.cxx
-// Source/cmGlobalGenerator.cxx
-void cmLocalNinjaGenerator::Configure()
-{
- // Compute the path to use when referencing the current output
- // directory from the top output directory.
- this->HomeRelativeOutputPath =
- this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
- if(this->HomeRelativeOutputPath == ".")
- {
- this->HomeRelativeOutputPath = "";
- }
- this->cmLocalGenerator::Configure();
-
-}
-
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
std::string cmLocalNinjaGenerator
::GetTargetDirectory(cmTarget const& target) const
@@ -204,16 +192,14 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
{
// Default required version
- // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
- std::string requiredVersion = "1.3";
+ std::string requiredVersion =
+ this->GetGlobalNinjaGenerator()->RequiredNinjaVersion();
// Ninja generator uses the 'console' pool if available (>= 1.5)
- std::string usedVersion = this->GetGlobalNinjaGenerator()->ninjaVersion();
- if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
- usedVersion.c_str(),
- "1.5") == false)
+ if(this->GetGlobalNinjaGenerator()->SupportsConsolePool())
{
- requiredVersion = "1.5";
+ requiredVersion =
+ this->GetGlobalNinjaGenerator()->RequiredNinjaVersionForConsolePool();
}
cmGlobalNinjaGenerator::WriteComment(os,
@@ -271,22 +257,6 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
os << "\n";
}
-void cmLocalNinjaGenerator::SetConfigName()
-{
- // Store the configuration name that will be generated.
- if(const char* config =
- this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE"))
- {
- // Use the build type given by the user.
- this->ConfigName = config;
- }
- else
- {
- // No configuration type given.
- this->ConfigName = "";
- }
-}
-
//----------------------------------------------------------------------------
void cmLocalNinjaGenerator::ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
@@ -308,7 +278,7 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
<< "# Write statements declared in CMakeLists.txt:" << std::endl
<< "# "
<< this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE") << std::endl;
- if(this->IsRootMakefile())
+ if(this->Makefile->IsRootMakefile())
os << "# Which is the root file." << std::endl;
cmGlobalNinjaGenerator::WriteDivider(os);
os << std::endl;
@@ -431,7 +401,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc))
return;
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile);
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
const std::vector<std::string> &outputs = ccg.GetOutputs();
const std::vector<std::string> &byproducts = ccg.GetByproducts();
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 7ae97de..8d3d49c 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -13,7 +13,7 @@
#ifndef cmLocalNinjaGenerator_h
# define cmLocalNinjaGenerator_h
-# include "cmLocalGenerator.h"
+# include "cmLocalCommonGenerator.h"
# include "cmNinjaTypes.h"
class cmCustomCommandGenerator;
@@ -28,18 +28,15 @@ class cmake;
* cmLocalNinjaGenerator produces a local build.ninja file from its
* member Makefile.
*/
-class cmLocalNinjaGenerator : public cmLocalGenerator
+class cmLocalNinjaGenerator : public cmLocalCommonGenerator
{
public:
- cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalNinjaGenerator();
virtual void Generate();
- virtual void Configure();
-
virtual std::string GetTargetDirectory(cmTarget const& target) const;
const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const;
@@ -48,9 +45,6 @@ public:
const cmake* GetCMakeInstance() const;
cmake* GetCMakeInstance();
- std::string const& GetConfigName() const
- { return this->ConfigName; }
-
/// @returns the relative path between the HomeOutputDirectory and this
/// local generators StartOutputDirectory.
std::string GetHomeRelativeOutputPath() const
@@ -112,8 +106,6 @@ private:
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
- void SetConfigName();
-
void WriteCustomCommandRule();
void WriteCustomCommandBuildStatement(cmCustomCommand const *cc,
const cmNinjaDeps& orderOnlyDeps);
@@ -122,7 +114,6 @@ private:
std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
- std::string ConfigName;
std::string HomeRelativeOutputPath;
typedef std::map<cmCustomCommand const*, std::set<cmTarget*> >
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 3eea59b..b131a63 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -80,9 +80,8 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
//----------------------------------------------------------------------------
cmLocalUnixMakefileGenerator3::
-cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : cmLocalGenerator(gg, parent, snapshot)
+cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf)
+ : cmLocalCommonGenerator(gg, mf)
{
this->MakefileVariableSize = 0;
this->ColorMakefile = false;
@@ -98,37 +97,9 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3()
}
//----------------------------------------------------------------------------
-void cmLocalUnixMakefileGenerator3::Configure()
-{
- // Compute the path to use when referencing the current output
- // directory from the top output directory.
- this->HomeRelativeOutputPath =
- this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
- if(this->HomeRelativeOutputPath == ".")
- {
- this->HomeRelativeOutputPath = "";
- }
- if(!this->HomeRelativeOutputPath.empty())
- {
- this->HomeRelativeOutputPath += "/";
- }
- this->cmLocalGenerator::Configure();
-}
-
-//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::Generate()
{
- // Store the configuration name that will be generated.
- if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
- {
- // Use the build type given by the user.
- this->ConfigurationName = config;
- }
- else
- {
- // No configuration type given.
- this->ConfigurationName = "";
- }
+ this->SetConfigName();
// Record whether some options are enabled to avoid checking many
// times later.
@@ -169,6 +140,22 @@ void cmLocalUnixMakefileGenerator3::Generate()
this->WriteDirectoryInformationFile();
}
+void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
+{
+ // Compute the path to use when referencing the current output
+ // directory from the top output directory.
+ this->HomeRelativeOutputPath =
+ this->Convert(this->Makefile->GetCurrentBinaryDirectory(), HOME_OUTPUT);
+ if(this->HomeRelativeOutputPath == ".")
+ {
+ this->HomeRelativeOutputPath = "";
+ }
+ if(!this->HomeRelativeOutputPath.empty())
+ {
+ this->HomeRelativeOutputPath += "/";
+ }
+}
+
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
@@ -268,7 +255,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
return;
}
// always write the top makefile
- if (this->Parent)
+ if (!this->GetMakefile()->IsRootMakefile())
{
ruleFileStream.SetCopyIfDifferent(true);
}
@@ -279,7 +266,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
// only write local targets unless at the top Keep track of targets already
// listed.
std::set<std::string> emittedTargets;
- if (this->Parent)
+ if (!this->GetMakefile()->IsRootMakefile())
{
// write our targets, and while doing it collect up the object
// file rules
@@ -498,8 +485,7 @@ void cmLocalUnixMakefileGenerator3
// Add a local name for the rule to relink the target before
// installation.
- if(t->second->Target
- ->NeedRelinkBeforeInstall(this->ConfigurationName))
+ if(t->second->NeedRelinkBeforeInstall(this->ConfigName))
{
makeTargetName = this->GetRelativeTargetDirectory(*t->second->Target);
makeTargetName += "/preinstall";
@@ -542,10 +528,10 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
infoFileStream
<< "# Relative path conversion top directories.\n"
<< "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
- << this->StateSnapshot.GetRelativePathTopSource()
+ << this->StateSnapshot.GetDirectory().GetRelativePathTopSource()
<< "\")\n"
<< "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
- << this->StateSnapshot.GetRelativePathTopBinary()
+ << this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()
<< "\")\n"
<< "\n";
@@ -900,7 +886,7 @@ void cmLocalUnixMakefileGenerator3
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(runRule);
- if(this->Parent)
+ if(!this->GetMakefile()->IsRootMakefile())
{
this->CreateCDCommand(commands,
this->Makefile->GetHomeOutputDirectory(),
@@ -1019,8 +1005,7 @@ cmLocalUnixMakefileGenerator3
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
i != ccs.end(); ++i)
{
- cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
- this->Makefile);
+ cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
this->AppendCustomDepend(depends, ccg);
}
}
@@ -1036,7 +1021,7 @@ cmLocalUnixMakefileGenerator3
{
// Lookup the real name of the dependency in case it is a CMake target.
std::string dep;
- if(this->GetRealDependency(*d, this->ConfigurationName,
+ if(this->GetRealDependency(*d, this->ConfigName,
dep))
{
depends.push_back(dep);
@@ -1055,8 +1040,7 @@ cmLocalUnixMakefileGenerator3
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
i != ccs.end(); ++i)
{
- cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
- this->Makefile);
+ cmCustomCommandGenerator ccg(*i, this->ConfigName, this);
this->AppendCustomCommand(commands, ccg, target, true, relative);
}
}
@@ -1259,7 +1243,7 @@ cmLocalUnixMakefileGenerator3
f != files.end(); ++f)
{
std::string fc = this->Convert(*f,START_OUTPUT,UNCHANGED);
- fout << " " << cmLocalGenerator::EscapeForCMake(fc) << "\n";
+ fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n";
}
fout << ")\n";
}
@@ -1272,7 +1256,9 @@ cmLocalUnixMakefileGenerator3
{
// Get the set of source languages in the target.
std::set<std::string> languages;
- target.GetLanguages(languages,
+ cmGeneratorTarget *gtgt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+ gtgt->GetLanguages(languages,
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
fout << "\n"
<< "# Per-language clean rules from dependency scanning.\n"
@@ -1614,12 +1600,14 @@ cmLocalUnixMakefileGenerator3
if(const char* relativePathTopSource =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
{
- this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource);
+ this->StateSnapshot.GetDirectory()
+ .SetRelativePathTopSource(relativePathTopSource);
}
if(const char* relativePathTopBinary =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
{
- this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary);
+ this->StateSnapshot.GetDirectory()
+ .SetRelativePathTopBinary(relativePathTopBinary);
}
}
else
@@ -1845,7 +1833,6 @@ void cmLocalUnixMakefileGenerator3
std::vector<std::string> commands;
// Write the all rule.
- std::string dir;
std::string recursiveTarget = this->Makefile->GetCurrentBinaryDirectory();
recursiveTarget += "/all";
@@ -2046,7 +2033,7 @@ void cmLocalUnixMakefileGenerator3
// Build a list of preprocessor definitions for the target.
std::set<std::string> defines;
this->AddCompileDefinitions(defines, &target,
- this->ConfigurationName, l->first);
+ this->ConfigName, l->first);
if(!defines.empty())
{
cmakefileStream
@@ -2057,7 +2044,7 @@ void cmLocalUnixMakefileGenerator3
di != defines.end(); ++di)
{
cmakefileStream
- << " " << cmLocalGenerator::EscapeForCMake(*di) << "\n";
+ << " " << cmOutputConverter::EscapeForCMake(*di) << "\n";
}
cmakefileStream
<< " )\n";
@@ -2111,7 +2098,7 @@ void cmLocalUnixMakefileGenerator3
tri != transformRules.end(); ++tri)
{
cmakefileStream << " "
- << cmLocalGenerator::EscapeForCMake(*tri) << "\n";
+ << cmOutputConverter::EscapeForCMake(*tri) << "\n";
}
cmakefileStream
<< " )\n";
@@ -2270,7 +2257,7 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p,
std::string());
std::vector<std::string>::const_iterator compStart
= components.begin() + 1;
- result += cmJoin(cmRange(compStart, compEnd), slash);
+ result += cmJoin(cmMakeRange(compStart, compEnd), slash);
// Only the last component can be empty to avoid double slashes.
result += slash;
result += components.back();
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 988d660..98f15e6 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -12,7 +12,7 @@
#ifndef cmLocalUnixMakefileGenerator3_h
#define cmLocalUnixMakefileGenerator3_h
-#include "cmLocalGenerator.h"
+#include "cmLocalCommonGenerator.h"
// for cmDepends::DependencyVector
#include "cmDepends.h"
@@ -31,26 +31,19 @@ class cmSourceFile;
* cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
* member Makefile.
*/
-class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
+class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator
{
public:
- cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalUnixMakefileGenerator3();
- /**
- * Process the CMakeLists files for this directory to fill in the
- * Makefile ivar
- */
- virtual void Configure();
+ virtual void ComputeHomeRelativeOutputPath();
/**
* Generate the makefile for this directory.
*/
virtual void Generate();
-
// this returns the relative path between the HomeOutputDirectory and this
// local generators StartOutputDirectory
const std::string &GetHomeRelativeOutputPath();
@@ -153,9 +146,6 @@ public:
void AddImplicitDepends(cmTarget const& tgt, const std::string& lang,
const char* obj, const char* src);
- void AppendGlobalTargetDepends(std::vector<std::string>& depends,
- cmTarget& target);
-
// write the target rules for the local Makefile into the stream
void WriteLocalAllRules(std::ostream& ruleFileStream);
@@ -260,26 +250,8 @@ private:
ImplicitDependTargetMap ImplicitDepends;
- //==========================================================================
- // Configuration settings.
- int MakefileVariableSize;
- std::string ConfigurationName;
- bool MakeCommandEscapeTargetTwice;
- bool BorlandMakeCurlyHack;
- //==========================================================================
-
std::string HomeRelativeOutputPath;
- /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
- beginning of generation to avoid many duplicate lookups. */
- bool ColorMakefile;
-
- /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
- CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to
- avoid many duplicate lookups. */
- bool SkipPreprocessedSourceRules;
- bool SkipAssemblySourceRules;
-
struct LocalObjectEntry
{
cmTarget* Target;
@@ -308,6 +280,13 @@ private:
/* does the work for each target */
std::map<std::string, std::string> MakeVariableMap;
std::map<std::string, std::string> ShortMakeVariableMap;
+
+ int MakefileVariableSize;
+ bool MakeCommandEscapeTargetTwice;
+ bool BorlandMakeCurlyHack;
+ bool ColorMakefile;
+ bool SkipPreprocessedSourceRules;
+ bool SkipAssemblySourceRules;
};
#endif
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index ad6a020..b043b00 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -33,7 +33,7 @@ class cmVS10XMLParser : public cmXMLParser
virtual void StartElement(const std::string& name, const char**)
{
// once the GUID is found do nothing
- if(this->GUID.size())
+ if(!this->GUID.empty())
{
return;
}
@@ -62,10 +62,8 @@ class cmVS10XMLParser : public cmXMLParser
//----------------------------------------------------------------------------
cmLocalVisualStudio10Generator
-::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot):
- cmLocalVisualStudio7Generator(gg, parent, snapshot)
+::cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudio7Generator(gg, mf)
{
}
@@ -107,10 +105,9 @@ void cmLocalVisualStudio10Generator
cmVS10XMLParser parser;
parser.ParseFile(path);
- // if we can not find a GUID then create one
+ // if we can not find a GUID then we will generate one later
if(parser.GUID.empty())
{
- this->GlobalGenerator->CreateGUID(name);
return;
}
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index c588aaf..e187590 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -25,9 +25,7 @@ class cmLocalVisualStudio10Generator : public cmLocalVisualStudio7Generator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio10Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalVisualStudio10Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio10Generator();
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index ad34857..cc94cd4 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -24,10 +24,8 @@
#include <cmsys/FStream.hxx>
cmLocalVisualStudio6Generator
-::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot):
- cmLocalVisualStudioGenerator(gg, parent, snapshot)
+::cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudioGenerator(gg, mf)
{
}
@@ -62,7 +60,7 @@ public:
}
void Write(cmCustomCommand const& cc)
{
- cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
+ cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
if(this->First)
{
this->Code += this->Event + "_Cmds=";
@@ -82,21 +80,14 @@ private:
std::string Event;
};
-void cmLocalVisualStudio6Generator::AddHelperCommands()
-{
- std::set<std::string> lang;
- lang.insert("C");
- lang.insert("CXX");
- this->CreateCustomTargetsAndCommands(lang);
-}
-
void cmLocalVisualStudio6Generator::AddCMakeListsRules()
{
cmTargets &tgts = this->Makefile->GetTargets();
for(cmTargets::iterator l = tgts.begin();
l != tgts.end(); l++)
{
- if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY
+ || l->second.GetType() == cmTarget::GLOBAL_TARGET)
{
continue;
}
@@ -235,13 +226,10 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
comment += makefileIn;
std::string args;
args = "-H";
- args += this->Convert(this->Makefile->GetHomeDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->Makefile->GetHomeDirectory();
commandLine.push_back(args);
args = "-B";
- args +=
- this->Convert(this->Makefile->GetHomeOutputDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->Makefile->GetHomeOutputDirectory();
commandLine.push_back(args);
std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
@@ -315,9 +303,12 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+
// get the classes from the source lists then add them to the groups
std::vector<cmSourceFile*> classes;
- if (!target.GetConfigCommonSourceFiles(classes))
+ if (!gt->GetConfigCommonSourceFiles(classes))
{
return;
}
@@ -498,7 +489,7 @@ void cmLocalVisualStudio6Generator
// Tell MS-Dev what the source is. If the compiler knows how to
// build it, then it will.
fout << "SOURCE=" <<
- this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n";
+ this->ConvertToOutputFormat(source.c_str(), SHELL) << "\n\n";
if(!depends.empty())
{
// Write out the dependencies for the rule.
@@ -507,7 +498,7 @@ void cmLocalVisualStudio6Generator
d != depends.end(); ++d)
{
fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ this->ConvertToOutputFormat(d->c_str(), SHELL);
}
fout << "\n";
}
@@ -628,7 +619,7 @@ cmLocalVisualStudio6Generator
for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
{
std::string config = this->GetConfigName(*i);
- cmCustomCommandGenerator ccg(command, config, this->Makefile);
+ cmCustomCommandGenerator ccg(command, config, this);
std::string comment =
this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
if(comment == "<hack>")
@@ -663,7 +654,7 @@ cmLocalVisualStudio6Generator
if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
{
fout << "\\\n\t" <<
- this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
+ this->ConvertToOutputFormat(dep.c_str(), SHELL);
}
}
fout << "\n";
@@ -689,7 +680,7 @@ cmLocalVisualStudio6Generator
++o)
{
// Write a rule for every output generated by this command.
- fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str())
+ fout << this->ConvertToOutputFormat(o->c_str(), SHELL)
<< " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
fout << script.c_str() << "\n\n";
}
@@ -906,7 +897,7 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target,
for(i = includes.begin(); i != includes.end(); ++i)
{
std::string tmp =
- this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+ this->ConvertToOutputFormat(i->c_str(), SHELL);
if(useShortPath)
{
cmSystemTools::GetShortPath(tmp.c_str(), tmp);
@@ -994,17 +985,17 @@ void cmLocalVisualStudio6Generator
std::string libMultiLineDebugOptions;
std::string libMultiLineOptimizedOptions;
- if(libPath.size())
+ if(!libPath.empty())
{
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(libPath.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(libPath.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = libPath + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
libOptions += " /LIBPATH:";
@@ -1027,17 +1018,17 @@ void cmLocalVisualStudio6Generator
libMultiLineOptionsForDebug += " \n";
}
}
- if(exePath.size())
+ if(!exePath.empty())
{
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(exePath.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(exePath.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = exePath + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
@@ -1071,14 +1062,14 @@ void cmLocalVisualStudio6Generator
path += "/";
}
std::string lpath =
- this->ConvertToOptionallyRelativeOutputPath(path.c_str());
- if(lpath.size() == 0)
+ this->ConvertToOutputFormat(path.c_str(), SHELL);
+ if(lpath.empty())
{
lpath = ".";
}
std::string lpathIntDir = path + "$(INTDIR)";
lpathIntDir =
- this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ this->ConvertToOutputFormat(lpathIntDir.c_str(), SHELL);
if(pathEmitted.insert(lpath).second)
{
libOptions += " /LIBPATH:";
@@ -1125,10 +1116,12 @@ void cmLocalVisualStudio6Generator
cmTarget* tgt = this->GlobalGenerator->FindTarget(j->first.c_str());
if(tgt)
{
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(tgt);
lib = cmSystemTools::GetFilenameWithoutExtension
- (tgt->GetFullName().c_str());
+ (gt->GetFullName().c_str());
libDebug = cmSystemTools::GetFilenameWithoutExtension
- (tgt->GetFullName("Debug").c_str());
+ (gt->GetFullName("Debug").c_str());
lib += ".lib";
libDebug += ".lib";
}
@@ -1142,9 +1135,9 @@ void cmLocalVisualStudio6Generator
libDebug += ".lib";
}
}
- lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str());
+ lib = this->ConvertToOutputFormat(lib.c_str(), SHELL);
libDebug =
- this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str());
+ this->ConvertToOutputFormat(libDebug.c_str(), SHELL);
if (j->second == cmTarget::GENERAL)
{
@@ -1268,8 +1261,8 @@ void cmLocalVisualStudio6Generator
extraLinkOptionsRelWithDebInfo += targetLinkFlags;
}
-
-
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
// Get standard libraries for this language.
if(targetBuilds)
@@ -1278,10 +1271,10 @@ void cmLocalVisualStudio6Generator
std::vector<std::string> configs;
target.GetMakefile()->GetConfigurations(configs);
std::vector<std::string>::const_iterator it = configs.begin();
- const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+ const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
for ( ; it != configs.end(); ++it)
{
- const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+ const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
if (configLinkLanguage != linkLanguage)
{
cmSystemTools::Error
@@ -1338,11 +1331,11 @@ void cmLocalVisualStudio6Generator
target.GetType() == cmTarget::SHARED_LIBRARY ||
target.GetType() == cmTarget::MODULE_LIBRARY)
{
- outputName = target.GetFullName();
- outputNameDebug = target.GetFullName("Debug");
- outputNameRelease = target.GetFullName("Release");
- outputNameMinSizeRel = target.GetFullName("MinSizeRel");
- outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo");
+ outputName = gt->GetFullName();
+ outputNameDebug = gt->GetFullName("Debug");
+ outputNameRelease = gt->GetFullName("Release");
+ outputNameMinSizeRel = gt->GetFullName("MinSizeRel");
+ outputNameRelWithDebInfo = gt->GetFullName("RelWithDebInfo");
}
else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
{
@@ -1367,21 +1360,21 @@ void cmLocalVisualStudio6Generator
{
#ifdef CM_USE_OLD_VS6
outputDirOld =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (target.GetDirectory().c_str()));
+ removeQuotes(this->ConvertToOutputFormat
+ (target.GetDirectory().c_str(), SHELL));
#endif
outputDirDebug =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("Debug").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target.GetDirectory("Debug").c_str(), SHELL));
outputDirRelease =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("Release").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target.GetDirectory("Release").c_str(), SHELL));
outputDirMinSizeRel =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("MinSizeRel").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target.GetDirectory("MinSizeRel").c_str(), SHELL));
outputDirRelWithDebInfo =
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
- target.GetDirectory("RelWithDebInfo").c_str()));
+ removeQuotes(this->ConvertToOutputFormat(
+ target.GetDirectory("RelWithDebInfo").c_str(), SHELL));
}
else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
{
@@ -1439,30 +1432,28 @@ void cmLocalVisualStudio6Generator
fullPathImpRelease += "/";
fullPathImpMinSizeRel += "/";
fullPathImpRelWithDebInfo += "/";
- fullPathImpDebug += target.GetFullName("Debug", true);
- fullPathImpRelease += target.GetFullName("Release", true);
- fullPathImpMinSizeRel += target.GetFullName("MinSizeRel", true);
- fullPathImpRelWithDebInfo += target.GetFullName("RelWithDebInfo", true);
+ fullPathImpDebug += gt->GetFullName("Debug", true);
+ fullPathImpRelease += gt->GetFullName("Release", true);
+ fullPathImpMinSizeRel += gt->GetFullName("MinSizeRel", true);
+ fullPathImpRelWithDebInfo += gt->GetFullName("RelWithDebInfo", true);
targetImplibFlagDebug = "/implib:";
targetImplibFlagRelease = "/implib:";
targetImplibFlagMinSizeRel = "/implib:";
targetImplibFlagRelWithDebInfo = "/implib:";
targetImplibFlagDebug +=
- this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str());
+ this->ConvertToOutputFormat(fullPathImpDebug.c_str(), SHELL);
targetImplibFlagRelease +=
- this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str());
+ this->ConvertToOutputFormat(fullPathImpRelease.c_str(), SHELL);
targetImplibFlagMinSizeRel +=
- this->ConvertToOptionallyRelativeOutputPath(
- fullPathImpMinSizeRel.c_str());
+ this->ConvertToOutputFormat(fullPathImpMinSizeRel.c_str(), SHELL);
targetImplibFlagRelWithDebInfo +=
- this->ConvertToOptionallyRelativeOutputPath(
- fullPathImpRelWithDebInfo.c_str());
+ this->ConvertToOutputFormat(fullPathImpRelWithDebInfo.c_str(), SHELL);
}
#ifdef CM_USE_OLD_VS6
// Compute link information for the target.
- if(extraLinkOptions.size())
+ if(!extraLinkOptions.empty())
{
libOptions += " ";
libOptions += extraLinkOptions;
@@ -1553,7 +1544,7 @@ void cmLocalVisualStudio6Generator
std::string line;
std::string libnameExports;
- if(exportSymbol.size())
+ if(!exportSymbol.empty())
{
libnameExports = "/D \"";
libnameExports += exportSymbol;
@@ -1669,12 +1660,12 @@ void cmLocalVisualStudio6Generator
// to convert to output path for unix to win32 conversion
cmSystemTools::ReplaceString
(line, "LIBRARY_OUTPUT_PATH",
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (libPath.c_str())).c_str());
+ removeQuotes(this->ConvertToOutputFormat
+ (libPath.c_str(), SHELL)).c_str());
cmSystemTools::ReplaceString
(line, "EXECUTABLE_OUTPUT_PATH",
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (exePath.c_str())).c_str());
+ removeQuotes(this->ConvertToOutputFormat
+ (exePath.c_str(), SHELL)).c_str());
#endif
if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
@@ -1713,10 +1704,10 @@ void cmLocalVisualStudio6Generator
std::vector<std::string> configs;
target.GetMakefile()->GetConfigurations(configs);
std::vector<std::string>::const_iterator it = configs.begin();
- const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+ const std::string& linkLanguage = gt->GetLinkerLanguage(*it);
for ( ; it != configs.end(); ++it)
{
- const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+ const std::string& configLinkLanguage = gt->GetLinkerLanguage(*it);
if (configLinkLanguage != linkLanguage)
{
cmSystemTools::Error
@@ -1858,8 +1849,10 @@ void cmLocalVisualStudio6Generator
const std::string extraOptions,
std::string& options)
{
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
// Compute the link information for this configuration.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
if(!pcli)
{
return;
@@ -1884,9 +1877,9 @@ void cmLocalVisualStudio6Generator
}
dir += "$(IntDir)";
options += "# ADD LINK32 /LIBPATH:";
- options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str());
+ options += this->ConvertToOutputFormat(dir.c_str(), SHELL);
options += " /LIBPATH:";
- options += this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ options += this->ConvertToOutputFormat(d->c_str(), SHELL);
options += "\n";
}
}
@@ -1897,7 +1890,7 @@ void cmLocalVisualStudio6Generator
if(l->IsPath)
{
options +=
- this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
+ this->ConvertToOutputFormat(l->Value.c_str(), SHELL);
}
else if (!l->Target
|| l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
@@ -1933,7 +1926,7 @@ void cmLocalVisualStudio6Generator
options += "# ADD ";
options += tool;
options += "32 ";
- options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str());
+ options += this->ConvertToOutputFormat(oi->c_str(), SHELL);
options += "\n";
}
}
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
index 8f4d521..828d252 100644
--- a/Source/cmLocalVisualStudio6Generator.h
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -29,13 +29,10 @@ class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio6Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalVisualStudio6Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio6Generator();
- virtual void AddHelperCommands();
virtual void AddCMakeListsRules();
/**
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 9c031cf..cf67251 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -23,8 +23,6 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
-#include <cmsys/System.h>
-
#include <ctype.h> // for isspace
static bool cmLVS6G_IsFAT(const char* dir);
@@ -55,10 +53,8 @@ static void cmConvertToWindowsSlash(std::string& s)
//----------------------------------------------------------------------------
cmLocalVisualStudio7Generator
-::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot):
- cmLocalVisualStudioGenerator(gg, parent, snapshot)
+::cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf):
+ cmLocalVisualStudioGenerator(gg, mf)
{
this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
}
@@ -70,20 +66,9 @@ cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
void cmLocalVisualStudio7Generator::AddHelperCommands()
{
- std::set<std::string> lang;
- lang.insert("C");
- lang.insert("CXX");
- lang.insert("RC");
- lang.insert("IDL");
- lang.insert("DEF");
- lang.insert("Fortran");
- this->CreateCustomTargetsAndCommands(lang);
-
// Now create GUIDs for targets
cmTargets &tgts = this->Makefile->GetTargets();
- cmGlobalVisualStudio7Generator* gg =
- static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{
if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
@@ -96,10 +81,6 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
this->ReadAndStoreExternalGUID(
l->second.GetName().c_str(), path);
}
- else
- {
- gg->CreateGUID(l->first.c_str());
- }
}
@@ -125,6 +106,10 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
// Add the rule to targets that need it.
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{
+ if (l->second.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ continue;
+ }
if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
{
l->second.AddSource(sf->GetFullPath());
@@ -305,13 +290,10 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
comment += makefileIn;
std::string args;
args = "-H";
- args += this->Convert(this->Makefile->GetHomeDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->Makefile->GetHomeDirectory();
commandLine.push_back(args);
args = "-B";
- args +=
- this->Convert(this->Makefile->GetHomeOutputDirectory(),
- START_OUTPUT, UNCHANGED, true);
+ args += this->Makefile->GetHomeOutputDirectory();
commandLine.push_back(args);
commandLine.push_back("--check-stamp-file");
std::string stampFilename = this->Convert(stampName.c_str(), FULL,
@@ -630,7 +612,7 @@ public:
}
void Write(cmCustomCommand const& cc)
{
- cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
+ cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
if(this->First)
{
const char* comment = ccg.GetComment();
@@ -680,6 +662,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
const char* configType = "10";
const char* projectType = 0;
bool targetBuilds = true;
+
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+
switch(target.GetType())
{
case cmTarget::OBJECT_LIBRARY:
@@ -712,7 +698,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
{
const std::string& linkLanguage = (this->FortranProject?
std::string("Fortran"):
- target.GetLinkerLanguage(configName));
+ gt->GetLinkerLanguage(configName));
if(linkLanguage.empty())
{
cmSystemTools::Error
@@ -774,10 +760,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
targetOptions.Parse(flags.c_str());
targetOptions.Parse(defineFlags.c_str());
targetOptions.ParseFinish();
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName, "CXX");
+ gt->GetCompileDefinitions(targetDefines, configName, "CXX");
targetOptions.AddDefines(targetDefines);
targetOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -819,7 +803,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
if (this->FortranProject)
{
// Intel Fortran >= 15.0 uses TargetName property.
- std::string targetNameFull = target.GetFullName(configName);
+ std::string targetNameFull = gt->GetFullName(configName);
std::string targetName =
cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
std::string targetExt =
@@ -897,7 +881,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
if(target.GetType() <= cmTarget::OBJECT_LIBRARY)
{
// Specify the compiler program database file if configured.
- std::string pdb = target.GetCompilePDBPath(configName);
+ std::string pdb = gt->GetCompilePDBPath(configName);
if(!pdb.empty())
{
fout << "\t\t\t\tProgramDataBaseFileName=\""
@@ -1087,9 +1071,20 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
if(!this->ModuleDefinitionFile.empty())
{
std::string defFile =
- this->ConvertToOptionallyRelativeOutputPath(this->ModuleDefinitionFile);
+ this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+
+ if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+ }
+ }
switch(target.GetType())
{
case cmTarget::UNKNOWN_LIBRARY:
@@ -1112,7 +1107,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
}
case cmTarget::STATIC_LIBRARY:
{
- std::string targetNameFull = target.GetFullName(configName);
+ std::string targetNameFull = gt->GetFullName(configName);
std::string libpath = target.GetDirectory(configName);
libpath += "/";
libpath += targetNameFull;
@@ -1152,11 +1147,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
- target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ gt->GetLibraryNames(targetName, targetNameSO, targetNameFull,
targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
if(!pcli)
{
return;
@@ -1249,11 +1244,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
std::string targetNameFull;
std::string targetNameImport;
std::string targetNamePDB;
- target.GetExecutableNames(targetName, targetNameFull,
+ gt->GetExecutableNames(targetName, targetNameFull,
targetNameImport, targetNamePDB, configName);
// Compute the link library and directory information.
- cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
if(!pcli)
{
return;
@@ -1472,10 +1467,13 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// We may be modifying the source groups temporarily, so make a copy.
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+
// get the classes from the source lists then add them to the groups
this->ModuleDefinitionFile = "";
std::vector<cmSourceFile*> classes;
- if (!target.GetConfigCommonSourceFiles(classes))
+ if (!gt->GetConfigCommonSourceFiles(classes))
{
return;
}
@@ -1517,8 +1515,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
{
// VS >= 8 support per-config source locations so we
// list object library content as external objects.
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> objs;
gt->UseObjectLibraries(objs, "");
if(!objs.empty())
@@ -1640,7 +1636,7 @@ cmLocalVisualStudio7GeneratorFCInfo
lg->GlobalGenerator->GetLanguageFromExtension
(sf.GetExtension().c_str());
const std::string& sourceLang = lg->GetSourceFileLanguage(sf);
- const std::string& linkLanguage = target.GetLinkerLanguage(i->c_str());
+ const std::string& linkLanguage = gt->GetLinkerLanguage(i->c_str());
bool needForceLang = false;
// source file does not match its extension language
if(lang != sourceLang)
@@ -1906,7 +1902,7 @@ WriteCustomRule(std::ostream& fout,
for (std::vector<std::string>::const_iterator i = configs.begin();
i != configs.end(); ++i)
{
- cmCustomCommandGenerator ccg(command, *i, this->Makefile);
+ cmCustomCommandGenerator ccg(command, *i, this);
cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
fout << "\t\t\t\t<FileConfiguration\n";
fout << "\t\t\t\t\tName=\"" << *i << "|"
@@ -2024,7 +2020,28 @@ void cmLocalVisualStudio7Generator
// Add pre-link event.
tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
event.Start(tool);
- event.Write(target.GetPreLinkCommands());
+ bool addedPrelink = false;
+ if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands =
+ target.GetPreLinkCommands();
+ cmGlobalVisualStudioGenerator* gg
+ = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+ gg->AddSymbolExportCommand(
+ gt, commands, configName);
+ event.Write(commands);
+ }
+ }
+ if (!addedPrelink)
+ {
+ event.Write(target.GetPreLinkCommands());
+ }
cmsys::auto_ptr<cmCustomCommand> pcc(
this->MaybeCreateImplibDir(target, configName, this->FortranProject));
if(pcc.get())
@@ -2234,7 +2251,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s)
std::string cmLocalVisualStudio7Generator
::ConvertToXMLOutputPath(const char* path)
{
- std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ std::string ret = this->ConvertToOutputFormat(path, SHELL);
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "\"", "&quot;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -2245,7 +2262,7 @@ std::string cmLocalVisualStudio7Generator
std::string cmLocalVisualStudio7Generator
::ConvertToXMLOutputPathSingle(const char* path)
{
- std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ std::string ret = this->ConvertToOutputFormat(path, SHELL);
cmSystemTools::ReplaceString(ret, "\"", "");
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
@@ -2265,7 +2282,7 @@ public:
virtual void StartElement(const std::string& name, const char** atts)
{
// once the GUID is found do nothing
- if(this->GUID.size())
+ if(!this->GUID.empty())
{
return;
}
@@ -2312,12 +2329,9 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
{
cmVS7XMLParser parser;
parser.ParseFile(path);
- // if we can not find a GUID then create one
- if(parser.GUID.size() == 0)
+ // if we can not find a GUID then we will generate one later
+ if(parser.GUID.empty())
{
- cmGlobalVisualStudio7Generator* gg =
- static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
- gg->CreateGUID(name);
return;
}
std::string guidStoreName = name;
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 43f3af9..bc05a06 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -35,9 +35,7 @@ class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalVisualStudio7Generator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalVisualStudio7Generator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudio7Generator();
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index ca72939..c0072de 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -19,10 +19,8 @@
//----------------------------------------------------------------------------
cmLocalVisualStudioGenerator
-::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : cmLocalGenerator(gg, parent, snapshot)
+::cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
{
}
@@ -57,7 +55,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
cmSourceFile const* sf = si->first;
std::string objectNameLower = cmSystemTools::LowerCase(
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
- objectNameLower += ".obj";
+ objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
counts[objectNameLower] += 1;
}
@@ -70,7 +68,7 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
cmSourceFile const* sf = si->first;
std::string objectName =
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
- objectName += ".obj";
+ objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
if(counts[cmSystemTools::LowerCase(objectName)] > 1)
{
const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index d414651..071bfb3 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -31,9 +31,7 @@ class cmCustomCommandGenerator;
class cmLocalVisualStudioGenerator : public cmLocalGenerator
{
public:
- cmLocalVisualStudioGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalVisualStudioGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
virtual ~cmLocalVisualStudioGenerator();
/** Construct a script from the given list of command lines. */
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 804dd7d..b19112d 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -16,9 +16,8 @@
//----------------------------------------------------------------------------
cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg,
- cmLocalGenerator* parent,
- cmState::Snapshot snapshot)
- : cmLocalGenerator(gg, parent, snapshot)
+ cmMakefile* mf)
+ : cmLocalGenerator(gg, mf)
{
// the global generator does this, so do not
// put these flags into the language flags
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
index 26fff9c..6d0926f 100644
--- a/Source/cmLocalXCodeGenerator.h
+++ b/Source/cmLocalXCodeGenerator.h
@@ -24,8 +24,8 @@ class cmLocalXCodeGenerator : public cmLocalGenerator
{
public:
///! Set cache only and recurse to false by default.
- cmLocalXCodeGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
- cmState::Snapshot snapshot);
+ cmLocalXCodeGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf);
virtual ~cmLocalXCodeGenerator();
virtual std::string GetTargetDirectory(cmTarget const& target) const;
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 7ac4432..e4026b0 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -96,12 +96,9 @@ bool cmMacroHelperCommand::InvokeInitialPass
return false;
}
- // Enforce matching logical blocks inside the macro.
- cmMakefile::LexicalPushPop lexScope(this->Makefile);
-
- // Push a weak policy scope which restores the policies recorded at
- // macro creation.
- cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies);
+ cmMakefile::MacroPushPop macroScope(this->Makefile,
+ this->FilePath,
+ this->Policies);
// set the value of argc
std::ostringstream argcDefStream;
@@ -110,7 +107,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
std::vector<std::string>::const_iterator eit
= expandedArgs.begin() + (this->Args.size() - 1);
- std::string expandedArgn = cmJoin(cmRange(eit, expandedArgs.end()), ";");
+ std::string expandedArgn = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
std::string expandedArgv = cmJoin(expandedArgs, ";");
std::vector<std::string> variables;
variables.reserve(this->Args.size() - 1);
@@ -126,10 +123,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
sprintf(argvName,"${ARGV%i}",j);
argVs.push_back(argvName);
}
- if(!this->Functions.empty())
- {
- this->FilePath = this->Functions[0].FilePath;
- }
// Invoke all the functions that were collected in the block.
cmListFileFunction newLFF;
// for each function
@@ -139,7 +132,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
newLFF.Arguments.clear();
newLFF.Arguments.reserve(this->Functions[c].Arguments.size());
newLFF.Name = this->Functions[c].Name;
- newLFF.FilePath = this->Functions[c].FilePath;
newLFF.Line = this->Functions[c].Line;
// for each argument of the current function
@@ -147,10 +139,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
this->Functions[c].Arguments.begin();
k != this->Functions[c].Arguments.end(); ++k)
{
- // Set the FilePath on the arguments to match the function since it is
- // not stored and the original values may be freed
- k->FilePath = this->FilePath.c_str();
-
cmListFileArgument arg;
arg.Value = k->Value;
if(k->Delim != cmListFileArgument::Bracket)
@@ -181,7 +169,6 @@ bool cmMacroHelperCommand::InvokeInitialPass
}
}
arg.Delim = k->Delim;
- arg.FilePath = k->FilePath;
arg.Line = k->Line;
newLFF.Arguments.push_back(arg);
}
@@ -191,8 +178,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
{
// The error message should have already included the call stack
// so we do not need to report an error here.
- lexScope.Quiet();
- polScope.Quiet();
+ macroScope.Quiet();
inStatus.SetNestedError(true);
return false;
}
@@ -225,11 +211,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
// if this is the endmacro for this macro then execute
if (!this->Depth)
{
- mf.AddMacro(this->Args[0].c_str());
+ mf.AppendProperty("MACROS", this->Args[0].c_str());
// create a new command and add it to cmake
cmMacroHelperCommand *f = new cmMacroHelperCommand();
f->Args = this->Args;
f->Functions = this->Functions;
+ f->FilePath = this->GetStartingContext().FilePath;
mf.RecordPolicies(f->Policies);
std::string newName = "_" + this->Args[0];
mf.GetState()->RenameCommand(this->Args[0], newName);
@@ -259,7 +246,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro"))
{
std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
// if the endmacro has arguments make sure they
// match the arguments of the macro
if ((expandedArguments.empty() ||
diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx
index a6d4e58..cbc7e02 100644
--- a/Source/cmMakeDepend.cxx
+++ b/Source/cmMakeDepend.cxx
@@ -49,7 +49,7 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile)
// Now extract the include file regular expression from the makefile.
this->IncludeFileRegularExpression.compile(
- this->Makefile->IncludeFileRegularExpression.c_str());
+ this->Makefile->GetIncludeRegularExpression());
this->ComplainFileRegularExpression.compile(
this->Makefile->ComplainFileRegularExpression.c_str());
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index bdc55f2..8a3d197 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -16,10 +16,11 @@
#include "cmSourceFileLocation.h"
#include "cmSystemTools.h"
#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
#include "cmCommands.h"
#include "cmState.h"
+#include "cmOutputConverter.h"
#include "cmFunctionBlocker.h"
+#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmListFileCache.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmGeneratorExpression.h"
@@ -29,7 +30,6 @@
#endif
#include "cmInstallGenerator.h"
#include "cmTestGenerator.h"
-#include "cmDefinitions.h"
#include "cmAlgorithms.h"
#include "cmake.h"
#include <stdlib.h> // required for atoi
@@ -42,115 +42,23 @@
#include <ctype.h> // for isspace
#include <assert.h>
-class cmMakefile::Internals
-{
-public:
- std::list<cmDefinitions> VarStack;
- bool IsSourceFileTryCompile;
-
- void PushDefinitions()
- {
- this->VarStack.push_back(cmDefinitions());
- }
-
- void InitializeDefinitions(cmMakefile* parent)
- {
- this->VarStack.back() =
- cmDefinitions::MakeClosure(parent->Internal->VarStack.rbegin(),
- parent->Internal->VarStack.rend());
- }
-
- const char* GetDefinition(std::string const& name)
- {
- return cmDefinitions::Get(name, this->VarStack.rbegin(),
- this->VarStack.rend());
- }
-
- bool IsInitialized(std::string const& name)
- {
- return cmDefinitions::HasKey(name, this->VarStack.rbegin(),
- this->VarStack.rend());
- }
-
- void SetDefinition(std::string const& name, std::string const& value)
- {
- this->VarStack.back().Set(name, value.c_str());
- }
-
- void RemoveDefinition(std::string const& name)
- {
- this->VarStack.back().Set(name, 0);
- }
-
- std::vector<std::string> UnusedKeys() const
- {
- return this->VarStack.back().UnusedKeys();
- }
-
- std::vector<std::string> ClosureKeys() const
- {
- return cmDefinitions::ClosureKeys(this->VarStack.rbegin(),
- this->VarStack.rend());
- }
-
- void PopDefinitions()
- {
- this->VarStack.pop_back();
- }
-
- bool RaiseScope(std::string const& var, const char* varDef, cmMakefile* mf)
- {
- std::list<cmDefinitions>::reverse_iterator it = this->VarStack.rbegin();
- assert(it != this->VarStack.rend());
- ++it;
- if(it == this->VarStack.rend())
- {
- cmLocalGenerator* plg = mf->GetLocalGenerator()->GetParent();
- if(!plg)
- {
- return false;
- }
- // Update the definition in the parent directory top scope. This
- // directory's scope was initialized by the closure of the parent
- // scope, so we do not need to localize the definition first.
- cmMakefile* parent = plg->GetMakefile();
- if (varDef)
- {
- parent->AddDefinition(var, varDef);
- }
- else
- {
- parent->RemoveDefinition(var);
- }
- return true;
- }
- // First localize the definition in the current scope.
- cmDefinitions::Raise(var, this->VarStack.rbegin(), this->VarStack.rend());
-
- // Now update the definition in the parent scope.
- it->Set(var, varDef);
- return true;
- }
-};
-
// default is not to be building executables
-cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
- : Internal(new Internals),
- LocalGenerator(localGenerator),
- StateSnapshot(localGenerator->GetStateSnapshot())
+cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
+ cmState::Snapshot const& snapshot)
+ : GlobalGenerator(globalGenerator),
+ StateSnapshot(snapshot)
{
- this->Internal->PushDefinitions();
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
// Initialize these first since AddDefaultDefinitions calls AddDefinition
this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
- this->GeneratingBuildSystem = false;
+ this->Configured = false;
this->SuppressWatches = false;
// Setup the default include file regular expression (match everything).
- this->IncludeFileRegularExpression = "^.*$";
+ this->SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$");
// Setup the default include complaint regular expression (match nothing).
this->ComplainFileRegularExpression = "^$";
// Source and header file extensions that we can handle
@@ -188,12 +96,12 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
+ this->StateSnapshot = this->StateSnapshot.GetState()
+ ->CreatePolicyScopeSnapshot(this->StateSnapshot);
+
// Enter a policy level for this directory.
this->PushPolicy();
- // Protect the directory-level policies.
- this->PushPolicyBarrier();
-
// push empty loop block
this->PushLoopBlockBarrier();
@@ -213,8 +121,6 @@ cmMakefile::cmMakefile(cmLocalGenerator* localGenerator)
this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
#endif
- this->Properties.SetCMakeInstance(this->GetCMakeInstance());
-
{
const char* dir = this->GetCMakeInstance()->GetHomeDirectory();
this->AddDefinition("CMAKE_SOURCE_DIR", dir);
@@ -236,12 +142,10 @@ cmMakefile::~cmMakefile()
cmDeleteAll(this->ImportedTargetsOwned);
cmDeleteAll(this->FinalPassCommands);
cmDeleteAll(this->FunctionBlockers);
+ cmDeleteAll(this->EvaluationFiles);
+ this->EvaluationFiles.clear();
+
this->FunctionBlockers.clear();
- if (this->PolicyStack.size() != 1)
- {
- cmSystemTools::Error("Internal CMake Error, Policy Stack has not been"
- " popped properly");
- }
}
//----------------------------------------------------------------------------
@@ -249,11 +153,11 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
std::string const& text) const
{
// Collect context information.
- if(!this->CallStack.empty())
+ if(!this->ExecutionStatusStack.empty())
{
if((t == cmake::FATAL_ERROR) || (t == cmake::INTERNAL_ERROR))
{
- this->CallStack.back().Status->SetNestedError(true);
+ this->ExecutionStatusStack.back()->SetNestedError(true);
}
this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
}
@@ -262,46 +166,99 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
cmListFileContext lfc;
// We are not currently executing a command. Add whatever context
// information we have.
- lfc.FilePath = this->ListFileStack.back();
+ lfc.FilePath = this->GetExecutionFilePath();
if(!this->GetCMakeInstance()->GetIsInTryCompile())
{
- lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
- cmLocalGenerator::HOME);
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
}
lfc.Line = 0;
this->GetCMakeInstance()->IssueMessage(t, text, lfc);
}
}
+cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
+{
+ return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
+}
+
+cmBacktraceRange cmMakefile::GetIncludeDirectoriesBacktraces() const
+{
+ return this->StateSnapshot.GetDirectory()
+ .GetIncludeDirectoriesEntryBacktraces();
+}
+
+cmStringRange cmMakefile::GetCompileOptionsEntries() const
+{
+ return this->StateSnapshot.GetDirectory().GetCompileOptionsEntries();
+}
+
+cmBacktraceRange cmMakefile::GetCompileOptionsBacktraces() const
+{
+ return this->StateSnapshot.GetDirectory().GetCompileOptionsEntryBacktraces();
+}
+
+cmStringRange cmMakefile::GetCompileDefinitionsEntries() const
+{
+ return this->StateSnapshot.GetDirectory().GetCompileDefinitionsEntries();
+}
+
+cmBacktraceRange cmMakefile::GetCompileDefinitionsBacktraces() const
+{
+ return this->StateSnapshot.GetDirectory()
+ .GetCompileDefinitionsEntryBacktraces();
+}
+
//----------------------------------------------------------------------------
cmListFileBacktrace cmMakefile::GetBacktrace() const
{
- cmListFileBacktrace backtrace(this->GetLocalGenerator());
- for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
- i != this->CallStack.rend(); ++i)
+ cmListFileBacktrace backtrace;
+ if (!this->ContextStack.empty())
{
- backtrace.Append(*i->Context);
+ backtrace = cmListFileBacktrace(this->StateSnapshot,
+ *this->ContextStack.back());
}
return backtrace;
}
//----------------------------------------------------------------------------
+cmListFileBacktrace
+cmMakefile::GetBacktrace(cmCommandContext const& cc) const
+{
+ cmState::Snapshot snp = this->StateSnapshot;
+ return cmListFileBacktrace(snp, cc);
+}
+
+//----------------------------------------------------------------------------
cmListFileContext cmMakefile::GetExecutionContext() const
{
- return *this->CallStack.back().Context;
+ return cmListFileContext::FromCommandContext(
+ *this->ContextStack.back(),
+ this->StateSnapshot.GetExecutionListFile());
}
//----------------------------------------------------------------------------
void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
{
std::ostringstream msg;
- msg << lff.FilePath << "(" << lff.Line << "): ";
+ msg << this->GetExecutionFilePath() << "(" << lff.Line << "): ";
msg << lff.Name << "(";
+ bool expand = this->GetCMakeInstance()->GetTraceExpand();
+ std::string temp;
for(std::vector<cmListFileArgument>::const_iterator i =
lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
{
- msg << i->Value;
+ if (expand)
+ {
+ temp = i->Value;
+ this->ExpandVariablesInString(temp);
+ msg << temp;
+ }
+ else
+ {
+ msg << i->Value;
+ }
msg << " ";
}
msg << ")";
@@ -397,12 +354,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
class cmMakefile::IncludeScope
{
public:
- IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
+ IncludeScope(cmMakefile* mf, std::string const& filenametoread,
+ bool noPolicyScope);
~IncludeScope();
void Quiet() { this->ReportError = false; }
private:
cmMakefile* Makefile;
- const char* File;
bool NoPolicyScope;
bool CheckCMP0011;
bool ReportError;
@@ -410,11 +367,20 @@ private:
};
//----------------------------------------------------------------------------
-cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
+cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
+ std::string const& filenametoread,
bool noPolicyScope):
- Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
+ Makefile(mf), NoPolicyScope(noPolicyScope),
CheckCMP0011(false), ReportError(true)
{
+ this->Makefile->PushFunctionBlockerBarrier();
+
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateCallStackSnapshot(
+ this->Makefile->StateSnapshot,
+ this->Makefile->ContextStack.back()->Name,
+ this->Makefile->ContextStack.back()->Line,
+ filenametoread);
if(!this->NoPolicyScope)
{
// Check CMP0011 to determine the policy scope type.
@@ -443,24 +409,19 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
break;
}
}
-
- // The included file cannot pop our policy scope.
- this->Makefile->PushPolicyBarrier();
}
//----------------------------------------------------------------------------
cmMakefile::IncludeScope::~IncludeScope()
{
- // Enforce matching policy scopes inside the included file.
- this->Makefile->PopPolicyBarrier(this->ReportError);
-
if(!this->NoPolicyScope)
{
// If we need to enforce policy CMP0011 then the top entry is the
// one we pushed above. If the entry is empty, then the included
// script did not set any policies that might affect the includer so
// we do not need to enforce the policy.
- if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().IsEmpty())
+ if(this->CheckCMP0011
+ && !this->Makefile->StateSnapshot.HasDefinedPolicyCMP0011())
{
this->CheckCMP0011 = false;
}
@@ -475,6 +436,9 @@ cmMakefile::IncludeScope::~IncludeScope()
this->EnforceCMP0011();
}
}
+ this->Makefile->PopPolicyBarrier(this->ReportError);
+
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
}
//----------------------------------------------------------------------------
@@ -489,7 +453,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
{
std::ostringstream w;
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0011) << "\n"
- << "The included script\n " << this->File << "\n"
+ << "The included script\n "
+ << this->Makefile->GetExecutionFilePath() << "\n"
<< "affects policy settings. "
<< "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
<< "so the effects are applied to the including context.";
@@ -501,7 +466,8 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
{
std::ostringstream e;
e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
- << "The included script\n " << this->File << "\n"
+ << "The included script\n "
+ << this->Makefile->GetExecutionFilePath() << "\n"
<< "affects policy settings, so it requires this policy to be set.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -515,38 +481,116 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
}
}
-bool cmMakefile::ProcessBuildsystemFile(const char* listfile)
+class cmParseFileScope
{
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", listfile);
- std::string curSrc = this->GetCurrentSourceDirectory();
- return this->ReadListFile(listfile, true,
- curSrc == this->GetHomeDirectory());
-}
+public:
+ cmParseFileScope(cmMakefile* mf)
+ : Makefile(mf)
+ {
+ this->Makefile->ContextStack.push_back(&this->Context);
+ }
+
+ ~cmParseFileScope()
+ {
+ this->Makefile->ContextStack.pop_back();
+ }
+
+private:
+ cmMakefile* Makefile;
+ cmCommandContext Context;
+};
-bool cmMakefile::ReadDependentFile(const char* listfile, bool noPolicyScope)
+bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
{
this->AddDefinition("CMAKE_PARENT_LIST_FILE",
this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
- bool result = this->ReadListFile(listfile, noPolicyScope, false);
- this->ListFileStack.pop_back();
- return result;
+ std::string filenametoread =
+ cmSystemTools::CollapseFullPath(filename,
+ this->GetCurrentSourceDirectory());
+
+ IncludeScope incScope(this, filenametoread, noPolicyScope);
+
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(filenametoread.c_str(), false, this))
+ {
+ return false;
+ }
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if(cmSystemTools::GetFatalErrorOccured())
+ {
+ incScope.Quiet();
+ }
+ return true;
}
-bool cmMakefile::ReadListFile(const char* listfile)
+class cmMakefile::ListFileScope
{
- bool result = this->ReadListFile(listfile, true, false);
- this->ListFileStack.pop_back();
- return result;
-}
+public:
+ ListFileScope(cmMakefile* mf, std::string const& filenametoread)
+ : Makefile(mf), ReportError(true)
+ {
+ long line = 0;
+ std::string name;
+ if (!this->Makefile->ContextStack.empty())
+ {
+ line = this->Makefile->ContextStack.back()->Line;
+ name = this->Makefile->ContextStack.back()->Name;
+ }
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateInlineListFileSnapshot(
+ this->Makefile->StateSnapshot, name, line, filenametoread);
+ assert(this->Makefile->StateSnapshot.IsValid());
+
+ this->Makefile->PushFunctionBlockerBarrier();
+ }
+
+ ~ListFileScope()
+ {
+ this->Makefile->PopPolicyBarrier(this->ReportError);
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ }
+
+ void Quiet() { this->ReportError = false; }
+private:
+ cmMakefile* Makefile;
+ bool ReportError;
+};
-bool cmMakefile::ReadListFile(const char* listfile,
- bool noPolicyScope,
- bool requireProjectCommand)
+bool cmMakefile::ReadListFile(const char* filename)
{
std::string filenametoread =
- cmSystemTools::CollapseFullPath(listfile,
+ cmSystemTools::CollapseFullPath(filename,
this->GetCurrentSourceDirectory());
+ ListFileScope scope(this, filenametoread);
+
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(filenametoread.c_str(), false, this))
+ {
+ return false;
+ }
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if(cmSystemTools::GetFatalErrorOccured())
+ {
+ scope.Quiet();
+ }
+ return true;
+}
+
+void cmMakefile::ReadListFile(cmListFile const& listFile,
+ std::string const& filenametoread)
+{
+ // add this list file to the list of dependencies
+ this->ListFiles.push_back(filenametoread);
+
std::string currentParentFile
= this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
std::string currentFile
@@ -560,55 +604,14 @@ bool cmMakefile::ReadListFile(const char* listfile,
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
- this->ListFileStack.push_back(filenametoread);
-
- bool res = this->ReadListFileInternal(filenametoread.c_str(),
- noPolicyScope, requireProjectCommand);
-
- this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
- this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
- this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
- cmSystemTools::GetFilenamePath(currentFile).c_str());
- this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
- this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
-
- if (res)
- {
- this->CheckForUnusedVariables();
- }
-
- return res;
-}
-
-bool cmMakefile::ReadListFileInternal(const char* filenametoread,
- bool noPolicyScope,
- bool requireProjectCommand)
-{
- cmListFile cacheFile;
- if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
- {
- return false;
- }
- // add this list file to the list of dependencies
- this->ListFiles.push_back( filenametoread);
-
- // Enforce balanced blocks (if/endif, function/endfunction, etc.).
- {
- LexicalPushPop lexScope(this);
- IncludeScope incScope(this, filenametoread, noPolicyScope);
-
// Run the parsed commands.
- const size_t numberFunctions = cacheFile.Functions.size();
+ const size_t numberFunctions = listFile.Functions.size();
for(size_t i =0; i < numberFunctions; ++i)
{
cmExecutionStatus status;
- this->ExecuteCommand(cacheFile.Functions[i],status);
+ this->ExecuteCommand(listFile.Functions[i],status);
if(cmSystemTools::GetFatalErrorOccured())
{
- // Exit early due to error.
- lexScope.Quiet();
- incScope.Quiet();
break;
}
if(status.GetReturnInvoked())
@@ -617,16 +620,15 @@ bool cmMakefile::ReadListFileInternal(const char* filenametoread,
break;
}
}
- }
-
- // If this is the directory-level CMakeLists.txt file then perform
- // some extra checks.
- if(this->ListFileStack.size() == 1)
- {
- this->EnforceDirectoryLevelRules();
- }
+ this->CheckForUnusedVariables();
- return true;
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
+ this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
+ this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
+ cmSystemTools::GetFilenamePath(currentFile).c_str());
+ this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
+ this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
+ this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
}
//----------------------------------------------------------------------------
@@ -668,6 +670,23 @@ void cmMakefile::EnforceDirectoryLevelRules() const
}
}
+void cmMakefile::AddEvaluationFile(const std::string& inputFile,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+ bool inputIsContent)
+{
+ this->EvaluationFiles.push_back(
+ new cmGeneratorExpressionEvaluationFile(inputFile, outputName,
+ condition,
+ inputIsContent));
+}
+
+std::vector<cmGeneratorExpressionEvaluationFile*>
+cmMakefile::GetEvaluationFiles() const
+{
+ return this->EvaluationFiles;
+}
+
namespace
{
struct file_not_persistent
@@ -1096,15 +1115,16 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target,
}
//----------------------------------------------------------------------------
-void cmMakefile::AddUtilityCommand(const std::string& utilityName,
- bool excludeFromAll,
- const std::vector<std::string>& depends,
- const char* workingDirectory,
- const char* command,
- const char* arg1,
- const char* arg2,
- const char* arg3,
- const char* arg4)
+cmTarget*
+cmMakefile::AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const std::vector<std::string>& depends,
+ const char* workingDirectory,
+ const char* command,
+ const char* arg1,
+ const char* arg2,
+ const char* arg3,
+ const char* arg4)
{
// Construct the command line for the custom command.
cmCustomCommandLine commandLine;
@@ -1129,8 +1149,8 @@ void cmMakefile::AddUtilityCommand(const std::string& utilityName,
commandLines.push_back(commandLine);
// Call the real signature of this method.
- this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
- depends, commandLines);
+ return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
+ depends, commandLines);
}
//----------------------------------------------------------------------------
@@ -1361,7 +1381,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
std::remove(defs.begin(), defs.end(), define);
std::vector<std::string>::const_iterator defBegin =
defs.begin();
- std::string ndefs = cmJoin(cmRange(defBegin, defEnd), ";");
+ std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
// Store the new list.
this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
@@ -1451,61 +1471,15 @@ void cmMakefile::AddLinkLibrary(const std::string& lib)
this->AddLinkLibrary(lib,cmTarget::GENERAL);
}
-void cmMakefile::AddLinkDirectory(const std::string& dir)
-{
- // Don't add a link directory that is already present. Yes, this
- // linear search results in n^2 behavior, but n won't be getting
- // much bigger than 20. We cannot use a set because of order
- // dependency of the link search path.
-
- if(dir.empty())
- {
- return;
- }
- std::string newdir = dir;
- // remove trailing slashes
- if(*dir.rbegin() == '/')
- {
- newdir = dir.substr(0, dir.size()-1);
- }
- if(std::find(this->LinkDirectories.begin(),
- this->LinkDirectories.end(), newdir)
- == this->LinkDirectories.end())
- {
- this->LinkDirectories.push_back(dir);
- }
-}
-
-void cmMakefile::InitializeFromParent()
+void cmMakefile::InitializeFromParent(cmMakefile* parent)
{
- cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
-
- // Initialize definitions with the closure of the parent scope.
- this->Internal->InitializeDefinitions(parent);
+ this->StateSnapshot.InitializeFromParent();
this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
this->GetCurrentSourceDirectory());
this->AddDefinition("CMAKE_CURRENT_BINARY_DIR",
this->GetCurrentBinaryDirectory());
- const std::vector<cmValueWithOrigin>& parentIncludes =
- parent->GetIncludeDirectoriesEntries();
- this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
- parentIncludes.begin(),
- parentIncludes.end());
-
- const std::vector<cmValueWithOrigin>& parentOptions =
- parent->GetCompileOptionsEntries();
- this->CompileOptionsEntries.insert(this->CompileOptionsEntries.end(),
- parentOptions.begin(),
- parentOptions.end());
-
- const std::vector<cmValueWithOrigin>& parentDefines =
- parent->GetCompileDefinitionsEntries();
- this->CompileDefinitionsEntries.insert(this->CompileDefinitionsEntries.end(),
- parentDefines.begin(),
- parentDefines.end());
-
this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
// define flags
@@ -1540,23 +1514,178 @@ void cmMakefile::InitializeFromParent()
this->LinkLibraries = parent->LinkLibraries;
// link directories
- this->LinkDirectories = parent->LinkDirectories;
+ this->SetProperty("LINK_DIRECTORIES",
+ parent->GetProperty("LINK_DIRECTORIES"));
// the initial project name
- this->ProjectName = parent->ProjectName;
+ this->SetProjectName(parent->GetProjectName());
// Copy include regular expressions.
- this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
// Imported targets.
this->ImportedTargets = parent->ImportedTargets;
}
-void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
+void cmMakefile::PushFunctionScope(std::string const& fileName,
+ const cmPolicies::PolicyMap& pm)
+{
+ this->StateSnapshot =
+ this->GetState()->CreateFunctionCallSnapshot(
+ this->StateSnapshot,
+ this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+ fileName);
+ assert(this->StateSnapshot.IsValid());
+
+ this->PushLoopBlockBarrier();
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
+#endif
+
+ this->PushFunctionBlockerBarrier();
+
+ this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopFunctionScope(bool reportError)
+{
+ this->PopPolicy();
+
+ this->PopPolicyBarrier(reportError);
+
+ this->PopFunctionBlockerBarrier(reportError);
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
+#endif
+
+ this->PopLoopBlockBarrier();
+
+ this->CheckForUnusedVariables();
+}
+
+void cmMakefile::PushMacroScope(std::string const& fileName,
+ const cmPolicies::PolicyMap& pm)
+{
+ this->StateSnapshot =
+ this->GetState()->CreateMacroCallSnapshot(
+ this->StateSnapshot,
+ this->ContextStack.back()->Name, this->ContextStack.back()->Line,
+ fileName);
+ assert(this->StateSnapshot.IsValid());
+
+ this->PushFunctionBlockerBarrier();
+
+ this->PushPolicy(true, pm);
+}
+
+void cmMakefile::PopMacroScope(bool reportError)
+{
+ this->PopPolicy();
+ this->PopPolicyBarrier(reportError);
+
+ this->PopFunctionBlockerBarrier(reportError);
+}
+
+bool cmMakefile::IsRootMakefile() const
+{
+ return !this->StateSnapshot.GetBuildsystemDirectoryParent().IsValid();
+}
+
+class cmMakefile::BuildsystemFileScope
+{
+public:
+ BuildsystemFileScope(cmMakefile* mf)
+ : Makefile(mf), ReportError(true)
+ {
+ std::string currentStart =
+ this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource();
+ currentStart += "/CMakeLists.txt";
+ this->Makefile->StateSnapshot.SetListFile(currentStart);
+ this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
+ ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
+ this->Makefile->PushFunctionBlockerBarrier();
+
+ this->GG = mf->GetGlobalGenerator();
+ this->CurrentMakefile = this->GG->GetCurrentMakefile();
+ this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
+ this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+ this->GG->SetCurrentMakefile(mf);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GG->GetFileLockPool().PushFileScope();
+#endif
+ }
+
+ ~BuildsystemFileScope()
+ {
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ this->Makefile->PopPolicyBarrier(this->ReportError);
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ this->GG->GetFileLockPool().PopFileScope();
+#endif
+ this->GG->SetCurrentMakefile(this->CurrentMakefile);
+ this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
+ }
+
+ void Quiet() { this->ReportError = false; }
+private:
+ cmMakefile* Makefile;
+ cmGlobalGenerator* GG;
+ cmMakefile* CurrentMakefile;
+ cmState::Snapshot Snapshot;
+ bool ReportError;
+};
+
+//----------------------------------------------------------------------------
+void cmMakefile::Configure()
+{
+ BuildsystemFileScope scope(this);
+
+ // make sure the CMakeFiles dir is there
+ std::string filesDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ filesDir += cmake::GetCMakeFilesDirectory();
+ cmSystemTools::MakeDirectory(filesDir.c_str());
+
+ std::string currentStart =
+ this->StateSnapshot.GetDirectory().GetCurrentSource();
+ currentStart += "/CMakeLists.txt";
+ assert(cmSystemTools::FileExists(currentStart.c_str(), true));
+ this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
+
+ cmListFile listFile;
+ {
+ cmParseFileScope pfs(this);
+ if (!listFile.ParseFile(currentStart.c_str(), this->IsRootMakefile(), this))
+ {
+ this->SetConfigured();
+ return;
+ }
+ }
+ this->ReadListFile(listFile, currentStart);
+ if(cmSystemTools::GetFatalErrorOccured())
+ {
+ scope.Quiet();
+ }
+
+ // at the end handle any old style subdirs
+ std::vector<cmMakefile*> subdirs = this->UnConfiguredDirectories;
+
+ // for each subdir recurse
+ std::vector<cmMakefile*>::iterator sdi = subdirs.begin();
+ for (; sdi != subdirs.end(); ++sdi)
+ {
+ this->ConfigureSubDirectory(*sdi);
+ }
+
+ this->AddCMakeDependFilesFromUser();
+ this->SetConfigured();
+}
+
+void cmMakefile::ConfigureSubDirectory(cmMakefile *mf)
{
- lg2->GetMakefile()->InitializeFromParent();
- std::string currentStart = lg2->GetMakefile()->GetCurrentSourceDirectory();
+ mf->InitializeFromParent(this);
+ std::string currentStart = mf->GetCurrentSourceDirectory();
if (this->GetCMakeInstance()->GetDebugOutput())
{
std::string msg=" Entering ";
@@ -1594,11 +1723,12 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
// NEW behavior prints the error.
this->IssueMessage(cmake::FATAL_ERROR, e.str());
}
- lg2->SetConfiguredCMP0014(true);
+ mf->SetConfigured();
return;
}
// finally configure the subdir
- lg2->Configure();
+ mf->Configure();
+
if (this->GetCMakeInstance()->GetDebugOutput())
{
std::string msg=" Returning to ";
@@ -1619,50 +1749,65 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
}
cmState::Snapshot newSnapshot = this->GetState()
- ->CreateSnapshot(this->StateSnapshot);
+ ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot,
+ this->ContextStack.back()->Name,
+ this->ContextStack.back()->Line);
+
+ cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
+ this->GetGlobalGenerator()->AddMakefile(subMf);
// create a new local generator and set its parent
cmLocalGenerator *lg2 = this->GetGlobalGenerator()
- ->MakeLocalGenerator(newSnapshot, this->LocalGenerator);
+ ->CreateLocalGenerator(subMf);
this->GetGlobalGenerator()->AddLocalGenerator(lg2);
// set the subdirs start dirs
- lg2->GetMakefile()->SetCurrentSourceDirectory(srcPath);
- lg2->GetMakefile()->SetCurrentBinaryDirectory(binPath);
+ subMf->SetCurrentSourceDirectory(srcPath);
+ subMf->SetCurrentBinaryDirectory(binPath);
if(excludeFromAll)
{
- lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
if (immediate)
{
- this->ConfigureSubDirectory(lg2);
+ this->ConfigureSubDirectory(subMf);
+ }
+ else
+ {
+ this->UnConfiguredDirectories.push_back(subMf);
}
}
void cmMakefile::SetCurrentSourceDirectory(const std::string& dir)
{
- this->StateSnapshot.SetCurrentSourceDirectory(dir);
+ this->StateSnapshot.GetDirectory().SetCurrentSource(dir);
this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR",
- this->StateSnapshot.GetCurrentSourceDirectory());
+ this->StateSnapshot.GetDirectory().GetCurrentSource());
}
const char* cmMakefile::GetCurrentSourceDirectory() const
{
- return this->StateSnapshot.GetCurrentSourceDirectory();
+ return this->StateSnapshot.GetDirectory().GetCurrentSource();
}
void cmMakefile::SetCurrentBinaryDirectory(const std::string& dir)
{
- this->StateSnapshot.SetCurrentBinaryDirectory(dir);
- const char* binDir = this->StateSnapshot.GetCurrentBinaryDirectory();
+ this->StateSnapshot.GetDirectory().SetCurrentBinary(dir);
+ const char* binDir = this->StateSnapshot.GetDirectory().GetCurrentBinary();
cmSystemTools::MakeDirectory(binDir);
this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", binDir);
}
const char* cmMakefile::GetCurrentBinaryDirectory() const
{
- return this->StateSnapshot.GetCurrentBinaryDirectory();
+ return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+}
+
+void cmMakefile::AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt)
+{
+ this->GeneratorTargets[t] = gt;
+ this->GetGlobalGenerator()->AddGeneratorTarget(t, gt);
}
//----------------------------------------------------------------------------
@@ -1674,20 +1819,25 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
return;
}
- std::vector<cmValueWithOrigin>::iterator position =
- before ? this->IncludeDirectoriesEntries.begin()
- : this->IncludeDirectoriesEntries.end();
-
cmListFileBacktrace lfbt = this->GetBacktrace();
- cmValueWithOrigin entry(cmJoin(incs, ";"), lfbt);
- this->IncludeDirectoriesEntries.insert(position, entry);
+ std::string entryString = cmJoin(incs, ";");
+ if (before)
+ {
+ this->StateSnapshot.GetDirectory()
+ .PrependIncludeDirectoriesEntry(entryString, lfbt);
+ }
+ else
+ {
+ this->StateSnapshot.GetDirectory()
+ .AppendIncludeDirectoriesEntry(entryString, lfbt);
+ }
// Property on each target:
for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); ++l)
{
cmTarget &t = l->second;
- t.InsertInclude(entry, before);
+ t.InsertInclude(entryString, lfbt, before);
}
}
@@ -1716,7 +1866,7 @@ void cmMakefile::AddDefinition(const std::string& name, const char* value)
{
this->LogUnused("changing definition", name);
}
- this->Internal->SetDefinition(name, value);
+ this->StateSnapshot.SetDefinition(name, value);
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
@@ -1779,7 +1929,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
this->GetState()->AddCacheEntry(name, haveVal ? val.c_str() : 0,
doc, type);
// if there was a definition then remove it
- this->Internal->RemoveDefinition(name);
+ this->StateSnapshot.RemoveDefinition(name);
}
@@ -1789,7 +1939,9 @@ void cmMakefile::AddDefinition(const std::string& name, bool value)
{
this->LogUnused("changing definition", name);
}
- this->Internal->SetDefinition(name, value ? "ON" : "OFF");
+
+ this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF");
+
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -1806,7 +1958,7 @@ void cmMakefile::CheckForUnusedVariables() const
{
return;
}
- const std::vector<std::string>& unused = this->Internal->UnusedKeys();
+ const std::vector<std::string>& unused = this->StateSnapshot.UnusedKeys();
std::vector<std::string>::const_iterator it = unused.begin();
for (; it != unused.end(); ++it)
{
@@ -1816,12 +1968,12 @@ void cmMakefile::CheckForUnusedVariables() const
void cmMakefile::MarkVariableAsUsed(const std::string& var)
{
- this->Internal->GetDefinition(var);
+ this->StateSnapshot.GetDefinition(var);
}
bool cmMakefile::VariableInitialized(const std::string& var) const
{
- return this->Internal->IsInitialized(var);
+ return this->StateSnapshot.IsInitialized(var);
}
void cmMakefile::LogUnused(const char* reason,
@@ -1831,7 +1983,7 @@ void cmMakefile::LogUnused(const char* reason,
{
std::string path;
cmListFileContext lfc;
- if (!this->CallStack.empty())
+ if (!this->ExecutionStatusStack.empty())
{
lfc = this->GetExecutionContext();
path = lfc.FilePath;
@@ -1843,8 +1995,8 @@ void cmMakefile::LogUnused(const char* reason,
lfc.FilePath = path;
lfc.Line = 0;
}
- lfc.FilePath = this->LocalGenerator->Convert(lfc.FilePath,
- cmLocalGenerator::HOME);
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
if (this->CheckSystemVars ||
cmSystemTools::IsSubDirectory(path,
@@ -1869,7 +2021,7 @@ void cmMakefile::RemoveDefinition(const std::string& name)
{
this->LogUnused("unsetting", name);
}
- this->Internal->RemoveDefinition(name);
+ this->StateSnapshot.RemoveDefinition(name);
#ifdef CMAKE_BUILD_WITH_CMAKE
cmVariableWatch* vv = this->GetVariableWatch();
if ( vv )
@@ -1885,11 +2037,15 @@ void cmMakefile::RemoveCacheDefinition(const std::string& name)
this->GetState()->RemoveCacheEntry(name);
}
-void cmMakefile::SetProjectName(const char* p)
+void cmMakefile::SetProjectName(std::string const& p)
{
- this->ProjectName = p;
+ this->StateSnapshot.SetProjectName(p);
}
+std::string cmMakefile::GetProjectName() const
+{
+ return this->StateSnapshot.GetProjectName();
+}
void cmMakefile::AddGlobalLinkInformation(const std::string& name,
cmTarget& target)
@@ -1903,11 +2059,27 @@ void cmMakefile::AddGlobalLinkInformation(const std::string& name,
return;
default:;
}
- std::vector<std::string>::iterator j;
- for(j = this->LinkDirectories.begin();
- j != this->LinkDirectories.end(); ++j)
+ if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
{
- target.AddLinkDirectory(*j);
+ std::vector<std::string> linkDirs;
+ cmSystemTools::ExpandListArgument(linkDirsProp, linkDirs);
+
+ for(std::vector<std::string>::iterator j = linkDirs.begin();
+ j != linkDirs.end(); ++j)
+ {
+ std::string newdir = *j;
+ // remove trailing slashes
+ if(*j->rbegin() == '/')
+ {
+ newdir = j->substr(0, j->size()-1);
+ }
+ if(std::find(this->LinkDirectories.begin(),
+ this->LinkDirectories.end(), newdir)
+ == this->LinkDirectories.end())
+ {
+ target.AddLinkDirectory(*j);
+ }
+ }
}
target.MergeLinkLibraries( *this, name, this->LinkLibraries );
}
@@ -2116,25 +2288,10 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
return;
}
// build the whole source group path
- const char* fullname = sg->GetFullName();
- cmGlobalGenerator* gg = this->GetGlobalGenerator();
- if(strlen(fullname))
- {
- std::string guidName = "SG_Filter_";
- guidName += fullname;
- gg->CreateGUID(guidName);
- }
for(++i; i<=lastElement; ++i)
{
sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
sg = sg->LookupChild(name[i].c_str());
- fullname = sg->GetFullName();
- if(strlen(fullname))
- {
- std::string guidName = "SG_Filter_";
- guidName += fullname;
- gg->CreateGUID(guidName);
- }
}
sg->SetGroupRegex(regex);
@@ -2177,7 +2334,8 @@ void cmMakefile::ExpandVariablesCMP0019()
l != this->Targets.end(); ++l)
{
cmTarget &t = l->second;
- if (t.GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (t.GetType() == cmTarget::INTERFACE_LIBRARY
+ || t.GetType() == cmTarget::GLOBAL_TARGET)
{
continue;
}
@@ -2197,19 +2355,19 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
- for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
- d != this->LinkDirectories.end(); ++d)
+ if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES"))
{
- if(mightExpandVariablesCMP0019(d->c_str()))
+ if(mightExpandVariablesCMP0019(linkDirsProp))
{
- std::string orig = *d;
- this->ExpandVariablesInString(*d, true, true);
- if(pol == cmPolicies::WARN && *d != orig)
+ std::string d = linkDirsProp;
+ std::string orig = linkDirsProp;
+ this->ExpandVariablesInString(d, true, true);
+ if(pol == cmPolicies::WARN && d != orig)
{
- w << "Evaluated link directory\n"
+ w << "Evaluated link directories\n"
<< " " << orig << "\n"
<< "as\n"
- << " " << *d << "\n";
+ << " " << d << "\n";
}
}
}
@@ -2278,6 +2436,18 @@ bool cmMakefile::PlatformIs64Bit() const
return false;
}
+bool cmMakefile::PlatformIsAppleIos() const
+{
+ std::string sdkRoot;
+ sdkRoot = this->GetSafeDefinition("CMAKE_OSX_SYSROOT");
+ sdkRoot = cmSystemTools::LowerCase(sdkRoot);
+
+ return sdkRoot.find("iphoneos") == 0 ||
+ sdkRoot.find("/iphoneos") != std::string::npos ||
+ sdkRoot.find("iphonesimulator") == 0 ||
+ sdkRoot.find("/iphonesimulator") != std::string::npos;
+}
+
const char* cmMakefile::GetSONameFlag(const std::string& language) const
{
std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
@@ -2335,7 +2505,7 @@ const char* cmMakefile::GetRequiredDefinition(const std::string& name) const
bool cmMakefile::IsDefinitionSet(const std::string& name) const
{
- const char* def = this->Internal->GetDefinition(name);
+ const char* def = this->StateSnapshot.GetDefinition(name);
if(!def)
{
def = this->GetState()->GetInitializedCacheValue(name);
@@ -2356,7 +2526,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const
const char* cmMakefile::GetDefinition(const std::string& name) const
{
- const char* def = this->Internal->GetDefinition(name);
+ const char* def = this->StateSnapshot.GetDefinition(name);
if(!def)
{
def = this->GetState()->GetInitializedCacheValue(name);
@@ -2390,18 +2560,11 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const
return ret;
}
-std::vector<std::string> cmMakefile
-::GetDefinitions(int cacheonly /* = 0 */) const
+std::vector<std::string> cmMakefile::GetDefinitions() const
{
- std::vector<std::string> res;
- if ( !cacheonly )
- {
- res = this->Internal->ClosureKeys();
- }
- std::vector<std::string> cacheKeys =
- this->GetState()->GetCacheEntryKeys();
+ std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
+ std::vector<std::string> cacheKeys = this->GetState()->GetCacheEntryKeys();
res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
-
std::sort(res.begin(), res.end());
return res;
}
@@ -2763,8 +2926,9 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
{
std::ostringstream msg;
cmListFileContext lfc;
- lfc.FilePath = this->LocalGenerator
- ->Convert(filename, cmLocalGenerator::HOME);
+ cmOutputConverter converter(this->StateSnapshot);
+ lfc.FilePath =
+ converter.Convert(filename, cmOutputConverter::HOME);
lfc.Line = line;
msg << "uninitialized variable \'" << lookup << "\'";
this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
@@ -3214,11 +3378,22 @@ bool cmMakefile::IsLoopBlock() const
return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0;
}
+std::string cmMakefile::GetExecutionFilePath() const
+{
+ assert(this->StateSnapshot.IsValid());
+ return this->StateSnapshot.GetExecutionListFile();
+}
+
//----------------------------------------------------------------------------
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
- std::vector<std::string>& outArgs) const
+ std::vector<std::string>& outArgs, const char* filename) const
{
+ std::string efp = this->GetExecutionFilePath();
+ if (!filename)
+ {
+ filename = efp.c_str();
+ }
std::vector<cmListFileArgument>::const_iterator i;
std::string value;
outArgs.reserve(inArgs.size());
@@ -3233,8 +3408,7 @@ bool cmMakefile::ExpandArguments(
// Expand the variables in the argument.
value = i->Value;
this->ExpandVariablesInString(value, false, false, false,
- i->FilePath, i->Line,
- false, false);
+ filename, i->Line, false, false);
// If the argument is quoted, it should be one argument.
// Otherwise, it may be a list of arguments.
@@ -3253,8 +3427,13 @@ bool cmMakefile::ExpandArguments(
//----------------------------------------------------------------------------
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
- std::vector<cmExpandedCommandArgument>& outArgs) const
+ std::vector<cmExpandedCommandArgument>& outArgs, const char* filename) const
{
+ std::string efp = this->GetExecutionFilePath();
+ if (!filename)
+ {
+ filename = efp.c_str();
+ }
std::vector<cmListFileArgument>::const_iterator i;
std::string value;
outArgs.reserve(inArgs.size());
@@ -3269,8 +3448,7 @@ bool cmMakefile::ExpandArguments(
// Expand the variables in the argument.
value = i->Value;
this->ExpandVariablesInString(value, false, false, false,
- i->FilePath, i->Line,
- false, false);
+ filename, i->Line, false, false);
// If the argument is quoted, it should be one argument.
// Otherwise, it may be a list of arguments.
@@ -3294,7 +3472,7 @@ bool cmMakefile::ExpandArguments(
//----------------------------------------------------------------------------
void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
{
- if(!this->CallStack.empty())
+ if(!this->ExecutionStatusStack.empty())
{
// Record the context in which the blocker is created.
fb->SetStartingContext(this->GetExecutionContext());
@@ -3327,11 +3505,13 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
if(!(*pos)->ShouldRemove(lff, *this))
{
cmListFileContext const& lfc = fb->GetStartingContext();
+ cmListFileContext closingContext =
+ cmListFileContext::FromCommandContext(lff, lfc.FilePath);
std::ostringstream e;
e << "A logical block opening on the line\n"
<< " " << lfc << "\n"
<< "closes on the line\n"
- << " " << lff << "\n"
+ << " " << closingContext << "\n"
<< "with mis-matching arguments.";
this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
}
@@ -3344,19 +3524,6 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
return cmsys::auto_ptr<cmFunctionBlocker>();
}
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
- Makefile(mf), ReportError(true)
-{
- this->Makefile->PushFunctionBlockerBarrier();
-}
-
-//----------------------------------------------------------------------------
-cmMakefile::LexicalPushPop::~LexicalPushPop()
-{
- this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
-}
-
const char* cmMakefile::GetHomeDirectory() const
{
return this->GetCMakeInstance()->GetHomeDirectory();
@@ -3448,7 +3615,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
const std::vector<std::string> *cmakeArgs,
std::string& output)
{
- this->Internal->IsSourceFileTryCompile = fast;
+ this->IsSourceFileTryCompile = fast;
// does the binary directory exist ? If not create it...
if (!cmSystemTools::FileIsDirectory(bindir))
{
@@ -3473,7 +3640,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
"Internal CMake error, TryCompile bad GlobalGenerator");
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
return 1;
}
cm.SetGlobalGenerator(gg);
@@ -3544,7 +3711,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
"Internal CMake error, TryCompile configure of cmake failed");
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3554,7 +3721,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
"Internal CMake error, TryCompile generation of cmake failed");
// return to the original directory
cmSystemTools::ChangeDirectory(cwd);
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
return 1;
}
@@ -3567,23 +3734,23 @@ int cmMakefile::TryCompile(const std::string& srcdir,
this);
cmSystemTools::ChangeDirectory(cwd);
- this->Internal->IsSourceFileTryCompile = false;
+ this->IsSourceFileTryCompile = false;
return ret;
}
bool cmMakefile::GetIsSourceFileTryCompile() const
{
- return this->Internal->IsSourceFileTryCompile;
+ return this->IsSourceFileTryCompile;
}
cmake *cmMakefile::GetCMakeInstance() const
{
- return this->GetGlobalGenerator()->GetCMakeInstance();
+ return this->GlobalGenerator->GetCMakeInstance();
}
cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const
{
- return this->LocalGenerator->GetGlobalGenerator();
+ return this->GlobalGenerator;
}
#ifdef CMAKE_BUILD_WITH_CMAKE
@@ -3598,18 +3765,6 @@ cmVariableWatch *cmMakefile::GetVariableWatch() const
}
#endif
-void cmMakefile::AddMacro(const char* name)
-{
- assert(name);
- this->MacrosList.push_back(name);
-}
-
-void cmMakefile::GetListOfMacros(std::string& macros) const
-{
- assert(macros.empty());
- macros = cmJoin(this->MacrosList, ";");
-}
-
cmState *cmMakefile::GetState() const
{
return this->GetCMakeInstance()->GetState();
@@ -3919,234 +4074,28 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
void cmMakefile::SetProperty(const std::string& prop, const char* value)
{
- if ( prop == "LINK_DIRECTORIES" )
- {
- std::vector<std::string> varArgsExpanded;
- if(value)
- {
- cmSystemTools::ExpandListArgument(value, varArgsExpanded);
- }
- this->SetLinkDirectories(varArgsExpanded);
- return;
- }
- if (prop == "INCLUDE_DIRECTORIES")
- {
- this->IncludeDirectoriesEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->IncludeDirectoriesEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (prop == "COMPILE_OPTIONS")
- {
- this->CompileOptionsEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->CompileOptionsEntries.push_back(cmValueWithOrigin(value, lfbt));
- return;
- }
- if (prop == "COMPILE_DEFINITIONS")
- {
- this->CompileDefinitionsEntries.clear();
- if (!value)
- {
- return;
- }
- cmListFileBacktrace lfbt = this->GetBacktrace();
- cmValueWithOrigin entry(value, lfbt);
- this->CompileDefinitionsEntries.push_back(entry);
- return;
- }
-
- if ( prop == "INCLUDE_REGULAR_EXPRESSION" )
- {
- this->SetIncludeRegularExpression(value);
- return;
- }
-
- if ( prop == "ADDITIONAL_MAKE_CLEAN_FILES" )
- {
- // This property is not inherrited
- if ( strcmp(this->GetCurrentSourceDirectory(),
- this->GetCurrentSourceDirectory()) != 0 )
- {
- return;
- }
- }
-
- this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
+ cmListFileBacktrace lfbt = this->GetBacktrace();
+ this->StateSnapshot.GetDirectory().SetProperty(prop, value, lfbt);
}
void cmMakefile::AppendProperty(const std::string& prop,
const char* value,
bool asString)
{
- if (prop == "INCLUDE_DIRECTORIES")
- {
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->IncludeDirectoriesEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (prop == "COMPILE_OPTIONS")
- {
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->CompileOptionsEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if (prop == "COMPILE_DEFINITIONS")
- {
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->CompileDefinitionsEntries.push_back(
- cmValueWithOrigin(value, lfbt));
- return;
- }
- if ( prop == "LINK_DIRECTORIES" )
- {
- std::vector<std::string> varArgsExpanded;
- cmSystemTools::ExpandListArgument(value, varArgsExpanded);
- for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin();
- vi != varArgsExpanded.end(); ++vi)
- {
- this->AddLinkDirectory(*vi);
- }
- return;
- }
-
- this->Properties.AppendProperty(prop,value,cmProperty::DIRECTORY,asString);
+ cmListFileBacktrace lfbt = this->GetBacktrace();
+ this->StateSnapshot.GetDirectory().AppendProperty(prop, value,
+ asString, lfbt);
}
const char *cmMakefile::GetProperty(const std::string& prop) const
{
- return this->GetProperty(prop, cmProperty::DIRECTORY);
+ return this->StateSnapshot.GetDirectory().GetProperty(prop);
}
const char *cmMakefile::GetProperty(const std::string& prop,
- cmProperty::ScopeType scope) const
+ bool chain) const
{
- // watch for specific properties
- static std::string output;
- output = "";
- if (prop == "PARENT_DIRECTORY")
- {
- cmState::Snapshot parent = this->StateSnapshot.GetParent();
- if(parent.IsValid())
- {
- return parent.GetCurrentSourceDirectory();
- }
- return "";
- }
- else if (prop == "INCLUDE_REGULAR_EXPRESSION" )
- {
- output = this->GetIncludeRegularExpression();
- return output.c_str();
- }
- else if (prop == "LISTFILE_STACK")
- {
- output = cmJoin(this->ListFileStack, ";");
- return output.c_str();
- }
- else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES")
- {
- int cacheonly = 0;
- if ( prop == "CACHE_VARIABLES" )
- {
- cacheonly = 1;
- }
- output = cmJoin(this->GetDefinitions(cacheonly), ";");
- return output.c_str();
- }
- else if (prop == "MACROS")
- {
- this->GetListOfMacros(output);
- return output.c_str();
- }
- else if (prop == "DEFINITIONS")
- {
- switch(this->GetPolicyStatus(cmPolicies::CMP0059))
- {
- case cmPolicies::WARN:
- this->IssueMessage(cmake::AUTHOR_WARNING, cmPolicies::
- GetPolicyWarning(cmPolicies::CMP0059));
- case cmPolicies::OLD:
- output += this->DefineFlagsOrig;
- return output.c_str();
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- break;
- }
- }
- else if (prop == "LINK_DIRECTORIES")
- {
- output = cmJoin(this->GetLinkDirectories(), ";");
- return output.c_str();
- }
- else if (prop == "INCLUDE_DIRECTORIES")
- {
- 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();
- }
- else if (prop == "COMPILE_OPTIONS")
- {
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->CompileOptionsEntries.begin(),
- end = this->CompileOptionsEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
- else if (prop == "COMPILE_DEFINITIONS")
- {
- std::string sep;
- for (std::vector<cmValueWithOrigin>::const_iterator
- it = this->CompileDefinitionsEntries.begin(),
- end = this->CompileDefinitionsEntries.end();
- it != end; ++it)
- {
- output += sep;
- output += it->Value;
- sep = ";";
- }
- return output.c_str();
- }
-
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, scope, chain);
- if (chain)
- {
- if(this->LocalGenerator->GetParent())
- {
- return this->LocalGenerator->GetParent()->GetMakefile()->
- GetProperty(prop, scope);
- }
- return this->GetState()->GetGlobalProperty(prop);
- }
-
- return retVal;
+ return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
}
bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
@@ -4154,31 +4103,9 @@ bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
return cmSystemTools::IsOn(this->GetProperty(prop));
}
-//----------------------------------------------------------------------------
-const char* cmMakefile::GetFeature(const std::string& feature,
- const std::string& config)
+std::vector<std::string> cmMakefile::GetPropertyKeys() const
{
- // TODO: Define accumulation policy for features (prepend, append, replace).
- // Currently we always replace.
- if(!config.empty())
- {
- std::string featureConfig = feature;
- featureConfig += "_";
- featureConfig += cmSystemTools::UpperCase(config);
- if(const char* value = this->GetProperty(featureConfig))
- {
- return value;
- }
- }
- if(const char* value = this->GetProperty(feature))
- {
- return value;
- }
- if(cmLocalGenerator* parent = this->LocalGenerator->GetParent())
- {
- return parent->GetMakefile()->GetFeature(feature, config);
- }
- return 0;
+ return this->StateSnapshot.GetDirectory().GetPropertyKeys();
}
cmTarget* cmMakefile::FindTarget(const std::string& name,
@@ -4253,14 +4180,22 @@ void cmMakefile::AddCMakeDependFilesFromUser()
std::string cmMakefile::FormatListFileStack() const
{
+ std::vector<std::string> listFiles;
+ cmState::Snapshot snp = this->StateSnapshot;
+ while (snp.IsValid())
+ {
+ listFiles.push_back(snp.GetExecutionListFile());
+ snp = snp.GetCallStackParent();
+ }
+ std::reverse(listFiles.begin(), listFiles.end());
std::ostringstream tmp;
- size_t depth = this->ListFileStack.size();
+ size_t depth = listFiles.size();
if (depth > 0)
{
- std::vector<std::string>::const_iterator it = this->ListFileStack.end();
+ std::vector<std::string>::const_iterator it = listFiles.end();
do
{
- if (depth != this->ListFileStack.size())
+ if (depth != listFiles.size())
{
tmp << "\n ";
}
@@ -4271,7 +4206,7 @@ std::string cmMakefile::FormatListFileStack() const
tmp << *it;
depth--;
}
- while (it != this->ListFileStack.begin());
+ while (it != listFiles.begin());
}
return tmp.str();
}
@@ -4279,8 +4214,17 @@ std::string cmMakefile::FormatListFileStack() const
void cmMakefile::PushScope()
{
- this->Internal->PushDefinitions();
-
+ std::string commandName;
+ long line = 0;
+ if (!this->ContextStack.empty())
+ {
+ commandName = this->ContextStack.back()->Name;
+ line = this->ContextStack.back()->Line;
+ }
+ this->StateSnapshot = this->GetState()->CreateVariableScopeSnapshot(
+ this->StateSnapshot,
+ commandName,
+ line);
this->PushLoopBlockBarrier();
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -4298,7 +4242,9 @@ void cmMakefile::PopScope()
this->CheckForUnusedVariables();
- this->Internal->PopDefinitions();
+ this->StateSnapshot =
+ this->GetState()->Pop(this->StateSnapshot);
+ assert(this->StateSnapshot.IsValid());
}
void cmMakefile::RaiseScope(const std::string& var, const char *varDef)
@@ -4308,7 +4254,7 @@ void cmMakefile::RaiseScope(const std::string& var, const char *varDef)
return;
}
- if (!this->Internal->RaiseScope(var, varDef, this))
+ if (!this->StateSnapshot.RaiseScope(var, varDef))
{
std::ostringstream m;
m << "Cannot set \"" << var << "\": current scope has no parent.";
@@ -4596,57 +4542,21 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re)
this->MarkVariableAsUsed(nMatchesVariable);
}
-//----------------------------------------------------------------------------
-cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
+cmState::Snapshot cmMakefile::GetStateSnapshot() const
{
- // Get the current setting of the policy.
- cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
-
- // If the policy is required to be set to NEW but is not, ignore the
- // current setting and tell the caller.
- if(cur != cmPolicies::NEW)
- {
- if(cur == cmPolicies::REQUIRED_ALWAYS ||
- cur == cmPolicies::REQUIRED_IF_USED)
- {
- return cur;
- }
- cmPolicies::PolicyStatus def = cmPolicies::GetPolicyStatus(id);
- if(def == cmPolicies::REQUIRED_ALWAYS ||
- def == cmPolicies::REQUIRED_IF_USED)
- {
- return def;
- }
- }
+ return this->StateSnapshot;
+}
- // The current setting is okay.
- return cur;
+const char* cmMakefile::GetDefineFlagsCMP0059() const
+{
+ return this->DefineFlagsOrig.c_str();
}
//----------------------------------------------------------------------------
cmPolicies::PolicyStatus
-cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id) const
+cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) const
{
- // Is the policy set in our stack?
- for(PolicyStackType::const_reverse_iterator psi = this->PolicyStack.rbegin();
- psi != this->PolicyStack.rend(); ++psi)
- {
- if(psi->IsDefined(id))
- {
- return psi->Get(id);
- }
- }
-
- // If we have a parent directory, recurse up to it.
- if(this->LocalGenerator->GetParent())
- {
- cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
- return parent->GetPolicyStatusInternal(id);
- }
-
- // The policy is not set. Use the default for this CMake version.
- return cmPolicies::GetPolicyStatus(id);
+ return this->StateSnapshot.GetPolicy(id);
}
//----------------------------------------------------------------------------
@@ -4660,7 +4570,8 @@ bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
return cmSystemTools::IsOn(val);
}
}
- // Enable optional policy warnings with --debug-output or --trace.
+ // Enable optional policy warnings with --debug-output, --trace,
+ // or --trace-expand.
cmake* cm = this->GetCMakeInstance();
return cm->GetDebugOutput() || cm->GetTrace();
}
@@ -4694,34 +4605,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
return false;
}
- // Update the policy stack from the top to the top-most strong entry.
- bool previous_was_weak = true;
- for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
- previous_was_weak && psi != this->PolicyStack.rend(); ++psi)
- {
- psi->Set(id, status);
- previous_was_weak = psi->Weak;
- }
-
- // Special hook for presenting compatibility variable as soon as
- // the user requests it.
- if(id == cmPolicies::CMP0001 &&
- (status == cmPolicies::WARN || status == cmPolicies::OLD))
- {
- if(!(this->GetState()
- ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
- {
- // Set it to 2.4 because that is the last version where the
- // variable had meaning.
- this->AddCacheDefinition
- ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
- "For backwards compatibility, what version of CMake "
- "commands and "
- "syntax should this version of CMake try to support.",
- cmState::STRING);
- }
- }
-
+ this->StateSnapshot.SetPolicy(id, status);
return true;
}
@@ -4730,32 +4614,28 @@ cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
cmPolicies::PolicyMap const& pm):
Makefile(m), ReportError(true)
{
+ this->Makefile->StateSnapshot = this->Makefile->StateSnapshot.GetState()
+ ->CreatePolicyScopeSnapshot(this->Makefile->StateSnapshot);
this->Makefile->PushPolicy(weak, pm);
- this->Makefile->PushPolicyBarrier();
}
//----------------------------------------------------------------------------
cmMakefile::PolicyPushPop::~PolicyPushPop()
{
- this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->PopPolicy();
+ this->Makefile->PopPolicyBarrier(this->ReportError);
}
//----------------------------------------------------------------------------
void cmMakefile::PushPolicy(bool weak, cmPolicies::PolicyMap const& pm)
{
- // Allocate a new stack entry.
- this->PolicyStack.push_back(PolicyStackEntry(pm, weak));
+ this->StateSnapshot.PushPolicy(pm, weak);
}
//----------------------------------------------------------------------------
void cmMakefile::PopPolicy()
{
- if(this->PolicyStack.size() > this->PolicyBarriers.back())
- {
- this->PolicyStack.pop_back();
- }
- else
+ if (!this->StateSnapshot.PopPolicy())
{
this->IssueMessage(cmake::FATAL_ERROR,
"cmake_policy POP without matching PUSH");
@@ -4763,17 +4643,9 @@ void cmMakefile::PopPolicy()
}
//----------------------------------------------------------------------------
-void cmMakefile::PushPolicyBarrier()
-{
- this->PolicyBarriers.push_back(this->PolicyStack.size());
-}
-
-//----------------------------------------------------------------------------
void cmMakefile::PopPolicyBarrier(bool reportError)
{
- // Remove any extra entries pushed on the barrier.
- PolicyStackType::size_type barrier = this->PolicyBarriers.back();
- while(this->PolicyStack.size() > barrier)
+ while (!this->StateSnapshot.CanPopPolicyScope())
{
if(reportError)
{
@@ -4784,8 +4656,8 @@ void cmMakefile::PopPolicyBarrier(bool reportError)
this->PopPolicy();
}
- // Remove the barrier.
- this->PolicyBarriers.pop_back();
+ this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+ assert(this->StateSnapshot.IsValid());
}
//----------------------------------------------------------------------------
@@ -5357,3 +5229,44 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
}
return true;
}
+
+
+cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
+ const std::string& fileName,
+ cmPolicies::PolicyMap const& pm)
+ : Makefile(mf), ReportError(true)
+{
+ this->Makefile->PushFunctionScope(fileName, pm);
+}
+
+cmMakefile::FunctionPushPop::~FunctionPushPop()
+{
+ this->Makefile->PopFunctionScope(this->ReportError);
+}
+
+
+cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf,
+ const std::string& fileName,
+ const cmPolicies::PolicyMap& pm)
+ : Makefile(mf), ReportError(true)
+{
+ this->Makefile->PushMacroScope(fileName, pm);
+}
+
+cmMakefile::MacroPushPop::~MacroPushPop()
+{
+ this->Makefile->PopMacroScope(this->ReportError);
+}
+
+cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc,
+ cmExecutionStatus& status): Makefile(mf)
+{
+ this->Makefile->ContextStack.push_back(&lfc);
+ this->Makefile->ExecutionStatusStack.push_back(&status);
+}
+
+cmMakefileCall::~cmMakefileCall()
+{
+ this->Makefile->ExecutionStatusStack.pop_back();
+ this->Makefile->ContextStack.pop_back();
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 27ef075..3cf20a6 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -14,8 +14,6 @@
#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
-#include "cmPolicies.h"
-#include "cmPropertyMap.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmNewLineStyle.h"
@@ -23,6 +21,7 @@
#include "cmExpandedCommandArgument.h"
#include "cmake.h"
#include "cmState.h"
+#include "cmAlgorithms.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmSourceGroup.h"
@@ -43,7 +42,6 @@
class cmFunctionBlocker;
class cmCommand;
class cmInstallGenerator;
-class cmLocalGenerator;
class cmMakeDepend;
class cmSourceFile;
class cmTest;
@@ -52,6 +50,7 @@ class cmVariableWatch;
class cmake;
class cmMakefileCall;
class cmCMakePolicyCommand;
+class cmGeneratorExpressionEvaluationFile;
/** \class cmMakefile
* \brief Process the input CMakeLists.txt file.
@@ -62,8 +61,6 @@ class cmCMakePolicyCommand;
*/
class cmMakefile
{
- class Internals;
- cmsys::auto_ptr<Internals> Internal;
public:
/* Mark a variable as used */
void MarkVariableAsUsed(const std::string& var);
@@ -73,24 +70,28 @@ public:
/**
* Construct an empty makefile.
*/
- cmMakefile(cmLocalGenerator* localGenerator);
+ cmMakefile(cmGlobalGenerator* globalGenerator,
+ const cmState::Snapshot& snapshot);
/**
* Destructor.
*/
~cmMakefile();
- bool ReadListFile(const char* listfile);
+ bool ReadListFile(const char* filename);
- bool ReadDependentFile(const char* listfile, bool noPolicyScope = true);
+ bool ReadDependentFile(const char* filename, bool noPolicyScope = true);
- bool ProcessBuildsystemFile(const char* listfile);
+ bool ProcessBuildsystemFile(const char* filename);
/**
* Add a function blocker to this makefile
*/
void AddFunctionBlocker(cmFunctionBlocker* fb);
+ /// @return whether we are processing the top CMakeLists.txt file.
+ bool IsRootMakefile() const;
+
/**
* Remove the function blocker whose scope ends with the given command.
* This returns ownership of the function blocker object.
@@ -98,19 +99,6 @@ public:
cmsys::auto_ptr<cmFunctionBlocker>
RemoveFunctionBlocker(cmFunctionBlocker* fb, const cmListFileFunction& lff);
- /** Push/pop a lexical (function blocker) barrier automatically. */
- class LexicalPushPop
- {
- public:
- LexicalPushPop(cmMakefile* mf);
- ~LexicalPushPop();
- void Quiet() { this->ReportError = false; }
- private:
- cmMakefile* Makefile;
- bool ReportError;
- };
- friend class LexicalPushPop;
-
/**
* Try running cmake and building a file. This is used for dynalically
* loaded commands, not as part of the usual build process.
@@ -123,10 +111,6 @@ public:
bool GetIsSourceFileTryCompile() const;
- ///! Get the current makefile generator.
- cmLocalGenerator* GetLocalGenerator() const
- { return this->LocalGenerator;}
-
/**
* Help enforce global target name uniqueness.
*/
@@ -204,14 +188,15 @@ public:
* Add a utility to the build. A utiltity target is a command that
* is run every time the target is built.
*/
- void AddUtilityCommand(const std::string& utilityName, bool excludeFromAll,
- const std::vector<std::string>& depends,
- const char* workingDirectory,
- const char* command,
- const char* arg1=0,
- const char* arg2=0,
- const char* arg3=0,
- const char* arg4=0);
+ cmTarget* AddUtilityCommand(const std::string& utilityName,
+ bool excludeFromAll,
+ const std::vector<std::string>& depends,
+ const char* workingDirectory,
+ const char* command,
+ const char* arg1=0,
+ const char* arg2=0,
+ const char* arg3=0,
+ const char* arg4=0);
cmTarget* AddUtilityCommand(const std::string& utilityName,
bool excludeFromAll,
const char* workingDirectory,
@@ -240,20 +225,6 @@ public:
void AddLinkDirectoryForTarget(const std::string& tgt, const std::string& d);
/**
- * Add a link directory to the build.
- */
- void AddLinkDirectory(const std::string&);
-
- const std::vector<std::string>& GetLinkDirectories() const
- {
- return this->LinkDirectories;
- }
- void SetLinkDirectories(const std::vector<std::string>& vec)
- {
- this->LinkDirectories = vec;
- }
-
- /**
* Add a subdirectory to the build.
*/
void AddSubDirectory(const std::string& fullSrcDir,
@@ -261,10 +232,12 @@ public:
bool excludeFromAll,
bool immediate);
+ void Configure();
+
/**
* Configure a subdirectory
*/
- void ConfigureSubDirectory(cmLocalGenerator *);
+ void ConfigureSubDirectory(cmMakefile* mf);
/**
* Add an include directory to the build.
@@ -299,15 +272,12 @@ public:
/**
* Specify the name of the project for this build.
*/
- void SetProjectName(const char*);
+ void SetProjectName(std::string const& name);
/**
* Get the name of the project for this build.
*/
- const char* GetProjectName() const
- {
- return this->ProjectName.c_str();
- }
+ std::string GetProjectName() const;
/** Get the configurations to be generated. */
std::string GetConfigurations(std::vector<std::string>& configs,
@@ -363,13 +333,6 @@ public:
friend class PolicyPushPop;
/**
- * Get the Policies Instance
- */
- cmPolicies *GetPolicies() const;
-
- mutable std::set<cmListFileContext> CMP0054ReportedIds;
-
- /**
* Determine if the given context, name pair has already been reported
* in context of CMP0054.
*/
@@ -403,11 +366,11 @@ public:
*/
void SetIncludeRegularExpression(const char* regex)
{
- this->IncludeFileRegularExpression = regex;
+ this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex);
}
const char* GetIncludeRegularExpression() const
{
- return this->IncludeFileRegularExpression.c_str();
+ return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
}
/**
@@ -445,6 +408,7 @@ public:
{
this->GeneratorTargets = targets;
}
+ void AddGeneratorTarget(cmTarget* t, cmGeneratorTarget* gt);
cmTarget* FindTarget(const std::string& name,
bool excludeAliases = false) const;
@@ -506,7 +470,7 @@ public:
* cacheonly is specified and is greater than 0, then only cache
* variables will be listed.
*/
- std::vector<std::string> GetDefinitions(int cacheonly=0) const;
+ std::vector<std::string> GetDefinitions() const;
/**
* Test a boolean variable to see if it is true or false.
@@ -520,6 +484,9 @@ public:
/** Return whether the target platform is 64-bit. */
bool PlatformIs64Bit() const;
+ /** Return whether the target platform is Apple iOS. */
+ bool PlatformIsAppleIos() const;
+
/** Retrieve soname flag for the specified language if supported */
const char* GetSONameFlag(const std::string& language) const;
@@ -563,6 +530,7 @@ public:
* Get the current context backtrace.
*/
cmListFileBacktrace GetBacktrace() const;
+ cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const;
cmListFileContext GetExecutionContext() const;
/**
@@ -658,10 +626,12 @@ public:
* variable replacement and list expansion.
*/
bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
- std::vector<std::string>& outArgs) const;
+ std::vector<std::string>& outArgs,
+ const char* filename = 0) const;
bool ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
- std::vector<cmExpandedCommandArgument>& outArgs) const;
+ std::vector<cmExpandedCommandArgument>& outArgs,
+ const char* filename = 0) const;
/**
* Get the instance
@@ -682,12 +652,6 @@ public:
*/
cmSourceFile *GetSourceFileWithOutput(const std::string& outName) const;
- /**
- * Add a macro to the list of macros. The arguments should be name of the
- * macro and a documentation signature of it
- */
- void AddMacro(const char* name);
-
///! Add a new cmTest to the list of tests for this makefile.
cmTest* CreateTest(const std::string& testName);
@@ -697,11 +661,6 @@ public:
cmTest* GetTest(const std::string& testName) const;
/**
- * Get a list of macros as a ; separated string
- */
- void GetListOfMacros(std::string& macros) const;
-
- /**
* Return a location of a file in cmake or custom modules directory
*/
std::string GetModulesFile(const char* name) const;
@@ -711,18 +670,12 @@ public:
void AppendProperty(const std::string& prop, const char *value,
bool asString=false);
const char *GetProperty(const std::string& prop) const;
- const char *GetProperty(const std::string& prop,
- cmProperty::ScopeType scope) const;
+ const char *GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
-
- const char* GetFeature(const std::string& feature,
- const std::string& config);
-
- // Get the properties
- cmPropertyMap &GetProperties() { return this->Properties; }
+ std::vector<std::string> GetPropertyKeys() const;
///! Initialize a makefile from its parent
- void InitializeFromParent();
+ void InitializeFromParent(cmMakefile* parent);
void AddInstallGenerator(cmInstallGenerator* g)
{ if(g) this->InstallGenerators.push_back(g); }
@@ -734,7 +687,38 @@ public:
const std::vector<cmTestGenerator*>& GetTestGenerators() const
{ return this->TestGenerators; }
- // push and pop variable scopes
+ class FunctionPushPop
+ {
+ public:
+ FunctionPushPop(cmMakefile* mf, std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ ~FunctionPushPop();
+
+ void Quiet() { this->ReportError = false; }
+ private:
+ cmMakefile* Makefile;
+ bool ReportError;
+ };
+
+ class MacroPushPop
+ {
+ public:
+ MacroPushPop(cmMakefile* mf, std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ ~MacroPushPop();
+
+ void Quiet() { this->ReportError = false; }
+ private:
+ cmMakefile* Makefile;
+ bool ReportError;
+ };
+
+ void PushFunctionScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ void PopFunctionScope(bool reportError);
+ void PushMacroScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
+ void PopMacroScope(bool reportError);
void PushScope();
void PopScope();
void RaiseScope(const std::string& var, const char *value);
@@ -759,21 +743,15 @@ public:
/** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
- const std::vector<cmValueWithOrigin>& GetIncludeDirectoriesEntries() const
- {
- return this->IncludeDirectoriesEntries;
- }
- const std::vector<cmValueWithOrigin>& GetCompileOptionsEntries() const
- {
- return this->CompileOptionsEntries;
- }
- const std::vector<cmValueWithOrigin>& GetCompileDefinitionsEntries() const
- {
- return this->CompileDefinitionsEntries;
- }
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsBacktraces() const;
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsBacktraces() const;
- bool IsGeneratingBuildSystem() const { return this->GeneratingBuildSystem; }
- void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+ bool IsConfigured() const { return this->Configured; }
+ void SetConfigured(){ this->Configured = true; }
void AddQtUiFileWithOptions(cmSourceFile *sf);
std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const;
@@ -807,6 +785,20 @@ public:
void ClearMatches();
void StoreMatches(cmsys::RegularExpression& re);
+ cmState::Snapshot GetStateSnapshot() const;
+
+ const char* GetDefineFlagsCMP0059() const;
+
+ std::string GetExecutionFilePath() const;
+
+ void EnforceDirectoryLevelRules() const;
+
+ void AddEvaluationFile(const std::string &inputFile,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> condition,
+ bool inputIsContent);
+ std::vector<cmGeneratorExpressionEvaluationFile*> GetEvaluationFiles() const;
+
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
@@ -814,7 +806,7 @@ protected:
// Check for a an unused variable
void LogUnused(const char* reason, const std::string& name) const;
- std::string ProjectName; // project name
+ mutable std::set<cmListFileContext> CMP0054ReportedIds;
// libraries, classes, and executables
mutable cmTargets Targets;
@@ -849,16 +841,11 @@ protected:
std::vector<cmInstallGenerator*> InstallGenerators;
std::vector<cmTestGenerator*> TestGenerators;
- std::string IncludeFileRegularExpression;
std::string ComplainFileRegularExpression;
std::vector<std::string> SourceFileExtensions;
std::vector<std::string> HeaderFileExtensions;
std::string DefineFlags;
- std::vector<cmValueWithOrigin> IncludeDirectoriesEntries;
- std::vector<cmValueWithOrigin> CompileOptionsEntries;
- std::vector<cmValueWithOrigin> CompileDefinitionsEntries;
-
// Track the value of the computed DEFINITIONS property.
void AddDefineFlag(const char*, std::string&);
void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
@@ -869,7 +856,7 @@ protected:
#endif
std::vector<cmCommand*> FinalPassCommands;
- cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* GlobalGenerator;
bool IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus &status);
@@ -879,13 +866,8 @@ private:
cmState::Snapshot StateSnapshot;
- bool ReadListFile(const char* listfile,
- bool noPolicyScope,
- bool requireProjectCommand);
-
- bool ReadListFileInternal(const char* filenametoread,
- bool noPolicyScope,
- bool requireProjectCommand);
+ void ReadListFile(cmListFile const& listFile,
+ const std::string& filenametoread);
bool ParseDefineFlag(std::string const& definition, bool remove);
@@ -904,31 +886,19 @@ private:
std::stack<int> LoopBlockCounter;
- std::vector<std::string> MacrosList;
-
mutable cmsys::RegularExpression cmDefineRegex;
mutable cmsys::RegularExpression cmDefine01Regex;
mutable cmsys::RegularExpression cmAtVarRegex;
mutable cmsys::RegularExpression cmNamedCurly;
- cmPropertyMap Properties;
-
- // Unused variable flags
- bool WarnUnused;
- bool CheckSystemVars;
+ std::vector<cmMakefile*> UnConfiguredDirectories;
- // stack of list files being read
- std::vector<std::string> ListFileStack;
+ std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
- // stack of commands being invoked.
- struct CallStackEntry
- {
- cmListFileContext const* Context;
- cmExecutionStatus* Status;
- };
- typedef std::vector<CallStackEntry> CallStackType;
- CallStackType CallStack;
+ std::vector<cmCommandContext const*> ContextStack;
+ std::vector<cmExecutionStatus*> ExecutionStatusStack;
friend class cmMakefileCall;
+ friend class cmParseFileScope;
std::vector<cmTarget*> ImportedTargetsOwned;
TargetMap ImportedTargets;
@@ -937,31 +907,15 @@ private:
void PushPolicy(bool weak = false,
cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
void PopPolicy();
- void PushPolicyBarrier();
void PopPolicyBarrier(bool reportError = true);
friend class cmCMakePolicyCommand;
class IncludeScope;
friend class IncludeScope;
+ class ListFileScope;
+ friend class ListFileScope;
+ class BuildsystemFileScope;
+ friend class BuildsystemFileScope;
- // stack of policy settings
- struct PolicyStackEntry: public cmPolicies::PolicyMap
- {
- typedef cmPolicies::PolicyMap derived;
- PolicyStackEntry(bool w = false): derived(), Weak(w) {}
- PolicyStackEntry(derived const& d, bool w = false): derived(d), Weak(w) {}
- PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
- bool Weak;
- };
- typedef std::vector<PolicyStackEntry> PolicyStackType;
- PolicyStackType PolicyStack;
- std::vector<PolicyStackType::size_type> PolicyBarriers;
- cmPolicies::PolicyStatus
- GetPolicyStatusInternal(cmPolicies::PolicyID id) const;
-
- bool CheckCMP0000;
-
- // Enforce rules about CMakeLists.txt files.
- void EnforceDirectoryLevelRules() const;
// CMP0053 == old
cmake::MessageType ExpandVariablesInStringOld(
@@ -985,7 +939,6 @@ private:
long line,
bool removeEmpty,
bool replaceAt) const;
- bool GeneratingBuildSystem;
/**
* Old version of GetSourceFileWithOutput(const std::string&) kept for
* backward-compatibility. It implements a linear search and support
@@ -1031,6 +984,12 @@ private:
void CheckForUnusedVariables() const;
+ // Unused variable flags
+ bool WarnUnused;
+ bool CheckSystemVars;
+ bool CheckCMP0000;
+ bool Configured;
+ bool IsSourceFileTryCompile;
mutable bool SuppressWatches;
};
@@ -1040,16 +999,9 @@ class cmMakefileCall
{
public:
cmMakefileCall(cmMakefile* mf,
- cmListFileContext const& lfc,
- cmExecutionStatus& status): Makefile(mf)
- {
- cmMakefile::CallStackEntry entry = {&lfc, &status};
- this->Makefile->CallStack.push_back(entry);
- }
- ~cmMakefileCall()
- {
- this->Makefile->CallStack.pop_back();
- }
+ cmCommandContext const& lfc,
+ cmExecutionStatus& status);
+ ~cmMakefileCall();
private:
cmMakefile* Makefile;
};
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 37b297e..ccb0974 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -22,10 +22,10 @@
//----------------------------------------------------------------------------
cmMakefileExecutableTargetGenerator
::cmMakefileExecutableTargetGenerator(cmGeneratorTarget* target):
- cmMakefileTargetGenerator(target->Target)
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
- this->Target->GetExecutableNames(
+ this->GeneratorTarget->GetExecutableNames(
this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
this->TargetNamePDB, this->ConfigName);
@@ -58,7 +58,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
// write the link rules
this->WriteExecutableRule(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteExecutableRule(true);
@@ -94,7 +94,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetExecutableNames
+ this->GeneratorTarget->GetExecutableNames
(targetName, targetNameReal, targetNameImport, targetNamePDB,
this->ConfigName);
@@ -130,7 +130,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
std::string compilePdbOutputPath =
- this->Target->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
@@ -161,7 +161,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the language to use for linking this executable.
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
// Make sure we have a link language.
if(linkLanguage.empty())
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 450f573..2f995e8 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -18,16 +18,17 @@
#include "cmSourceFile.h"
#include "cmTarget.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmMakefileLibraryTargetGenerator
::cmMakefileLibraryTargetGenerator(cmGeneratorTarget* target):
- cmMakefileTargetGenerator(target->Target)
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnDepends;
if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
- this->Target->GetLibraryNames(
+ this->GeneratorTarget->GetLibraryNames(
this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
}
@@ -68,7 +69,7 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
break;
case cmTarget::SHARED_LIBRARY:
this->WriteSharedLibraryRules(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteSharedLibraryRules(true);
@@ -76,7 +77,7 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
break;
case cmTarget::MODULE_LIBRARY:
this->WriteModuleLibraryRules(false);
- if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ if(this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName))
{
// Write rules to link an installable version of the target.
this->WriteModuleLibraryRules(true);
@@ -132,7 +133,7 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_STATIC_LIBRARY";
@@ -158,7 +159,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
return;
}
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_SHARED_LIBRARY";
@@ -182,7 +183,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_SHARED_MODULE";
@@ -205,7 +206,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
std::string linkRuleVar = "CMAKE_";
linkRuleVar += linkLanguage;
linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
@@ -237,7 +238,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Get the language to use for linking this library.
std::string linkLanguage =
- this->Target->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
// Make sure we have a link language.
if(linkLanguage.empty())
@@ -265,7 +266,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string targetNameReal;
std::string targetNameImport;
std::string targetNamePDB;
- this->Target->GetLibraryNames(
+ this->GeneratorTarget->GetLibraryNames(
targetName, targetNameSO, targetNameReal, targetNameImport, targetNamePDB,
this->ConfigName);
@@ -310,7 +311,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
std::string compilePdbOutputPath =
- this->Target->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
@@ -563,6 +564,58 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
useResponseFileForObjects, buildObjs, depends,
useWatcomQuote);
+ // maybe create .def file from list of objects
+ if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if(this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string name_of_def_file =
+ this->Target->GetSupportDirectory();
+ name_of_def_file += std::string("/") +
+ this->Target->GetName();
+ name_of_def_file += ".def";
+ std::string cmd = cmSystemTools::GetCMakeCommand();
+ cmd = this->Convert(cmd, cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ cmd += " -E __create_def ";
+ cmd += this->Convert(name_of_def_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ cmd += " ";
+ std::string objlist_file = name_of_def_file;
+ objlist_file += ".objs";
+ cmd += this->Convert(objlist_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ real_link_commands.push_back(cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(objlist_file.c_str());
+ for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i)
+ {
+ if(cmHasLiteralSuffix(*i, ".obj"))
+ {
+ fout << *i << "\n";
+ }
+ }
+ for(std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i)
+ {
+ fout << *i << "\n";
+ }
+ // now add the def file link flag
+ linkFlags += " ";
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += this->Convert(name_of_def_file,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ linkFlags += " ";
+ }
+ }
+
cmLocalGenerator::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -600,7 +653,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
- if (this->Target->HasSOName(this->ConfigName))
+ if (this->GeneratorTarget->HasSOName(this->ConfigName))
{
vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
vars.TargetSOName= targetNameSO.c_str();
@@ -613,7 +666,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
{
// Get the install_name directory for the build tree.
install_name_dir =
- this->Target->GetInstallNameDirForBuildTree(this->ConfigName);
+ this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
// Set the rule variable replacement value.
if(install_name_dir.empty())
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 7b88bc7..cf88a74 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -32,25 +32,20 @@
#include <ctype.h>
-cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
- : OSXBundleGenerator(0)
+cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
+ : cmCommonTargetGenerator(cmOutputConverter::START_OUTPUT, target)
+ , OSXBundleGenerator(0)
, MacOSXContentGenerator(0)
{
this->BuildFileStream = 0;
this->InfoFileStream = 0;
this->FlagFileStream = 0;
this->CustomCommandDriver = OnBuild;
- this->FortranModuleDirectoryComputed = false;
- this->Target = target;
- this->Makefile = this->Target->GetMakefile();
this->LocalGenerator =
- static_cast<cmLocalUnixMakefileGenerator3*>(
- this->Makefile->GetLocalGenerator());
- this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
+ static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
this->GlobalGenerator =
static_cast<cmGlobalUnixMakefileGenerator3*>(
this->LocalGenerator->GetGlobalGenerator());
- this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
this->NoRuleMessages = false;
if(const char* ruleStatus = cm->GetState()
@@ -172,7 +167,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
cmCustomCommandGenerator ccg(*(*si)->GetCustomCommand(),
this->ConfigName,
- this->Makefile);
+ this->LocalGenerator);
this->GenerateCustomRuleFile(ccg);
if (clean)
{
@@ -277,85 +272,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< "\n\n";
}
-//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
-{
- ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
- if (i == this->FlagsByLanguage.end())
- {
- std::string flags;
- const char *lang = l.c_str();
-
- // Add language feature flags.
- this->AddFeatureFlags(flags, lang);
-
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- lang, this->ConfigName);
-
- // Fortran-specific flags computed for this target.
- if(l == "Fortran")
- {
- this->AddFortranFlags(flags);
- }
-
- this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
- lang, this->ConfigName);
-
- this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target,
- lang);
-
- // Add include directory flags.
- this->AddIncludeFlags(flags, lang);
-
- // Append old-style preprocessor definition flags.
- this->LocalGenerator->
- AppendFlags(flags, this->Makefile->GetDefineFlags());
-
- // Add include directory flags.
- this->LocalGenerator->
- AppendFlags(flags,this->GetFrameworkFlags(l));
-
- // Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->Target,
- lang, this->ConfigName);
-
- ByLanguageMap::value_type entry(l, flags);
- i = this->FlagsByLanguage.insert(entry).first;
- }
- return i->second;
-}
-
-std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
-{
- ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
- if (i == this->DefinesByLanguage.end())
- {
- std::set<std::string> defines;
- const char *lang = l.c_str();
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->LocalGenerator->ConfigurationName, l);
-
- std::string definesString;
- this->LocalGenerator->JoinDefines(defines, definesString, lang);
-
- ByLanguageMap::value_type entry(l, definesString);
- i = this->DefinesByLanguage.insert(entry).first;
- }
- return i->second;
-}
-
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
// write language flags for target
std::set<std::string> languages;
- this->Target->GetLanguages(languages,
+ this->GeneratorTarget->GetLanguages(languages,
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
// put the compiler in the rules.make file so that if it changes
// things rebuild
@@ -374,11 +295,14 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
std::string flags = this->GetFlags(*l);
std::string defines = this->GetDefines(*l);
+ std::string includes = this->GetIncludes(*l);
// Escape comment characters so they do not terminate assignment.
cmSystemTools::ReplaceString(flags, "#", "\\#");
cmSystemTools::ReplaceString(defines, "#", "\\#");
+ cmSystemTools::ReplaceString(includes, "#", "\\#");
*this->FlagFileStream << *l << "_FLAGS = " << flags << "\n\n";
*this->FlagFileStream << *l << "_DEFINES = " << defines << "\n\n";
+ *this->FlagFileStream << *l << "_INCLUDES = " << includes << "\n\n";
}
}
@@ -389,7 +313,7 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
(cmSourceFile const& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(!this->Generator->GetTarget()->IsBundleOnApple())
+ if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
{
return;
}
@@ -490,7 +414,6 @@ void cmMakefileTargetGenerator
// we compute some depends when writing the depend.make that we will also
// use in the build.make, same with depMakeFile
std::vector<std::string> depends;
- std::string depMakeFile;
// generate the build rule file
this->WriteObjectBuildFile(obj, lang, source, depends);
@@ -512,35 +435,6 @@ void cmMakefileTargetGenerator
//----------------------------------------------------------------------------
void
cmMakefileTargetGenerator
-::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source)
-{
- const char* srcfmt = source.GetProperty("Fortran_FORMAT");
- cmLocalGenerator::FortranFormat format =
- this->LocalGenerator->GetFortranFormat(srcfmt);
- if(format == cmLocalGenerator::FortranFormatNone)
- {
- const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
- format = this->LocalGenerator->GetFortranFormat(tgtfmt);
- }
- const char* var = 0;
- switch (format)
- {
- case cmLocalGenerator::FortranFormatFixed:
- var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
- case cmLocalGenerator::FortranFormatFree:
- var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
- default: break;
- }
- if(var)
- {
- this->LocalGenerator->AppendFlags(
- flags, this->Makefile->GetDefinition(var));
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmMakefileTargetGenerator
::WriteObjectBuildFile(std::string &obj,
const std::string& lang,
cmSourceFile const& source,
@@ -568,7 +462,7 @@ cmMakefileTargetGenerator
this->LocalGenerator->AppendFlags(flags, langFlags);
std::string configUpper =
- cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName());
// Add Fortran format flags.
if(lang == "Fortran")
@@ -614,13 +508,7 @@ cmMakefileTargetGenerator
}
// Get the output paths for source and object files.
- std::string sourceFile = source.GetFullPath();
- if(this->LocalGenerator->UseRelativePaths)
- {
- sourceFile = this->Convert(sourceFile,
- cmLocalGenerator::START_OUTPUT);
- }
- sourceFile = this->Convert(sourceFile,
+ std::string sourceFile = this->Convert(source.GetFullPath(),
cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
@@ -657,15 +545,15 @@ cmMakefileTargetGenerator
this->Target->GetType() == cmTarget::MODULE_LIBRARY)
{
targetFullPathReal =
- this->Target->GetFullPath(this->ConfigName, false, true);
+ this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
targetFullPathPDB += "/";
- targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
+ targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
}
if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
{
targetFullPathCompilePDB =
- this->Target->GetCompilePDBPath(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBPath(this->ConfigName);
if(targetFullPathCompilePDB.empty())
{
targetFullPathCompilePDB = this->Target->GetSupportDirectory() + "/";
@@ -725,6 +613,9 @@ cmMakefileTargetGenerator
vars.Defines = definesString.c_str();
+ std::string const includesString = "$(" + lang + "_INCLUDES)";
+ vars.Includes = includesString.c_str();
+
// At the moment, it is assumed that C, C++, and Fortran have both
// assembly and preprocessor capabilities. The same is true for the
// ability to export compile commands
@@ -757,6 +648,9 @@ cmMakefileTargetGenerator
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
compileCommand.replace(compileCommand.find(langDefines),
langDefines.size(), this->GetDefines(lang));
+ std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
+ compileCommand.replace(compileCommand.find(langIncludes),
+ langIncludes.size(), this->GetIncludes(lang));
this->GlobalGenerator->AddCXXCompileCommand(
source.GetFullPath(), workingDirectory, compileCommand);
}
@@ -775,6 +669,25 @@ cmMakefileTargetGenerator
}
}
+ // Maybe insert a compiler launcher like ccache or distcc
+ if (!compileCommands.empty() && (lang == "C" || lang == "CXX"))
+ {
+ std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+ const char *clauncher = this->Target->GetProperty(clauncher_prop);
+ if (clauncher && *clauncher)
+ {
+ std::vector<std::string> launcher_cmd;
+ cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+ for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+ e = launcher_cmd.end(); i != e; ++i)
+ {
+ *i = this->LocalGenerator->EscapeForShell(*i);
+ }
+ std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+ compileCommands.front().insert(0, run_launcher);
+ }
+ }
+
// Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i)
@@ -1132,8 +1045,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
pi != this->MultipleOutputPairs.end(); ++pi)
{
*this->InfoFileStream
- << " " << cmLocalGenerator::EscapeForCMake(pi->first)
- << " " << cmLocalGenerator::EscapeForCMake(pi->second)
+ << " " << cmOutputConverter::EscapeForCMake(pi->first)
+ << " " << cmOutputConverter::EscapeForCMake(pi->second)
<< "\n";
}
*this->InfoFileStream << " )\n\n";
@@ -1145,44 +1058,21 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "\n"
<< "# Targets to which this target links.\n"
<< "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
- std::set<cmTarget const*> emitted;
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
+ std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+ for (std::vector<std::string>::iterator i = dirs.begin();
+ i != dirs.end(); ++i)
{
- cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
- for(cmComputeLinkInformation::ItemVector::const_iterator
- i = items.begin(); i != items.end(); ++i)
- {
- cmTarget const* linkee = i->Target;
- if(linkee && !linkee->IsImported()
- // We can ignore the INTERFACE_LIBRARY items because
- // Target->GetLinkInformation already processed their
- // link interface and they don't have any output themselves.
- && linkee->GetType() != cmTarget::INTERFACE_LIBRARY
- && emitted.insert(linkee).second)
- {
- cmMakefile* mf = linkee->GetMakefile();
- cmLocalGenerator* lg = mf->GetLocalGenerator();
- std::string di = mf->GetCurrentBinaryDirectory();
- di += "/";
- di += lg->GetTargetDirectory(*linkee);
- di += "/DependInfo.cmake";
- *this->InfoFileStream << " \"" << di << "\"\n";
- }
- }
+ *this->InfoFileStream << " \"" << *i << "/DependInfo.cmake\"\n";
}
*this->InfoFileStream
<< " )\n";
}
- // Check for a target-specific module output directory.
- if(const char* mdir = this->GetFortranModuleDirectory())
- {
- *this->InfoFileStream
- << "\n"
- << "# Fortran module output directory.\n"
- << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
- }
+ *this->InfoFileStream
+ << "\n"
+ << "# Fortran module output directory.\n"
+ << "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
+ << this->GetFortranModuleDirectory() << "\")\n";
// and now write the rule to use it
std::vector<std::string> depends;
@@ -1266,7 +1156,8 @@ cmMakefileTargetGenerator
{
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{
- cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->Makefile);
+ cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+ this->LocalGenerator);
const std::vector<std::string>& outputs = ccg.GetOutputs();
depends.insert(depends.end(), outputs.begin(), outputs.end());
}
@@ -1544,68 +1435,6 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
}
//----------------------------------------------------------------------------
-std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l)
-{
- if(!this->Makefile->IsOn("APPLE"))
- {
- return std::string();
- }
-
- std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG";
- const char* fwSearchFlag =
- this->Makefile->GetDefinition(fwSearchFlagVar);
- if(!(fwSearchFlag && *fwSearchFlag))
- {
- return std::string();
- }
-
- std::set<std::string> emitted;
-#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */
- emitted.insert("/System/Library/Frameworks");
-#endif
- std::vector<std::string> includes;
-
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- // check all include directories for frameworks as this
- // will already have added a -F for the framework
- for(std::vector<std::string>::iterator i = includes.begin();
- i != includes.end(); ++i)
- {
- if(this->Target->NameResolvesToFramework(*i))
- {
- std::string frameworkDir = *i;
- frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
- emitted.insert(frameworkDir);
- }
- }
-
- std::string flags;
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
- {
- std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
- for(std::vector<std::string>::const_iterator i = frameworks.begin();
- i != frameworks.end(); ++i)
- {
- if(emitted.insert(*i).second)
- {
- flags += fwSearchFlag;
- flags += this->Convert(*i,
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL, true);
- flags += " ";
- }
- }
- }
- return flags;
-}
-
-//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
::AppendTargetDepends(std::vector<std::string>& depends)
{
@@ -1616,8 +1445,9 @@ void cmMakefileTargetGenerator
}
// Loop over all library dependencies.
- const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
- if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
+ const char* cfg = this->LocalGenerator->GetConfigName().c_str();
+ if(cmComputeLinkInformation* cli =
+ this->GeneratorTarget->GetLinkInformation(cfg))
{
std::vector<std::string> const& libDeps = cli->GetDepends();
depends.insert(depends.end(), libDeps.begin(), libDeps.end());
@@ -1658,11 +1488,9 @@ void cmMakefileTargetGenerator
this->AppendTargetDepends(depends);
// Add a dependency on the link definitions file, if any.
- std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
- if(!def.empty())
+ if(!this->ModuleDefinitionFile.empty())
{
- depends.push_back(def);
+ depends.push_back(this->ModuleDefinitionFile);
}
// Add user-specified dependencies.
@@ -1681,7 +1509,7 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
if(this->Target->HasImplibGNUtoMS())
{
std::string ruleVar = "CMAKE_";
- ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
if(const char* rule = this->Makefile->GetDefinition(ruleVar))
{
@@ -1835,7 +1663,8 @@ cmMakefileTargetGenerator
{
// Lookup the response file reference flag.
std::string responseFlagVar = "CMAKE_";
- responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ responseFlagVar += this->GeneratorTarget
+ ->GetLinkerLanguage(this->ConfigName);
responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
const char* responseFlag =
this->Makefile->GetDefinition(responseFlagVar);
@@ -1879,7 +1708,8 @@ cmMakefileTargetGenerator
// Lookup the response file reference flag.
std::string responseFlagVar = "CMAKE_";
- responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ responseFlagVar += this->GeneratorTarget
+ ->GetLinkerLanguage(this->ConfigName);
responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
const char* responseFlag =
this->Makefile->GetDefinition(responseFlagVar);
@@ -1969,149 +1799,3 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
this->LocalGenerator->AppendFlags(flags, includeFlags);
}
}
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
-{
- // Compute the module directory.
- if(!this->FortranModuleDirectoryComputed)
- {
- const char* target_mod_dir =
- this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
- const char* moddir_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
- if(target_mod_dir && moddir_flag)
- {
- // Compute the full path to the module directory.
- if(cmSystemTools::FileIsFullPath(target_mod_dir))
- {
- // Already a full path.
- this->FortranModuleDirectory = target_mod_dir;
- }
- else
- {
- // Interpret relative to the current output directory.
- this->FortranModuleDirectory =
- this->Makefile->GetCurrentBinaryDirectory();
- this->FortranModuleDirectory += "/";
- this->FortranModuleDirectory += target_mod_dir;
- }
-
- // Make sure the module output directory exists.
- cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
- }
- this->FortranModuleDirectoryComputed = true;
- }
-
- // Return the computed directory.
- if(this->FortranModuleDirectory.empty())
- {
- return 0;
- }
- else
- {
- return this->FortranModuleDirectory.c_str();
- }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
-{
- // Enable module output if necessary.
- if(const char* modout_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
- {
- this->LocalGenerator->AppendFlags(flags, modout_flag);
- }
-
- // Add a module output directory flag if necessary.
- const char* mod_dir = this->GetFortranModuleDirectory();
- if(!mod_dir)
- {
- mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
- }
- if(mod_dir)
- {
- const char* moddir_flag =
- this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
- std::string modflag = moddir_flag;
- modflag += this->Convert(mod_dir,
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::SHELL);
- this->LocalGenerator->AppendFlags(flags, modflag);
- }
-
- // If there is a separate module path flag then duplicate the
- // include path with it. This compiler does not search the include
- // path for modules.
- if(const char* modpath_flag =
- this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
- {
- std::vector<std::string> includes;
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- for(std::vector<std::string>::const_iterator idi = includes.begin();
- idi != includes.end(); ++idi)
- {
- std::string flg = modpath_flag;
- flg += this->Convert(*idi,
- cmLocalGenerator::NONE,
- cmLocalGenerator::SHELL);
- this->LocalGenerator->AppendFlags(flags, flg);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
-{
- std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
- if(def.empty())
- {
- return;
- }
-
- // TODO: Create a per-language flag variable.
- const char* defFileFlag =
- this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- if(!defFileFlag)
- {
- return;
- }
-
- // Append the flag and value. Use ConvertToLinkReference to help
- // vs6's "cl -link" pass it to the linker.
- std::string flag = defFileFlag;
- flag += (this->LocalGenerator->ConvertToLinkReference(def));
- this->LocalGenerator->AppendFlags(flags, flag);
-}
-
-//----------------------------------------------------------------------------
-const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature)
-{
- return this->Target->GetFeature(feature, this->ConfigName);
-}
-
-//----------------------------------------------------------------------------
-bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature)
-{
- return this->Target->GetFeatureAsBool(feature, this->ConfigName);
-}
-
-//----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::AddFeatureFlags(
- std::string& flags, const std::string& lang
- )
-{
- // Add language-specific flags.
- this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
-
- if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
- {
- this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
- }
-}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 58044e8..fd4527b 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -12,6 +12,8 @@
#ifndef cmMakefileTargetGenerator_h
#define cmMakefileTargetGenerator_h
+#include "cmCommonTargetGenerator.h"
+
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmOSXBundleGenerator.h"
@@ -30,11 +32,11 @@ class cmSourceFile;
* \brief Support Routines for writing makefiles
*
*/
-class cmMakefileTargetGenerator
+class cmMakefileTargetGenerator: public cmCommonTargetGenerator
{
public:
// constructor to set the ivars
- cmMakefileTargetGenerator(cmTarget* target);
+ cmMakefileTargetGenerator(cmGeneratorTarget* target);
virtual ~cmMakefileTargetGenerator();
// construct using this factory call
@@ -51,6 +53,7 @@ public:
{ return this->ProgressFileNameFull; }
cmTarget* GetTarget() { return this->Target;}
+ cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget;}
protected:
@@ -124,12 +127,6 @@ protected:
void DriveCustomCommands(std::vector<std::string>& depends);
- // Return the a string with -F flags on apple
- std::string GetFrameworkFlags(std::string const& l);
-
- void AppendFortranFormatFlags(std::string& flags,
- cmSourceFile const& source);
-
// append intertarget dependencies
void AppendTargetDepends(std::vector<std::string>& depends);
@@ -173,12 +170,8 @@ protected:
virtual void CloseFileStreams();
void RemoveForbiddenFlags(const char* flagVar, const std::string& linkLang,
std::string& linkFlags);
- cmTarget *Target;
- cmGeneratorTarget* GeneratorTarget;
cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
- cmMakefile *Makefile;
- std::string ConfigName;
enum CustomCommandDriveType { OnBuild, OnDepends, OnUtility };
CustomCommandDriveType CustomCommandDriver;
@@ -242,43 +235,6 @@ protected:
std::set<std::string> MacContentFolders;
cmOSXBundleGenerator* OSXBundleGenerator;
MacOSXContentGeneratorType* MacOSXContentGenerator;
-
- typedef std::map<std::string, std::string> ByLanguageMap;
- std::string GetFlags(const std::string &l);
- ByLanguageMap FlagsByLanguage;
- std::string GetDefines(const std::string &l);
- ByLanguageMap DefinesByLanguage;
-
- // Target-wide Fortran module output directory.
- bool FortranModuleDirectoryComputed;
- std::string FortranModuleDirectory;
- const char* GetFortranModuleDirectory();
-
- // Compute target-specific Fortran language flags.
- void AddFortranFlags(std::string& flags);
-
- // Helper to add flag for windows .def file.
- void AddModuleDefinitionFlag(std::string& flags);
-
- // Add language feature flags.
- void AddFeatureFlags(std::string& flags, const std::string& lang);
-
- // Feature query methods.
- const char* GetFeature(const std::string& feature);
- bool GetFeatureAsBool(const std::string& feature);
-
- //==================================================================
- // Convenience routines that do nothing more than forward to
- // implementaitons
- std::string Convert(const std::string& source,
- cmLocalGenerator::RelativeRoot relative,
- cmLocalGenerator::OutputFormat output =
- cmLocalGenerator::UNCHANGED,
- bool optional = false)
- {
- return this->LocalGenerator->Convert(source, relative, output, optional);
- }
-
};
#endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 25d929c..303ca63 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -21,7 +21,7 @@
//----------------------------------------------------------------------------
cmMakefileUtilityTargetGenerator
::cmMakefileUtilityTargetGenerator(cmGeneratorTarget* target):
- cmMakefileTargetGenerator(target->Target)
+ cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 0449c50..467555f 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -43,7 +43,19 @@ bool cmMessageCommand
}
else if (*i == "AUTHOR_WARNING")
{
- type = cmake::AUTHOR_WARNING;
+ if (this->Makefile->IsOn("CMAKE_ERROR_DEVELOPER_WARNINGS"))
+ {
+ fatal = true;
+ type = cmake::AUTHOR_ERROR;
+ }
+ else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
+ {
+ type = cmake::AUTHOR_WARNING;
+ }
+ else
+ {
+ return true;
+ }
++i;
}
else if (*i == "STATUS")
@@ -69,7 +81,7 @@ bool cmMessageCommand
++i;
}
- std::string message = cmJoin(cmRange(i, args.end()), std::string());
+ std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
if (type != cmake::MESSAGE)
{
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index bbf03ff..b855bea 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -32,7 +32,7 @@
cmNinjaNormalTargetGenerator::
cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
- : cmNinjaTargetGenerator(target->Target)
+ : cmNinjaTargetGenerator(target)
, TargetNameOut()
, TargetNameSO()
, TargetNameReal()
@@ -40,16 +40,15 @@ cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
, TargetNamePDB()
, TargetLinkLanguage("")
{
- this->TargetLinkLanguage = target->Target
- ->GetLinkerLanguage(this->GetConfigName());
+ this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
if (target->GetType() == cmTarget::EXECUTABLE)
- target->Target->GetExecutableNames(this->TargetNameOut,
+ this->GetGeneratorTarget()->GetExecutableNames(this->TargetNameOut,
this->TargetNameReal,
this->TargetNameImport,
this->TargetNamePDB,
GetLocalGenerator()->GetConfigName());
else
- target->Target->GetLibraryNames(this->TargetNameOut,
+ this->GetGeneratorTarget()->GetLibraryNames(this->TargetNameOut,
this->TargetNameSO,
this->TargetNameReal,
this->TargetNameImport,
@@ -398,15 +397,16 @@ static int calculateCommandLineLengthLimit(int linkRuleLength)
void cmNinjaNormalTargetGenerator::WriteLinkStatement()
{
cmTarget& target = *this->GetTarget();
+ cmGeneratorTarget& gt = *this->GetGeneratorTarget();
const std::string cfgName = this->GetConfigName();
std::string targetOutput = ConvertToNinjaPath(
- target.GetFullPath(cfgName));
+ gt.GetFullPath(cfgName));
std::string targetOutputReal = ConvertToNinjaPath(
- target.GetFullPath(cfgName,
+ gt.GetFullPath(cfgName,
/*implib=*/false,
/*realpath=*/true));
std::string targetOutputImplib = ConvertToNinjaPath(
- target.GetFullPath(cfgName,
+ gt.GetFullPath(cfgName,
/*implib=*/true));
if (target.IsAppBundleOnApple())
@@ -486,6 +486,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
linkPath,
&genTarget,
useWatcomQuote);
+ if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")
+ && target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string dllname = targetOutput;
+ std::string name_of_def_file
+ = target.GetSupportDirectory();
+ name_of_def_file += "/" + target.GetName();
+ name_of_def_file += ".def ";
+ vars["LINK_FLAGS"] += " /DEF:";
+ vars["LINK_FLAGS"] += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(name_of_def_file.c_str(),
+ cmLocalGenerator::SHELL);
+ }
+ }
this->addPoolNinjaVariable("JOB_POOL_LINK", &target, vars);
@@ -514,13 +530,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["LANGUAGE_COMPILE_FLAGS"] = t;
}
- if (target.HasSOName(cfgName))
+ if (this->GetGeneratorTarget()->HasSOName(cfgName))
{
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
vars["SONAME"] = this->TargetNameSO;
if (targetType == cmTarget::SHARED_LIBRARY)
{
- std::string install_dir = target.GetInstallNameDirForBuildTree(cfgName);
+ std::string install_dir =
+ this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
if (!install_dir.empty())
{
vars["INSTALLNAME_DIR"] = localGen.Convert(install_dir,
@@ -530,6 +547,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
}
+ cmNinjaDeps byproducts;
+
if (!this->TargetNameImport.empty())
{
const std::string impLibPath = localGen.ConvertToOutputFormat(
@@ -539,7 +558,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
EnsureParentDirectoryExists(impLibPath);
if(target.HasImportLibrary())
{
- outputs.push_back(targetOutputImplib);
+ byproducts.push_back(targetOutputImplib);
}
}
@@ -550,7 +569,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string prefix;
std::string base;
std::string suffix;
- target.GetFullNameComponents(prefix, base, suffix);
+ this->GetGeneratorTarget()->GetFullNameComponents(prefix, base, suffix);
std::string dbg_suffix = ".dbg";
// TODO: Where to document?
if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"))
@@ -585,14 +604,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
&postBuildCmdLines
};
- cmNinjaDeps byproducts;
for (unsigned i = 0; i != 3; ++i)
{
for (std::vector<cmCustomCommand>::const_iterator
ci = cmdLists[i]->begin();
ci != cmdLists[i]->end(); ++ci)
{
- cmCustomCommandGenerator ccg(*ci, cfgName, mf);
+ cmCustomCommandGenerator ccg(*ci, cfgName, this->GetLocalGenerator());
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -600,6 +618,44 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
}
+ // maybe create .def file from list of objects
+ if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+ this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+ std::string dllname = targetOutput;
+ std::string name_of_def_file
+ = target.GetSupportDirectory();
+ name_of_def_file += "/" + target.GetName();
+ name_of_def_file += ".def";
+ std::string cmd = cmakeCommand;
+ cmd += " -E __create_def ";
+ cmd += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(name_of_def_file.c_str(),
+ cmLocalGenerator::SHELL);
+ cmd += " ";
+ cmNinjaDeps objs = this->GetObjects();
+ std::string obj_list_file = name_of_def_file;
+ obj_list_file += ".objs";
+ cmd += this->GetLocalGenerator()
+ ->ConvertToOutputFormat(obj_list_file.c_str(),
+ cmLocalGenerator::SHELL);
+ preLinkCmdLines.push_back(cmd);
+ // create a list of obj files for the -E __create_def to read
+ cmGeneratedFileStream fout(obj_list_file.c_str());
+ for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i)
+ {
+ if(cmHasLiteralSuffix(*i, ".obj"))
+ {
+ fout << *i << "\n";
+ }
+ }
+ }
+ }
// If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
// the link commands.
if (!preLinkCmdLines.empty())
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 879d6b7..81fdde2 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -22,6 +22,7 @@
#include "cmComputeLinkInformation.h"
#include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h"
+#include "cmAlgorithms.h"
#include <algorithm>
@@ -56,19 +57,15 @@ cmNinjaTargetGenerator::New(cmGeneratorTarget* target)
}
}
-cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
- :
+cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
+ : cmCommonTargetGenerator(cmOutputConverter::HOME_OUTPUT, target),
MacOSXContentGenerator(0),
OSXBundleGenerator(0),
MacContentFolders(),
- Target(target),
- Makefile(target->GetMakefile()),
LocalGenerator(
- static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
+ static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator())),
Objects()
{
- this->GeneratorTarget =
- this->GetGlobalGenerator()->GetGeneratorTarget(target);
MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
}
@@ -92,11 +89,6 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
return this->LocalGenerator->GetGlobalNinjaGenerator();
}
-std::string const& cmNinjaTargetGenerator::GetConfigName() const
-{
- return this->LocalGenerator->GetConfigName();
-}
-
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
const std::string& lang) const
{
@@ -104,31 +96,6 @@ std::string cmNinjaTargetGenerator::LanguageCompilerRule(
cmGlobalNinjaGenerator::EncodeRuleName(this->Target->GetName());
}
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature)
-{
- return this->Target->GetFeature(feature, this->GetConfigName());
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature)
-{
- return this->Target->GetFeatureAsBool(feature, this->GetConfigName());
-}
-
-// TODO: Picked up from cmMakefileTargetGenerator. Refactor it.
-void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags,
- const std::string& lang)
-{
- // Add language-specific flags.
- this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName());
-
- if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
- {
- this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
- }
-}
-
std::string
cmNinjaTargetGenerator::OrderDependsTargetForTarget()
{
@@ -143,71 +110,43 @@ std::string
cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language)
{
- // TODO: Fortran support.
- // // Fortran-specific flags computed for this target.
- // if(*l == "Fortran")
- // {
- // this->AddFortranFlags(flags);
- // }
-
- bool hasLangCached = this->LanguageFlags.count(language) != 0;
- std::string& languageFlags = this->LanguageFlags[language];
- if(!hasLangCached)
- {
- this->AddFeatureFlags(languageFlags, language);
-
- this->GetLocalGenerator()->AddArchitectureFlags(languageFlags,
- this->GeneratorTarget,
- language,
- this->GetConfigName());
+ std::string flags = this->GetFlags(language);
- // Add shared-library flags if needed.
- this->LocalGenerator->AddCMP0018Flags(languageFlags, this->Target,
- language,
- this->GetConfigName());
-
- this->LocalGenerator->AddVisibilityPresetFlags(languageFlags, this->Target,
- language);
-
- std::vector<std::string> includes;
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- language,
- this->GetConfigName());
- // Add include directory flags.
- std::string includeFlags =
- this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
- language,
- language == "RC" ? true : false, // full include paths for RC
- // needed by cmcldeps
- false,
- this->GetConfigName());
- if (this->GetGlobalGenerator()->IsGCCOnWindows())
- cmSystemTools::ReplaceString(includeFlags, "\\", "/");
-
- this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
-
- // Append old-style preprocessor definition flags.
- this->LocalGenerator->AppendFlags(languageFlags,
- this->Makefile->GetDefineFlags());
-
- // Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(languageFlags, this->Target,
- language,
- this->GetConfigName());
+ // Add Fortran format flags.
+ if(language == "Fortran")
+ {
+ this->AppendFortranFormatFlags(flags, *source);
}
- std::string flags = languageFlags;
-
// Add source file specific flags.
this->LocalGenerator->AppendFlags(flags,
source->GetProperty("COMPILE_FLAGS"));
- // TODO: Handle Apple frameworks.
-
return flags;
}
+void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
+ std::string const& language)
+{
+ std::vector<std::string> includes;
+ this->LocalGenerator->GetIncludeDirectories(includes,
+ this->GeneratorTarget,
+ language,
+ this->GetConfigName());
+ // Add include directory flags.
+ std::string includeFlags =
+ this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget,
+ language,
+ language == "RC" ? true : false, // full include paths for RC
+ // needed by cmcldeps
+ false,
+ this->GetConfigName());
+ if (this->GetGlobalGenerator()->IsGCCOnWindows())
+ cmSystemTools::ReplaceString(includeFlags, "\\", "/");
+
+ this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
+}
+
bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
{
if (lang == "C" || lang == "CXX")
@@ -230,16 +169,6 @@ cmNinjaTargetGenerator::
ComputeDefines(cmSourceFile const* source, const std::string& language)
{
std::set<std::string> defines;
-
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = this->Target->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro);
- }
-
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->GetConfigName(), language);
this->LocalGenerator->AppendDefines
(defines,
source->GetProperty("COMPILE_DEFINITIONS"));
@@ -251,7 +180,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language)
source->GetProperty(defPropName));
}
- std::string definesString;
+ std::string definesString = this->GetDefines(language);
this->LocalGenerator->JoinDefines(defines, definesString,
language);
@@ -266,7 +195,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
return cmNinjaDeps();
cmComputeLinkInformation* cli =
- this->Target->GetLinkInformation(this->GetConfigName());
+ this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
if(!cli)
return cmNinjaDeps();
@@ -277,7 +206,16 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
// Add a dependency on the link definitions file, if any.
if(!this->ModuleDefinitionFile.empty())
{
- result.push_back(this->ModuleDefinitionFile);
+ result.push_back(this->ConvertToNinjaPath(this->ModuleDefinitionFile));
+ }
+
+ // Add user-specified dependencies.
+ if (const char* linkDepends = this->Target->GetProperty("LINK_DEPENDS"))
+ {
+ std::vector<std::string> linkDeps;
+ cmSystemTools::ExpandListArgument(linkDepends, linkDeps);
+ std::transform(linkDeps.begin(), linkDeps.end(),
+ std::back_inserter(result), MapToNinjaPath());
}
return result;
@@ -344,11 +282,12 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
{
pdbPath = this->Target->GetPDBDirectory(this->GetConfigName());
pdbPath += "/";
- pdbPath += this->Target->GetPDBName(this->GetConfigName());
+ pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
}
if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
{
- compilePdbPath = this->Target->GetCompilePDBPath(this->GetConfigName());
+ compilePdbPath =
+ this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
if(compilePdbPath.empty())
{
compilePdbPath = this->Target->GetSupportDirectory() + "/";
@@ -392,6 +331,7 @@ cmNinjaTargetGenerator
vars.Source = "$in";
vars.Object = "$out";
vars.Defines = "$DEFINES";
+ vars.Includes = "$INCLUDES";
vars.TargetPDB = "$TARGET_PDB";
vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
@@ -475,6 +415,25 @@ cmNinjaTargetGenerator
}
}
+ // Maybe insert a compiler launcher like ccache or distcc
+ if (!compileCmds.empty() && (lang == "C" || lang == "CXX"))
+ {
+ std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
+ const char *clauncher = this->Target->GetProperty(clauncher_prop);
+ if (clauncher && *clauncher)
+ {
+ std::vector<std::string> launcher_cmd;
+ cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
+ for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
+ e = launcher_cmd.end(); i != e; ++i)
+ {
+ *i = this->LocalGenerator->EscapeForShell(*i);
+ }
+ std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
+ compileCmds.front().insert(0, run_launcher);
+ }
+ }
+
if (!compileCmds.empty())
{
compileCmds.front().insert(0, cldeps);
@@ -560,7 +519,7 @@ cmNinjaTargetGenerator
{
cmCustomCommand const* cc = *cci;
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
- this->GetMakefile());
+ this->GetLocalGenerator());
const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
const std::vector<std::string>& ccbyproducts= ccg.GetByproducts();
std::transform(ccoutputs.begin(), ccoutputs.end(),
@@ -588,11 +547,6 @@ cmNinjaTargetGenerator
{
this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
}
- std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config);
- if(!def.empty())
- {
- this->ModuleDefinitionFile = this->ConvertToNinjaPath(def);
- }
this->GetBuildFileStream() << "\n";
}
@@ -602,22 +556,39 @@ cmNinjaTargetGenerator
::WriteObjectBuildStatement(
cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
{
+ std::string const language = source->GetLanguage();
+ std::string const sourceFileName =
+ language=="RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
+ std::string const objectDir = this->Target->GetSupportDirectory();
+ std::string const objectFileName = this->GetObjectFilePath(source);
+ std::string const objectFileDir =
+ cmSystemTools::GetFilenamePath(objectFileName);
+
+ cmNinjaVars vars;
+ vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
+ vars["DEFINES"] = this->ComputeDefines(source, language);
+ vars["INCLUDES"] = this->GetIncludes(language);
+ if (!this->NeedDepTypeMSVC(language))
+ {
+ vars["DEP_FILE"] =
+ cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
+ }
+
+ this->ExportObjectCompileCommand(
+ language, sourceFileName,
+ objectDir, objectFileName, objectFileDir,
+ vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]
+ );
+
std::string comment;
- const std::string language = source->GetLanguage();
std::string rule = this->LanguageCompilerRule(language);
cmNinjaDeps outputs;
- std::string objectFileName = this->GetObjectFilePath(source);
outputs.push_back(objectFileName);
// Add this object to the list of object files.
this->Objects.push_back(objectFileName);
cmNinjaDeps explicitDeps;
- std::string sourceFileName;
- if (language == "RC")
- sourceFileName = source->GetFullPath();
- else
- sourceFileName = this->GetSourceFilePath(source);
explicitDeps.push_back(sourceFileName);
cmNinjaDeps implicitDeps;
@@ -652,20 +623,11 @@ cmNinjaTargetGenerator
orderOnlyDeps);
}
- cmNinjaVars vars;
- vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
- vars["DEFINES"] = this->ComputeDefines(source, language);
- if (!this->NeedDepTypeMSVC(language)) {
- vars["DEP_FILE"] =
- cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d");
- }
EnsureParentDirectoryExists(objectFileName);
- std::string objectDir = this->Target->GetSupportDirectory();
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
ConvertToNinjaPath(objectDir),
cmLocalGenerator::SHELL);
- std::string objectFileDir = cmSystemTools::GetFilenamePath(objectFileName);
vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
ConvertToNinjaPath(objectFileDir),
cmLocalGenerator::SHELL);
@@ -674,53 +636,6 @@ cmNinjaTargetGenerator
this->SetMsvcTargetPdbVariable(vars);
- if(this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
- {
- cmLocalGenerator::RuleVariables compileObjectVars;
- std::string lang = language;
- compileObjectVars.Language = lang.c_str();
-
- std::string escapedSourceFileName = sourceFileName;
-
- if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
- {
- escapedSourceFileName = cmSystemTools::CollapseFullPath(
- escapedSourceFileName,
- this->GetGlobalGenerator()->GetCMakeInstance()->
- GetHomeOutputDirectory());
- }
-
- escapedSourceFileName =
- this->LocalGenerator->ConvertToOutputFormat(
- escapedSourceFileName, cmLocalGenerator::SHELL);
-
- compileObjectVars.Source = escapedSourceFileName.c_str();
- compileObjectVars.Object = objectFileName.c_str();
- compileObjectVars.ObjectDir = objectDir.c_str();
- compileObjectVars.ObjectFileDir = objectFileDir.c_str();
- compileObjectVars.Flags = vars["FLAGS"].c_str();
- compileObjectVars.Defines = vars["DEFINES"].c_str();
-
- // Rule for compiling object file.
- std::string compileCmdVar = "CMAKE_";
- compileCmdVar += language;
- compileCmdVar += "_COMPILE_OBJECT";
- std::string compileCmd =
- this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
- std::vector<std::string> compileCmds;
- cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
-
- for (std::vector<std::string>::iterator i = compileCmds.begin();
- i != compileCmds.end(); ++i)
- this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
-
- std::string cmdLine =
- this->GetLocalGenerator()->BuildCommandLine(compileCmds);
-
- this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
- sourceFileName);
- }
-
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
comment,
rule,
@@ -742,30 +657,67 @@ cmNinjaTargetGenerator
}
}
-//----------------------------------------------------------------------------
void
cmNinjaTargetGenerator
-::AddModuleDefinitionFlag(std::string& flags)
+::ExportObjectCompileCommand(
+ std::string const& language,
+ std::string const& sourceFileName,
+ std::string const& objectDir,
+ std::string const& objectFileName,
+ std::string const& objectFileDir,
+ std::string const& flags,
+ std::string const& defines,
+ std::string const& includes
+ )
{
- if(this->ModuleDefinitionFile.empty())
+ if(!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS"))
{
return;
}
- // TODO: Create a per-language flag variable.
- const char* defFileFlag =
- this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- if(!defFileFlag)
+ cmLocalGenerator::RuleVariables compileObjectVars;
+ compileObjectVars.Language = language.c_str();
+
+ std::string escapedSourceFileName = sourceFileName;
+
+ if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
{
- return;
+ escapedSourceFileName = cmSystemTools::CollapseFullPath(
+ escapedSourceFileName,
+ this->GetGlobalGenerator()->GetCMakeInstance()->
+ GetHomeOutputDirectory());
}
- // Append the flag and value. Use ConvertToLinkReference to help
- // vs6's "cl -link" pass it to the linker.
- std::string flag = defFileFlag;
- flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile));
- this->LocalGenerator->AppendFlags(flags, flag);
+ escapedSourceFileName =
+ this->LocalGenerator->ConvertToOutputFormat(
+ escapedSourceFileName, cmLocalGenerator::SHELL);
+
+ compileObjectVars.Source = escapedSourceFileName.c_str();
+ compileObjectVars.Object = objectFileName.c_str();
+ compileObjectVars.ObjectDir = objectDir.c_str();
+ compileObjectVars.ObjectFileDir = objectFileDir.c_str();
+ compileObjectVars.Flags = flags.c_str();
+ compileObjectVars.Defines = defines.c_str();
+ compileObjectVars.Includes = includes.c_str();
+
+ // Rule for compiling object file.
+ std::string compileCmdVar = "CMAKE_";
+ compileCmdVar += language;
+ compileCmdVar += "_COMPILE_OBJECT";
+ std::string compileCmd =
+ this->GetMakefile()->GetRequiredDefinition(compileCmdVar);
+ std::vector<std::string> compileCmds;
+ cmSystemTools::ExpandListArgument(compileCmd, compileCmds);
+
+ for (std::vector<std::string>::iterator i = compileCmds.begin();
+ i != compileCmds.end(); ++i)
+ this->GetLocalGenerator()->ExpandRuleVariables(*i, compileObjectVars);
+
+ std::string cmdLine =
+ this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+
+ this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine,
+ sourceFileName);
}
void
@@ -799,7 +751,7 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
cmSourceFile const& source, const char* pkgloc)
{
// Skip OS X content when not building a Framework or Bundle.
- if(!this->Generator->GetTarget()->IsBundleOnApple())
+ if(!this->Generator->GetGeneratorTarget()->IsBundleOnApple())
{
return;
}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4e7d8b3..a10ceba 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -13,6 +13,8 @@
#ifndef cmNinjaTargetGenerator_h
#define cmNinjaTargetGenerator_h
+#include "cmCommonTargetGenerator.h"
+
#include "cmStandardIncludes.h"
#include "cmNinjaTypes.h"
#include "cmLocalNinjaGenerator.h"
@@ -26,14 +28,14 @@ class cmMakefile;
class cmSourceFile;
class cmCustomCommand;
-class cmNinjaTargetGenerator
+class cmNinjaTargetGenerator: public cmCommonTargetGenerator
{
public:
/// Create a cmNinjaTargetGenerator according to the @a target's type.
static cmNinjaTargetGenerator* New(cmGeneratorTarget* target);
/// Build a NinjaTargetGenerator.
- cmNinjaTargetGenerator(cmTarget* target);
+ cmNinjaTargetGenerator(cmGeneratorTarget* target);
/// Destructor.
virtual ~cmNinjaTargetGenerator();
@@ -65,14 +67,8 @@ protected:
cmMakefile* GetMakefile() const
{ return this->Makefile; }
- std::string const& GetConfigName() const;
-
std::string LanguageCompilerRule(const std::string& lang) const;
- const char* GetFeature(const std::string& feature);
- bool GetFeatureAsBool(const std::string& feature);
- void AddFeatureFlags(std::string& flags, const std::string& lang);
-
std::string OrderDependsTargetForTarget();
std::string ComputeOrderDependsForTarget();
@@ -85,6 +81,8 @@ protected:
std::string ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language);
+ void AddIncludeFlags(std::string& flags, std::string const& lang);
+
std::string ComputeDefines(cmSourceFile const* source,
const std::string& language);
@@ -116,12 +114,20 @@ protected:
void WriteObjectBuildStatement(cmSourceFile const* source,
bool writeOrderDependsTargetForTarget);
+ void ExportObjectCompileCommand(
+ std::string const& language,
+ std::string const& sourceFileName,
+ std::string const& objectDir,
+ std::string const& objectFileName,
+ std::string const& objectFileDir,
+ std::string const& flags,
+ std::string const& defines,
+ std::string const& includes
+ );
+
cmNinjaDeps GetObjects() const
{ return this->Objects; }
- // Helper to add flag for windows .def file.
- void AddModuleDefinitionFlag(std::string& flags);
-
void EnsureDirectoryExists(const std::string& dir) const;
void EnsureParentDirectoryExists(const std::string& path) const;
@@ -150,19 +156,10 @@ protected:
cmNinjaVars& vars);
private:
- cmTarget* Target;
- cmGeneratorTarget* GeneratorTarget;
- cmMakefile* Makefile;
cmLocalNinjaGenerator* LocalGenerator;
/// List of object files for this target.
cmNinjaDeps Objects;
std::vector<cmCustomCommand const*> CustomCommands;
-
- typedef std::map<std::string, std::string> LanguageFlagMap;
- LanguageFlagMap LanguageFlags;
-
- // The windows module definition source file (.def), if any.
- std::string ModuleDefinitionFile;
};
#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 42d6b46..58b901a 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -21,7 +21,7 @@
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmGeneratorTarget *target)
- : cmNinjaTargetGenerator(target->Target) {}
+ : cmNinjaTargetGenerator(target) {}
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
@@ -44,7 +44,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
for (std::vector<cmCustomCommand>::const_iterator
ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
- this->GetMakefile());
+ this->GetLocalGenerator());
this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
@@ -65,7 +65,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
{
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
- this->GetMakefile());
+ this->GetLocalGenerator());
this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
// Depend on all custom command outputs.
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index a8eef82..4fe99e3 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -22,7 +22,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target,
const std::string& configName)
: GT(target)
, Makefile(target->Target->GetMakefile())
- , LocalGenerator(Makefile->GetLocalGenerator())
+ , LocalGenerator(target->GetLocalGenerator())
, ConfigName(configName)
, MacContentFolders(0)
{
@@ -47,7 +47,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
// Compute bundle directory names.
std::string out = outpath;
out += "/";
- out += this->GT->Target->GetAppBundleDirectory(this->ConfigName, false);
+ out += this->GT->GetAppBundleDirectory(this->ConfigName, false);
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
@@ -57,7 +57,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
// to be set.
std::string plist = outpath;
plist += "/";
- plist += this->GT->Target->GetAppBundleDirectory(this->ConfigName, true);
+ plist += this->GT->GetAppBundleDirectory(this->ConfigName, true);
plist += "/Info.plist";
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
targetName,
@@ -77,11 +77,11 @@ void cmOSXBundleGenerator::CreateFramework(
// Compute the location of the top-level foo.framework directory.
std::string contentdir = outpath + "/" +
- this->GT->Target->GetFrameworkDirectory(this->ConfigName, true);
+ this->GT->GetFrameworkDirectory(this->ConfigName, true);
contentdir += "/";
std::string newoutpath = outpath + "/" +
- this->GT->Target->GetFrameworkDirectory(this->ConfigName, false);
+ this->GT->GetFrameworkDirectory(this->ConfigName, false);
std::string frameworkVersion = this->GT->Target->GetFrameworkVersion();
@@ -172,14 +172,14 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
// Compute bundle directory names.
std::string out = root;
out += "/";
- out += this->GT->Target->GetCFBundleDirectory(this->ConfigName, false);
+ out += this->GT->GetCFBundleDirectory(this->ConfigName, false);
cmSystemTools::MakeDirectory(out.c_str());
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
std::string plist = root + "/" +
- this->GT->Target->GetCFBundleDirectory(this->ConfigName, true);
+ this->GT->GetCFBundleDirectory(this->ConfigName, true);
plist += "/Info.plist";
std::string name = cmSystemTools::GetFilenameName(targetName);
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
@@ -217,7 +217,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
// Construct the full path to the content subdirectory.
std::string macdir =
- this->GT->Target->GetMacContentDirectory(this->ConfigName,
+ this->GT->GetMacContentDirectory(this->ConfigName,
/*implib*/ false);
macdir += "/";
macdir += pkgloc;
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index a612437..35ee127 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -280,7 +280,7 @@ bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
//----------------------------------------------------------------------------
cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
- cmTarget const* target,
+ const cmGeneratorTarget* target,
const char* purpose)
{
this->GlobalGenerator = gg;
@@ -554,7 +554,8 @@ void cmOrderDirectories::FindImplicitConflicts()
<< text
<< "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::WARNING, w.str(), this->Target->GetBacktrace());
+ ->IssueMessage(cmake::WARNING, w.str(),
+ this->Target->Target->GetBacktrace());
}
//----------------------------------------------------------------------------
@@ -635,5 +636,6 @@ void cmOrderDirectories::DiagnoseCycle()
}
e << "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::WARNING, e.str(), this->Target->GetBacktrace());
+ ->IssueMessage(cmake::WARNING, e.str(),
+ this->Target->Target->GetBacktrace());
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 07c85dd..211c786 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -19,7 +19,7 @@
class cmGlobalGenerator;
class cmOrderDirectoriesConstraint;
class cmOrderDirectoriesConstraintLibrary;
-class cmTarget;
+class cmGeneratorTarget;
/** \class cmOrderDirectories
* \brief Compute a safe runtime path order for a set of shared libraries.
@@ -27,7 +27,7 @@ class cmTarget;
class cmOrderDirectories
{
public:
- cmOrderDirectories(cmGlobalGenerator* gg, cmTarget const* target,
+ cmOrderDirectories(cmGlobalGenerator* gg, cmGeneratorTarget const* target,
const char* purpose);
~cmOrderDirectories();
void AddRuntimeLibrary(std::string const& fullPath, const char* soname = 0);
@@ -41,11 +41,9 @@ public:
std::vector<std::string> const& GetOrderedDirectories();
private:
cmGlobalGenerator* GlobalGenerator;
- cmTarget const* Target;
+ cmGeneratorTarget const* Target;
std::string Purpose;
- bool Computed;
-
std::vector<std::string> OrderedDirectories;
std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
@@ -68,8 +66,9 @@ private:
void OrderDirectories();
void VisitDirectory(unsigned int i);
void DiagnoseCycle();
- bool CycleDiagnosed;
int WalkId;
+ bool CycleDiagnosed;
+ bool Computed;
// Adjacency-list representation of runtime path ordering graph.
// This maps from directory to those that must come *before* it.
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
new file mode 100644
index 0000000..7be5b3f
--- /dev/null
+++ b/Source/cmOutputConverter.cxx
@@ -0,0 +1,1056 @@
+/*============================================================================
+ 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 "cmOutputConverter.h"
+
+#include "cmAlgorithms.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+#include <string.h> /* strlen */
+#include <ctype.h> /* isalpha */
+
+cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot)
+ : StateSnapshot(snapshot), LinkScriptShell(false)
+{
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExistingCommon(const std::string& remote,
+ std::string const& result,
+ OutputFormat format) const
+{
+ // If this is a windows shell, the result has a space, and the path
+ // already exists, we can use a short-path to reference it without a
+ // space.
+ if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
+ cmSystemTools::FileExists(remote.c_str()))
+ {
+ std::string tmp;
+ if(cmSystemTools::GetShortPath(remote, tmp))
+ {
+ return this->ConvertToOutputFormat(tmp, format);
+ }
+ }
+
+ // Otherwise, leave it unchanged.
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(const std::string& remote,
+ RelativeRoot local,
+ OutputFormat format) const
+{
+ static_cast<void>(local);
+
+ // Perform standard conversion.
+ std::string result = this->ConvertToOutputFormat(remote, format);
+
+ // Consider short-path.
+ return this->ConvertToOutputForExistingCommon(remote, result, format);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToOutputForExisting(RelativeRoot remote,
+ const std::string& local,
+ OutputFormat format) const
+{
+ // Perform standard conversion.
+ std::string result = this->Convert(remote, local, format, true);
+
+ // Consider short-path.
+ const char* remotePath = this->GetRelativeRootPath(remote);
+ return this->ConvertToOutputForExistingCommon(remotePath, result, format);
+}
+
+//----------------------------------------------------------------------------
+const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const
+{
+ switch (relroot)
+ {
+ case HOME:
+ return this->GetState()->GetSourceDirectory();
+ case START:
+ return this->StateSnapshot.GetDirectory().GetCurrentSource();
+ case HOME_OUTPUT:
+ return this->GetState()->GetBinaryDirectory();
+ case START_OUTPUT:
+ return this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ default: break;
+ }
+ return 0;
+}
+
+std::string cmOutputConverter::Convert(const std::string& source,
+ RelativeRoot relative,
+ OutputFormat output) const
+{
+ // Convert the path to a relative path.
+ std::string result = source;
+
+ switch (relative)
+ {
+ case HOME:
+ result = this->ConvertToRelativePath(
+ this->GetState()->GetSourceDirectoryComponents(), result);
+ break;
+ case START:
+ result = this->ConvertToRelativePath(
+ this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
+ result);
+ break;
+ case HOME_OUTPUT:
+ result = this->ConvertToRelativePath(
+ this->GetState()->GetBinaryDirectoryComponents(), result);
+ break;
+ case START_OUTPUT:
+ result = this->ConvertToRelativePath(
+ this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
+ result);
+ break;
+ case FULL:
+ result = cmSystemTools::CollapseFullPath(result);
+ break;
+ case NONE:
+ break;
+ }
+ return this->ConvertToOutputFormat(result, output);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
+ OutputFormat output) const
+{
+ std::string result = source;
+ // Convert it to an output path.
+ if (output == MAKERULE)
+ {
+ result = cmSystemTools::ConvertToOutputPath(result.c_str());
+ }
+ else if(output == SHELL || output == WATCOMQUOTE)
+ {
+ // For the MSYS shell convert drive letters to posix paths, so
+ // that c:/some/path becomes /c/some/path. This is needed to
+ // avoid problems with the shell path translation.
+ if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
+ {
+ if(result.size() > 2 && result[1] == ':')
+ {
+ result[1] = result[0];
+ result[0] = '/';
+ }
+ }
+ if(this->GetState()->UseWindowsShell())
+ {
+ std::replace(result.begin(), result.end(), '/', '\\');
+ }
+ result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
+ }
+ else if(output == RESPONSE)
+ {
+ result = this->EscapeForShell(result, false, false, false);
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::Convert(RelativeRoot remote,
+ const std::string& local,
+ OutputFormat output,
+ bool optional) const
+{
+ const char* remotePath = this->GetRelativeRootPath(remote);
+
+ // The relative root must have a path (i.e. not FULL or NONE)
+ assert(remotePath != 0);
+
+ if(!local.empty() && !optional)
+ {
+ std::vector<std::string> components;
+ cmSystemTools::SplitPath(local, components);
+ std::string result = this->ConvertToRelativePath(components, remotePath);
+ return this->ConvertToOutputFormat(result, output);
+ }
+
+ return this->ConvertToOutputFormat(remotePath, output);
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterNotAbove(const char* a, const char* b)
+{
+ return (cmSystemTools::ComparePath(a, b) ||
+ cmSystemTools::IsSubDirectory(a, b));
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::ConvertToRelativePath(const std::vector<std::string>& local,
+ const std::string& in_remote,
+ bool force) const
+{
+ // The path should never be quoted.
+ assert(in_remote[0] != '\"');
+
+ // The local path should never have a trailing slash.
+ assert(!local.empty() && !(local[local.size()-1] == ""));
+
+ // If the path is already relative then just return the path.
+ if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
+ {
+ return in_remote;
+ }
+
+ if(!force)
+ {
+ // Skip conversion if the path and local are not both in the source
+ // or both in the binary tree.
+ std::string local_path = cmSystemTools::JoinPath(local);
+ if(!((cmOutputConverterNotAbove(local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())
+ && cmOutputConverterNotAbove(in_remote.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()))
+ || (cmOutputConverterNotAbove(local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource())
+ && cmOutputConverterNotAbove(in_remote.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource()))))
+ {
+ return in_remote;
+ }
+ }
+
+ // Identify the longest shared path component between the remote
+ // path and the local path.
+ std::vector<std::string> remote;
+ cmSystemTools::SplitPath(in_remote, remote);
+ unsigned int common=0;
+ while(common < remote.size() &&
+ common < local.size() &&
+ cmSystemTools::ComparePath(remote[common],
+ local[common]))
+ {
+ ++common;
+ }
+
+ // If no part of the path is in common then return the full path.
+ if(common == 0)
+ {
+ return in_remote;
+ }
+
+ // If the entire path is in common then just return a ".".
+ if(common == remote.size() &&
+ common == local.size())
+ {
+ return ".";
+ }
+
+ // If the entire path is in common except for a trailing slash then
+ // just return a "./".
+ if(common+1 == remote.size() &&
+ remote[common].empty() &&
+ common == local.size())
+ {
+ return "./";
+ }
+
+ // Construct the relative path.
+ std::string relative;
+
+ // First add enough ../ to get up to the level of the shared portion
+ // of the path. Leave off the trailing slash. Note that the last
+ // component of local will never be empty because local should never
+ // have a trailing slash.
+ for(unsigned int i=common; i < local.size(); ++i)
+ {
+ relative += "..";
+ if(i < local.size()-1)
+ {
+ relative += "/";
+ }
+ }
+
+ // Now add the portion of the destination path that is not included
+ // in the shared portion of the path. Add a slash the first time
+ // only if there was already something in the path. If there was a
+ // trailing slash in the input then the last iteration of the loop
+ // will add a slash followed by an empty string which will preserve
+ // the trailing slash in the output.
+
+ if(!relative.empty() && !remote.empty())
+ {
+ relative += "/";
+ }
+ relative += cmJoin(cmMakeRange(remote).advance(common), "/");
+
+ // Finally return the path.
+ return relative;
+}
+
+//----------------------------------------------------------------------------
+static bool cmOutputConverterIsShellOperator(const std::string& str)
+{
+ static std::set<std::string> shellOperators;
+ if(shellOperators.empty())
+ {
+ shellOperators.insert("<");
+ shellOperators.insert(">");
+ shellOperators.insert("<<");
+ shellOperators.insert(">>");
+ shellOperators.insert("|");
+ shellOperators.insert("||");
+ shellOperators.insert("&&");
+ shellOperators.insert("&>");
+ shellOperators.insert("1>");
+ shellOperators.insert("2>");
+ shellOperators.insert("2>&1");
+ shellOperators.insert("1>&2");
+ }
+ return shellOperators.count(str) > 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForShell(const std::string& str,
+ bool makeVars,
+ bool forEcho,
+ bool useWatcomQuote) const
+{
+ // Do not escape shell operators.
+ if(cmOutputConverterIsShellOperator(str))
+ {
+ return str;
+ }
+
+ // Compute the flags for the target shell environment.
+ int flags = 0;
+ if(this->GetState()->UseWindowsVSIDE())
+ {
+ flags |= Shell_Flag_VSIDE;
+ }
+ else if(!this->LinkScriptShell)
+ {
+ flags |= Shell_Flag_Make;
+ }
+ if(makeVars)
+ {
+ flags |= Shell_Flag_AllowMakeVariables;
+ }
+ if(forEcho)
+ {
+ flags |= Shell_Flag_EchoWindows;
+ }
+ if(useWatcomQuote)
+ {
+ flags |= Shell_Flag_WatcomQuote;
+ }
+ if(this->GetState()->UseWatcomWMake())
+ {
+ flags |= Shell_Flag_WatcomWMake;
+ }
+ if(this->GetState()->UseMinGWMake())
+ {
+ flags |= Shell_Flag_MinGWMake;
+ }
+ if(this->GetState()->UseNMake())
+ {
+ flags |= Shell_Flag_NMake;
+ }
+
+ // Compute the buffer size needed.
+ int size = (this->GetState()->UseWindowsShell() ?
+ Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
+ Shell_GetArgumentSizeForUnix(str.c_str(), flags));
+
+ // Compute the shell argument itself.
+ std::vector<char> arg(size);
+ if(this->GetState()->UseWindowsShell())
+ {
+ Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
+ }
+ else
+ {
+ Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
+ }
+ return std::string(&arg[0]);
+}
+
+//----------------------------------------------------------------------------
+std::string cmOutputConverter::EscapeForCMake(const std::string& str)
+{
+ // Always double-quote the argument to take care of most escapes.
+ std::string result = "\"";
+ for(const char* c = str.c_str(); *c; ++c)
+ {
+ if(*c == '"')
+ {
+ // Escape the double quote to avoid ending the argument.
+ result += "\\\"";
+ }
+ else if(*c == '$')
+ {
+ // Escape the dollar to avoid expanding variables.
+ result += "\\$";
+ }
+ else if(*c == '\\')
+ {
+ // Escape the backslash to avoid other escapes.
+ result += "\\\\";
+ }
+ else
+ {
+ // Other characters will be parsed correctly.
+ result += *c;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOutputConverter::EscapeWindowsShellArgument(const char* arg, int shell_flags)
+{
+ char local_buffer[1024];
+ char* buffer = local_buffer;
+ int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
+ if(size > 1024)
+ {
+ buffer = new char[size];
+ }
+ Shell_GetArgumentForWindows(arg, buffer, shell_flags);
+ std::string result(buffer);
+ if(buffer != local_buffer)
+ {
+ delete [] buffer;
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+cmOutputConverter::FortranFormat
+cmOutputConverter::GetFortranFormat(const char* value)
+{
+ FortranFormat format = FortranFormatNone;
+ if(value && *value)
+ {
+ std::vector<std::string> fmt;
+ cmSystemTools::ExpandListArgument(value, fmt);
+ for(std::vector<std::string>::iterator fi = fmt.begin();
+ fi != fmt.end(); ++fi)
+ {
+ if(*fi == "FIXED")
+ {
+ format = FortranFormatFixed;
+ }
+ if(*fi == "FREE")
+ {
+ format = FortranFormatFree;
+ }
+ }
+ }
+ return format;
+}
+
+void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
+{
+ this->LinkScriptShell = linkScriptShell;
+}
+
+cmState* cmOutputConverter::GetState() const
+{
+ return this->StateSnapshot.GetState();
+}
+
+//----------------------------------------------------------------------------
+/*
+
+Notes:
+
+Make variable replacements open a can of worms. Sometimes they should
+be quoted and sometimes not. Sometimes their replacement values are
+already quoted.
+
+VS variables cause problems. In order to pass the referenced value
+with spaces the reference must be quoted. If the variable value ends
+in a backslash then it will escape the ending quote! In order to make
+the ending backslash appear we need this:
+
+ "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+ "$(InputDir)"
+
+Make variable references are platform specific so we should probably
+just NOT quote them and let the listfile author deal with it.
+
+*/
+
+/*
+TODO: For windows echo:
+
+To display a pipe (|) or redirection character (< or >) when using the
+echo command, use a caret character immediately before the pipe or
+redirection character (for example, ^>, ^<, or ^| ). If you need to
+use the caret character itself (^), use two in a row (^^).
+*/
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsWhitespace(char c)
+{
+ return ((c == ' ') || (c == '\t'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnUnix(char c)
+{
+ return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
+ (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
+ (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
+ (c == '*') || (c == '^') || (c == '\\'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
+{
+ return ((c == '\'') || (c == '#') || (c == '&') ||
+ (c == '<') || (c == '>') || (c == '|') || (c == '^'));
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
+{
+ /* On Windows the built-in command shell echo never needs quotes. */
+ if(!isUnix && (flags & Shell_Flag_EchoWindows))
+ {
+ return 0;
+ }
+
+ /* On all platforms quotes are needed to preserve whitespace. */
+ if(Shell__CharIsWhitespace(c))
+ {
+ return 1;
+ }
+
+ if(isUnix)
+ {
+ /* On UNIX several special characters need quotes to preserve them. */
+ if(Shell__CharNeedsQuotesOnUnix(c))
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ /* On Windows several special characters need quotes to preserve them. */
+ if(Shell__CharNeedsQuotesOnWindows(c))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__CharIsMakeVariableName(char c)
+{
+ return c && (c == '_' || isalpha(((int)c)));
+}
+
+/*--------------------------------------------------------------------------*/
+const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
+{
+ while(*c == '$' && *(c+1) == '(')
+ {
+ const char* skip = c+2;
+ while(Shell__CharIsMakeVariableName(*skip))
+ {
+ ++skip;
+ }
+ if(*skip == ')')
+ {
+ c = skip+1;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return c;
+}
+
+/*
+Allowing make variable replacements opens a can of worms. Sometimes
+they should be quoted and sometimes not. Sometimes their replacement
+values are already quoted or contain escapes.
+
+Some Visual Studio variables cause problems. In order to pass the
+referenced value with spaces the reference must be quoted. If the
+variable value ends in a backslash then it will escape the ending
+quote! In order to make the ending backslash appear we need this:
+
+ "$(InputDir)\"
+
+However if there is not a trailing backslash then this will put a
+quote in the value so we need:
+
+ "$(InputDir)"
+
+This macro decides whether we quote an argument just because it
+contains a make variable reference. This should be replaced with a
+flag later when we understand applications of this better.
+*/
+#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in,
+ int isUnix, int flags)
+{
+ /* The empty string needs quotes. */
+ if(!*in)
+ {
+ return 1;
+ }
+
+ /* Scan the string for characters that require quoting. */
+ {
+ const char* c;
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
+ const char* skip = Shell__SkipMakeVariables(c);
+ if(skip != c)
+ {
+ /* We need to quote make variable references to preserve the
+ string with contents substituted in its place. */
+ return 1;
+ }
+#else
+ /* Skip over the make variable references if any are present. */
+ c = Shell__SkipMakeVariables(c);
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+#endif
+ }
+
+ /* Check whether this character needs quotes. */
+ if(Shell__CharNeedsQuotes(*c, isUnix, flags))
+ {
+ return 1;
+ }
+ }
+ }
+
+ /* On Windows some single character arguments need quotes. */
+ if(!isUnix && *in && !*(in+1))
+ {
+ char c = *in;
+ if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell__GetArgumentSize(const char* in,
+ int isUnix, int flags)
+{
+ /* Start with the length of the original argument, plus one for
+ either a terminating null or a separating space. */
+ int size = (int)strlen(in) + 1;
+
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+ /* Skip over the make variable references if any are present. */
+ c = Shell__SkipMakeVariables(c);
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+ }
+
+ /* Check whether this character needs escaping for the shell. */
+ if(isUnix)
+ {
+ /* On Unix a few special characters need escaping even inside a
+ quoted argument. */
+ if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+ {
+ /* This character needs a backslash to escape it. */
+ ++size;
+ }
+ }
+ else if(flags & Shell_Flag_EchoWindows)
+ {
+ /* On Windows the built-in command shell echo never needs escaping. */
+ }
+ else
+ {
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. We need to escape it and all
+ immediately preceding backslashes. */
+ size += windows_backslashes + 1;
+ windows_backslashes = 0;
+ }
+ else
+ {
+ /* Found another character. This eliminates the possibility
+ that any immediately preceding backslashes will be
+ escaped. */
+ windows_backslashes = 0;
+ }
+ }
+
+ /* Check whether this character needs escaping for a make tool. */
+ if(*c == '$')
+ {
+ if(flags & Shell_Flag_Make)
+ {
+ /* In Makefiles a dollar is written $$ so we need one extra
+ character. */
+ ++size;
+ }
+ else if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a dollar is written "$" so we need two extra
+ characters. */
+ size += 2;
+ }
+ }
+ else if(*c == '#')
+ {
+ if((flags & Shell_Flag_Make) &&
+ (flags & Shell_Flag_WatcomWMake))
+ {
+ /* In Watcom WMake makefiles a pound is written $# so we need
+ one extra character. */
+ ++size;
+ }
+ }
+ else if(*c == '%')
+ {
+ if((flags & Shell_Flag_VSIDE) ||
+ ((flags & Shell_Flag_Make) &&
+ ((flags & Shell_Flag_MinGWMake) ||
+ (flags & Shell_Flag_NMake))))
+ {
+ /* In the VS IDE, NMake, or MinGW make a percent is written %%
+ so we need one extra characters. */
+ size += 1;
+ }
+ }
+ else if(*c == ';')
+ {
+ if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a semicolon is written ";" so we need two extra
+ characters. */
+ size += 2;
+ }
+ }
+ }
+
+ /* Check whether the argument needs surrounding quotes. */
+ if(Shell__ArgumentNeedsQuotes(in, isUnix, flags))
+ {
+ /* Surrounding quotes are needed. Allocate space for them. */
+ if((flags & Shell_Flag_WatcomQuote) && (isUnix))
+ {
+ size += 2;
+ }
+ size += 2;
+
+ /* We must escape all ending backslashes when quoting on windows. */
+ size += windows_backslashes;
+ }
+
+ return size;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
+ int isUnix, int flags)
+{
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Whether the argument must be quoted. */
+ int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
+ if(needQuotes)
+ {
+ /* Add the opening quote for this argument. */
+ if(flags & Shell_Flag_WatcomQuote)
+ {
+ if(isUnix)
+ {
+ *out++ = '"';
+ }
+ *out++ = '\'';
+ }
+ else
+ {
+ *out++ = '"';
+ }
+ }
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if(flags & Shell_Flag_AllowMakeVariables)
+ {
+ const char* skip = Shell__SkipMakeVariables(c);
+ if(skip != c)
+ {
+ /* Copy to the end of the make variable references. */
+ while(c != skip)
+ {
+ *out++ = *c++;
+ }
+
+ /* The make variable reference eliminates any escaping needed
+ for preceding backslashes. */
+ windows_backslashes = 0;
+
+ /* Stop if we have reached the end of the string. */
+ if(!*c)
+ {
+ break;
+ }
+ }
+ }
+
+ /* Check whether this character needs escaping for the shell. */
+ if(isUnix)
+ {
+ /* On Unix a few special characters need escaping even inside a
+ quoted argument. */
+ if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
+ {
+ /* This character needs a backslash to escape it. */
+ *out++ = '\\';
+ }
+ }
+ else if(flags & Shell_Flag_EchoWindows)
+ {
+ /* On Windows the built-in command shell echo never needs escaping. */
+ }
+ else
+ {
+ /* On Windows only backslashes and double-quotes need escaping. */
+ if(*c == '\\')
+ {
+ /* Found a backslash. It may need to be escaped later. */
+ ++windows_backslashes;
+ }
+ else if(*c == '"')
+ {
+ /* Found a double-quote. Escape all immediately preceding
+ backslashes. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the backslash to escape the double-quote. */
+ *out++ = '\\';
+ }
+ else
+ {
+ /* We encountered a normal character. This eliminates any
+ escaping needed for preceding backslashes. */
+ windows_backslashes = 0;
+ }
+ }
+
+ /* Check whether this character needs escaping for a make tool. */
+ if(*c == '$')
+ {
+ if(flags & Shell_Flag_Make)
+ {
+ /* In Makefiles a dollar is written $$. The make tool will
+ replace it with just $ before passing it to the shell. */
+ *out++ = '$';
+ *out++ = '$';
+ }
+ else if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a dollar is written "$". If this is written in
+ an un-quoted argument it starts a quoted segment, inserts
+ the $ and ends the segment. If it is written in a quoted
+ argument it ends quoting, inserts the $ and restarts
+ quoting. Either way the $ is isolated from surrounding
+ text to avoid looking like a variable reference. */
+ *out++ = '"';
+ *out++ = '$';
+ *out++ = '"';
+ }
+ else
+ {
+ /* Otherwise a dollar is written just $. */
+ *out++ = '$';
+ }
+ }
+ else if(*c == '#')
+ {
+ if((flags & Shell_Flag_Make) &&
+ (flags & Shell_Flag_WatcomWMake))
+ {
+ /* In Watcom WMake makefiles a pound is written $#. The make
+ tool will replace it with just # before passing it to the
+ shell. */
+ *out++ = '$';
+ *out++ = '#';
+ }
+ else
+ {
+ /* Otherwise a pound is written just #. */
+ *out++ = '#';
+ }
+ }
+ else if(*c == '%')
+ {
+ if((flags & Shell_Flag_VSIDE) ||
+ ((flags & Shell_Flag_Make) &&
+ ((flags & Shell_Flag_MinGWMake) ||
+ (flags & Shell_Flag_NMake))))
+ {
+ /* In the VS IDE, NMake, or MinGW make a percent is written %%. */
+ *out++ = '%';
+ *out++ = '%';
+ }
+ else
+ {
+ /* Otherwise a percent is written just %. */
+ *out++ = '%';
+ }
+ }
+ else if(*c == ';')
+ {
+ if(flags & Shell_Flag_VSIDE)
+ {
+ /* In a VS IDE a semicolon is written ";". If this is written
+ in an un-quoted argument it starts a quoted segment,
+ inserts the ; and ends the segment. If it is written in a
+ quoted argument it ends quoting, inserts the ; and restarts
+ quoting. Either way the ; is isolated. */
+ *out++ = '"';
+ *out++ = ';';
+ *out++ = '"';
+ }
+ else
+ {
+ /* Otherwise a semicolon is written just ;. */
+ *out++ = ';';
+ }
+ }
+ else
+ {
+ /* Store this character. */
+ *out++ = *c;
+ }
+ }
+
+ if(needQuotes)
+ {
+ /* Add enough backslashes to escape any trailing ones. */
+ while(windows_backslashes > 0)
+ {
+ --windows_backslashes;
+ *out++ = '\\';
+ }
+
+ /* Add the closing quote for this argument. */
+ if(flags & Shell_Flag_WatcomQuote)
+ {
+ *out++ = '\'';
+ if(isUnix)
+ {
+ *out++ = '"';
+ }
+ }
+ else
+ {
+ *out++ = '"';
+ }
+ }
+
+ /* Store a terminating null without incrementing. */
+ *out = 0;
+
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
+ char* out, int flags)
+{
+ return Shell__GetArgument(in, out, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
+ char* out, int flags)
+{
+ return Shell__GetArgument(in, out, 1, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
+ int flags)
+{
+ return Shell__GetArgumentSize(in, 0, flags);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in,
+ int flags)
+{
+ return Shell__GetArgumentSize(in, 1, flags);
+}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
new file mode 100644
index 0000000..ed7739e
--- /dev/null
+++ b/Source/cmOutputConverter.h
@@ -0,0 +1,181 @@
+/*============================================================================
+ 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 cmOutputConverter_h
+#define cmOutputConverter_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmState.h"
+
+class cmOutputConverter
+{
+public:
+ cmOutputConverter(cmState::Snapshot snapshot);
+
+ /**
+ * Convert something to something else. This is a centralized conversion
+ * routine used by the generators to handle relative paths and the like.
+ * The flags determine what is actually done.
+ *
+ * relative: treat the argument as a directory and convert it to make it
+ * relative or full or unchanged. If relative (HOME, START etc) then that
+ * specifies what it should be relative to.
+ *
+ * output: make the result suitable for output to a...
+ *
+ * optional: should any relative path operation be controlled by the rel
+ * path setting
+ */
+ enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
+ enum OutputFormat { UNCHANGED, MAKERULE, SHELL, WATCOMQUOTE, RESPONSE };
+ std::string ConvertToOutputFormat(const std::string& source,
+ OutputFormat output) const;
+ std::string Convert(const std::string& remote, RelativeRoot local,
+ OutputFormat output = UNCHANGED) const;
+ std::string Convert(RelativeRoot remote, const std::string& local,
+ OutputFormat output = UNCHANGED,
+ bool optional = false) const;
+
+ /**
+ * Get path for the specified relative root.
+ */
+ const char* GetRelativeRootPath(RelativeRoot relroot) const;
+
+ ///! for existing files convert to output path and short path if spaces
+ std::string ConvertToOutputForExisting(const std::string& remote,
+ RelativeRoot local = START_OUTPUT,
+ OutputFormat format = SHELL) const;
+
+ /** For existing path identified by RelativeRoot convert to output
+ path and short path if spaces. */
+ std::string ConvertToOutputForExisting(RelativeRoot remote,
+ const std::string& local = "",
+ OutputFormat format = SHELL) const;
+
+ void SetLinkScriptShell(bool linkScriptShell);
+
+ /**
+ * Flags to pass to Shell_GetArgumentForWindows or
+ * Shell_GetArgumentForUnix. These modify the generated
+ * quoting and escape sequences to work under alternative
+ * environments.
+ */
+ enum Shell_Flag_e
+ {
+ /** The target shell is in a makefile. */
+ Shell_Flag_Make = (1<<0),
+
+ /** The target shell is in a VS project file. Do not use with
+ Shell_Flag_Make. */
+ Shell_Flag_VSIDE = (1<<1),
+
+ /** In a windows shell the argument is being passed to "echo". */
+ Shell_Flag_EchoWindows = (1<<2),
+
+ /** The target shell is in a Watcom WMake makefile. */
+ Shell_Flag_WatcomWMake = (1<<3),
+
+ /** The target shell is in a MinGW Make makefile. */
+ Shell_Flag_MinGWMake = (1<<4),
+
+ /** The target shell is in a NMake makefile. */
+ Shell_Flag_NMake = (1<<5),
+
+ /** Make variable reference syntax $(MAKEVAR) should not be escaped
+ to allow a build tool to replace it. Replacement values
+ containing spaces, quotes, backslashes, or other
+ non-alphanumeric characters that have significance to some makes
+ or shells produce undefined behavior. */
+ Shell_Flag_AllowMakeVariables = (1<<6),
+
+ /** The target shell quoting uses extra single Quotes for Watcom tools. */
+ Shell_Flag_WatcomQuote = (1<<7)
+ };
+
+ /**
+ * Transform the given command line argument for use in a Windows or
+ * Unix shell. Returns a pointer to the end of the command line
+ * argument in the provided output buffer. Flags may be passed to
+ * modify the generated quoting and escape sequences to work under
+ * alternative environments.
+ */
+ static char* Shell_GetArgumentForWindows(const char* in, char* out,
+ int flags);
+ static char* Shell_GetArgumentForUnix(const char* in, char* out, int flags);
+
+ /**
+ * Compute the size of the buffer required to store the output from
+ * Shell_GetArgumentForWindows or Shell_GetArgumentForUnix. The flags
+ * passed must be identical between the two calls.
+ */
+ static int Shell_GetArgumentSizeForWindows(const char* in, int flags);
+ static int Shell_GetArgumentSizeForUnix(const char* in, int flags);
+
+ std::string EscapeForShell(const std::string& str,
+ bool makeVars = false,
+ bool forEcho = false,
+ bool useWatcomQuote = false) const;
+
+ static std::string EscapeForCMake(const std::string& str);
+
+ /** Compute an escaped version of the given argument for use in a
+ windows shell. */
+ static std::string EscapeWindowsShellArgument(const char* arg,
+ int shell_flags);
+
+ enum FortranFormat
+ {
+ FortranFormatNone,
+ FortranFormatFixed,
+ FortranFormatFree
+ };
+ static FortranFormat GetFortranFormat(const char* value);
+
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * the given local path. The local path must be given in component
+ * form (see SystemTools::SplitPath) without a trailing slash. The
+ * remote path must use forward slashes and not already be escaped
+ * or quoted.
+ */
+ std::string ConvertToRelativePath(const std::vector<std::string>& local,
+ const std::string& in_remote,
+ bool force = false) const;
+
+private:
+ cmState* GetState() const;
+
+ std::string ConvertToOutputForExistingCommon(const std::string& remote,
+ std::string const& result,
+ OutputFormat format) const;
+
+ static int Shell__CharIsWhitespace(char c);
+ static int Shell__CharNeedsQuotesOnUnix(char c);
+ static int Shell__CharNeedsQuotesOnWindows(char c);
+ static int Shell__CharNeedsQuotes(char c, int isUnix, int flags);
+ static int Shell__CharIsMakeVariableName(char c);
+ static const char* Shell__SkipMakeVariables(const char* c);
+ static int Shell__ArgumentNeedsQuotes(const char* in,
+ int isUnix, int flags);
+ static int Shell__GetArgumentSize(const char* in,
+ int isUnix, int flags);
+ static char* Shell__GetArgument(const char* in, char* out,
+ int isUnix, int flags);
+
+private:
+ cmState::Snapshot StateSnapshot;
+
+ bool LinkScriptShell;
+};
+
+#endif
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index f8d61db..3eb19bb 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -255,6 +255,22 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
{
return false;
}
+ if(pid == cmPolicies::CMP0001 &&
+ (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ {
+ if(!(mf->GetState()
+ ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
+ {
+ // Set it to 2.4 because that is the last version where the
+ // variable had meaning.
+ mf->AddCacheDefinition
+ ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+ "For backwards compatibility, what version of CMake "
+ "commands and "
+ "syntax should this version of CMake try to support.",
+ cmState::STRING);
+ }
+ }
}
}
else
@@ -343,51 +359,38 @@ cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
return e.str();
}
-cmPolicies::PolicyMap::PolicyMap()
-{
- this->UNDEFINED.set();
-}
-
cmPolicies::PolicyStatus
cmPolicies::PolicyMap::Get(cmPolicies::PolicyID id) const
{
PolicyStatus status = cmPolicies::WARN;
- if (this->OLD[id])
+ if (this->Status[(POLICY_STATUS_COUNT * id) + OLD])
{
status = cmPolicies::OLD;
}
- else if (this->NEW[id])
+ else if (this->Status[(POLICY_STATUS_COUNT * id) + NEW])
{
status = cmPolicies::NEW;
}
- else if (this->REQUIRED_ALWAYS[id])
- {
- status = cmPolicies::REQUIRED_ALWAYS;
- }
- else if (this->REQUIRED_IF_USED[id])
- {
- status = cmPolicies::REQUIRED_IF_USED;
- }
return status;
}
void cmPolicies::PolicyMap::Set(cmPolicies::PolicyID id,
cmPolicies::PolicyStatus status)
{
- this->UNDEFINED.reset(id);
- this->OLD[id] = (status == cmPolicies::OLD);
- this->NEW[id] = (status == cmPolicies::NEW);
- this->REQUIRED_ALWAYS[id] = (status == cmPolicies::REQUIRED_ALWAYS);
- this->REQUIRED_IF_USED[id] = (status == cmPolicies::REQUIRED_IF_USED);
+ this->Status[(POLICY_STATUS_COUNT * id) + OLD] = (status == OLD);
+ this->Status[(POLICY_STATUS_COUNT * id) + WARN] = (status == WARN);
+ this->Status[(POLICY_STATUS_COUNT * id) + NEW] = (status == NEW);
}
bool cmPolicies::PolicyMap::IsDefined(cmPolicies::PolicyID id) const
{
- return !this->UNDEFINED[id];
+ return this->Status[(POLICY_STATUS_COUNT * id) + OLD]
+ || this->Status[(POLICY_STATUS_COUNT * id) + WARN]
+ || this->Status[(POLICY_STATUS_COUNT * id) + NEW];
}
bool cmPolicies::PolicyMap::IsEmpty() const
{
- return !this->UNDEFINED.none();
+ return this->Status.none();
}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 00d857a..a791b89 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -12,7 +12,7 @@
#ifndef cmPolicies_h
#define cmPolicies_h
-#include "cmCustomCommand.h"
+#include "cmStandardIncludes.h"
#include <bitset>
@@ -217,6 +217,9 @@ class cmPolicy;
3, 3, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0063, \
"Honor visibility properties for all target types.", \
+ 3, 3, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0064, \
+ "Support new TEST if() operator.", \
3, 3, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -281,18 +284,14 @@ public:
/** Represent a set of policy values. */
struct PolicyMap
{
- PolicyMap();
PolicyStatus Get(PolicyID id) const;
void Set(PolicyID id, PolicyStatus status);
bool IsDefined(PolicyID id) const;
bool IsEmpty() const;
private:
- std::bitset<cmPolicies::CMPCOUNT> UNDEFINED;
- std::bitset<cmPolicies::CMPCOUNT> OLD;
- std::bitset<cmPolicies::CMPCOUNT> NEW;
- std::bitset<cmPolicies::CMPCOUNT> REQUIRED_IF_USED;
- std::bitset<cmPolicies::CMPCOUNT> REQUIRED_ALWAYS;
+#define POLICY_STATUS_COUNT 3
+ std::bitset<cmPolicies::CMPCOUNT * POLICY_STATUS_COUNT> Status;
};
};
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index d2f7bf3..15d9ed0 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -44,7 +44,7 @@ void cmProcessTools::RunProcess(struct cmsysProcess_s* cp,
//----------------------------------------------------------------------------
cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR):
- Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0')
+ Log(0), Prefix(0), Separator(sep), LineEnd('\0'), IgnoreCR(ignoreCR)
{
}
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
index 439726d..23833ca 100644
--- a/Source/cmProcessTools.h
+++ b/Source/cmProcessTools.h
@@ -51,12 +51,12 @@ public:
/** Configure logging of lines as they are extracted. */
void SetLog(std::ostream* log, const char* prefix);
protected:
- char Separator;
- bool IgnoreCR;
std::ostream* Log;
const char* Prefix;
- char LineEnd;
std::string Line;
+ char Separator;
+ char LineEnd;
+ bool IgnoreCR;
virtual bool ProcessChunk(const char* data, int length);
/** Implement in a subclass to process one line of input. It
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 176cb0d..7123125 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -20,7 +20,7 @@ bool cmProjectCommand
this->SetError("PROJECT called with incorrect number of arguments");
return false;
}
- this->Makefile->SetProjectName(args[0].c_str());
+ this->Makefile->SetProjectName(args[0]);
std::string bindir = args[0];
bindir += "_BINARY_DIR";
@@ -53,7 +53,7 @@ bool cmProjectCommand
// CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build
// will work.
if(!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME")
- || (this->Makefile->GetLocalGenerator()->IsRootMakefile()))
+ || (this->Makefile->IsRootMakefile()))
{
this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str());
this->Makefile->AddCacheDefinition
@@ -233,7 +233,6 @@ bool cmProjectCommand
const char* include = this->Makefile->GetDefinition(extraInclude);
if(include)
{
- std::string fullFilePath;
bool readit =
this->Makefile->ReadDependentFile(include);
if(!readit && !cmSystemTools::GetFatalErrorOccured())
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
index 40976db..ef57068 100644
--- a/Source/cmProperty.cxx
+++ b/Source/cmProperty.cxx
@@ -12,17 +12,14 @@
#include "cmProperty.h"
#include "cmSystemTools.h"
-void cmProperty::Set(const std::string& name, const char *value)
+void cmProperty::Set(const char *value)
{
- this->Name = name;
this->Value = value;
this->ValueHasBeenSet = true;
}
-void cmProperty::Append(const std::string& name, const char *value,
- bool asString)
+void cmProperty::Append(const char *value, bool asString)
{
- this->Name = name;
if(!this->Value.empty() && *value && !asString)
{
this->Value += ";";
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index 659c4c3..e026372 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -21,11 +21,10 @@ public:
TEST, VARIABLE, CACHED_VARIABLE, INSTALL };
// set this property
- void Set(const std::string& name, const char *value);
+ void Set(const char *value);
// append to this property
- void Append(const std::string& name, const char *value,
- bool asString = false);
+ void Append(const char *value, bool asString = false);
// get the value
const char *GetValue() const;
@@ -34,7 +33,6 @@ public:
cmProperty() { this->ValueHasBeenSet = false; }
protected:
- std::string Name;
std::string Value;
bool ValueHasBeenSet;
};
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index 3875318..776fad1 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -29,9 +29,9 @@ void cmPropertyDefinitionMap
}
}
-bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name)
+bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
{
- cmPropertyDefinitionMap::iterator it = this->find(name);
+ cmPropertyDefinitionMap::const_iterator it = this->find(name);
if (it == this->end())
{
return false;
@@ -40,9 +40,9 @@ bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name)
return true;
}
-bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name)
+bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
{
- cmPropertyDefinitionMap::iterator it = this->find(name);
+ cmPropertyDefinitionMap::const_iterator it = this->find(name);
if (it == this->end())
{
return false;
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 00c7328..f95c721 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -27,10 +27,10 @@ public:
bool chain);
// has a named property been defined
- bool IsPropertyDefined(const std::string& name);
+ bool IsPropertyDefined(const std::string& name) const;
// is a named property set to chain
- bool IsPropertyChained(const std::string& name);
+ bool IsPropertyChained(const std::string& name) const;
};
#endif
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 070f6f1..ef09dbc 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -14,6 +14,8 @@
#include "cmake.h"
#include "cmState.h"
+#include <assert.h>
+
cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name)
{
cmPropertyMap::iterator it = this->find(name);
@@ -29,54 +31,39 @@ cmProperty *cmPropertyMap::GetOrCreateProperty(const std::string& name)
return prop;
}
-void cmPropertyMap::SetProperty(const std::string& name, const char *value,
- cmProperty::ScopeType scope)
+void cmPropertyMap::SetProperty(const std::string& name, const char *value)
{
if(!value)
{
this->erase(name);
return;
}
- (void)scope;
cmProperty *prop = this->GetOrCreateProperty(name);
- prop->Set(name,value);
+ prop->Set(value);
}
void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
- cmProperty::ScopeType scope, bool asString)
+ bool asString)
{
// Skip if nothing to append.
if(!value || !*value)
{
return;
}
- (void)scope;
cmProperty *prop = this->GetOrCreateProperty(name);
- prop->Append(name,value,asString);
+ prop->Append(value,asString);
}
const char *cmPropertyMap
-::GetPropertyValue(const std::string& name,
- cmProperty::ScopeType scope,
- bool &chain) const
+::GetPropertyValue(const std::string& name) const
{
- chain = false;
- if (name.empty())
- {
- return 0;
- }
+ assert(!name.empty());
cmPropertyMap::const_iterator it = this->find(name);
if (it == this->end())
{
- // should we chain up?
- if (this->CMakeInstance)
- {
- chain = this->CMakeInstance->GetState()->
- IsPropertyChained(name,scope);
- }
return 0;
}
return it->second.GetValue();
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 02d4235..a9062db 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -14,29 +14,17 @@
#include "cmProperty.h"
-class cmake;
-
class cmPropertyMap : public std::map<std::string,cmProperty>
{
public:
cmProperty *GetOrCreateProperty(const std::string& name);
- void SetProperty(const std::string& name, const char *value,
- cmProperty::ScopeType scope);
+ void SetProperty(const std::string& name, const char *value);
void AppendProperty(const std::string& name, const char* value,
- cmProperty::ScopeType scope, bool asString=false);
-
- const char *GetPropertyValue(const std::string& name,
- cmProperty::ScopeType scope,
- bool &chain) const;
-
- void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; }
-
- cmPropertyMap() { this->CMakeInstance = 0;}
+ bool asString=false);
-private:
- cmake *CMakeInstance;
+ const char *GetPropertyValue(const std::string& name) const;
};
#endif
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index cbb06cd..becfeba 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -26,7 +26,6 @@
#include <sys/stat.h>
#include <cmsys/Terminal.h>
-#include <cmsys/ios/sstream>
#include <cmsys/FStream.hxx>
#include <assert.h>
@@ -122,7 +121,7 @@ static void copyTargetProperty(cmTarget* destinationTarget,
static std::string ReadAll(const std::string& filename)
{
cmsys::ifstream file(filename.c_str());
- cmsys_ios::stringstream stream;
+ std::stringstream stream;
stream << file.rdbuf();
file.close();
return stream.str();
@@ -190,7 +189,7 @@ std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf,
std::vector<std::string> command;
command.push_back(rccCommand);
- command.push_back("--list");
+ command.push_back("-list");
std::string absFile = cmsys::SystemTools::GetRealPath(
sf->GetFullPath());
@@ -287,7 +286,8 @@ std::string cmQtAutoGenerators::ListQt4RccInputs(cmSourceFile* sf,
return entriesList;
}
-bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
+bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg,
+ cmTarget* target)
{
cmMakefile* makefile = target->GetMakefile();
// don't do anything if there is no Qt4 or Qt5Core (which contains moc):
@@ -368,8 +368,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
#if defined(_WIN32) && !defined(__CYGWIN__)
bool usePRE_BUILD = false;
- cmLocalGenerator* localGen = makefile->GetLocalGenerator();
- cmGlobalGenerator* gg = localGen->GetGlobalGenerator();
+ cmGlobalGenerator* gg = lg->GetGlobalGenerator();
if(gg->GetName().find("Visual Studio") != std::string::npos)
{
cmGlobalVisualStudioGenerator* vsgg =
@@ -396,7 +395,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
std::vector<std::string> rcc_output;
bool const isNinja =
- makefile->GetGlobalGenerator()->GetName() == "Ninja";
+ lg->GetGlobalGenerator()->GetName() == "Ninja";
if(isNinja
#if defined(_WIN32) && !defined(__CYGWIN__)
|| usePRE_BUILD
@@ -404,7 +403,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
)
{
std::vector<cmSourceFile*> srcFiles;
- target->GetConfigCommonSourceFiles(srcFiles);
+ cmGeneratorTarget* gtgt =
+ lg->GetGlobalGenerator()->GetGeneratorTarget(target);
+ gtgt->GetConfigCommonSourceFiles(srcFiles);
for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end();
++fileIt)
@@ -440,6 +441,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
this->ListQt4RccInputs(sf, depends);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Cannot use PRE_BUILD because the resource files themselves
+ // may not be sources within the target so VS may not know the
+ // target needs to re-build at all.
usePRE_BUILD = false;
#endif
}
@@ -466,31 +470,14 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
else
#endif
{
- cmTarget* autogenTarget = 0;
- if (!rcc_output.empty() && !isNinja)
- {
- std::vector<std::string> no_byproducts;
- makefile->AddCustomCommandToOutput(rcc_output, no_byproducts,
- depends, "",
- commandLines, 0,
- workingDirectory.c_str(),
- false, false);
-
- cmCustomCommandLines no_commands;
- autogenTarget = makefile->AddUtilityCommand(
- autogenTargetName, true,
- workingDirectory.c_str(), rcc_output,
- no_commands, false, autogenComment.c_str());
-
- }
- else
- {
- autogenTarget = makefile->AddUtilityCommand(
+ cmTarget* autogenTarget = makefile->AddUtilityCommand(
autogenTargetName, true,
workingDirectory.c_str(),
/*byproducts=*/rcc_output, depends,
commandLines, false, autogenComment.c_str());
- }
+
+ cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
+ makefile->AddGeneratorTarget(autogenTarget, gt);
// Set target folder
const char* autogenFolder = makefile->GetState()
@@ -522,10 +509,10 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
std::string &defs)
{
cmMakefile* makefile = target->GetMakefile();
- cmLocalGenerator* localGen = makefile->GetLocalGenerator();
+ cmGlobalGenerator* globalGen = makefile->GetGlobalGenerator();
std::vector<std::string> includeDirs;
- cmGeneratorTarget *gtgt = localGen->GetGlobalGenerator()
- ->GetGeneratorTarget(target);
+ cmGeneratorTarget *gtgt = globalGen->GetGeneratorTarget(target);
+ cmLocalGenerator *localGen = gtgt->GetLocalGenerator();
// 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", config, false);
@@ -550,9 +537,9 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
std::string autogenTargetName = getAutogenTargetName(target);
makefile->AddDefinition("_moc_target_name",
- cmLocalGenerator::EscapeForCMake(autogenTargetName).c_str());
+ cmOutputConverter::EscapeForCMake(autogenTargetName).c_str());
makefile->AddDefinition("_origin_target_name",
- cmLocalGenerator::EscapeForCMake(target->GetName()).c_str());
+ cmOutputConverter::EscapeForCMake(target->GetName()).c_str());
std::string targetDir = getAutogenTargetDir(target);
@@ -561,8 +548,11 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
{
qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
}
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
if (const char *targetQtVersion =
- target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
+ gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
{
qtVersion = targetQtVersion;
}
@@ -582,7 +572,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
this->SetupSourceFiles(target);
}
makefile->AddDefinition("_cpp_files",
- cmLocalGenerator::EscapeForCMake(this->Sources).c_str());
+ cmOutputConverter::EscapeForCMake(this->Sources).c_str());
if (target->GetPropertyAsBool("AUTOMOC"))
{
this->SetupAutoMocTarget(target, autogenTargetName,
@@ -609,7 +599,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target)
// Ensure we have write permission in case .in was read-only.
mode_t perm = 0;
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
mode_t mode_write = S_IWRITE;
#else
mode_t mode_write = S_IWUSR;
@@ -673,7 +663,10 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
const char* sepHeaders = "";
std::vector<cmSourceFile*> srcFiles;
- target->GetConfigCommonSourceFiles(srcFiles);
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ gtgt->GetConfigCommonSourceFiles(srcFiles);
const char *skipMocSep = "";
const char *skipUicSep = "";
@@ -764,11 +757,11 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
std::string _moc_options = (tmp!=0 ? tmp : "");
makefile->AddDefinition("_moc_options",
- cmLocalGenerator::EscapeForCMake(_moc_options).c_str());
+ cmOutputConverter::EscapeForCMake(_moc_options).c_str());
makefile->AddDefinition("_skip_moc",
- cmLocalGenerator::EscapeForCMake(this->SkipMoc).c_str());
+ cmOutputConverter::EscapeForCMake(this->SkipMoc).c_str());
makefile->AddDefinition("_moc_headers",
- cmLocalGenerator::EscapeForCMake(this->Headers).c_str());
+ cmOutputConverter::EscapeForCMake(this->Headers).c_str());
bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
@@ -780,9 +773,9 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
_moc_incs, _moc_compile_defs);
makefile->AddDefinition("_moc_incs",
- cmLocalGenerator::EscapeForCMake(_moc_incs).c_str());
+ cmOutputConverter::EscapeForCMake(_moc_incs).c_str());
makefile->AddDefinition("_moc_compile_defs",
- cmLocalGenerator::EscapeForCMake(_moc_compile_defs).c_str());
+ cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str());
for (std::vector<std::string>::const_iterator li = configs.begin();
li != configs.end(); ++li)
@@ -795,7 +788,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
if (config_moc_incs != _moc_incs)
{
configIncludes[*li] =
- cmLocalGenerator::EscapeForCMake(config_moc_incs);
+ cmOutputConverter::EscapeForCMake(config_moc_incs);
if(_moc_incs.empty())
{
_moc_incs = config_moc_incs;
@@ -804,7 +797,7 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
if (config_moc_compile_defs != _moc_compile_defs)
{
configDefines[*li] =
- cmLocalGenerator::EscapeForCMake(config_moc_compile_defs);
+ cmOutputConverter::EscapeForCMake(config_moc_compile_defs);
if(_moc_compile_defs.empty())
{
_moc_compile_defs = config_moc_compile_defs;
@@ -822,7 +815,8 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
autogenTargetName.c_str());
return;
}
- makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(""));
+ makefile->AddDefinition("_qt_moc_executable",
+ qt5Moc->ImportedGetLocation(""));
}
else if (strcmp(qtVersion, "4") == 0)
{
@@ -833,7 +827,8 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
autogenTargetName.c_str());
return;
}
- makefile->AddDefinition("_qt_moc_executable", qt4Moc->GetLocation(""));
+ makefile->AddDefinition("_qt_moc_executable",
+ qt4Moc->ImportedGetLocation(""));
}
else
{
@@ -890,8 +885,11 @@ void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
static void GetUicOpts(cmTarget const* target, const std::string& config,
std::string &optString)
{
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
std::vector<std::string> opts;
- target->GetAutoUicOptions(opts, config);
+ gtgt->GetAutoUicOptions(opts, config);
optString = cmJoin(opts, ";");
}
@@ -906,7 +904,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
skipped.insert(skipVec.begin(), skipVec.end());
makefile->AddDefinition("_skip_uic",
- cmLocalGenerator::EscapeForCMake(this->SkipUic).c_str());
+ cmOutputConverter::EscapeForCMake(this->SkipUic).c_str());
std::vector<cmSourceFile*> uiFilesWithOptions
= makefile->GetQtUiFilesWithOptions();
@@ -920,7 +918,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
if (!_uic_opts.empty())
{
- _uic_opts = cmLocalGenerator::EscapeForCMake(_uic_opts);
+ _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);
makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());
}
for (std::vector<std::string>::const_iterator li = configs.begin();
@@ -931,7 +929,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
if (config_uic_opts != _uic_opts)
{
configUicOptions[*li] =
- cmLocalGenerator::EscapeForCMake(config_uic_opts);
+ cmOutputConverter::EscapeForCMake(config_uic_opts);
if(_uic_opts.empty())
{
_uic_opts = config_uic_opts;
@@ -966,9 +964,9 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
}
makefile->AddDefinition("_qt_uic_options_files",
- cmLocalGenerator::EscapeForCMake(uiFileFiles).c_str());
+ cmOutputConverter::EscapeForCMake(uiFileFiles).c_str());
makefile->AddDefinition("_qt_uic_options_options",
- cmLocalGenerator::EscapeForCMake(uiFileOptions).c_str());
+ cmOutputConverter::EscapeForCMake(uiFileOptions).c_str());
std::string targetName = target->GetName();
if (strcmp(qtVersion, "5") == 0)
@@ -980,7 +978,8 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
}
else
{
- makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(""));
+ makefile->AddDefinition("_qt_uic_executable",
+ qt5Uic->ImportedGetLocation(""));
}
}
else if (strcmp(qtVersion, "4") == 0)
@@ -992,7 +991,8 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
targetName.c_str());
return;
}
- makefile->AddDefinition("_qt_uic_executable", qt4Uic->GetLocation(""));
+ makefile->AddDefinition("_qt_uic_executable",
+ qt4Uic->ImportedGetLocation(""));
}
else
{
@@ -1051,7 +1051,10 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
cmMakefile *makefile = target->GetMakefile();
std::vector<cmSourceFile*> srcFiles;
- target->GetConfigCommonSourceFiles(srcFiles);
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
+ gtgt->GetConfigCommonSourceFiles(srcFiles);
std::string qrcInputs;
const char* qrcInputsSep = "";
@@ -1141,15 +1144,15 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
}
}
makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),
- cmLocalGenerator::EscapeForCMake(qrcInputs).c_str());
+ cmOutputConverter::EscapeForCMake(qrcInputs).c_str());
makefile->AddDefinition("_rcc_files",
- cmLocalGenerator::EscapeForCMake(_rcc_files).c_str());
+ cmOutputConverter::EscapeForCMake(_rcc_files).c_str());
makefile->AddDefinition("_qt_rcc_options_files",
- cmLocalGenerator::EscapeForCMake(rccFileFiles).c_str());
+ cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());
makefile->AddDefinition("_qt_rcc_options_options",
- cmLocalGenerator::EscapeForCMake(rccFileOptions).c_str());
+ cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());
makefile->AddDefinition("_qt_rcc_executable",
this->GetRccExecutable(target).c_str());
@@ -1157,6 +1160,9 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
{
+ cmGeneratorTarget *gtgt = target->GetMakefile()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(target);
cmMakefile *makefile = target->GetMakefile();
const char *qtVersion = makefile->GetDefinition("_target_qt_version");
if (!qtVersion)
@@ -1167,8 +1173,7 @@ std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
}
if (const char *targetQtVersion =
- target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",
- ""))
+ gtgt->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
{
qtVersion = targetQtVersion;
}
@@ -1184,7 +1189,7 @@ std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
targetName.c_str());
return std::string();
}
- return qt5Rcc->GetLocation("");
+ return qt5Rcc->ImportedGetLocation("");
}
else if (strcmp(qtVersion, "4") == 0)
{
@@ -1195,7 +1200,7 @@ std::string cmQtAutoGenerators::GetRccExecutable(cmTarget const* target)
targetName.c_str());
return std::string();
}
- return qt4Rcc->GetLocation("");
+ return qt4Rcc->ImportedGetLocation("");
}
cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
@@ -1212,10 +1217,12 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
cm.SetHomeDirectory(targetDirectory);
cmGlobalGenerator gg(&cm);
- cmLocalGenerator* lg = gg.MakeLocalGenerator();
+ cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, snapshot));
+ cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
lg->GetMakefile()->SetCurrentBinaryDirectory(targetDirectory);
lg->GetMakefile()->SetCurrentSourceDirectory(targetDirectory);
- gg.SetCurrentLocalGenerator(lg);
+ gg.SetCurrentMakefile(lg->GetMakefile());
this->ReadAutogenInfoFile(lg->GetMakefile(), targetDirectory, config);
this->ReadOldMocDefinitionsFile(lg->GetMakefile(), targetDirectory);
@@ -1229,7 +1236,6 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
this->WriteOldMocDefinitionsFile(targetDirectory);
- delete lg;
return success;
}
@@ -1434,7 +1440,7 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile(
outfile.open(filename.c_str(),
std::ios::trunc);
outfile << "set(AM_OLD_COMPILE_SETTINGS "
- << cmLocalGenerator::EscapeForCMake(
+ << cmOutputConverter::EscapeForCMake(
this->CurrentCompileSettingsStr) << ")\n";
outfile.close();
@@ -1640,7 +1646,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
this->GenerateQrc();
}
- cmsys_ios::stringstream outStream;
+ std::stringstream outStream;
outStream << "/* This file is autogenerated, do not edit*/\n";
bool automocCppChanged = false;
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index f74e3c5..4f03348 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -18,6 +18,7 @@
class cmGlobalGenerator;
class cmMakefile;
+class cmLocalGenerator;
class cmQtAutoGenerators
{
@@ -25,7 +26,7 @@ public:
cmQtAutoGenerators();
bool Run(const std::string& targetDirectory, const std::string& config);
- bool InitializeAutogenTarget(cmTarget* target);
+ bool InitializeAutogenTarget(cmLocalGenerator* lg, cmTarget* target);
void SetupAutoGenerateTarget(cmTarget const* target);
void SetupSourceFiles(cmTarget const* target);
@@ -105,7 +106,6 @@ private:
std::string SkipMoc;
std::string SkipUic;
std::string Headers;
- bool IncludeProjectDirsBefore;
std::string Srcdir;
std::string Builddir;
std::string MocExecutable;
@@ -131,6 +131,7 @@ private:
std::map<std::string, std::string> RccOptions;
std::map<std::string, std::vector<std::string> > RccInputs;
+ bool IncludeProjectDirsBefore;
bool Verbose;
bool ColorOutput;
bool RunMocFailed;
@@ -138,7 +139,6 @@ private:
bool RunRccFailed;
bool GenerateAll;
bool RelaxedMode;
-
};
#endif
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index 9ab04f1..bc9372f 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -54,9 +54,6 @@ public:
void Generate(std::ostream& os, const std::string& config,
std::vector<std::string> const& configurationTypes);
- const std::vector<std::string>& GetConfigurations() const
- { return this->Configurations; }
-
protected:
typedef cmScriptGeneratorIndent Indent;
virtual void GenerateScript(std::ostream& os);
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index bf9f42c..306276b 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -108,7 +108,7 @@ bool cmSetCommand
}
// collect any values into a single semi-colon separated value list
- value = cmJoin(cmRange(args).advance(1).retreat(ignoreLastArgs), ";");
+ value = cmJoin(cmMakeRange(args).advance(1).retreat(ignoreLastArgs), ";");
if (parentScope)
{
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 31e460f..17ad475 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -205,14 +205,8 @@ bool cmSetPropertyCommand::HandleDirectoryMode()
// The local generators are associated with collapsed paths.
dir = cmSystemTools::CollapseFullPath(dir);
- // Lookup the generator.
- if(cmLocalGenerator* lg =
- this->Makefile->GetGlobalGenerator()->FindLocalGenerator(dir))
- {
- // Use the makefile for the directory found.
- mf = lg->GetMakefile();
- }
- else
+ mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
+ if (!mf)
{
// Could not find the directory.
this->SetError
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index e9cfacc..53dc5a8 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -85,8 +85,10 @@ bool cmSetTestsPropertiesCommand
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
- test->SetProperty(propertyPairs[k],
- propertyPairs[k+1].c_str());
+ if (!propertyPairs[k].empty())
+ {
+ test->SetProperty(propertyPairs[k], propertyPairs[k+1].c_str());
+ }
}
}
else
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 724ab39..86f0a7a 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -22,7 +22,6 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name):
Location(mf, name)
{
this->CustomCommand = 0;
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
this->FindFullPathFailed = false;
this->IsUiFile = (".ui" ==
cmSystemTools::GetFilenameLastExtension(this->Location.GetName()));
@@ -299,7 +298,7 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
//----------------------------------------------------------------------------
void cmSourceFile::SetProperty(const std::string& prop, const char* value)
{
- this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+ this->Properties.SetProperty(prop, value);
if (this->IsUiFile)
{
@@ -315,8 +314,7 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
bool asString)
{
- this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE,
- asString);
+ this->Properties.AppendProperty(prop, value, asString);
}
//----------------------------------------------------------------------------
@@ -362,13 +360,16 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
}
}
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain);
- if (chain)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
{
cmMakefile const* mf = this->Location.GetMakefile();
- return mf->GetProperty(prop,cmProperty::SOURCE_FILE);
+ const bool chain = mf->GetState()->
+ IsPropertyChained(prop, cmProperty::SOURCE_FILE);
+ if (chain)
+ {
+ return mf->GetProperty(prop, chain);
+ }
}
return retVal;
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index f898260..1433b54 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -107,8 +107,9 @@ private:
std::string Extension;
std::string Language;
std::string FullPath;
- bool FindFullPathFailed;
std::string ObjectLibrary;
+ std::vector<std::string> Depends;
+ bool FindFullPathFailed;
bool IsUiFile;
bool FindFullPath(std::string* error);
@@ -116,7 +117,6 @@ private:
void CheckExtension();
void CheckLanguage(std::string const& ext);
- std::vector<std::string> Depends;
static const std::string propLANGUAGE;
};
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index a9796b9..468a589 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -33,14 +33,6 @@
// Provide fixed-size integer types.
#include <cmIML/INT.h>
-// Include stream compatibility layer from KWSys.
-// This is needed to work with large file support
-// on some platforms whose stream operators do not
-// support the large integer types.
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include <cmsys/IOStream.hxx>
-#endif
-
#include <fstream>
#include <iostream>
#include <iomanip>
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 042fabe..b30c10b 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -15,9 +15,73 @@
#include "cmCacheManager.h"
#include "cmCommand.h"
#include "cmAlgorithms.h"
+#include "cmDefinitions.h"
#include <assert.h>
+struct cmState::SnapshotDataType
+{
+ cmState::PositionType ScopeParent;
+ cmState::PositionType DirectoryParent;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator Policies;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyRoot;
+ cmLinkedTree<cmState::PolicyStackEntry>::iterator PolicyScope;
+ cmState::SnapshotType SnapshotType;
+ cmLinkedTree<std::string>::iterator ExecutionListFile;
+ cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
+ BuildSystemDirectory;
+ cmLinkedTree<cmDefinitions>::iterator Vars;
+ cmLinkedTree<cmDefinitions>::iterator Root;
+ cmLinkedTree<cmDefinitions>::iterator Parent;
+ std::string EntryPointCommand;
+ long EntryPointLine;
+ std::vector<std::string>::size_type IncludeDirectoryPosition;
+ std::vector<std::string>::size_type CompileDefinitionsPosition;
+ std::vector<std::string>::size_type CompileOptionsPosition;
+};
+
+struct cmState::PolicyStackEntry: public cmPolicies::PolicyMap
+{
+ typedef cmPolicies::PolicyMap derived;
+ PolicyStackEntry(bool w = false): derived(), Weak(w) {}
+ PolicyStackEntry(derived const& d, bool w): derived(d), Weak(w) {}
+ PolicyStackEntry(PolicyStackEntry const& r): derived(r), Weak(r.Weak) {}
+ bool Weak;
+};
+
+struct cmState::BuildsystemDirectoryStateType
+{
+ cmState::PositionType DirectoryEnd;
+
+ std::string Location;
+ std::string OutputLocation;
+
+ std::vector<std::string> CurrentSourceDirectoryComponents;
+ std::vector<std::string> CurrentBinaryDirectoryComponents;
+ // The top-most directories for relative path conversion. Both the
+ // source and destination location of a relative path conversion
+ // must be underneath one of these directories (both under source or
+ // both under binary) in order for the relative path to be evaluated
+ // safely by the build tools.
+ std::string RelativePathTopSource;
+ std::string RelativePathTopBinary;
+
+ std::vector<std::string> IncludeDirectories;
+ std::vector<cmListFileBacktrace> IncludeDirectoryBacktraces;
+
+ std::vector<std::string> CompileDefinitions;
+ std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
+
+ std::vector<std::string> CompileOptions;
+ std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+
+ std::string ProjectName;
+
+ cmPropertyMap Properties;
+
+ std::vector<cmState::Snapshot> Children;
+};
+
cmState::cmState(cmake* cm)
: CMakeInstance(cm),
IsInTryCompile(false),
@@ -195,34 +259,38 @@ void cmState::RemoveCacheEntryProperty(std::string const& key,
->GetCacheIterator(key.c_str()).SetProperty(propertyName, (void*)0);
}
-void cmState::Reset()
+cmState::Snapshot cmState::Reset()
{
this->GlobalProperties.clear();
this->PropertyDefinitions.clear();
- assert(this->Locations.size() > 0);
- assert(this->OutputLocations.size() > 0);
- assert(this->ParentPositions.size() > 0);
- assert(this->CurrentSourceDirectoryComponents.size() > 0);
- assert(this->CurrentBinaryDirectoryComponents.size() > 0);
- assert(this->RelativePathTopSource.size() > 0);
- assert(this->RelativePathTopBinary.size() > 0);
-
- this->Locations.erase(this->Locations.begin() + 1, this->Locations.end());
- this->OutputLocations.erase(this->OutputLocations.begin() + 1,
- this->OutputLocations.end());
- this->ParentPositions.erase(this->ParentPositions.begin() + 1,
- this->ParentPositions.end());
- this->CurrentSourceDirectoryComponents.erase(
- this->CurrentSourceDirectoryComponents.begin() + 1,
- this->CurrentSourceDirectoryComponents.end());
- this->CurrentBinaryDirectoryComponents.erase(
- this->CurrentBinaryDirectoryComponents.begin() + 1,
- this->CurrentBinaryDirectoryComponents.end());
- this->RelativePathTopSource.erase(this->RelativePathTopSource.begin() + 1,
- this->RelativePathTopSource.end());
- this->RelativePathTopBinary.erase(this->RelativePathTopBinary.begin() + 1,
- this->RelativePathTopBinary.end());
+ PositionType pos = this->SnapshotData.Truncate();
+ this->ExecutionListFiles.Truncate();
+
+ {
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator it =
+ this->BuildsystemDirectory.Truncate();
+ it->IncludeDirectories.clear();
+ it->IncludeDirectoryBacktraces.clear();
+ it->CompileDefinitions.clear();
+ it->CompileDefinitionsBacktraces.clear();
+ it->CompileOptions.clear();
+ it->CompileOptionsBacktraces.clear();
+ it->DirectoryEnd = pos;
+ it->Properties.clear();
+ it->Children.clear();
+ }
+
+ this->PolicyStack.Clear();
+ pos->Policies = this->PolicyStack.Root();
+ pos->PolicyRoot = this->PolicyStack.Root();
+ pos->PolicyScope = this->PolicyStack.Root();
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+ this->VarTree.Clear();
+ pos->Vars = this->VarTree.Extend(this->VarTree.Root());
+ pos->Parent = this->VarTree.Root();
+ pos->Root = this->VarTree.Root();
this->DefineProperty
("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
@@ -243,6 +311,8 @@ void cmState::Reset()
this->DefineProperty
("RULE_LAUNCH_CUSTOM", cmProperty::TARGET,
"", "", true);
+
+ return Snapshot(this, pos);
}
void cmState::DefineProperty(const std::string& name,
@@ -256,27 +326,41 @@ void cmState::DefineProperty(const std::string& name,
chained);
}
-cmPropertyDefinition *cmState
+cmPropertyDefinition const* cmState
::GetPropertyDefinition(const std::string& name,
- cmProperty::ScopeType scope)
+ cmProperty::ScopeType scope) const
{
if (this->IsPropertyDefined(name,scope))
{
- return &(this->PropertyDefinitions[scope][name]);
+ cmPropertyDefinitionMap const& defs =
+ this->PropertyDefinitions.find(scope)->second;
+ return &defs.find(name)->second;
}
return 0;
}
bool cmState::IsPropertyDefined(const std::string& name,
- cmProperty::ScopeType scope)
+ cmProperty::ScopeType scope) const
{
- return this->PropertyDefinitions[scope].IsPropertyDefined(name);
+ std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+ = this->PropertyDefinitions.find(scope);
+ if (it == this->PropertyDefinitions.end())
+ {
+ return false;
+ }
+ return it->second.IsPropertyDefined(name);
}
bool cmState::IsPropertyChained(const std::string& name,
- cmProperty::ScopeType scope)
+ cmProperty::ScopeType scope) const
{
- return this->PropertyDefinitions[scope].IsPropertyChained(name);
+ std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it
+ = this->PropertyDefinitions.find(scope);
+ if (it == this->PropertyDefinitions.end())
+ {
+ return false;
+ }
+ return it->second.IsPropertyChained(name);
}
void cmState::SetLanguageEnabled(std::string const& l)
@@ -435,20 +519,17 @@ void cmState::RemoveUserDefinedCommands()
void cmState::SetGlobalProperty(const std::string& prop, const char* value)
{
- this->GlobalProperties.SetProperty(prop, value, cmProperty::GLOBAL);
+ this->GlobalProperties.SetProperty(prop, value);
}
void cmState::AppendGlobalProperty(const std::string& prop,
const char* value, bool asString)
{
- this->GlobalProperties.AppendProperty(prop, value,
- cmProperty::GLOBAL, asString);
+ this->GlobalProperties.AppendProperty(prop, value, asString);
}
const char *cmState::GetGlobalProperty(const std::string& prop)
{
- // watch for special properties
- std::string output = "";
if ( prop == "CACHE_VARIABLES" )
{
std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
@@ -480,9 +561,7 @@ const char *cmState::GetGlobalProperty(const std::string& prop)
return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
}
#undef STRING_LIST_ELEMENT
- bool dummy = false;
- return this->GlobalProperties.GetPropertyValue(prop, cmProperty::GLOBAL,
- dummy);
+ return this->GlobalProperties.GetPropertyValue(prop);
}
bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
@@ -590,18 +669,18 @@ std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
return this->BinaryDirectoryComponents;
}
-void cmState::Snapshot::ComputeRelativePathTopSource()
+void cmState::Directory::ComputeRelativePathTopSource()
{
// Relative path conversion inside the source tree is not used to
// construct relative paths passed to build tools so it is safe to use
// even when the source is a network path.
- cmState::Snapshot snapshot = *this;
+ cmState::Snapshot snapshot = this->Snapshot_;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
- snapshot = snapshot.GetParent();
+ snapshot = snapshot.GetBuildsystemDirectoryParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
@@ -612,28 +691,28 @@ void cmState::Snapshot::ComputeRelativePathTopSource()
}
}
- std::string result = snapshots.front().GetCurrentSourceDirectory();
+ std::string result = snapshots.front().GetDirectory().GetCurrentSource();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
- std::string currentSource = it->GetCurrentSourceDirectory();
+ std::string currentSource = it->GetDirectory().GetCurrentSource();
if(cmSystemTools::IsSubDirectory(result, currentSource))
{
result = currentSource;
}
}
- this->State->RelativePathTopSource[this->Position] = result;
+ this->DirectoryState->RelativePathTopSource = result;
}
-void cmState::Snapshot::ComputeRelativePathTopBinary()
+void cmState::Directory::ComputeRelativePathTopBinary()
{
- cmState::Snapshot snapshot = *this;
+ cmState::Snapshot snapshot = this->Snapshot_;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
- snapshot = snapshot.GetParent();
+ snapshot = snapshot.GetBuildsystemDirectoryParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
@@ -645,12 +724,12 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
}
std::string result =
- snapshots.front().GetCurrentBinaryDirectory();
+ snapshots.front().GetDirectory().GetCurrentBinary();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
- std::string currentBinary = it->GetCurrentBinaryDirectory();
+ std::string currentBinary = it->GetDirectory().GetCurrentBinary();
if(cmSystemTools::IsSubDirectory(result, currentBinary))
{
result = currentBinary;
@@ -662,33 +741,215 @@ void cmState::Snapshot::ComputeRelativePathTopBinary()
// is a network path.
if(result.size() < 2 || result.substr(0, 2) != "//")
{
- this->State->RelativePathTopBinary[this->Position] = result;
+ this->DirectoryState->RelativePathTopBinary = result;
}
else
{
- this->State->RelativePathTopBinary[this->Position] = "";
+ this->DirectoryState->RelativePathTopBinary = "";
}
}
-cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot)
+cmState::Snapshot cmState::CreateBaseSnapshot()
+{
+ PositionType pos = this->SnapshotData.Extend(this->SnapshotData.Root());
+ pos->DirectoryParent = this->SnapshotData.Root();
+ pos->ScopeParent = this->SnapshotData.Root();
+ pos->SnapshotType = BaseType;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root());
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Extend(this->ExecutionListFiles.Root());
+ pos->IncludeDirectoryPosition = 0;
+ pos->CompileDefinitionsPosition = 0;
+ pos->CompileOptionsPosition = 0;
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->Policies = this->PolicyStack.Root();
+ pos->PolicyRoot = this->PolicyStack.Root();
+ pos->PolicyScope = this->PolicyStack.Root();
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+ pos->Vars = this->VarTree.Extend(this->VarTree.Root());
+ assert(pos->Vars.IsValid());
+ pos->Parent = this->VarTree.Root();
+ pos->Root = this->VarTree.Root();
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine)
+{
+ assert(originSnapshot.IsValid());
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->DirectoryParent = originSnapshot.Position;
+ pos->ScopeParent = originSnapshot.Position;
+ pos->SnapshotType = BuildsystemDirectoryType;
+ pos->BuildSystemDirectory =
+ this->BuildsystemDirectory.Extend(
+ originSnapshot.Position->BuildSystemDirectory);
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->Policies = originSnapshot.Position->Policies;
+ pos->PolicyRoot = originSnapshot.Position->Policies;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ assert(pos->Policies.IsValid());
+ assert(pos->PolicyRoot.IsValid());
+
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Root = origin;
+ pos->Vars = this->VarTree.Extend(origin);
+ cmState::Snapshot snapshot = cmState::Snapshot(this, pos);
+ originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
+ return snapshot;
+}
+
+cmState::Snapshot
+cmState::CreateFunctionCallSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->ScopeParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = FunctionCallType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ assert(originSnapshot.Position->Vars.IsValid());
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Vars = this->VarTree.Extend(origin);
+ return cmState::Snapshot(this, pos);
+}
+
+
+cmState::Snapshot
+cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName)
{
- if (!originSnapshot.IsValid())
- {
- originSnapshot.State = this;
- }
- PositionType pos = this->ParentPositions.size();
- this->ParentPositions.push_back(originSnapshot.Position);
- this->Locations.resize(this->Locations.size() + 1);
- this->OutputLocations.resize(this->OutputLocations.size() + 1);
- this->CurrentSourceDirectoryComponents.resize(
- this->CurrentSourceDirectoryComponents.size() + 1);
- this->CurrentBinaryDirectoryComponents.resize(
- this->CurrentBinaryDirectoryComponents.size() + 1);
- this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1);
- this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1);
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = MacroCallType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ assert(originSnapshot.Position->Vars.IsValid());
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateCallStackSnapshot(cmState::Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ const std::string& fileName)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = CallStackType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ assert(originSnapshot.Position->Vars.IsValid());
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreateVariableScopeSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->ScopeParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = VariableScopeType;
+ assert(originSnapshot.Position->Vars.IsValid());
+
+ cmLinkedTree<cmDefinitions>::iterator origin =
+ originSnapshot.Position->Vars;
+ pos->Parent = origin;
+ pos->Vars = this->VarTree.Extend(origin);
+ assert(pos->Vars.IsValid());
return cmState::Snapshot(this, pos);
}
+cmState::Snapshot
+cmState::CreateInlineListFileSnapshot(cmState::Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ const std::string& fileName)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = InlineListFileType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot
+cmState::CreatePolicyScopeSnapshot(cmState::Snapshot originSnapshot)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->SnapshotType = PolicyScopeType;
+ pos->BuildSystemDirectory->DirectoryEnd = pos;
+ pos->PolicyScope = originSnapshot.Position->Policies;
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
+{
+ PositionType pos = originSnapshot.Position;
+ PositionType prevPos = pos;
+ ++prevPos;
+ prevPos->IncludeDirectoryPosition =
+ prevPos->BuildSystemDirectory->IncludeDirectories.size();
+ prevPos->CompileDefinitionsPosition =
+ prevPos->BuildSystemDirectory->CompileDefinitions.size();
+ prevPos->CompileOptionsPosition =
+ prevPos->BuildSystemDirectory->CompileOptions.size();
+ prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
+
+ return Snapshot(this, prevPos);
+}
+
+cmState::Snapshot::Snapshot(cmState* state)
+ : State(state)
+ , Position()
+{
+}
+
+std::vector<cmState::Snapshot> cmState::Snapshot::GetChildren()
+{
+ return this->Position->BuildSystemDirectory->Children;
+}
+
cmState::Snapshot::Snapshot(cmState* state, PositionType position)
: State(state),
Position(position)
@@ -696,94 +957,779 @@ cmState::Snapshot::Snapshot(cmState* state, PositionType position)
}
-const char* cmState::Snapshot::GetCurrentSourceDirectory() const
+cmState::SnapshotType cmState::Snapshot::GetType() const
{
- return this->State->Locations[this->Position].c_str();
+ return this->Position->SnapshotType;
}
-void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
+const char* cmState::Directory::GetCurrentSource() const
{
- assert(this->State);
- assert(this->State->Locations.size() > this->Position);
- this->State->Locations[this->Position] = dir;
- cmSystemTools::ConvertToUnixSlashes(
- this->State->Locations[this->Position]);
- this->State->Locations[this->Position] =
- cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]);
+ return this->DirectoryState->Location.c_str();
+}
+
+void cmState::Directory::SetCurrentSource(std::string const& dir)
+{
+ std::string& loc = this->DirectoryState->Location;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
cmSystemTools::SplitPath(
- this->State->Locations[this->Position],
- this->State->CurrentSourceDirectoryComponents[this->Position]);
+ loc,
+ this->DirectoryState->CurrentSourceDirectoryComponents);
this->ComputeRelativePathTopSource();
}
-const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
+const char* cmState::Directory::GetCurrentBinary() const
{
- return this->State->OutputLocations[this->Position].c_str();
+ return this->DirectoryState->OutputLocation.c_str();
}
-void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
+void cmState::Directory::SetCurrentBinary(std::string const& dir)
{
- assert(this->State->OutputLocations.size() > this->Position);
- this->State->OutputLocations[this->Position] = dir;
- cmSystemTools::ConvertToUnixSlashes(
- this->State->OutputLocations[this->Position]);
- this->State->OutputLocations[this->Position] =
- cmSystemTools::CollapseFullPath(
- this->State->OutputLocations[this->Position]);
+ std::string& loc = this->DirectoryState->OutputLocation;
+ loc = dir;
+ cmSystemTools::ConvertToUnixSlashes(loc);
+ loc = cmSystemTools::CollapseFullPath(loc);
cmSystemTools::SplitPath(
- this->State->OutputLocations[this->Position],
- this->State->CurrentBinaryDirectoryComponents[this->Position]);
+ loc,
+ this->DirectoryState->CurrentBinaryDirectoryComponents);
this->ComputeRelativePathTopBinary();
}
+void cmState::Snapshot::SetListFile(const std::string& listfile)
+{
+ *this->Position->ExecutionListFile = listfile;
+}
+
std::vector<std::string> const&
-cmState::Snapshot::GetCurrentSourceDirectoryComponents()
+cmState::Directory::GetCurrentSourceComponents() const
{
- return this->State->CurrentSourceDirectoryComponents[this->Position];
+ return this->DirectoryState->CurrentSourceDirectoryComponents;
}
std::vector<std::string> const&
-cmState::Snapshot::GetCurrentBinaryDirectoryComponents()
+cmState::Directory::GetCurrentBinaryComponents() const
+{
+ return this->DirectoryState->CurrentBinaryDirectoryComponents;
+}
+
+const char* cmState::Directory::GetRelativePathTopSource() const
+{
+ return this->DirectoryState->RelativePathTopSource.c_str();
+}
+
+const char* cmState::Directory::GetRelativePathTopBinary() const
+{
+ return this->DirectoryState->RelativePathTopBinary.c_str();
+}
+
+void cmState::Directory::SetRelativePathTopSource(const char* dir)
{
- return this->State->CurrentBinaryDirectoryComponents[this->Position];
+ this->DirectoryState->RelativePathTopSource = dir;
}
-const char* cmState::Snapshot::GetRelativePathTopSource() const
+void cmState::Directory::SetRelativePathTopBinary(const char* dir)
{
- return this->State->RelativePathTopSource[this->Position].c_str();
+ this->DirectoryState->RelativePathTopBinary = dir;
}
-const char* cmState::Snapshot::GetRelativePathTopBinary() const
+std::string cmState::Snapshot::GetExecutionListFile() const
{
- return this->State->RelativePathTopBinary[this->Position].c_str();
+ return *this->Position->ExecutionListFile;
}
-void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
+std::string cmState::Snapshot::GetEntryPointCommand() const
{
- this->State->RelativePathTopSource[this->Position] = dir;
+ return this->Position->EntryPointCommand;
}
-void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
+long cmState::Snapshot::GetEntryPointLine() const
{
- this->State->RelativePathTopBinary[this->Position] = dir;
+ return this->Position->EntryPointLine;
}
bool cmState::Snapshot::IsValid() const
{
- return this->State ? true : false;
+ return this->State && this->Position.IsValid()
+ ? this->Position != this->State->SnapshotData.Root()
+ : false;
}
-cmState::Snapshot cmState::Snapshot::GetParent() const
+cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
{
Snapshot snapshot;
- if (!this->State || this->Position == 0)
+ if (!this->State || this->Position == this->State->SnapshotData.Root())
{
return snapshot;
}
- PositionType parentPos = this->State->ParentPositions[this->Position];
- snapshot = Snapshot(this->State, parentPos);
+ PositionType parentPos = this->Position->DirectoryParent;
+ if (parentPos != this->State->SnapshotData.Root())
+ {
+ snapshot = Snapshot(this->State, parentPos);
+ }
return snapshot;
}
+
+cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
+{
+ assert(this->State);
+ assert(this->Position != this->State->SnapshotData.Root());
+
+ Snapshot snapshot;
+ PositionType parentPos = this->Position;
+ while(parentPos->SnapshotType == cmState::PolicyScopeType)
+ {
+ ++parentPos;
+ }
+ if (parentPos->SnapshotType == cmState::BuildsystemDirectoryType
+ || parentPos->SnapshotType == cmState::BaseType)
+ {
+ return snapshot;
+ }
+
+ ++parentPos;
+ while(parentPos->SnapshotType == cmState::PolicyScopeType)
+ {
+ ++parentPos;
+ }
+
+ if (parentPos == this->State->SnapshotData.Root())
+ {
+ return snapshot;
+ }
+
+ snapshot = Snapshot(this->State, parentPos);
+ return snapshot;
+}
+
+void cmState::Snapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak)
+{
+ PositionType pos = this->Position;
+ pos->Policies =
+ this->State->PolicyStack.Extend(pos->Policies,
+ PolicyStackEntry(entry, weak));
+}
+
+bool cmState::Snapshot::PopPolicy()
+{
+ PositionType pos = this->Position;
+ if (pos->Policies == pos->PolicyScope)
+ {
+ return false;
+ }
+ ++pos->Policies;
+ return true;
+}
+
+bool cmState::Snapshot::CanPopPolicyScope()
+{
+ return this->Position->Policies == this->Position->PolicyScope;
+}
+
+void cmState::Snapshot::SetPolicy(cmPolicies::PolicyID id,
+ cmPolicies::PolicyStatus status)
+{
+ // Update the policy stack from the top to the top-most strong entry.
+ bool previous_was_weak = true;
+ for(cmLinkedTree<PolicyStackEntry>::iterator psi = this->Position->Policies;
+ previous_was_weak && psi != this->Position->PolicyRoot; ++psi)
+ {
+ psi->Set(id, status);
+ previous_was_weak = psi->Weak;
+ }
+}
+
+cmPolicies::PolicyStatus
+cmState::Snapshot::GetPolicy(cmPolicies::PolicyID id) const
+{
+ cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id);
+
+ if(status == cmPolicies::REQUIRED_ALWAYS ||
+ status == cmPolicies::REQUIRED_IF_USED)
+ {
+ return status;
+ }
+
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator dir =
+ this->Position->BuildSystemDirectory;
+
+ while (true)
+ {
+ assert(dir.IsValid());
+ cmLinkedTree<PolicyStackEntry>::iterator leaf =
+ dir->DirectoryEnd->Policies;
+ cmLinkedTree<PolicyStackEntry>::iterator root =
+ dir->DirectoryEnd->PolicyRoot;
+ for( ; leaf != root; ++leaf)
+ {
+ if(leaf->IsDefined(id))
+ {
+ status = leaf->Get(id);
+ return status;
+ }
+ }
+ cmState::PositionType e = dir->DirectoryEnd;
+ cmState::PositionType p = e->DirectoryParent;
+ if (p == this->State->SnapshotData.Root())
+ {
+ break;
+ }
+ dir = p->BuildSystemDirectory;
+ }
+ return status;
+}
+
+bool cmState::Snapshot::HasDefinedPolicyCMP0011()
+{
+ return !this->Position->Policies->IsEmpty();
+}
+
+const char* cmState::Snapshot::GetDefinition(std::string const& name) const
+{
+ assert(this->Position->Vars.IsValid());
+ return cmDefinitions::Get(name, this->Position->Vars,
+ this->Position->Root);
+}
+
+bool cmState::Snapshot::IsInitialized(std::string const& name) const
+{
+ return cmDefinitions::HasKey(name, this->Position->Vars,
+ this->Position->Root);
+}
+
+void cmState::Snapshot::SetDefinition(std::string const& name,
+ std::string const& value)
+{
+ this->Position->Vars->Set(name, value.c_str());
+}
+
+void cmState::Snapshot::RemoveDefinition(std::string const& name)
+{
+ this->Position->Vars->Set(name, 0);
+}
+
+std::vector<std::string> cmState::Snapshot::UnusedKeys() const
+{
+ return this->Position->Vars->UnusedKeys();
+}
+
+std::vector<std::string> cmState::Snapshot::ClosureKeys() const
+{
+ return cmDefinitions::ClosureKeys(this->Position->Vars,
+ this->Position->Root);
+}
+
+bool cmState::Snapshot::RaiseScope(std::string const& var, const char* varDef)
+{
+ if(this->Position->ScopeParent == this->Position->DirectoryParent)
+ {
+ Snapshot parentDir = this->GetBuildsystemDirectoryParent();
+ if(!parentDir.IsValid())
+ {
+ return false;
+ }
+ // Update the definition in the parent directory top scope. This
+ // directory's scope was initialized by the closure of the parent
+ // scope, so we do not need to localize the definition first.
+ if (varDef)
+ {
+ parentDir.SetDefinition(var, varDef);
+ }
+ else
+ {
+ parentDir.RemoveDefinition(var);
+ }
+ return true;
+ }
+ // First localize the definition in the current scope.
+ cmDefinitions::Raise(var, this->Position->Vars,
+ this->Position->Root);
+
+ // Now update the definition in the parent scope.
+ this->Position->Parent->Set(var, varDef);
+ return true;
+}
+
+static const std::string cmPropertySentinal = std::string();
+
+template<typename T, typename U, typename V>
+void InitializeContentFromParent(T& parentContent,
+ T& thisContent,
+ U& parentBacktraces,
+ U& thisBacktraces,
+ V& contentEndPosition)
+{
+ std::vector<std::string>::const_iterator parentBegin =
+ parentContent.begin();
+ std::vector<std::string>::const_iterator parentEnd =
+ parentContent.end();
+
+ std::vector<std::string>::const_reverse_iterator parentRbegin =
+ cmMakeReverseIterator(parentEnd);
+ std::vector<std::string>::const_reverse_iterator parentRend =
+ parentContent.rend();
+ parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal);
+ std::vector<std::string>::const_iterator parentIt = parentRbegin.base();
+
+ thisContent = std::vector<std::string>(parentIt, parentEnd);
+
+ std::vector<cmListFileBacktrace>::const_iterator btIt =
+ parentBacktraces.begin() + std::distance(parentBegin, parentIt);
+ std::vector<cmListFileBacktrace>::const_iterator btEnd =
+ parentBacktraces.end();
+
+ thisBacktraces = std::vector<cmListFileBacktrace>(btIt, btEnd);
+
+ contentEndPosition = thisContent.size();
+}
+
+void cmState::Snapshot::InitializeFromParent()
+{
+ PositionType parent = this->Position->DirectoryParent;
+ assert(this->Position->Vars.IsValid());
+ assert(parent->Vars.IsValid());
+
+ *this->Position->Vars =
+ cmDefinitions::MakeClosure(parent->Vars, parent->Root);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->IncludeDirectories,
+ this->Position->BuildSystemDirectory->IncludeDirectories,
+ parent->BuildSystemDirectory->IncludeDirectoryBacktraces,
+ this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces,
+ this->Position->IncludeDirectoryPosition);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->CompileDefinitions,
+ this->Position->BuildSystemDirectory->CompileDefinitions,
+ parent->BuildSystemDirectory->CompileDefinitionsBacktraces,
+ this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces,
+ this->Position->CompileDefinitionsPosition);
+
+ InitializeContentFromParent(parent->BuildSystemDirectory->CompileOptions,
+ this->Position->BuildSystemDirectory->CompileOptions,
+ parent->BuildSystemDirectory->CompileOptionsBacktraces,
+ this->Position->BuildSystemDirectory->CompileOptionsBacktraces,
+ this->Position->CompileOptionsPosition);
+}
+
+cmState* cmState::Snapshot::GetState() const
+{
+ return this->State;
+}
+
+cmState::Directory cmState::Snapshot::GetDirectory() const
+{
+ return Directory(this->Position->BuildSystemDirectory, *this);
+}
+
+void cmState::Snapshot::SetProjectName(const std::string& name)
+{
+ this->Position->BuildSystemDirectory->ProjectName = name;
+}
+
+std::string cmState::Snapshot::GetProjectName() const
+{
+ return this->Position->BuildSystemDirectory->ProjectName;
+}
+
+cmState::Directory::Directory(
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+ const cmState::Snapshot& snapshot)
+ : DirectoryState(iter), Snapshot_(snapshot)
+{
+
+}
+
+template <typename T, typename U>
+cmStringRange GetPropertyContent(T const& content, U contentEndPosition)
+{
+ std::vector<std::string>::const_iterator end =
+ content.begin() + contentEndPosition;
+
+ std::vector<std::string>::const_reverse_iterator rbegin =
+ cmMakeReverseIterator(end);
+ rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+ return cmMakeRange(rbegin.base(), end);
+}
+
+template <typename T, typename U, typename V>
+cmBacktraceRange GetPropertyBacktraces(T const& content,
+ U const& backtraces,
+ V contentEndPosition)
+{
+ std::vector<std::string>::const_iterator entryEnd =
+ content.begin() + contentEndPosition;
+
+ std::vector<std::string>::const_reverse_iterator rbegin =
+ cmMakeReverseIterator(entryEnd);
+ rbegin = std::find(rbegin, content.rend(), cmPropertySentinal);
+
+ std::vector<cmListFileBacktrace>::const_iterator it =
+ backtraces.begin() + std::distance(content.begin(), rbegin.base());
+
+ std::vector<cmListFileBacktrace>::const_iterator end = backtraces.end();
+ return cmMakeRange(it, end);
+}
+
+template <typename T, typename U, typename V>
+void AppendEntry(T& content, U& backtraces, V& endContentPosition,
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ assert(endContentPosition == content.size());
+
+ content.push_back(vec);
+ backtraces.push_back(lfbt);
+
+ endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void SetContent(T& content, U& backtraces, V& endContentPosition,
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ assert(endContentPosition == content.size());
+
+ content.resize(content.size() + 2);
+ backtraces.resize(backtraces.size() + 2);
+
+ content.back() = vec;
+ backtraces.back() = lfbt;
+
+ endContentPosition = content.size();
+}
+
+template <typename T, typename U, typename V>
+void ClearContent(T& content, U& backtraces, V& endContentPosition)
+{
+ assert(endContentPosition == content.size());
+
+ content.resize(content.size() + 1);
+ backtraces.resize(backtraces.size() + 1);
+
+ endContentPosition = content.size();
+}
+
+cmStringRange
+cmState::Directory::GetIncludeDirectoriesEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->IncludeDirectories,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetIncludeDirectoriesEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+void cmState::Directory::AppendIncludeDirectoriesEntry(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::PrependIncludeDirectoriesEntry(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ std::vector<std::string>::iterator entryEnd =
+ this->DirectoryState->IncludeDirectories.begin()
+ + this->Snapshot_.Position->IncludeDirectoryPosition;
+
+ std::vector<std::string>::reverse_iterator rend =
+ this->DirectoryState->IncludeDirectories.rend();
+ std::vector<std::string>::reverse_iterator rbegin =
+ cmMakeReverseIterator(entryEnd);
+ rbegin = std::find(rbegin, rend, cmPropertySentinal);
+
+ std::vector<std::string>::iterator entryIt = rbegin.base();
+ std::vector<std::string>::iterator entryBegin =
+ this->DirectoryState->IncludeDirectories.begin();
+
+ std::vector<cmListFileBacktrace>::iterator btIt =
+ this->DirectoryState->IncludeDirectoryBacktraces.begin()
+ + std::distance(entryBegin, entryIt);
+
+ this->DirectoryState->IncludeDirectories.insert(entryIt, vec);
+ this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt);
+
+ this->Snapshot_.Position->IncludeDirectoryPosition =
+ this->DirectoryState->IncludeDirectories.size();
+}
+
+void cmState::Directory::SetIncludeDirectories(
+ const std::string& vec, const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearIncludeDirectories()
+{
+ ClearContent(this->DirectoryState->IncludeDirectories,
+ this->DirectoryState->IncludeDirectoryBacktraces,
+ this->Snapshot_.Position->IncludeDirectoryPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileDefinitionsEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->CompileDefinitions,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmBacktraceRange
+cmState::Directory::GetCompileDefinitionsEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+void cmState::Directory::AppendCompileDefinitionsEntry(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::SetCompileDefinitions(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileDefinitions()
+{
+ ClearContent(this->DirectoryState->CompileDefinitions,
+ this->DirectoryState->CompileDefinitionsBacktraces,
+ this->Snapshot_.Position->CompileDefinitionsPosition);
+}
+
+cmStringRange cmState::Directory::GetCompileOptionsEntries() const
+{
+ return GetPropertyContent(this->DirectoryState->CompileOptions,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+cmBacktraceRange cmState::Directory::GetCompileOptionsEntryBacktraces() const
+{
+ return GetPropertyBacktraces(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+void
+cmState::Directory::AppendCompileOptionsEntry(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ AppendEntry(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::SetCompileOptions(const std::string& vec,
+ const cmListFileBacktrace& lfbt)
+{
+ SetContent(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition,
+ vec, lfbt);
+}
+
+void cmState::Directory::ClearCompileOptions()
+{
+ ClearContent(this->DirectoryState->CompileOptions,
+ this->DirectoryState->CompileOptionsBacktraces,
+ this->Snapshot_.Position->CompileOptionsPosition);
+}
+
+bool cmState::Snapshot::StrictWeakOrder::operator()(
+ const cmState::Snapshot& lhs, const cmState::Snapshot& rhs) const
+{
+ return lhs.Position.StrictWeakOrdered(rhs.Position);
+}
+
+void cmState::Directory::SetProperty(const std::string& prop,
+ const char* value,
+ cmListFileBacktrace lfbt)
+{
+ if (prop == "INCLUDE_DIRECTORIES")
+ {
+ if (!value)
+ {
+ this->ClearIncludeDirectories();
+ return;
+ }
+ this->SetIncludeDirectories(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_OPTIONS")
+ {
+ if (!value)
+ {
+ this->ClearCompileOptions();
+ return;
+ }
+ this->SetCompileOptions(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_DEFINITIONS")
+ {
+ if (!value)
+ {
+ this->ClearCompileDefinitions();
+ return;
+ }
+ this->SetCompileDefinitions(value, lfbt);
+ return;
+ }
+
+ this->DirectoryState->Properties.SetProperty(prop, value);
+}
+
+void cmState::Directory::AppendProperty(const std::string& prop,
+ const char* value,
+ bool asString,
+ cmListFileBacktrace lfbt)
+{
+ if (prop == "INCLUDE_DIRECTORIES")
+ {
+ this->AppendIncludeDirectoriesEntry(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_OPTIONS")
+ {
+ this->AppendCompileOptionsEntry(value, lfbt);
+ return;
+ }
+ if (prop == "COMPILE_DEFINITIONS")
+ {
+ this->AppendCompileDefinitionsEntry(value, lfbt);
+ return;
+ }
+
+ this->DirectoryState->Properties.AppendProperty(prop, value, asString);
+}
+
+const char*cmState::Directory::GetProperty(const std::string& prop) const
+{
+ const bool chain = this->Snapshot_.State->
+ IsPropertyChained(prop, cmProperty::DIRECTORY);
+ return this->GetProperty(prop, chain);
+}
+
+const char*
+cmState::Directory::GetProperty(const std::string& prop, bool chain) const
+{
+ static std::string output;
+ output = "";
+ if (prop == "PARENT_DIRECTORY")
+ {
+ cmState::Snapshot parent =
+ this->Snapshot_.GetBuildsystemDirectoryParent();
+ if(parent.IsValid())
+ {
+ return parent.GetDirectory().GetCurrentSource();
+ }
+ return "";
+ }
+ else if (prop == "LISTFILE_STACK")
+ {
+ std::vector<std::string> listFiles;
+ cmState::Snapshot snp = this->Snapshot_;
+ while (snp.IsValid())
+ {
+ listFiles.push_back(snp.GetExecutionListFile());
+ snp = snp.GetCallStackParent();
+ }
+ std::reverse(listFiles.begin(), listFiles.end());
+ output = cmJoin(listFiles, ";");
+ return output.c_str();
+ }
+ else if ( prop == "CACHE_VARIABLES" )
+ {
+ output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
+ return output.c_str();
+ }
+ else if (prop == "VARIABLES")
+ {
+ std::vector<std::string> res = this->Snapshot_.ClosureKeys();
+ std::vector<std::string> cacheKeys =
+ this->Snapshot_.State->GetCacheEntryKeys();
+ res.insert(res.end(), cacheKeys.begin(), cacheKeys.end());
+ std::sort(res.begin(), res.end());
+ output = cmJoin(res, ";");
+ return output.c_str();
+ }
+ else if (prop == "INCLUDE_DIRECTORIES")
+ {
+ output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
+ return output.c_str();
+ }
+ else if (prop == "COMPILE_OPTIONS")
+ {
+ output = cmJoin(this->GetCompileOptionsEntries(), ";");
+ return output.c_str();
+ }
+ else if (prop == "COMPILE_DEFINITIONS")
+ {
+ output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
+ return output.c_str();
+ }
+
+ const char *retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+ if (!retVal && chain)
+ {
+ Snapshot parentSnapshot = this->Snapshot_.GetBuildsystemDirectoryParent();
+ if (parentSnapshot.IsValid())
+ {
+ return parentSnapshot.GetDirectory().GetProperty(prop, chain);
+ }
+ return this->Snapshot_.State->GetGlobalProperty(prop);
+ }
+
+ return retVal;
+}
+
+bool cmState::Directory::GetPropertyAsBool(const std::string& prop) const
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+std::vector<std::string> cmState::Directory::GetPropertyKeys() const
+{
+ std::vector<std::string> keys;
+ keys.reserve(this->DirectoryState->Properties.size());
+ for(cmPropertyMap::const_iterator it =
+ this->DirectoryState->Properties.begin();
+ it != this->DirectoryState->Properties.end(); ++it)
+ {
+ keys.push_back(it->first);
+ }
+ return keys;
+}
+
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+ return lhs.Position == rhs.Position;
+}
+
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
+{
+ return lhs.Position != rhs.Position;
+}
diff --git a/Source/cmState.h b/Source/cmState.h
index 77a066f..99e537c 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -15,49 +15,191 @@
#include "cmStandardIncludes.h"
#include "cmPropertyDefinitionMap.h"
#include "cmPropertyMap.h"
+#include "cmLinkedTree.h"
+#include "cmAlgorithms.h"
+#include "cmPolicies.h"
class cmake;
class cmCommand;
+class cmDefinitions;
+class cmListFileBacktrace;
class cmState
{
- typedef std::vector<std::string>::size_type PositionType;
+ struct SnapshotDataType;
+ struct PolicyStackEntry;
+ struct BuildsystemDirectoryStateType;
+ typedef cmLinkedTree<SnapshotDataType>::iterator PositionType;
friend class Snapshot;
public:
cmState(cmake* cm);
~cmState();
+ enum SnapshotType
+ {
+ BaseType,
+ BuildsystemDirectoryType,
+ FunctionCallType,
+ MacroCallType,
+ CallStackType,
+ InlineListFileType,
+ PolicyScopeType,
+ VariableScopeType
+ };
+
+ class Directory;
+
class Snapshot {
public:
- Snapshot(cmState* state = 0, PositionType position = 0);
+ Snapshot(cmState* state = 0);
+ Snapshot(cmState* state, PositionType position);
+
+ const char* GetDefinition(std::string const& name) const;
+ bool IsInitialized(std::string const& name) const;
+ void SetDefinition(std::string const& name, std::string const& value);
+ void RemoveDefinition(std::string const& name);
+ std::vector<std::string> UnusedKeys() const;
+ std::vector<std::string> ClosureKeys() const;
+ bool RaiseScope(std::string const& var, const char* varDef);
+
+ void SetListFile(std::string const& listfile);
+
+ std::string GetExecutionListFile() const;
+
+ std::vector<Snapshot> GetChildren();
+ std::string GetEntryPointCommand() const;
+ long GetEntryPointLine() const;
+
+ bool IsValid() const;
+ Snapshot GetBuildsystemDirectoryParent() const;
+ Snapshot GetCallStackParent() const;
+ SnapshotType GetType() const;
- const char* GetCurrentSourceDirectory() const;
- void SetCurrentSourceDirectory(std::string const& dir);
- const char* GetCurrentBinaryDirectory() const;
- void SetCurrentBinaryDirectory(std::string const& dir);
+ void InitializeFromParent();
- std::vector<std::string> const& GetCurrentSourceDirectoryComponents();
- std::vector<std::string> const& GetCurrentBinaryDirectoryComponents();
+ void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+ cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const;
+ bool HasDefinedPolicyCMP0011();
+ void PushPolicy(cmPolicies::PolicyMap entry, bool weak);
+ bool PopPolicy();
+ bool CanPopPolicyScope();
+
+ cmState* GetState() const;
+
+ Directory GetDirectory() const;
+
+ void SetProjectName(std::string const& name);
+ std::string GetProjectName() const;
+
+ struct StrictWeakOrder
+ {
+ bool operator()(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs) const;
+ };
+
+ private:
+ friend bool operator==(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs);
+ friend bool operator!=(const cmState::Snapshot& lhs,
+ const cmState::Snapshot& rhs);
+ friend class cmState;
+ friend class Directory;
+ friend struct StrictWeakOrder;
+ cmState* State;
+ cmState::PositionType Position;
+ };
+
+ class Directory
+ {
+ Directory(cmLinkedTree<BuildsystemDirectoryStateType>::iterator iter,
+ Snapshot const& snapshot);
+ public:
+ const char* GetCurrentSource() const;
+ void SetCurrentSource(std::string const& dir);
+ const char* GetCurrentBinary() const;
+ void SetCurrentBinary(std::string const& dir);
+
+ std::vector<std::string> const&
+ GetCurrentSourceComponents() const;
+ std::vector<std::string> const&
+ GetCurrentBinaryComponents() const;
const char* GetRelativePathTopSource() const;
const char* GetRelativePathTopBinary() const;
void SetRelativePathTopSource(const char* dir);
void SetRelativePathTopBinary(const char* dir);
- bool IsValid() const;
- Snapshot GetParent() const;
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const;
+ void AppendIncludeDirectoriesEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void PrependIncludeDirectoriesEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetIncludeDirectories(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearIncludeDirectories();
+
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const;
+ void AppendCompileDefinitionsEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetCompileDefinitions(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearCompileDefinitions();
+
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsEntryBacktraces() const;
+ void AppendCompileOptionsEntry(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void SetCompileOptions(std::string const& vec,
+ cmListFileBacktrace const& lfbt);
+ void ClearCompileOptions();
+
+ void SetProperty(const std::string& prop, const char *value,
+ cmListFileBacktrace lfbt);
+ void AppendProperty(const std::string& prop, const char *value,
+ bool asString, cmListFileBacktrace lfbt);
+ const char *GetProperty(const std::string& prop) const;
+ const char *GetProperty(const std::string& prop, bool chain) const;
+ bool GetPropertyAsBool(const std::string& prop) const;
+ std::vector<std::string> GetPropertyKeys() const;
private:
void ComputeRelativePathTopSource();
void ComputeRelativePathTopBinary();
private:
- friend class cmState;
- cmState* State;
- cmState::PositionType Position;
+ cmLinkedTree<BuildsystemDirectoryStateType>::iterator DirectoryState;
+ Snapshot Snapshot_;
+ friend class Snapshot;
};
- Snapshot CreateSnapshot(Snapshot originSnapshot);
+ Snapshot CreateBaseSnapshot();
+ Snapshot
+ CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine);
+ Snapshot CreateFunctionCallSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateMacroCallSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateCallStackSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreateVariableScopeSnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine);
+ Snapshot CreateInlineListFileSnapshot(Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot CreatePolicyScopeSnapshot(Snapshot originSnapshot);
+ Snapshot Pop(Snapshot originSnapshot);
enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
UNINITIALIZED };
@@ -93,7 +235,7 @@ public:
void RemoveCacheEntryProperty(std::string const& key,
std::string const& propertyName);
- void Reset();
+ Snapshot Reset();
// Define a property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
const char *ShortDescription,
@@ -101,12 +243,14 @@ public:
bool chain = false);
// get property definition
- cmPropertyDefinition *GetPropertyDefinition
- (const std::string& name, cmProperty::ScopeType scope);
+ cmPropertyDefinition const* GetPropertyDefinition
+ (const std::string& name, cmProperty::ScopeType scope) const;
// Is a property defined?
- bool IsPropertyDefined(const std::string& name, cmProperty::ScopeType scope);
- bool IsPropertyChained(const std::string& name, cmProperty::ScopeType scope);
+ bool IsPropertyDefined(const std::string& name,
+ cmProperty::ScopeType scope) const;
+ bool IsPropertyChained(const std::string& name,
+ cmProperty::ScopeType scope) const;
void SetLanguageEnabled(std::string const& l);
bool GetLanguageEnabled(std::string const& l) const;
@@ -157,19 +301,14 @@ private:
std::map<std::string, cmCommand*> Commands;
cmPropertyMap GlobalProperties;
cmake* CMakeInstance;
- std::vector<std::string> Locations;
- std::vector<std::string> OutputLocations;
- std::vector<PositionType> ParentPositions;
-
- std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents;
- std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents;
- // The top-most directories for relative path conversion. Both the
- // source and destination location of a relative path conversion
- // must be underneath one of these directories (both under source or
- // both under binary) in order for the relative path to be evaluated
- // safely by the build tools.
- std::vector<std::string> RelativePathTopSource;
- std::vector<std::string> RelativePathTopBinary;
+
+ cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory;
+
+ cmLinkedTree<std::string> ExecutionListFiles;
+
+ cmLinkedTree<PolicyStackEntry> PolicyStack;
+ cmLinkedTree<SnapshotDataType> SnapshotData;
+ cmLinkedTree<cmDefinitions> VarTree;
std::vector<std::string> SourceDirectoryComponents;
std::vector<std::string> BinaryDirectoryComponents;
@@ -184,4 +323,7 @@ private:
bool MSYSShell;
};
+bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+bool operator!=(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs);
+
#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index edc6afc..649fb39 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -74,6 +74,10 @@ bool cmStringCommand
{
return this->HandleLengthCommand(args);
}
+ else if(subCommand == "APPEND")
+ {
+ return this->HandleAppendCommand(args);
+ }
else if(subCommand == "CONCAT")
{
return this->HandleConcatCommand(args);
@@ -315,7 +319,7 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
}
// Concatenate all the last arguments together.
- std::string input = cmJoin(cmRange(args).advance(4), std::string());
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
// Scan through the input for all matches.
std::string output;
@@ -361,7 +365,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
}
// Concatenate all the last arguments together.
- std::string input = cmJoin(cmRange(args).advance(4), std::string());
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
// Scan through the input for all matches.
std::string output;
@@ -461,7 +465,7 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
}
// Concatenate all the last arguments together.
- std::string input = cmJoin(cmRange(args).advance(5), std::string());
+ std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
// Scan through the input for all matches.
std::string output;
@@ -661,7 +665,7 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const&
const std::string& replaceExpression = args[2];
const std::string& variableName = args[3];
- std::string input = cmJoin(cmRange(args).advance(4), std::string());
+ std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
replaceExpression.c_str());
@@ -730,6 +734,34 @@ bool cmStringCommand
}
//----------------------------------------------------------------------------
+bool cmStringCommand::HandleAppendCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command APPEND requires at least one argument.");
+ return false;
+ }
+
+ // Skip if nothing to append.
+ if(args.size() < 3)
+ {
+ return true;
+ }
+
+ const std::string& variable = args[1];
+
+ std::string value;
+ const char* oldValue = this->Makefile->GetDefinition(variable);
+ if(oldValue)
+ {
+ value = oldValue;
+ }
+ value += cmJoin(cmMakeRange(args).advance(2), std::string());
+ this->Makefile->AddDefinition(variable, value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
bool cmStringCommand
::HandleConcatCommand(std::vector<std::string> const& args)
{
@@ -740,7 +772,7 @@ bool cmStringCommand
}
std::string const& variableName = args[1];
- std::string value = cmJoin(cmRange(args).advance(2), std::string());
+ std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
this->Makefile->AddDefinition(variableName, value.c_str());
return true;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 9c75095..3ed17eb 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -67,6 +67,7 @@ protected:
bool HandleReplaceCommand(std::vector<std::string> const& args);
bool HandleLengthCommand(std::vector<std::string> const& args);
bool HandleSubstringCommand(std::vector<std::string> const& args);
+ bool HandleAppendCommand(std::vector<std::string> const& args);
bool HandleConcatCommand(std::vector<std::string> const& args);
bool HandleStripCommand(std::vector<std::string> const& args);
bool HandleRandomCommand(std::vector<std::string> const& args);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index b440a17..f711016 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -30,7 +30,6 @@
# include "cmLocale.h"
# include <cm_libarchive.h>
#endif
-#include <cmsys/stl/algorithm>
#include <cmsys/FStream.hxx>
#include <cmsys/Terminal.h>
@@ -556,25 +555,6 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
argv.Store(args);
}
-std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
- int shell_flags)
-{
- char local_buffer[1024];
- char* buffer = local_buffer;
- int size = cmsysSystem_Shell_GetArgumentSizeForWindows(arg, shell_flags);
- if(size > 1024)
- {
- buffer = new char[size];
- }
- cmsysSystem_Shell_GetArgumentForWindows(arg, buffer, shell_flags);
- std::string result(buffer);
- if(buffer != local_buffer)
- {
- delete [] buffer;
- }
- return result;
-}
-
std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
{
std::vector<std::string> args;
@@ -969,8 +949,9 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
Try multiple times since we may be racing against another process
creating/opening the destination file just before our MoveFileEx. */
WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
- while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).c_str(),
- cmsys::Encoding::ToWide(newname).c_str(),
+ while(!MoveFileExW(
+ SystemTools::ConvertToWindowsExtendedPath(oldname).c_str(),
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
MOVEFILE_REPLACE_EXISTING) && --retry.Count)
{
DWORD last_error = GetLastError();
@@ -981,12 +962,14 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
return false;
}
DWORD attrs =
- GetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str());
+ GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str());
if((attrs != INVALID_FILE_ATTRIBUTES) &&
(attrs & FILE_ATTRIBUTE_READONLY))
{
// Remove the read-only attribute from the destination file.
- SetFileAttributesW(cmsys::Encoding::ToWide(newname).c_str(),
+ SetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(newname).c_str(),
attrs & ~FILE_ATTRIBUTE_READONLY);
}
else
@@ -1029,6 +1012,94 @@ std::string cmSystemTools::ComputeStringMD5(const std::string& input)
#endif
}
+//----------------------------------------------------------------------------
+std::string cmSystemTools::ComputeCertificateThumbprint(
+ const std::string& source)
+{
+ std::string thumbprint;
+
+#ifdef _WIN32
+ BYTE* certData = NULL;
+ CRYPT_INTEGER_BLOB cryptBlob;
+ HCERTSTORE certStore = NULL;
+ PCCERT_CONTEXT certContext = NULL;
+
+ HANDLE certFile = CreateFile(cmsys::Encoding::ToWide(source.c_str()).c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (certFile != INVALID_HANDLE_VALUE && certFile != NULL)
+ {
+ DWORD fileSize = GetFileSize(certFile, NULL);
+ if (fileSize != INVALID_FILE_SIZE)
+ {
+ certData = new BYTE[fileSize];
+ if (certData != NULL)
+ {
+ DWORD dwRead = 0;
+ if (ReadFile(certFile, certData, fileSize, &dwRead, NULL))
+ {
+ cryptBlob.cbData = fileSize;
+ cryptBlob.pbData = certData;
+
+ // Verify that this is a valid cert
+ if (PFXIsPFXBlob(&cryptBlob))
+ {
+ // Open the certificate as a store
+ certStore = PFXImportCertStore(
+ &cryptBlob, NULL, CRYPT_EXPORTABLE);
+ if (certStore != NULL)
+ {
+ // There should only be 1 cert.
+ certContext = CertEnumCertificatesInStore(certStore,
+ certContext);
+ if (certContext != NULL)
+ {
+ // The hash is 20 bytes
+ BYTE hashData[20];
+ DWORD hashLength = 20;
+
+ // Buffer to print the hash. Each byte takes 2 chars +
+ // terminating character
+ char hashPrint[41];
+ char *pHashPrint = hashPrint;
+ // Get the hash property from the certificate
+ if (CertGetCertificateContextProperty(certContext,
+ CERT_HASH_PROP_ID, hashData, &hashLength))
+ {
+ for (DWORD i = 0; i < hashLength; i++)
+ {
+ // Convert each byte to hexadecimal
+ sprintf(pHashPrint, "%02X", hashData[i]);
+ pHashPrint += 2;
+ }
+ *pHashPrint = '\0';
+ thumbprint = hashPrint;
+ }
+ CertFreeCertificateContext(certContext);
+ }
+ CertCloseStore(certStore, 0);
+ }
+ }
+ }
+ delete[] certData;
+ }
+ }
+ CloseHandle(certFile);
+ }
+#else
+ (void)source;
+ cmSystemTools::Message("ComputeCertificateThumbprint is not implemented",
+ "Error");
+#endif
+
+ return thumbprint;
+}
+
void cmSystemTools::Glob(const std::string& directory,
const std::string& regexp,
std::vector<std::string>& files)
@@ -1498,7 +1569,7 @@ bool cmSystemTools::CreateTar(const char* outFileName,
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- cmsys::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
+ cmsys::ofstream fout(outFileName, std::ios::out | std::ios::binary);
if(!fout)
{
std::string e = "Cannot open output file \"";
@@ -1721,7 +1792,7 @@ bool extract_tar(const char* outFileName, bool verbose,
static_cast<void>(localeRAII);
struct archive* a = archive_read_new();
struct archive *ext = archive_write_disk_new();
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
struct archive_entry *entry;
int r = cm_archive_read_open_file(a, outFileName, 10240);
@@ -1808,7 +1879,7 @@ bool extract_tar(const char* outFileName, bool verbose,
}
archive_write_free(ext);
archive_read_close(a);
- archive_read_finish(a);
+ archive_read_free(a);
return r == ARCHIVE_EOF || r == ARCHIVE_OK;
}
}
@@ -1975,11 +2046,11 @@ bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle hFrom =
- CreateFileW(cmsys::Encoding::ToWide(fromFile).c_str(),
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fromFile).c_str(),
GENERIC_READ, FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0);
cmSystemToolsWindowsHandle hTo =
- CreateFileW(cmsys::Encoding::ToWide(toFile).c_str(),
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(toFile).c_str(),
GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(!hFrom || !hTo)
{
@@ -2031,7 +2102,7 @@ bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle h =
- CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(!h)
{
@@ -2058,7 +2129,7 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
cmSystemToolsWindowsHandle h =
- CreateFileW(cmsys::Encoding::ToWide(fname).c_str(),
+ CreateFileW(SystemTools::ConvertToWindowsExtendedPath(fname).c_str(),
GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(!h)
{
@@ -2955,3 +3026,12 @@ bool cmSystemTools::StringToLong(const char* str, long* value)
*value = strtol(str, &endp, 10);
return (*endp == '\0') && (endp != str) && (errno == 0);
}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::StringToULong(const char* str, unsigned long* value)
+{
+ errno = 0;
+ char *endp;
+ *value = strtoul(str, &endp, 10);
+ return (*endp == '\0') && (endp != str) && (errno == 0);
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 6feb6c5..c12a1db 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -194,6 +194,9 @@ public:
/** Compute the md5sum of a string. */
static std::string ComputeStringMD5(const std::string& input);
+ ///! Get the SHA thumbprint for a certificate file
+ static std::string ComputeCertificateThumbprint(const std::string& source);
+
/**
* Run a single executable command
*
@@ -256,11 +259,6 @@ public:
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
- /** Compute an escaped version of the given argument for use in a
- windows shell. See kwsys/System.h.in for details. */
- static std::string EscapeWindowsShellArgument(const char* arg,
- int shell_flags);
-
static void EnableMessages() { s_DisableMessages = false; }
static void DisableMessages() { s_DisableMessages = true; }
static void DisableRunCommandOutput() {s_DisableRunCommandOutput = true; }
@@ -469,6 +467,7 @@ public:
/** Convert string to long. Expected that the whole string is an integer */
static bool StringToLong(const char* str, long* value);
+ static bool StringToULong(const char* str, unsigned long* value);
#ifdef _WIN32
struct WindowsFileRetry
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 20d3208..4affc8d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -13,7 +13,7 @@
#include "cmake.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmGlobalGenerator.h"
#include "cmComputeLinkInformation.h"
#include "cmListFileCache.h"
@@ -66,27 +66,8 @@ struct cmTarget::OutputInfo
std::string OutDir;
std::string ImpDir;
std::string PdbDir;
-};
-
-//----------------------------------------------------------------------------
-struct cmTarget::ImportInfo
-{
- ImportInfo(): NoSOName(false), Multiplicity(0) {}
- bool NoSOName;
- int Multiplicity;
- std::string Location;
- std::string SOName;
- std::string ImportLibrary;
- std::string Languages;
- std::string Libraries;
- std::string LibrariesProp;
- std::string SharedDeps;
-};
-
-//----------------------------------------------------------------------------
-struct cmTarget::CompileInfo
-{
- std::string CompilePdbDir;
+ bool empty() const
+ { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
};
//----------------------------------------------------------------------------
@@ -94,15 +75,13 @@ class cmTargetInternals
{
public:
cmTargetInternals()
- : Backtrace(NULL)
+ : Backtrace()
{
- this->PolicyWarnedCMP0022 = false;
this->UtilityItemsDone = false;
}
cmTargetInternals(cmTargetInternals const&)
- : Backtrace(NULL)
+ : Backtrace()
{
- this->PolicyWarnedCMP0022 = false;
this->UtilityItemsDone = false;
}
~cmTargetInternals();
@@ -110,88 +89,18 @@ public:
// The backtrace when the target was created.
cmListFileBacktrace Backtrace;
- // Cache link interface computation from each configuration.
- struct OptionalLinkInterface: public cmTarget::LinkInterface
- {
- OptionalLinkInterface():
- LibrariesDone(false), AllDone(false),
- Exists(false), HadHeadSensitiveCondition(false),
- ExplicitLibraries(0) {}
- bool LibrariesDone;
- bool AllDone;
- bool Exists;
- bool HadHeadSensitiveCondition;
- const char* ExplicitLibraries;
- };
- void ComputeLinkInterface(cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkInterface& iface,
- cmTarget const* head) const;
- void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkInterface& iface,
- cmTarget const* head,
- bool usage_requirements_only);
-
- struct HeadToLinkInterfaceMap:
- public std::map<cmTarget const*, OptionalLinkInterface> {};
- typedef std::map<std::string, HeadToLinkInterfaceMap>
- LinkInterfaceMapType;
- LinkInterfaceMapType LinkInterfaceMap;
- LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
- bool PolicyWarnedCMP0022;
-
typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
OutputInfoMapType OutputInfoMap;
typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap;
- typedef std::map<std::string, cmTarget::CompileInfo> CompileInfoMapType;
- CompileInfoMapType CompileInfoMap;
-
- // Cache link implementation computation from each configuration.
- struct OptionalLinkImplementation: public cmTarget::LinkImplementation
- {
- OptionalLinkImplementation():
- LibrariesDone(false), LanguagesDone(false),
- HadHeadSensitiveCondition(false) {}
- bool LibrariesDone;
- bool LanguagesDone;
- bool HadHeadSensitiveCondition;
- };
- void ComputeLinkImplementationLibraries(cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkImplementation& impl,
- cmTarget const* head) const;
- void ComputeLinkImplementationLanguages(cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkImplementation& impl
- ) const;
-
struct HeadToLinkImplementationMap:
- public std::map<cmTarget const*, OptionalLinkImplementation> {};
+ public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
typedef std::map<std::string,
HeadToLinkImplementationMap> LinkImplMapType;
LinkImplMapType LinkImplMap;
- typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType;
- LinkClosureMapType LinkClosureMap;
-
- struct LinkImplClosure: public std::vector<cmTarget const*>
- {
- LinkImplClosure(): Done(false) {}
- bool Done;
- };
- std::map<std::string, LinkImplClosure> LinkImplClosureMap;
-
- struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces
- {
- CompatibleInterfaces(): Done(false) {}
- bool Done;
- };
- std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
-
typedef std::map<std::string, std::vector<cmSourceFile*> >
SourceFilesMapType;
SourceFilesMapType SourceFilesMap;
@@ -209,10 +118,14 @@ public:
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
cmLinkImplItem const& LinkImplItem;
};
- std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
- std::vector<TargetPropertyEntry*> CompileOptionsEntries;
- std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
- std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+ std::vector<std::string> IncludeDirectoriesEntries;
+ std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
+ std::vector<std::string> CompileOptionsEntries;
+ std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+ std::vector<std::string> CompileFeaturesEntries;
+ std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
+ std::vector<std::string> CompileDefinitionsEntries;
+ std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
std::vector<TargetPropertyEntry*> SourceEntries;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
@@ -224,14 +137,6 @@ public:
cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
//----------------------------------------------------------------------------
-static void deleteAndClear(
- std::vector<cmTargetInternals::TargetPropertyEntry*> &entries)
-{
- cmDeleteAll(entries);
- entries.clear();
-}
-
-//----------------------------------------------------------------------------
cmTargetInternals::~cmTargetInternals()
{
}
@@ -239,13 +144,6 @@ cmTargetInternals::~cmTargetInternals()
//----------------------------------------------------------------------------
cmTarget::cmTarget()
{
-#define INITIALIZE_TARGET_POLICY_MEMBER(POLICY) \
- this->PolicyStatus ## POLICY = cmPolicies::WARN;
-
- CM_FOR_EACH_TARGET_POLICY(INITIALIZE_TARGET_POLICY_MEMBER)
-
-#undef INITIALIZE_TARGET_POLICY_MEMBER
-
this->Makefile = 0;
#if defined(_WIN32) && !defined(__CYGWIN__)
this->LinkLibrariesForVS6Analyzed = false;
@@ -256,10 +154,6 @@ cmTarget::cmTarget()
this->IsApple = false;
this->IsImportedTarget = false;
this->BuildInterfaceIncludesAppended = false;
- this->DebugIncludesDone = false;
- this->DebugCompileOptionsDone = false;
- this->DebugCompileFeaturesDone = false;
- this->DebugCompileDefinitionsDone = false;
this->DebugSourcesDone = false;
this->LinkImplementationLanguageIsContextDependent = true;
}
@@ -286,9 +180,6 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// Set our makefile.
this->Makefile = mf;
- // set the cmake instance of the properties
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
-
// Check whether this is a DLL platform.
this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
this->Makefile->IsOn("CYGWIN") ||
@@ -307,6 +198,20 @@ void cmTarget::SetMakefile(cmMakefile* mf)
{
this->SetPropertyDefault("ANDROID_API", 0);
this->SetPropertyDefault("ANDROID_API_MIN", 0);
+ this->SetPropertyDefault("ANDROID_ARCH", 0);
+ this->SetPropertyDefault("ANDROID_STL_TYPE", 0);
+ this->SetPropertyDefault("ANDROID_SKIP_ANT_STEP", 0);
+ this->SetPropertyDefault("ANDROID_PROCESS_MAX", 0);
+ this->SetPropertyDefault("ANDROID_PROGUARD", 0);
+ this->SetPropertyDefault("ANDROID_PROGUARD_CONFIG_PATH", 0);
+ this->SetPropertyDefault("ANDROID_SECURE_PROPS_PATH", 0);
+ this->SetPropertyDefault("ANDROID_NATIVE_LIB_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_NATIVE_LIB_DEPENDENCIES", 0);
+ this->SetPropertyDefault("ANDROID_JAVA_SOURCE_DIR", 0);
+ this->SetPropertyDefault("ANDROID_JAR_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", 0);
+ this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", 0);
+ this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", 0);
this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
@@ -333,14 +238,18 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
+ this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
this->SetPropertyDefault("C_STANDARD", 0);
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
this->SetPropertyDefault("C_EXTENSIONS", 0);
+ this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0);
this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0);
this->SetPropertyDefault("CXX_STANDARD", 0);
this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
this->SetPropertyDefault("CXX_EXTENSIONS", 0);
+ this->SetPropertyDefault("LINK_SEARCH_START_STATIC", 0);
+ this->SetPropertyDefault("LINK_SEARCH_END_STATIC", 0);
}
// Collect the set of configuration types.
@@ -396,28 +305,35 @@ void cmTarget::SetMakefile(cmMakefile* mf)
{
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- const std::vector<cmValueWithOrigin> parentIncludes =
- this->Makefile->GetIncludeDirectoriesEntries();
+ const cmStringRange parentIncludes =
+ this->Makefile->GetIncludeDirectoriesEntries();
+ const cmBacktraceRange parentIncludesBts =
+ this->Makefile->GetIncludeDirectoriesBacktraces();
+
+ this->Internal->IncludeDirectoriesEntries.insert(
+ this->Internal->IncludeDirectoriesEntries.end(),
+ parentIncludes.begin(), parentIncludes.end());
+ this->Internal->IncludeDirectoriesBacktraces.insert(
+ this->Internal->IncludeDirectoriesBacktraces.end(),
+ parentIncludesBts.begin(), parentIncludesBts.end());
- for (std::vector<cmValueWithOrigin>::const_iterator it
- = parentIncludes.begin(); it != parentIncludes.end(); ++it)
- {
- this->InsertInclude(*it);
- }
const std::set<std::string> parentSystemIncludes =
this->Makefile->GetSystemIncludeDirectories();
this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
parentSystemIncludes.end());
- const std::vector<cmValueWithOrigin> parentOptions =
+ const cmStringRange parentOptions =
this->Makefile->GetCompileOptionsEntries();
+ const cmBacktraceRange parentOptionsBts =
+ this->Makefile->GetCompileOptionsBacktraces();
- for (std::vector<cmValueWithOrigin>::const_iterator it
- = parentOptions.begin(); it != parentOptions.end(); ++it)
- {
- this->InsertCompileOption(*it);
- }
+ this->Internal->CompileOptionsEntries.insert(
+ this->Internal->CompileOptionsEntries.end(),
+ parentOptions.begin(), parentOptions.end());
+ this->Internal->CompileOptionsBacktraces.insert(
+ this->Internal->CompileOptionsBacktraces.end(),
+ parentOptionsBts.begin(), parentOptionsBts.end());
}
if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
@@ -437,26 +353,25 @@ void cmTarget::SetMakefile(cmMakefile* mf)
{
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
}
+ if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY)
+ {
+ this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
+ }
+
if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
{
this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
}
// Record current policies for later use.
-#define CAPTURE_TARGET_POLICY(POLICY) \
- this->PolicyStatus ## POLICY = \
- this->Makefile->GetPolicyStatus(cmPolicies::POLICY);
-
- CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY)
-
-#undef CAPTURE_TARGET_POLICY
+ this->Makefile->RecordPolicies(this->PolicyMap);
if (this->TargetTypeValue == INTERFACE_LIBRARY)
{
// This policy is checked in a few conditions. The properties relevant
// to the policy are always ignored for INTERFACE_LIBRARY targets,
// so ensure that the conditions don't lead to nonsense.
- this->PolicyStatusCMP0022 = cmPolicies::NEW;
+ this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
}
if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
@@ -466,6 +381,21 @@ void cmTarget::SetMakefile(cmMakefile* mf)
}
}
+void CreatePropertyGeneratorExpressions(
+ std::vector<std::string> const& entries,
+ std::vector<cmListFileBacktrace> const& backtraces,
+ std::vector<cmTargetInternals::TargetPropertyEntry*>& items)
+{
+ std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+ for (std::vector<std::string>::const_iterator it = entries.begin();
+ it != entries.end(); ++it, ++btIt)
+ {
+ cmGeneratorExpression ge(*btIt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+ items.push_back(new cmTargetInternals::TargetPropertyEntry(cge));
+ }
+}
+
//----------------------------------------------------------------------------
void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
{
@@ -525,12 +455,7 @@ void cmTarget::ClearLinkMaps()
{
this->LinkImplementationLanguageIsContextDependent = true;
this->Internal->LinkImplMap.clear();
- this->Internal->LinkInterfaceMap.clear();
- this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear();
- this->Internal->LinkClosureMap.clear();
this->Internal->SourceFilesMap.clear();
- cmDeleteAll(this->LinkInformation);
- this->LinkInformation.clear();
}
//----------------------------------------------------------------------------
@@ -612,13 +537,6 @@ bool cmTarget::IsXCTestOnApple() const
}
//----------------------------------------------------------------------------
-bool cmTarget::IsBundleOnApple() const
-{
- return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() ||
- this->IsCFBundleOnApple();
-}
-
-//----------------------------------------------------------------------------
static bool processSources(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &srcs,
@@ -718,7 +636,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
{
assert(this->GetType() != INTERFACE_LIBRARY);
- if (this->Makefile->GetGeneratorTargets().empty())
+ if (!this->Makefile->IsConfigured())
{
// At configure-time, this method can be called as part of getting the
// LOCATION property or to export() a file to be include()d. However
@@ -764,7 +682,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
"SOURCES")
!= debugProperties.end();
- if (this->Makefile->IsGeneratingBuildSystem())
+ if (this->Makefile->IsConfigured())
{
this->DebugSourcesDone = true;
}
@@ -803,63 +721,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
this->LinkImplementationLanguageIsContextDependent = false;
}
- deleteAndClear(linkInterfaceSourcesEntries);
-}
-
-//----------------------------------------------------------------------------
-bool
-cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
-{
- std::vector<std::string> configs;
- this->Makefile->GetConfigurations(configs);
- if (configs.empty())
- {
- configs.push_back("");
- }
-
- std::vector<std::string>::const_iterator it = configs.begin();
- const std::string& firstConfig = *it;
- this->GetSourceFiles(files, firstConfig);
-
- for ( ; it != configs.end(); ++it)
- {
- std::vector<cmSourceFile*> configFiles;
- this->GetSourceFiles(configFiles, *it);
- if (configFiles != files)
- {
- std::string firstConfigFiles;
- const char* sep = "";
- for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
- fi != files.end(); ++fi)
- {
- firstConfigFiles += sep;
- firstConfigFiles += (*fi)->GetFullPath();
- sep = "\n ";
- }
-
- std::string thisConfigFiles;
- sep = "";
- for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
- fi != configFiles.end(); ++fi)
- {
- thisConfigFiles += sep;
- thisConfigFiles += (*fi)->GetFullPath();
- sep = "\n ";
- }
- std::ostringstream e;
- e << "Target \"" << this->Name << "\" has source files which vary by "
- "configuration. This is not supported by the \""
- << this->Makefile->GetGlobalGenerator()->GetName()
- << "\" generator.\n"
- "Config \"" << firstConfig << "\":\n"
- " " << firstConfigFiles << "\n"
- "Config \"" << *it << "\":\n"
- " " << thisConfigFiles << "\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
- }
- }
- return true;
+ cmDeleteAll(linkInterfaceSourcesEntries);
}
//----------------------------------------------------------------------------
@@ -911,7 +773,7 @@ void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
this->Internal->SourceFilesMap.clear();
this->LinkImplementationLanguageIsContextDependent = true;
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
+ cmGeneratorExpression ge(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
cge->SetEvaluateForBuildsystem(true);
this->Internal->SourceEntries.push_back(
@@ -951,7 +813,7 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
this->Internal->SourceFilesMap.clear();
this->LinkImplementationLanguageIsContextDependent = true;
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
+ cmGeneratorExpression ge(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
cge->SetEvaluateForBuildsystem(true);
this->Internal->SourceEntries.push_back(
@@ -1084,7 +946,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
this->Internal->SourceFilesMap.clear();
this->LinkImplementationLanguageIsContextDependent = true;
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
+ cmGeneratorExpression ge(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
cge->SetEvaluateForBuildsystem(true);
this->Internal->SourceEntries.push_back(
@@ -1257,14 +1119,14 @@ void cmTarget::GetTllSignatureTraces(std::ostringstream &s,
: "plain");
s << "The uses of the " << sigString << " signature are here:\n";
typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container;
- cmLocalGenerator* lg = this->GetMakefile()->GetLocalGenerator();
+ cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot());
for(Container::const_iterator it = this->TLLCommands.begin();
it != this->TLLCommands.end(); ++it)
{
if (it->first == sig)
{
cmListFileContext lfc = it->second;
- lfc.FilePath = lg->Convert(lfc.FilePath, cmLocalGenerator::HOME);
+ lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
s << " * " << lfc << std::endl;
}
}
@@ -1351,11 +1213,44 @@ cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
}
-//----------------------------------------------------------------------------
-void
-cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
+cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
- this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
+ return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
+}
+
+cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
+{
+ return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileOptionsEntries() const
+{
+ return cmMakeRange(this->Internal->CompileOptionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileOptionsBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileFeaturesEntries() const
+{
+ return cmMakeRange(this->Internal->CompileFeaturesEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
+}
+
+cmStringRange cmTarget::GetCompileDefinitionsEntries() const
+{
+ return cmMakeRange(this->Internal->CompileDefinitionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
+{
+ return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1704,39 +1599,35 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
}
else if(prop == "INCLUDE_DIRECTORIES")
{
+ this->Internal->IncludeDirectoriesEntries.clear();
+ this->Internal->IncludeDirectoriesBacktraces.clear();
+ this->Internal->IncludeDirectoriesEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- deleteAndClear(this->Internal->IncludeDirectoriesEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->IncludeDirectoriesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
+ this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_OPTIONS")
{
+ this->Internal->CompileOptionsEntries.clear();
+ this->Internal->CompileOptionsBacktraces.clear();
+ this->Internal->CompileOptionsEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- deleteAndClear(this->Internal->CompileOptionsEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->CompileOptionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
+ this->Internal->CompileOptionsBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_FEATURES")
{
+ this->Internal->CompileFeaturesEntries.clear();
+ this->Internal->CompileFeaturesBacktraces.clear();
+ this->Internal->CompileFeaturesEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- deleteAndClear(this->Internal->CompileFeaturesEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->CompileFeaturesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
+ this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_DEFINITIONS")
{
+ this->Internal->CompileDefinitionsEntries.clear();
+ this->Internal->CompileDefinitionsBacktraces.clear();
+ this->Internal->CompileDefinitionsEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- deleteAndClear(this->Internal->CompileDefinitionsEntries);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->CompileDefinitionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
+ this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
else if(prop == "EXPORT_NAME" && this->IsImported())
{
@@ -1767,7 +1658,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
}
this->Internal->SourceFilesMap.clear();
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
+ cmGeneratorExpression ge(lfbt);
this->Internal->SourceEntries.clear();
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
this->Internal->SourceEntries.push_back(
@@ -1775,7 +1666,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
}
else
{
- this->Properties.SetProperty(prop, value, cmProperty::TARGET);
+ this->Properties.SetProperty(prop, value);
this->MaybeInvalidatePropertyCache(prop);
}
}
@@ -1802,31 +1693,27 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
}
else if(prop == "INCLUDE_DIRECTORIES")
{
+ this->Internal->IncludeDirectoriesEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- this->Internal->IncludeDirectoriesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+ this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_OPTIONS")
{
+ this->Internal->CompileOptionsEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- this->Internal->CompileOptionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+ this->Internal->CompileOptionsBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_FEATURES")
{
+ this->Internal->CompileFeaturesEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- this->Internal->CompileFeaturesEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+ this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
}
else if(prop == "COMPILE_DEFINITIONS")
{
+ this->Internal->CompileDefinitionsEntries.push_back(value);
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- this->Internal->CompileDefinitionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+ this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
else if(prop == "EXPORT_NAME" && this->IsImported())
{
@@ -1854,16 +1741,16 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- this->Internal->SourceFilesMap.clear();
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmGeneratorExpression ge(&lfbt);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- this->Internal->SourceEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(cge));
+ this->Internal->SourceFilesMap.clear();
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ this->Internal->SourceEntries.push_back(
+ new cmTargetInternals::TargetPropertyEntry(cge));
}
else
{
- this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
+ this->Properties.AppendProperty(prop, value, asString);
this->MaybeInvalidatePropertyCache(prop);
}
}
@@ -1921,568 +1808,45 @@ void cmTarget::AppendBuildInterfaceIncludes()
}
//----------------------------------------------------------------------------
-void cmTarget::InsertInclude(const cmValueWithOrigin &entry,
- bool before)
-{
- cmGeneratorExpression ge(&entry.Backtrace);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
- = before ? this->Internal->IncludeDirectoriesEntries.begin()
- : this->Internal->IncludeDirectoriesEntries.end();
-
- this->Internal->IncludeDirectoriesEntries.insert(position,
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry,
- bool before)
-{
- cmGeneratorExpression ge(&entry.Backtrace);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position
- = before ? this->Internal->CompileOptionsEntries.begin()
- : this->Internal->CompileOptionsEntries.end();
-
- this->Internal->CompileOptionsEntries.insert(position,
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::InsertCompileDefinition(const cmValueWithOrigin &entry)
-{
- cmGeneratorExpression ge(&entry.Backtrace);
-
- this->Internal->CompileDefinitionsEntries.push_back(
- new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value)));
-}
-
-//----------------------------------------------------------------------------
-static void processIncludeDirectories(cmTarget const* tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &includes,
- UNORDERED_SET<std::string> &uniqueIncludes,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugIncludes,
- const std::string& language)
-{
- cmMakefile *mf = tgt->GetMakefile();
-
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
- {
- cmLinkImplItem const& item = (*it)->LinkImplItem;
- std::string const& targetName = item;
- bool const fromImported = item.Target && item.Target->IsImported();
- bool const checkCMP0027 = item.FromGenex;
- std::vector<std::string> entryIncludes;
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker, language),
- entryIncludes);
-
- std::string usedIncludes;
- for(std::vector<std::string>::iterator
- li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
- {
- if (fromImported
- && !cmSystemTools::FileExists(li->c_str()))
- {
- std::ostringstream e;
- cmake::MessageType messageType = cmake::FATAL_ERROR;
- if (checkCMP0027)
- {
- switch(tgt->GetPolicyStatusCMP0027())
- {
- case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
- case cmPolicies::OLD:
- messageType = cmake::AUTHOR_WARNING;
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- break;
- }
- }
- e << "Imported target \"" << 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(messageType, e.str());
- return;
- }
-
- if (!cmSystemTools::FileIsFullPath(li->c_str()))
- {
- std::ostringstream e;
- bool noMessage = false;
- cmake::MessageType messageType = cmake::FATAL_ERROR;
- if (!targetName.empty())
- {
- e << "Target \"" << targetName << "\" contains relative "
- "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
- " \"" << *li << "\"";
- }
- else
- {
- switch(tgt->GetPolicyStatusCMP0021())
- {
- case cmPolicies::WARN:
- {
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
- messageType = cmake::AUTHOR_WARNING;
- }
- break;
- case cmPolicies::OLD:
- noMessage = true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Issue the fatal message.
- break;
- }
- e << "Found relative path while evaluating include directories of "
- "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n";
- }
- if (!noMessage)
- {
- tgt->GetMakefile()->IssueMessage(messageType, e.str());
- if (messageType == cmake::FATAL_ERROR)
- {
- return;
- }
- }
- }
-
- if (!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 (!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 std::string& config,
- const std::string& language) const
+void cmTarget::InsertInclude(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before)
{
- std::vector<std::string> includes;
- UNORDERED_SET<std::string> uniqueIncludes;
-
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- "INCLUDE_DIRECTORIES", 0, 0);
-
- 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,
- language);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>
- linkInterfaceIncludeDirectoriesEntries;
- this->Internal->AddInterfaceEntries(
- this, config, "INTERFACE_INCLUDE_DIRECTORIES",
- linkInterfaceIncludeDirectoriesEntries);
-
- if(this->Makefile->IsOn("APPLE"))
- {
- LinkImplementation const* impl = this->GetLinkImplementation(config);
- for(std::vector<cmLinkImplItem>::const_iterator
- it = impl->Libraries.begin();
- it != impl->Libraries.end(); ++it)
- {
- std::string libDir = cmSystemTools::CollapseFullPath(*it);
-
- static cmsys::RegularExpression
- frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
- if(!frameworkCheck.find(libDir))
- {
- continue;
- }
-
- libDir = frameworkCheck.match(1);
-
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(libDir.c_str());
- linkInterfaceIncludeDirectoriesEntries
- .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
- }
- }
-
- processIncludeDirectories(this,
- linkInterfaceIncludeDirectoriesEntries,
- includes,
- uniqueIncludes,
- &dagChecker,
- config,
- debugIncludes,
- language);
-
- deleteAndClear(linkInterfaceIncludeDirectoriesEntries);
-
- return includes;
-}
-
-//----------------------------------------------------------------------------
-static void processCompileOptionsInternal(cmTarget const* tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- UNORDERED_SET<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions, const char *logName,
- std::string const& language)
-{
- cmMakefile *mf = tgt->GetMakefile();
-
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = entries.begin(), end = entries.end(); it != end; ++it)
- {
- std::vector<std::string> entryOptions;
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
- config,
- false,
- tgt,
- dagChecker,
- language),
- entryOptions);
- std::string usedOptions;
- for(std::vector<std::string>::iterator
- li = entryOptions.begin(); li != entryOptions.end(); ++li)
- {
- std::string const& opt = *li;
-
- if(uniqueOptions.insert(opt).second)
- {
- options.push_back(opt);
- if (debugOptions)
- {
- usedOptions += " * " + opt + "\n";
- }
- }
- }
- if (!usedOptions.empty())
- {
- mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
- std::string("Used compile ") + logName
- + std::string(" for target ")
- + tgt->GetName() + ":\n"
- + usedOptions, (*it)->ge->GetBacktrace());
- }
- }
-}
-
-//----------------------------------------------------------------------------
-static void processCompileOptions(cmTarget const* tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- UNORDERED_SET<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions,
- std::string const& language)
-{
- processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions, "options",
- language);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetAutoUicOptions(std::vector<std::string> &result,
- const std::string& config) const
-{
- const char *prop
- = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
- config);
- if (!prop)
- {
- return;
- }
- cmGeneratorExpression ge;
-
- cmGeneratorExpressionDAGChecker dagChecker(
- this->GetName(),
- "AUTOUIC_OPTIONS", 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(prop)
- ->Evaluate(this->Makefile,
- config,
- false,
- this,
- &dagChecker),
- result);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileOptions(std::vector<std::string> &result,
- const std::string& config,
- const std::string& language) const
-{
- UNORDERED_SET<std::string> uniqueOptions;
-
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- "COMPILE_OPTIONS", 0, 0);
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
- {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
- }
+ std::vector<std::string>::iterator position =
+ before ? this->Internal->IncludeDirectoriesEntries.begin()
+ : this->Internal->IncludeDirectoriesEntries.end();
- bool debugOptions = !this->DebugCompileOptionsDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "COMPILE_OPTIONS")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
- {
- this->DebugCompileOptionsDone = true;
- }
+ std::vector<cmListFileBacktrace>::iterator btPosition =
+ before ? this->Internal->IncludeDirectoriesBacktraces.begin()
+ : this->Internal->IncludeDirectoriesBacktraces.end();
- processCompileOptions(this,
- this->Internal->CompileOptionsEntries,
- result,
- uniqueOptions,
- &dagChecker,
- config,
- debugOptions,
- language);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>
- linkInterfaceCompileOptionsEntries;
-
- this->Internal->AddInterfaceEntries(
- this, config, "INTERFACE_COMPILE_OPTIONS",
- linkInterfaceCompileOptionsEntries);
-
- processCompileOptions(this,
- linkInterfaceCompileOptionsEntries,
- result,
- uniqueOptions,
- &dagChecker,
- config,
- debugOptions,
- language);
-
- deleteAndClear(linkInterfaceCompileOptionsEntries);
+ this->Internal->IncludeDirectoriesEntries.insert(position, entry);
+ this->Internal->IncludeDirectoriesBacktraces.insert(btPosition, bt);
}
//----------------------------------------------------------------------------
-static void processCompileDefinitions(cmTarget const* tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- UNORDERED_SET<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions,
- std::string const& language)
+void cmTarget::InsertCompileOption(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before)
{
- processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions,
- "definitions", language);
-}
+ std::vector<std::string>::iterator position =
+ before ? this->Internal->CompileOptionsEntries.begin()
+ : this->Internal->CompileOptionsEntries.end();
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
- const std::string& config,
- const std::string& language) const
-{
- UNORDERED_SET<std::string> uniqueOptions;
-
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- "COMPILE_DEFINITIONS", 0, 0);
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
- {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
- }
-
- bool debugDefines = !this->DebugCompileDefinitionsDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "COMPILE_DEFINITIONS")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
- {
- this->DebugCompileDefinitionsDone = true;
- }
-
- processCompileDefinitions(this,
- this->Internal->CompileDefinitionsEntries,
- list,
- uniqueOptions,
- &dagChecker,
- config,
- debugDefines,
- language);
+ std::vector<cmListFileBacktrace>::iterator btPosition =
+ before ? this->Internal->CompileOptionsBacktraces.begin()
+ : this->Internal->CompileOptionsBacktraces.end();
- std::vector<cmTargetInternals::TargetPropertyEntry*>
- linkInterfaceCompileDefinitionsEntries;
- this->Internal->AddInterfaceEntries(
- this, config, "INTERFACE_COMPILE_DEFINITIONS",
- linkInterfaceCompileDefinitionsEntries);
- if (!config.empty())
- {
- std::string configPropName = "COMPILE_DEFINITIONS_"
- + cmSystemTools::UpperCase(config);
- const char *configProp = this->GetProperty(configPropName);
- if (configProp)
- {
- switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
- {
- case cmPolicies::WARN:
- {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
- e.str());
- }
- case cmPolicies::OLD:
- {
- cmGeneratorExpression ge;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(configProp);
- linkInterfaceCompileDefinitionsEntries
- .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
- }
- break;
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- break;
- }
- }
- }
-
- processCompileDefinitions(this,
- linkInterfaceCompileDefinitionsEntries,
- list,
- uniqueOptions,
- &dagChecker,
- config,
- debugDefines,
- language);
-
- deleteAndClear(linkInterfaceCompileDefinitionsEntries);
-}
-
-//----------------------------------------------------------------------------
-static void processCompileFeatures(cmTarget const* tgt,
- const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
- std::vector<std::string> &options,
- UNORDERED_SET<std::string> &uniqueOptions,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions)
-{
- processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions, "features",
- std::string());
+ this->Internal->CompileOptionsEntries.insert(position, entry);
+ this->Internal->CompileOptionsBacktraces.insert(btPosition, bt);
}
//----------------------------------------------------------------------------
-void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
- const std::string& config) const
+void cmTarget::InsertCompileDefinition(std::string const& entry,
+ cmListFileBacktrace const& bt)
{
- UNORDERED_SET<std::string> uniqueFeatures;
-
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
- "COMPILE_FEATURES",
- 0, 0);
-
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
- {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
- }
-
- bool debugFeatures = !this->DebugCompileFeaturesDone
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- "COMPILE_FEATURES")
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
- {
- this->DebugCompileFeaturesDone = true;
- }
-
- processCompileFeatures(this,
- this->Internal->CompileFeaturesEntries,
- result,
- uniqueFeatures,
- &dagChecker,
- config,
- debugFeatures);
-
- std::vector<cmTargetInternals::TargetPropertyEntry*>
- linkInterfaceCompileFeaturesEntries;
- this->Internal->AddInterfaceEntries(
- this, config, "INTERFACE_COMPILE_FEATURES",
- linkInterfaceCompileFeaturesEntries);
-
- processCompileFeatures(this,
- linkInterfaceCompileFeaturesEntries,
- result,
- uniqueFeatures,
- &dagChecker,
- config,
- debugFeatures);
-
- deleteAndClear(linkInterfaceCompileFeaturesEntries);
+ this->Internal->CompileDefinitionsEntries.push_back(entry);
+ this->Internal->CompileDefinitionsBacktraces.push_back(bt);
}
//----------------------------------------------------------------------------
@@ -2637,59 +2001,36 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(
config_upper = cmSystemTools::UpperCase(config);
}
typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
- OutputInfoMapType::const_iterator i =
+ OutputInfoMapType::iterator i =
this->Internal->OutputInfoMap.find(config_upper);
if(i == this->Internal->OutputInfoMap.end())
{
+ // Add empty info in map to detect potential recursion.
OutputInfo info;
+ OutputInfoMapType::value_type entry(config_upper, info);
+ i = this->Internal->OutputInfoMap.insert(entry).first;
+
+ // Compute output directories.
this->ComputeOutputDir(config, false, info.OutDir);
this->ComputeOutputDir(config, true, info.ImpDir);
if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
{
info.PdbDir = info.OutDir;
}
- OutputInfoMapType::value_type entry(config_upper, info);
- i = this->Internal->OutputInfoMap.insert(entry).first;
- }
- return &i->second;
-}
-//----------------------------------------------------------------------------
-cmTarget::CompileInfo const* cmTarget::GetCompileInfo(
- const std::string& config) const
-{
- // There is no compile information for imported targets.
- if(this->IsImported())
- {
- return 0;
+ // Now update the previously-prepared map entry.
+ i->second = info;
}
-
- if(this->GetType() > cmTarget::OBJECT_LIBRARY)
+ else if(i->second.empty())
{
- std::string msg = "cmTarget::GetCompileInfo called for ";
- msg += this->GetName();
- msg += " which has type ";
- msg += cmTarget::GetTargetTypeName(this->GetType());
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+ this->GetBacktrace());
return 0;
}
-
- // Lookup/compute/cache the compile information for this configuration.
- std::string config_upper;
- if(!config.empty())
- {
- config_upper = cmSystemTools::UpperCase(config);
- }
- typedef cmTargetInternals::CompileInfoMapType CompileInfoMapType;
- CompileInfoMapType::const_iterator i =
- this->Internal->CompileInfoMap.find(config_upper);
- if(i == this->Internal->CompileInfoMap.end())
- {
- CompileInfo info;
- this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
- CompileInfoMapType::value_type entry(config_upper, info);
- i = this->Internal->CompileInfoMap.insert(entry).first;
- }
return &i->second;
}
@@ -2724,60 +2065,11 @@ std::string cmTarget::GetPDBDirectory(const std::string& config) const
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBDirectory(const std::string& config) const
-{
- if(CompileInfo const* info = this->GetCompileInfo(config))
- {
- return info->CompilePdbDir;
- }
- return "";
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetLocation(const std::string& config) const
+const char* cmTarget::ImportedGetLocation(const std::string& config) const
{
static std::string location;
- if (this->IsImported())
- {
- location = this->ImportedGetFullPath(config, false);
- }
- else
- {
- location = this->GetFullPath(config, false);
- }
- return location.c_str();
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetLocationForBuild() const
-{
- static std::string location;
- if(this->IsImported())
- {
- location = this->ImportedGetFullPath("", false);
- return location.c_str();
- }
-
- // Now handle the deprecated build-time configuration location.
- location = this->GetDirectory();
- const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
- if(cfgid && strcmp(cfgid, ".") != 0)
- {
- location += "/";
- location += cfgid;
- }
-
- if(this->IsAppBundleOnApple())
- {
- std::string macdir = this->BuildMacContentDirectory("", "", false);
- if(!macdir.empty())
- {
- location += "/";
- location += macdir;
- }
- }
- location += "/";
- location += this->GetFullName("", false);
+ assert(this->IsImported());
+ location = this->ImportedGetFullPath(config, false);
return location.c_str();
}
@@ -2820,34 +2112,6 @@ void cmTarget::GetTargetVersion(bool soversion,
}
//----------------------------------------------------------------------------
-const char* cmTarget::GetFeature(const std::string& feature,
- const std::string& config) const
-{
- if(!config.empty())
- {
- std::string featureConfig = feature;
- featureConfig += "_";
- featureConfig += cmSystemTools::UpperCase(config);
- if(const char* value = this->GetProperty(featureConfig))
- {
- return value;
- }
- }
- if(const char* value = this->GetProperty(feature))
- {
- return value;
- }
- return this->Makefile->GetFeature(feature, config);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetFeatureAsBool(const std::string& feature,
- const std::string& config) const
-{
- return cmSystemTools::IsOn(this->GetFeature(feature, config));
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
{
if (this->IsImported())
@@ -2884,22 +2148,6 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
}
//----------------------------------------------------------------------------
-static void MakePropertyList(std::string& output,
- std::vector<cmTargetInternals::TargetPropertyEntry*> const& values)
-{
- output = "";
- std::string sep;
- for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
- it = values.begin(), end = values.end();
- it != end; ++it)
- {
- output += sep;
- output += (*it)->ge->GetInput();
- sep = ";";
- }
-}
-
-//----------------------------------------------------------------------------
const char *cmTarget::GetProperty(const std::string& prop) const
{
return this->GetProperty(prop, this->Makefile);
@@ -2940,12 +2188,24 @@ const char *cmTarget::GetProperty(const std::string& prop,
// For an imported target this is the location of an arbitrary
// available configuration.
//
- // For a non-imported target this is deprecated because it
- // cannot take into account the per-configuration name of the
- // target because the configuration type may not be known at
- // CMake time.
- this->Properties.SetProperty(propLOCATION, this->GetLocationForBuild(),
- cmProperty::TARGET);
+ if(this->IsImported())
+ {
+ this->Properties.SetProperty(
+ propLOCATION, this->ImportedGetFullPath("", false).c_str());
+ }
+ else
+ {
+ // For a non-imported target this is deprecated because it
+ // cannot take into account the per-configuration name of the
+ // target because the configuration type may not be known at
+ // CMake time.
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+ this->Properties.SetProperty(propLOCATION,
+ gt->GetLocationForBuild());
+ }
+
}
// Support "LOCATION_<CONFIG>".
@@ -2956,9 +2216,20 @@ const char *cmTarget::GetProperty(const std::string& prop,
return 0;
}
const char* configName = prop.c_str() + 9;
- this->Properties.SetProperty(prop,
- this->GetLocation(configName),
- cmProperty::TARGET);
+
+ if (this->IsImported())
+ {
+ this->Properties.SetProperty(
+ prop, this->ImportedGetFullPath(configName, false).c_str());
+ }
+ else
+ {
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+ this->Properties.SetProperty(
+ prop, gt->GetFullPath(configName, false).c_str());
+ }
}
// Support "<CONFIG>_LOCATION".
else if(cmHasLiteralSuffix(prop, "_LOCATION"))
@@ -2970,9 +2241,19 @@ const char *cmTarget::GetProperty(const std::string& prop,
{
return 0;
}
- this->Properties.SetProperty(prop,
- this->GetLocation(configName),
- cmProperty::TARGET);
+ if (this->IsImported())
+ {
+ this->Properties.SetProperty(
+ prop, this->ImportedGetFullPath(configName, false).c_str());
+ }
+ else
+ {
+ cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
+ gg->CreateGenerationObjects();
+ cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
+ this->Properties.SetProperty(
+ prop, gt->GetFullPath(configName, false).c_str());
+ }
}
}
}
@@ -2987,6 +2268,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
MAKE_STATIC_PROP(IMPORTED);
MAKE_STATIC_PROP(NAME);
+ MAKE_STATIC_PROP(BINARY_DIR);
+ MAKE_STATIC_PROP(SOURCE_DIR);
MAKE_STATIC_PROP(SOURCES);
#undef MAKE_STATIC_PROP
if(specialProps.empty())
@@ -2999,6 +2282,8 @@ const char *cmTarget::GetProperty(const std::string& prop,
specialProps.insert(propCOMPILE_DEFINITIONS);
specialProps.insert(propIMPORTED);
specialProps.insert(propNAME);
+ specialProps.insert(propBINARY_DIR);
+ specialProps.insert(propSOURCE_DIR);
specialProps.insert(propSOURCES);
}
if(specialProps.count(prop))
@@ -3037,7 +2322,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
static std::string output;
- MakePropertyList(output, this->Internal->IncludeDirectoriesEntries);
+ output = cmJoin(this->Internal->IncludeDirectoriesEntries, ";");
return output.c_str();
}
else if(prop == propCOMPILE_FEATURES)
@@ -3048,7 +2333,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
static std::string output;
- MakePropertyList(output, this->Internal->CompileFeaturesEntries);
+ output = cmJoin(this->Internal->CompileFeaturesEntries, ";");
return output.c_str();
}
else if(prop == propCOMPILE_OPTIONS)
@@ -3059,7 +2344,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
static std::string output;
- MakePropertyList(output, this->Internal->CompileOptionsEntries);
+ output = cmJoin(this->Internal->CompileOptionsEntries, ";");
return output.c_str();
}
else if(prop == propCOMPILE_DEFINITIONS)
@@ -3070,7 +2355,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
static std::string output;
- MakePropertyList(output, this->Internal->CompileDefinitionsEntries);
+ output = cmJoin(this->Internal->CompileDefinitionsEntries, ";");
return output.c_str();
}
else if (prop == propIMPORTED)
@@ -3081,6 +2366,14 @@ const char *cmTarget::GetProperty(const std::string& prop,
{
return this->GetName().c_str();
}
+ else if (prop == propBINARY_DIR)
+ {
+ return this->GetMakefile()->GetCurrentBinaryDirectory();
+ }
+ else if (prop == propSOURCE_DIR)
+ {
+ return this->GetMakefile()->GetCurrentSourceDirectory();
+ }
else if(prop == propSOURCES)
{
if (this->Internal->SourceEntries.empty())
@@ -3174,17 +2467,19 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
}
}
- this->Properties.SetProperty("SOURCES", ss.str().c_str(),
- cmProperty::TARGET);
+ this->Properties.SetProperty("SOURCES", ss.str().c_str());
}
}
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, cmProperty::TARGET, chain);
- if (chain)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
{
- return this->Makefile->GetProperty(prop, cmProperty::TARGET);
+ const bool chain = this->GetMakefile()->GetState()->
+ IsPropertyChained(prop, cmProperty::TARGET);
+ if (chain)
+ {
+ return this->Makefile->GetProperty(prop, chain);
+ }
}
return retVal;
}
@@ -3196,274 +2491,6 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const
}
//----------------------------------------------------------------------------
-class cmTargetCollectLinkLanguages
-{
-public:
- cmTargetCollectLinkLanguages(cmTarget const* target,
- const std::string& config,
- UNORDERED_SET<std::string>& languages,
- cmTarget const* head):
- Config(config), Languages(languages), HeadTarget(head),
- Makefile(target->GetMakefile()), Target(target)
- { this->Visited.insert(target); }
-
- void Visit(cmLinkItem const& item)
- {
- if(!item.Target)
- {
- if(item.find("::") != std::string::npos)
- {
- bool noMessage = false;
- cmake::MessageType messageType = cmake::FATAL_ERROR;
- std::ostringstream e;
- switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
- {
- case cmPolicies::WARN:
- {
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
- messageType = cmake::AUTHOR_WARNING;
- }
- break;
- case cmPolicies::OLD:
- noMessage = true;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Issue the fatal message.
- break;
- }
-
- if(!noMessage)
- {
- e << "Target \"" << this->Target->GetName()
- << "\" links to target \"" << item
- << "\" but the target was not found. Perhaps a find_package() "
- "call is missing for an IMPORTED target, or an ALIAS target is "
- "missing?";
- this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
- e.str(),
- this->Target->GetBacktrace());
- }
- }
- return;
- }
- if(!this->Visited.insert(item.Target).second)
- {
- return;
- }
-
- cmTarget::LinkInterface const* iface =
- item.Target->GetLinkInterface(this->Config, this->HeadTarget);
- if(!iface) { return; }
-
- for(std::vector<std::string>::const_iterator
- li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
- {
- this->Languages.insert(*li);
- }
-
- for(std::vector<cmLinkItem>::const_iterator
- li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
- {
- this->Visit(*li);
- }
- }
-private:
- std::string Config;
- UNORDERED_SET<std::string>& Languages;
- cmTarget const* HeadTarget;
- cmMakefile* Makefile;
- const cmTarget* Target;
- std::set<cmTarget const*> Visited;
-};
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetLinkerLanguage(const std::string& config) const
-{
- return this->GetLinkClosure(config)->LinkerLanguage;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkClosure const*
-cmTarget::GetLinkClosure(const std::string& config) const
-{
- std::string key(cmSystemTools::UpperCase(config));
- cmTargetInternals::LinkClosureMapType::iterator
- i = this->Internal->LinkClosureMap.find(key);
- if(i == this->Internal->LinkClosureMap.end())
- {
- LinkClosure lc;
- this->ComputeLinkClosure(config, lc);
- cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
- i = this->Internal->LinkClosureMap.insert(entry).first;
- }
- return &i->second;
-}
-
-//----------------------------------------------------------------------------
-class cmTargetSelectLinker
-{
- int Preference;
- cmTarget const* Target;
- cmMakefile* Makefile;
- cmGlobalGenerator* GG;
- UNORDERED_SET<std::string> Preferred;
-public:
- cmTargetSelectLinker(cmTarget const* target): Preference(0), Target(target)
- {
- this->Makefile = this->Target->GetMakefile();
- this->GG = this->Makefile->GetGlobalGenerator();
- }
- void Consider(const std::string& lang)
- {
- int preference = this->GG->GetLinkerPreference(lang);
- if(preference > this->Preference)
- {
- this->Preference = preference;
- this->Preferred.clear();
- }
- if(preference == this->Preference)
- {
- this->Preferred.insert(lang);
- }
- }
- std::string Choose()
- {
- if(this->Preferred.empty())
- {
- return "";
- }
- else if(this->Preferred.size() > 1)
- {
- std::ostringstream e;
- e << "Target " << this->Target->GetName()
- << " contains multiple languages with the highest linker preference"
- << " (" << this->Preference << "):\n";
- for(UNORDERED_SET<std::string>::const_iterator
- li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
- {
- e << " " << *li << "\n";
- }
- e << "Set the LINKER_LANGUAGE property for this target.";
- cmake* cm = this->Makefile->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- }
- return *this->Preferred.begin();
- }
-};
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const std::string& config,
- LinkClosure& lc) const
-{
- // Get languages built in this target.
- UNORDERED_SET<std::string> languages;
- LinkImplementation const* impl = this->GetLinkImplementation(config);
- for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
- li != impl->Languages.end(); ++li)
- {
- languages.insert(*li);
- }
-
- // Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, this);
- for(std::vector<cmLinkImplItem>::const_iterator
- li = impl->Libraries.begin();
- li != impl->Libraries.end(); ++li)
- {
- cll.Visit(*li);
- }
-
- // Store the transitive closure of languages.
- for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
- li != languages.end(); ++li)
- {
- lc.Languages.push_back(*li);
- }
-
- // Choose the language whose linker should be used.
- if(this->GetProperty("HAS_CXX"))
- {
- lc.LinkerLanguage = "CXX";
- }
- else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
- {
- lc.LinkerLanguage = linkerLang;
- }
- else
- {
- // Find the language with the highest preference value.
- cmTargetSelectLinker tsl(this);
-
- // First select from the languages compiled directly in this target.
- for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
- li != impl->Languages.end(); ++li)
- {
- tsl.Consider(*li);
- }
-
- // Now consider languages that propagate from linked targets.
- for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
- sit != languages.end(); ++sit)
- {
- std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
- if(this->Makefile->IsOn(propagates))
- {
- tsl.Consider(*sit);
- }
- }
-
- lc.LinkerLanguage = tsl.Choose();
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ExpandLinkItems(std::string const& prop,
- std::string const& value,
- std::string const& config,
- cmTarget const* headTarget,
- bool usage_requirements_only,
- std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const
-{
- cmGeneratorExpression ge;
- cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
- // The $<LINK_ONLY> expression may be in a link interface to specify private
- // link dependencies that are otherwise excluded from usage requirements.
- if(usage_requirements_only)
- {
- dagChecker.SetTransitivePropertiesOnly();
- }
- std::vector<std::string> libs;
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- cmSystemTools::ExpandListArgument(cge->Evaluate(
- this->Makefile,
- config,
- false,
- headTarget,
- this, &dagChecker), libs);
- this->LookupLinkItems(libs, items);
- hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::LookupLinkItems(std::vector<std::string> const& names,
- std::vector<cmLinkItem>& items) const
-{
- for(std::vector<std::string>::const_iterator i = names.begin();
- i != names.end(); ++i)
- {
- std::string name = this->CheckCMP0004(*i);
- if(name == this->GetName() || name.empty())
- {
- continue;
- }
- items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
- }
-}
-
-//----------------------------------------------------------------------------
const char* cmTarget::GetSuffixVariableInternal(bool implib) const
{
switch(this->GetType())
@@ -3521,133 +2548,6 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetPDBName(const std::string& config) const
-{
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- std::vector<std::string> props;
- std::string configUpper = cmSystemTools::UpperCase(config);
- if(!configUpper.empty())
- {
- // PDB_NAME_<CONFIG>
- props.push_back("PDB_NAME_" + configUpper);
- }
-
- // PDB_NAME
- props.push_back("PDB_NAME");
-
- for(std::vector<std::string>::const_iterator i = props.begin();
- i != props.end(); ++i)
- {
- if(const char* outName = this->GetProperty(*i))
- {
- base = outName;
- break;
- }
- }
- return prefix+base+".pdb";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBName(const std::string& config) const
-{
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- // Check for a per-configuration output directory target property.
- std::string configUpper = cmSystemTools::UpperCase(config);
- std::string configProp = "COMPILE_PDB_NAME_";
- configProp += configUpper;
- const char* config_name = this->GetProperty(configProp);
- if(config_name && *config_name)
- {
- return prefix + config_name + ".pdb";
- }
-
- const char* name = this->GetProperty("COMPILE_PDB_NAME");
- if(name && *name)
- {
- return prefix + name + ".pdb";
- }
-
- return "";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCompilePDBPath(const std::string& config) const
-{
- std::string dir = this->GetCompilePDBDirectory(config);
- std::string name = this->GetCompilePDBName(config);
- if(dir.empty() && !name.empty())
- {
- dir = this->GetPDBDirectory(config);
- }
- if(!dir.empty())
- {
- dir += "/";
- }
- return dir + name;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::HasSOName(const std::string& config) const
-{
- // soname is supported only for shared libraries and modules,
- // and then only when the platform supports an soname flag.
- return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY) &&
- !this->GetPropertyAsBool("NO_SONAME") &&
- this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetSOName(const std::string& config) const
-{
- if(this->IsImported())
- {
- // Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
- {
- if(info->NoSOName)
- {
- // The imported library has no builtin soname so the name
- // searched at runtime will be just the filename.
- return cmSystemTools::GetFilenameName(info->Location);
- }
- else
- {
- // Use the soname given if any.
- if(info->SOName.find("@rpath/") == 0)
- {
- return info->SOName.substr(6);
- }
- return info->SOName;
- }
- }
- else
- {
- return "";
- }
- }
- else
- {
- // Compute the soname that will be built.
- std::string name;
- std::string soName;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
- return soName;
- }
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
{
bool install_name_is_rpath = false;
@@ -3774,58 +2674,6 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(
}
//----------------------------------------------------------------------------
-std::string cmTarget::NormalGetRealName(const std::string& config) const
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg = "NormalGetRealName called on imported target: ";
- msg += this->GetName();
- this->GetMakefile()->
- IssueMessage(cmake::INTERNAL_ERROR,
- msg);
- }
-
- if(this->GetType() == cmTarget::EXECUTABLE)
- {
- // Compute the real name that will be built.
- std::string name;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetExecutableNames(name, realName, impName, pdbName, config);
- return realName;
- }
- else
- {
- // Compute the real name that will be built.
- std::string name;
- std::string soName;
- std::string realName;
- std::string impName;
- std::string pdbName;
- this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
- return realName;
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullName(const std::string& config,
- bool implib) const
-{
- if(this->IsImported())
- {
- return this->GetFullNameImported(config, implib);
- }
- else
- {
- return this->GetFullNameInternal(config, implib);
- }
-}
-
-//----------------------------------------------------------------------------
std::string
cmTarget::GetFullNameImported(const std::string& config, bool implib) const
{
@@ -3834,57 +2682,6 @@ cmTarget::GetFullNameImported(const std::string& config, bool implib) const
}
//----------------------------------------------------------------------------
-void cmTarget::GetFullNameComponents(std::string& prefix, std::string& base,
- std::string& suffix,
- const std::string& config,
- bool implib) const
-{
- this->GetFullNameInternal(config, implib, prefix, base, suffix);
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetFullPath(const std::string& config, bool implib,
- bool realname) const
-{
- if(this->IsImported())
- {
- return this->ImportedGetFullPath(config, implib);
- }
- else
- {
- return this->NormalGetFullPath(config, implib, realname);
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::NormalGetFullPath(const std::string& config,
- bool implib, bool realname) const
-{
- std::string fpath = this->GetDirectory(config, implib);
- fpath += "/";
- if(this->IsAppBundleOnApple())
- {
- fpath = this->BuildMacContentDirectory(fpath, config, false);
- fpath += "/";
- }
-
- // Add the full name of the target.
- if(implib)
- {
- fpath += this->GetFullName(config, true);
- }
- else if(realname)
- {
- fpath += this->NormalGetRealName(config);
- }
- else
- {
- fpath += this->GetFullName(config, false);
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
std::string
cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
{
@@ -3902,237 +2699,6 @@ cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
}
//----------------------------------------------------------------------------
-std::string
-cmTarget::GetFullNameInternal(const std::string& config, bool implib) const
-{
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, implib, prefix, base, suffix);
- return prefix+base+suffix;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetFullNameInternal(const std::string& config,
- bool implib,
- std::string& outPrefix,
- std::string& outBase,
- std::string& outSuffix) const
-{
- // Use just the target name for non-main target types.
- if(this->GetType() != cmTarget::STATIC_LIBRARY &&
- this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
- {
- outPrefix = "";
- outBase = this->GetName();
- outSuffix = "";
- return;
- }
-
- // Return an empty name for the import library if this platform
- // does not support import libraries.
- if(implib &&
- !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
- {
- outPrefix = "";
- outBase = "";
- outSuffix = "";
- return;
- }
-
- // The implib option is only allowed for shared libraries, module
- // libraries, and executables.
- if(this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
- {
- implib = false;
- }
-
- // Compute the full name for main target types.
- const char* targetPrefix = (implib
- ? this->GetProperty("IMPORT_PREFIX")
- : this->GetProperty("PREFIX"));
- const char* targetSuffix = (implib
- ? this->GetProperty("IMPORT_SUFFIX")
- : this->GetProperty("SUFFIX"));
- const char* configPostfix = 0;
- if(!config.empty())
- {
- std::string configProp = cmSystemTools::UpperCase(config);
- configProp += "_POSTFIX";
- configPostfix = this->GetProperty(configProp);
- // Mac application bundles and frameworks have no postfix.
- if(configPostfix &&
- (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
- {
- configPostfix = 0;
- }
- }
- const char* prefixVar = this->GetPrefixVariableInternal(implib);
- const char* suffixVar = this->GetSuffixVariableInternal(implib);
-
- // Check for language-specific default prefix and suffix.
- std::string ll = this->GetLinkerLanguage(config);
- if(!ll.empty())
- {
- if(!targetSuffix && suffixVar && *suffixVar)
- {
- std::string langSuff = suffixVar + std::string("_") + ll;
- targetSuffix = this->Makefile->GetDefinition(langSuff);
- }
- if(!targetPrefix && prefixVar && *prefixVar)
- {
- std::string langPrefix = prefixVar + std::string("_") + ll;
- targetPrefix = this->Makefile->GetDefinition(langPrefix);
- }
- }
-
- // if there is no prefix on the target use the cmake definition
- if(!targetPrefix && prefixVar)
- {
- targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
- }
- // if there is no suffix on the target use the cmake definition
- if(!targetSuffix && suffixVar)
- {
- targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
- }
-
- // frameworks have directory prefix but no suffix
- std::string fw_prefix;
- if(this->IsFrameworkOnApple())
- {
- fw_prefix = this->GetOutputName(config, false);
- fw_prefix += ".framework/";
- targetPrefix = fw_prefix.c_str();
- targetSuffix = 0;
- }
-
- if(this->IsCFBundleOnApple())
- {
- fw_prefix = this->GetCFBundleDirectory(config, false);
- fw_prefix += "/";
- targetPrefix = fw_prefix.c_str();
- targetSuffix = 0;
- }
-
- // Begin the final name with the prefix.
- outPrefix = targetPrefix?targetPrefix:"";
-
- // Append the target name or property-specified name.
- outBase += this->GetOutputName(config, implib);
-
- // Append the per-configuration postfix.
- outBase += configPostfix?configPostfix:"";
-
- // Name shared libraries with their version number on some platforms.
- if(const char* soversion = this->GetProperty("SOVERSION"))
- {
- if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
- this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
- {
- outBase += "-";
- outBase += soversion;
- }
- }
-
- // Append the suffix.
- outSuffix = targetSuffix?targetSuffix:"";
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetLibraryNames(std::string& name,
- std::string& soName,
- std::string& realName,
- std::string& impName,
- std::string& pdbName,
- const std::string& config) const
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg = "GetLibraryNames called on imported target: ";
- msg += this->GetName();
- this->Makefile->IssueMessage(cmake::INTERNAL_ERROR,
- msg);
- return;
- }
-
- assert(this->GetType() != INTERFACE_LIBRARY);
-
- // Check for library version properties.
- const char* version = this->GetProperty("VERSION");
- const char* soversion = this->GetProperty("SOVERSION");
- if(!this->HasSOName(config) ||
- this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
- this->IsFrameworkOnApple())
- {
- // Versioning is supported only for shared libraries and modules,
- // and then only when the platform supports an soname flag.
- version = 0;
- soversion = 0;
- }
- if(version && !soversion)
- {
- // The soversion must be set if the library version is set. Use
- // the library version as the soversion.
- soversion = version;
- }
- if(!version && soversion)
- {
- // Use the soversion as the library version.
- version = soversion;
- }
-
- // Get the components of the library name.
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- // The library name.
- name = prefix+base+suffix;
-
- if(this->IsFrameworkOnApple())
- {
- realName = prefix;
- realName += "Versions/";
- realName += this->GetFrameworkVersion();
- realName += "/";
- realName += base;
- soName = realName;
- }
- else
- {
- // The library's soname.
- this->ComputeVersionedName(soName, prefix, base, suffix,
- name, soversion);
- // The library's real name on disk.
- this->ComputeVersionedName(realName, prefix, base, suffix,
- name, version);
- }
-
- // The import library name.
- if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
- {
- impName = this->GetFullNameInternal(config, true);
- }
- else
- {
- impName = "";
- }
-
- // The program database file name.
- pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
void cmTarget::ComputeVersionedName(std::string& vName,
std::string const& prefix,
std::string const& base,
@@ -4150,68 +2716,6 @@ void cmTarget::ComputeVersionedName(std::string& vName,
}
//----------------------------------------------------------------------------
-void cmTarget::GetExecutableNames(std::string& name,
- std::string& realName,
- std::string& impName,
- std::string& pdbName,
- const std::string& config) const
-{
- // This should not be called for imported targets.
- // TODO: Split cmTarget into a class hierarchy to get compile-time
- // enforcement of the limited imported target API.
- if(this->IsImported())
- {
- std::string msg =
- "GetExecutableNames called on imported target: ";
- msg += this->GetName();
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
- }
-
- // This versioning is supported only for executables and then only
- // when the platform supports symbolic links.
-#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* version = 0;
-#else
- // Check for executable version properties.
- const char* version = this->GetProperty("VERSION");
- if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
- {
- version = 0;
- }
-#endif
-
- // Get the components of the executable name.
- std::string prefix;
- std::string base;
- std::string suffix;
- this->GetFullNameInternal(config, false, prefix, base, suffix);
-
- // The executable name.
- name = prefix+base+suffix;
-
- // The executable's real name on disk.
-#if defined(__CYGWIN__)
- realName = prefix+base;
-#else
- realName = name;
-#endif
- if(version)
- {
- realName += "-";
- realName += version;
- }
-#if defined(__CYGWIN__)
- realName += suffix;
-#endif
-
- // The import library name.
- impName = this->GetFullNameInternal(config, true);
-
- // The program database file name.
- pdbName = this->GetPDBName(config);
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::HasImplibGNUtoMS() const
{
return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
@@ -4250,21 +2754,6 @@ void cmTarget::SetPropertyDefault(const std::string& property,
}
//----------------------------------------------------------------------------
-bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
-{
- if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
- {
- return false;
- }
- if(LinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibraries(config))
- {
- return !impl->Libraries.empty();
- }
- return false;
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::HaveInstallTreeRPATH() const
{
const char* install_rpath = this->GetProperty("INSTALL_RPATH");
@@ -4273,137 +2762,6 @@ bool cmTarget::HaveInstallTreeRPATH() const
}
//----------------------------------------------------------------------------
-bool cmTarget::NeedRelinkBeforeInstall(const std::string& config) const
-{
- // Only executables and shared libraries can have an rpath and may
- // need relinking.
- if(this->TargetTypeValue != cmTarget::EXECUTABLE &&
- this->TargetTypeValue != cmTarget::SHARED_LIBRARY &&
- this->TargetTypeValue != cmTarget::MODULE_LIBRARY)
- {
- return false;
- }
-
- // If there is no install location this target will not be installed
- // and therefore does not need relinking.
- if(!this->GetHaveInstallRule())
- {
- return false;
- }
-
- // If skipping all rpaths completely then no relinking is needed.
- if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
- {
- return false;
- }
-
- // If building with the install-tree rpath no relinking is needed.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return false;
- }
-
- // If chrpath is going to be used no relinking is needed.
- if(this->IsChrpathUsed(config))
- {
- return false;
- }
-
- // Check for rpath support on this platform.
- std::string ll = this->GetLinkerLanguage(config);
- if(!ll.empty())
- {
- std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- flagVar += ll;
- flagVar += "_FLAG";
- if(!this->Makefile->IsSet(flagVar))
- {
- // There is no rpath support on this platform so nothing needs
- // relinking.
- return false;
- }
- }
- else
- {
- // No linker language is known. This error will be reported by
- // other code.
- return false;
- }
-
- // 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(config) || this->HaveInstallTreeRPATH();
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForBuildTree(
- const std::string& config) const
-{
- // If building directly for installation then the build tree install_name
- // is the same as the install tree.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return GetInstallNameDirForInstallTree();
- }
-
- // Use the build tree directory for the target.
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
- !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
- !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
- {
- std::string dir;
- bool macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
- if(macosx_rpath)
- {
- dir = "@rpath";
- }
- else
- {
- dir = this->GetDirectory(config);
- }
- dir += "/";
- return dir;
- }
- else
- {
- return "";
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetInstallNameDirForInstallTree() const
-{
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
- {
- std::string dir;
- const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
-
- if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
- !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
- {
- if(install_name_dir && *install_name_dir)
- {
- dir = install_name_dir;
- dir += "/";
- }
- }
- if(!install_name_dir)
- {
- if(this->MacOSXRpathInstallNameDirDefault())
- {
- dir = "@rpath/";
- }
- }
- return dir;
- }
- else
- {
- return "";
- }
-}
-
-//----------------------------------------------------------------------------
const char* cmTarget::GetOutputTargetType(bool implib) const
{
switch(this->GetType())
@@ -4492,7 +2850,10 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
if(const char* config_outdir = this->GetProperty(configProp))
{
// Use the user-specified per-configuration output directory.
- out = config_outdir;
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(config_outdir);
+ out = cge->Evaluate(this->Makefile, config);
// Skip per-configuration subdirectory.
conf = "";
@@ -4500,7 +2861,17 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
else if(const char* outdir = this->GetProperty(propertyName))
{
// Use the user-specified output directory.
- out = outdir;
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(outdir);
+ out = cge->Evaluate(this->Makefile, config);
+
+ // Skip per-configuration subdirectory if the value contained a
+ // generator expression.
+ if (out != outdir)
+ {
+ conf = "";
+ }
}
else if(this->GetType() == cmTarget::EXECUTABLE)
{
@@ -4611,44 +2982,6 @@ bool cmTarget::UsesDefaultOutputDir(const std::string& config,
}
//----------------------------------------------------------------------------
-std::string cmTarget::GetOutputName(const std::string& config,
- bool implib) const
-{
- std::vector<std::string> props;
- std::string type = this->GetOutputTargetType(implib);
- std::string configUpper = cmSystemTools::UpperCase(config);
- if(!type.empty() && !configUpper.empty())
- {
- // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
- props.push_back(type + "_OUTPUT_NAME_" + configUpper);
- }
- if(!type.empty())
- {
- // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
- props.push_back(type + "_OUTPUT_NAME");
- }
- if(!configUpper.empty())
- {
- // OUTPUT_NAME_<CONFIG>
- props.push_back("OUTPUT_NAME_" + configUpper);
- // <CONFIG>_OUTPUT_NAME
- props.push_back(configUpper + "_OUTPUT_NAME");
- }
- // OUTPUT_NAME
- props.push_back("OUTPUT_NAME");
-
- for(std::vector<std::string>::const_iterator i = props.begin();
- i != props.end(); ++i)
- {
- if(const char* outName = this->GetProperty(*i))
- {
- return outName;
- }
- }
- return this->GetName();
-}
-
-//----------------------------------------------------------------------------
std::string cmTarget::GetFrameworkVersion() const
{
assert(this->GetType() != INTERFACE_LIBRARY);
@@ -4701,500 +3034,6 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
}
//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
-
-//----------------------------------------------------------------------------
-template<>
-bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
-{
- return tgt->GetPropertyAsBool(prop);
-}
-
-//----------------------------------------------------------------------------
-template<>
-const char *getTypedProperty<const char *>(cmTarget const* tgt,
- const std::string& prop)
-{
- return tgt->GetProperty(prop);
-}
-
-enum CompatibleType
-{
- BoolType,
- StringType,
- NumberMinType,
- NumberMaxType
-};
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
- PropertyType rhs,
- CompatibleType t);
-
-//----------------------------------------------------------------------------
-template<>
-std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType)
-{
- return std::make_pair(lhs == rhs, lhs);
-}
-
-//----------------------------------------------------------------------------
-std::pair<bool, const char*> consistentStringProperty(const char *lhs,
- const char *rhs)
-{
- const bool b = strcmp(lhs, rhs) == 0;
- return std::make_pair(b, b ? lhs : 0);
-}
-
-//----------------------------------------------------------------------------
-std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
- const char *rhs,
- CompatibleType t)
-{
- char *pEnd;
-
- const char* const null_ptr = 0;
-
- long lnum = strtol(lhs, &pEnd, 0);
- if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
- {
- return std::pair<bool, const char*>(false, null_ptr);
- }
-
- long rnum = strtol(rhs, &pEnd, 0);
- if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
- {
- return std::pair<bool, const char*>(false, null_ptr);
- }
-
- if (t == NumberMaxType)
- {
- return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
- }
- else
- {
- return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
- }
-}
-
-//----------------------------------------------------------------------------
-template<>
-std::pair<bool, const char*> consistentProperty(const char *lhs,
- const char *rhs,
- CompatibleType t)
-{
- if (!lhs && !rhs)
- {
- return std::make_pair(true, lhs);
- }
- if (!lhs)
- {
- return std::make_pair(true, rhs);
- }
- if (!rhs)
- {
- return std::make_pair(true, lhs);
- }
-
- const char* const null_ptr = 0;
-
- switch(t)
- {
- case BoolType:
- assert(0 && "consistentProperty for strings called with BoolType");
- return std::pair<bool, const char*>(false, null_ptr);
- case StringType:
- return consistentStringProperty(lhs, rhs);
- case NumberMinType:
- case NumberMaxType:
- return consistentNumberProperty(lhs, rhs, t);
- }
- assert(0 && "Unreachable!");
- return std::pair<bool, const char*>(false, null_ptr);
-}
-
-template<typename PropertyType>
-PropertyType impliedValue(PropertyType);
-template<>
-bool impliedValue<bool>(bool)
-{
- return false;
-}
-template<>
-const char* impliedValue<const char*>(const char*)
-{
- return "";
-}
-
-
-template<typename PropertyType>
-std::string valueAsString(PropertyType);
-template<>
-std::string valueAsString<bool>(bool value)
-{
- return value ? "TRUE" : "FALSE";
-}
-template<>
-std::string valueAsString<const char*>(const char* value)
-{
- return value ? value : "(unset)";
-}
-
-//----------------------------------------------------------------------------
-void
-cmTarget::ReportPropertyOrigin(const std::string &p,
- const std::string &result,
- const std::string &report,
- const std::string &compatibilityType) const
-{
- std::vector<std::string> debugProperties;
- const char *debugProp =
- this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
- if (debugProp)
- {
- cmSystemTools::ExpandListArgument(debugProp, debugProperties);
- }
-
- bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
- && std::find(debugProperties.begin(),
- debugProperties.end(),
- p)
- != debugProperties.end();
-
- if (this->Makefile->IsGeneratingBuildSystem())
- {
- this->DebugCompatiblePropertiesDone[p] = true;
- }
- if (!debugOrigin)
- {
- return;
- }
-
- std::string areport = compatibilityType;
- areport += std::string(" of property \"") + p + "\" for target \"";
- areport += std::string(this->GetName());
- areport += "\" (result: \"";
- areport += result;
- areport += "\"):\n" + report;
-
- this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
-}
-
-//----------------------------------------------------------------------------
-std::string compatibilityType(CompatibleType t)
-{
- switch(t)
- {
- case BoolType:
- return "Boolean compatibility";
- case StringType:
- return "String compatibility";
- case NumberMaxType:
- return "Numeric maximum compatibility";
- case NumberMinType:
- return "Numeric minimum compatibility";
- }
- assert(0 && "Unreachable!");
- return "";
-}
-
-//----------------------------------------------------------------------------
-std::string compatibilityAgree(CompatibleType t, bool dominant)
-{
- switch(t)
- {
- case BoolType:
- case StringType:
- return dominant ? "(Disagree)\n" : "(Agree)\n";
- case NumberMaxType:
- case NumberMinType:
- return dominant ? "(Dominant)\n" : "(Ignored)\n";
- }
- assert(0 && "Unreachable!");
- return "";
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
- const std::string &p,
- const std::string& config,
- const char *defaultValue,
- CompatibleType t,
- PropertyType *)
-{
- PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
- const bool explicitlySet = tgt->GetProperties()
- .find(p)
- != tgt->GetProperties().end();
- const bool impliedByUse =
- tgt->IsNullImpliedByLinkLibraries(p);
- assert((impliedByUse ^ explicitlySet)
- || (!impliedByUse && !explicitlySet));
-
- std::vector<cmTarget const*> const& deps =
- tgt->GetLinkImplementationClosure(config);
-
- if(deps.empty())
- {
- return propContent;
- }
- bool propInitialized = explicitlySet;
-
- std::string report = " * Target \"";
- report += tgt->GetName();
- if (explicitlySet)
- {
- report += "\" has property content \"";
- report += valueAsString<PropertyType>(propContent);
- report += "\"\n";
- }
- else if (impliedByUse)
- {
- report += "\" property is implied by use.\n";
- }
- else
- {
- report += "\" property not set.\n";
- }
-
- std::string interfaceProperty = "INTERFACE_" + p;
- for(std::vector<cmTarget const*>::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.
-
- cmTarget const* theTarget = *li;
-
- const bool ifaceIsSet = theTarget->GetProperties()
- .find(interfaceProperty)
- != theTarget->GetProperties().end();
- PropertyType ifacePropContent =
- getTypedProperty<PropertyType>(theTarget,
- interfaceProperty);
-
- std::string reportEntry;
- if (ifaceIsSet)
- {
- reportEntry += " * Target \"";
- reportEntry += theTarget->GetName();
- reportEntry += "\" property value \"";
- reportEntry += valueAsString<PropertyType>(ifacePropContent);
- reportEntry += "\" ";
- }
-
- if (explicitlySet)
- {
- if (ifaceIsSet)
- {
- std::pair<bool, PropertyType> consistent =
- consistentProperty(propContent,
- ifacePropContent, t);
- report += reportEntry;
- report += compatibilityAgree(t, propContent != consistent.second);
- if (!consistent.first)
- {
- std::ostringstream e;
- e << "Property " << p << " on target \""
- << tgt->GetName() << "\" does\nnot match the "
- "INTERFACE_" << p << " property requirement\nof "
- "dependency \"" << theTarget->GetName() << "\".\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- propContent = consistent.second;
- continue;
- }
- }
- else
- {
- // Explicitly set on target and not set in iface. Can't disagree.
- continue;
- }
- }
- else if (impliedByUse)
- {
- propContent = impliedValue<PropertyType>(propContent);
-
- if (ifaceIsSet)
- {
- std::pair<bool, PropertyType> consistent =
- consistentProperty(propContent,
- ifacePropContent, t);
- report += reportEntry;
- report += compatibilityAgree(t, propContent != consistent.second);
- if (!consistent.first)
- {
- std::ostringstream 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 \""
- << theTarget->GetName() << "\" is in conflict.\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- propContent = consistent.second;
- continue;
- }
- }
- else
- {
- // Implicitly set on target and not set in iface. Can't disagree.
- continue;
- }
- }
- else
- {
- if (ifaceIsSet)
- {
- if (propInitialized)
- {
- std::pair<bool, PropertyType> consistent =
- consistentProperty(propContent,
- ifacePropContent, t);
- report += reportEntry;
- report += compatibilityAgree(t, propContent != consistent.second);
- if (!consistent.first)
- {
- std::ostringstream e;
- e << "The INTERFACE_" << p << " property of \""
- << theTarget->GetName() << "\" does\nnot agree with the value "
- "of " << p << " already determined\nfor \""
- << tgt->GetName() << "\".\n";
- cmSystemTools::Error(e.str().c_str());
- break;
- }
- else
- {
- propContent = consistent.second;
- continue;
- }
- }
- else
- {
- report += reportEntry + "(Interface set)\n";
- propContent = ifacePropContent;
- propInitialized = true;
- }
- }
- else
- {
- // Not set. Nothing to agree on.
- continue;
- }
- }
- }
-
- tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
- report, compatibilityType(t));
- return propContent;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
- const std::string& config) const
-{
- return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
- BoolType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentStringProperty(
- const std::string &p,
- const std::string& config) const
-{
- return checkInterfacePropertyCompatibility<const char *>(this,
- p,
- config,
- "empty",
- StringType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty(
- const std::string &p,
- const std::string& config) const
-{
- return checkInterfacePropertyCompatibility<const char *>(this,
- p,
- config,
- "empty",
- NumberMinType, 0);
-}
-
-//----------------------------------------------------------------------------
-const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty(
- const std::string &p,
- const std::string& config) const
-{
- return checkInterfacePropertyCompatibility<const char *>(this,
- p,
- config,
- "empty",
- NumberMaxType, 0);
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
- const std::string& config) const
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY
- || this->TargetTypeValue == INTERFACE_LIBRARY)
- {
- return false;
- }
- return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
- const std::string& config) const
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY
- || this->TargetTypeValue == INTERFACE_LIBRARY)
- {
- return false;
- }
- return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
- const std::string& config) const
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY
- || this->TargetTypeValue == INTERFACE_LIBRARY)
- {
- return false;
- }
- return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
- const std::string& config) const
-{
- if (this->TargetTypeValue == OBJECT_LIBRARY
- || this->TargetTypeValue == INTERFACE_LIBRARY)
- {
- return false;
- }
- return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
-}
-
-//----------------------------------------------------------------------------
void
cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
{
@@ -5236,117 +3075,6 @@ cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
}
//----------------------------------------------------------------------------
-void cmTarget::GetLanguages(std::set<std::string>& languages,
- const std::string& config) const
-{
- std::vector<cmSourceFile*> sourceFiles;
- this->GetSourceFiles(sourceFiles, config);
- for(std::vector<cmSourceFile*>::const_iterator
- i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
- {
- const std::string& lang = (*i)->GetLanguage();
- if(!lang.empty())
- {
- languages.insert(lang);
- }
- }
-
- std::vector<cmTarget*> objectLibraries;
- std::vector<cmSourceFile const*> externalObjects;
- if (this->Makefile->GetGeneratorTargets().empty())
- {
- this->GetObjectLibrariesCMP0026(objectLibraries);
- }
- else
- {
- cmGeneratorTarget* gt = this->Makefile->GetGlobalGenerator()
- ->GetGeneratorTarget(this);
- gt->GetExternalObjects(externalObjects, config);
- for(std::vector<cmSourceFile const*>::const_iterator
- i = externalObjects.begin(); i != externalObjects.end(); ++i)
- {
- std::string objLib = (*i)->GetObjectLibrary();
- if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
- {
- objectLibraries.push_back(tgt);
- }
- }
- }
- for(std::vector<cmTarget*>::const_iterator
- i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
- {
- (*i)->GetLanguages(languages, config);
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsChrpathUsed(const std::string& config) const
-{
- // Only certain target types have an rpath.
- if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::EXECUTABLE))
- {
- return false;
- }
-
- // If the target will not be installed we do not need to change its
- // rpath.
- if(!this->GetHaveInstallRule())
- {
- return false;
- }
-
- // Skip chrpath if skipping rpath altogether.
- if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
- {
- return false;
- }
-
- // Skip chrpath if it does not need to be changed at install time.
- if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
- {
- return false;
- }
-
- // Allow the user to disable builtin chrpath explicitly.
- if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
- {
- return false;
- }
-
- if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
- {
- return true;
- }
-
-#if defined(CMAKE_USE_ELF_PARSER)
- // Enable if the rpath flag uses a separator and the target uses ELF
- // binaries.
- std::string ll = this->GetLinkerLanguage(config);
- if(!ll.empty())
- {
- std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- sepVar += ll;
- sepVar += "_FLAG_SEP";
- const char* sep = this->Makefile->GetDefinition(sepVar);
- if(sep && *sep)
- {
- // TODO: Add ELF check to ABI detection and get rid of
- // CMAKE_EXECUTABLE_FORMAT.
- if(const char* fmt =
- this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
- {
- return strcmp(fmt, "ELF") == 0;
- }
- }
- }
-#endif
- static_cast<void>(config);
- return false;
-}
-
-//----------------------------------------------------------------------------
cmTarget::ImportInfo const*
cmTarget::GetImportInfo(const std::string& config) const
{
@@ -5696,478 +3424,11 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
}
//----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
- const std::string& config,
- cmTarget const* head) const
-{
- // Imported targets have their own link interface.
- if(this->IsImported())
- {
- return this->GetImportLinkInterface(config, head, false);
- }
-
- // Link interfaces are not supported for executables that do not
- // export symbols.
- if(this->GetType() == cmTarget::EXECUTABLE &&
- !this->IsExecutableWithExports())
- {
- return 0;
- }
-
- // Lookup any existing link interface for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
- cmTargetInternals::HeadToLinkInterfaceMap& hm =
- this->Internal->LinkInterfaceMap[CONFIG];
-
- // If the link interface does not depend on the head target
- // then return the one we computed first.
- if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
- {
- return &hm.begin()->second;
- }
-
- cmTargetInternals::OptionalLinkInterface& iface = hm[head];
- if(!iface.LibrariesDone)
- {
- iface.LibrariesDone = true;
- this->Internal->ComputeLinkInterfaceLibraries(
- this, config, iface, head, false);
- }
- if(!iface.AllDone)
- {
- iface.AllDone = true;
- if(iface.Exists)
- {
- this->Internal->ComputeLinkInterface(this, config, iface, head);
- }
- }
-
- return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterfaceLibraries const*
-cmTarget::GetLinkInterfaceLibraries(const std::string& config,
- cmTarget const* head,
- bool usage_requirements_only) const
-{
- // Imported targets have their own link interface.
- if(this->IsImported())
- {
- return this->GetImportLinkInterface(config, head, usage_requirements_only);
- }
-
- // Link interfaces are not supported for executables that do not
- // export symbols.
- if(this->GetType() == cmTarget::EXECUTABLE &&
- !this->IsExecutableWithExports())
- {
- return 0;
- }
-
- // Lookup any existing link interface for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
- cmTargetInternals::HeadToLinkInterfaceMap& hm =
- (usage_requirements_only ?
- this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
- this->Internal->LinkInterfaceMap[CONFIG]);
-
- // If the link interface does not depend on the head target
- // then return the one we computed first.
- if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
- {
- return &hm.begin()->second;
- }
-
- cmTargetInternals::OptionalLinkInterface& iface = hm[head];
- if(!iface.LibrariesDone)
- {
- iface.LibrariesDone = true;
- this->Internal->ComputeLinkInterfaceLibraries(
- this, config, iface, head, usage_requirements_only);
- }
-
- return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterface const*
-cmTarget::GetImportLinkInterface(const std::string& config,
- cmTarget const* headTarget,
- bool usage_requirements_only) const
-{
- cmTarget::ImportInfo const* info = this->GetImportInfo(config);
- if(!info)
- {
- return 0;
- }
-
- std::string CONFIG = cmSystemTools::UpperCase(config);
- cmTargetInternals::HeadToLinkInterfaceMap& hm =
- (usage_requirements_only ?
- this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
- this->Internal->LinkInterfaceMap[CONFIG]);
-
- // If the link interface does not depend on the head target
- // then return the one we computed first.
- if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
- {
- return &hm.begin()->second;
- }
-
- cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget];
- if(!iface.AllDone)
- {
- iface.AllDone = true;
- iface.Multiplicity = info->Multiplicity;
- cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
- this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
- headTarget, usage_requirements_only,
- iface.Libraries,
- iface.HadHeadSensitiveCondition);
- std::vector<std::string> deps;
- cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
- this->LookupLinkItems(deps, iface.SharedDeps);
- }
-
- return &iface;
-}
-
-//----------------------------------------------------------------------------
-void processILibs(const std::string& config,
- cmTarget const* headTarget,
- cmLinkItem const& item,
- std::vector<cmTarget const*>& tgts,
- std::set<cmTarget const*>& emitted)
-{
- if (item.Target && emitted.insert(item.Target).second)
- {
- tgts.push_back(item.Target);
- if(cmTarget::LinkInterfaceLibraries const* iface =
- item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
- {
- for(std::vector<cmLinkItem>::const_iterator
- it = iface->Libraries.begin();
- it != iface->Libraries.end(); ++it)
- {
- processILibs(config, headTarget, *it, tgts, emitted);
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
-std::vector<cmTarget const*> const&
-cmTarget::GetLinkImplementationClosure(const std::string& config) const
-{
- cmTargetInternals::LinkImplClosure& tgts =
- this->Internal->LinkImplClosureMap[config];
- if(!tgts.Done)
- {
- tgts.Done = true;
- std::set<cmTarget const*> emitted;
-
- cmTarget::LinkImplementationLibraries const* impl
- = this->GetLinkImplementationLibraries(config);
-
- for(std::vector<cmLinkImplItem>::const_iterator
- it = impl->Libraries.begin();
- it != impl->Libraries.end(); ++it)
- {
- processILibs(config, this, *it, tgts , emitted);
- }
- }
- return tgts;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::CompatibleInterfaces const&
-cmTarget::GetCompatibleInterfaces(std::string const& config) const
-{
- cmTargetInternals::CompatibleInterfaces& compat =
- this->Internal->CompatibleInterfacesMap[config];
- if(!compat.Done)
- {
- compat.Done = true;
- compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
- compat.PropsString.insert("AUTOUIC_OPTIONS");
- std::vector<cmTarget const*> const& deps =
- this->GetLinkImplementationClosure(config);
- for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
- li != deps.end(); ++li)
- {
-#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
- if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
- { \
- std::vector<std::string> props; \
- cmSystemTools::ExpandListArgument(prop, props); \
- compat.Props##x.insert(props.begin(), props.end()); \
- }
- CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
- CM_READ_COMPATIBLE_INTERFACE(STRING, String)
- CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
- CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
-#undef CM_READ_COMPATIBLE_INTERFACE
- }
- }
- return compat;
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkInterfaceLibraries(
- cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkInterface& iface,
- cmTarget const* headTarget,
- bool usage_requirements_only)
-{
- // Construct the property name suffix for this configuration.
- std::string suffix = "_";
- if(!config.empty())
- {
- suffix += cmSystemTools::UpperCase(config);
- }
- else
- {
- suffix += "NOCONFIG";
- }
-
- // 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(thisTarget->PolicyStatusCMP0022 != cmPolicies::OLD &&
- thisTarget->PolicyStatusCMP0022 != cmPolicies::WARN)
- {
- // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
- linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
- explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
- }
- else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
- thisTarget->IsExecutableWithExports())
- {
- // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
- // shared lib or executable.
-
- // Lookup the per-configuration property.
- linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- linkIfaceProp += suffix;
- explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-
- // If not set, try the generic property.
- if(!explicitLibraries)
- {
- linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
- explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
- }
- }
-
- if(explicitLibraries &&
- thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->PolicyWarnedCMP0022)
- {
- // Compare the explicitly set old link interface properties to the
- // preferred new link interface property one and warn if different.
- const char* newExplicitLibraries =
- thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
- if (newExplicitLibraries
- && strcmp(newExplicitLibraries, explicitLibraries) != 0)
- {
- std::ostringstream w;
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
- "Target \"" << thisTarget->GetName() << "\" has an "
- "INTERFACE_LINK_LIBRARIES property which differs from its " <<
- linkIfaceProp << " properties."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n"
- " " << newExplicitLibraries << "\n" <<
- linkIfaceProp << ":\n"
- " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
- thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->PolicyWarnedCMP0022 = true;
- }
- }
-
- // There is no implicit link interface for executables or modules
- // so if none was explicitly set then there is no link interface.
- if(!explicitLibraries &&
- (thisTarget->GetType() == cmTarget::EXECUTABLE ||
- (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
- {
- return;
- }
- iface.Exists = true;
- iface.ExplicitLibraries = explicitLibraries;
-
- if(explicitLibraries)
- {
- // The interface libraries have been explicitly set.
- thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
- headTarget, usage_requirements_only,
- iface.Libraries,
- iface.HadHeadSensitiveCondition);
- }
- else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
- || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
- // If CMP0022 is NEW then the plain tll signature sets the
- // INTERFACE_LINK_LIBRARIES, so if we get here then the project
- // cleared the property explicitly and we should not fall back
- // to the link implementation.
- {
- // The link implementation is the default link interface.
- cmTarget::LinkImplementationLibraries const* impl =
- thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
- iface.Libraries.insert(iface.Libraries.end(),
- impl->Libraries.begin(), impl->Libraries.end());
- if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN &&
- !this->PolicyWarnedCMP0022 && !usage_requirements_only)
- {
- // Compare the link implementation fallback link interface to the
- // preferred new link interface property and warn if different.
- std::vector<cmLinkItem> ifaceLibs;
- static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
- if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
- {
- bool hadHeadSensitiveConditionDummy = false;
- thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
- headTarget, usage_requirements_only,
- ifaceLibs, hadHeadSensitiveConditionDummy);
- }
- if (ifaceLibs != iface.Libraries)
- {
- std::string oldLibraries = cmJoin(impl->Libraries, ";");
- std::string newLibraries = cmJoin(ifaceLibs, ";");
- if(oldLibraries.empty())
- { oldLibraries = "(empty)"; }
- if(newLibraries.empty())
- { newLibraries = "(empty)"; }
-
- std::ostringstream w;
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
- "Target \"" << thisTarget->GetName() << "\" has an "
- "INTERFACE_LINK_LIBRARIES property. "
- "This should be preferred as the source of the link interface "
- "for this library but because CMP0022 is not set CMake is "
- "ignoring the property and using the link implementation "
- "as the link interface instead."
- "\n"
- "INTERFACE_LINK_LIBRARIES:\n"
- " " << newLibraries << "\n"
- "Link implementation:\n"
- " " << oldLibraries << "\n";
- thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- this->PolicyWarnedCMP0022 = true;
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkInterface& iface,
- cmTarget const* headTarget) const
-{
- if(iface.ExplicitLibraries)
- {
- if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
- || thisTarget->GetType() == cmTarget::STATIC_LIBRARY
- || thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY)
- {
- // Shared libraries may have runtime implementation dependencies
- // on other shared libraries that are not in the interface.
- UNORDERED_SET<std::string> emitted;
- for(std::vector<cmLinkItem>::const_iterator
- li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
- {
- emitted.insert(*li);
- }
- if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
- {
- cmTarget::LinkImplementation const* impl =
- thisTarget->GetLinkImplementation(config);
- for(std::vector<cmLinkImplItem>::const_iterator
- li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
- {
- if(emitted.insert(*li).second)
- {
- if(li->Target)
- {
- // This is a runtime dependency on another shared library.
- if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
- {
- iface.SharedDeps.push_back(*li);
- }
- }
- else
- {
- // TODO: Recognize shared library file names. Perhaps this
- // should be moved to cmComputeLinkInformation, but that creates
- // a chicken-and-egg problem since this list is needed for its
- // construction.
- }
- }
- }
- }
- }
- }
- else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
- || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
- {
- // The link implementation is the default link interface.
- cmTarget::LinkImplementationLibraries const*
- impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
- headTarget);
- iface.ImplementationIsInterface = true;
- iface.WrongConfigLibraries = impl->WrongConfigLibraries;
- }
-
- if(thisTarget->LinkLanguagePropagatesToDependents())
- {
- // Targets using this archive need its language runtime libraries.
- if(cmTarget::LinkImplementation const* impl =
- thisTarget->GetLinkImplementation(config))
- {
- iface.Languages = impl->Languages;
- }
- }
-
- if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
- {
- // Construct the property name suffix for this configuration.
- std::string suffix = "_";
- if(!config.empty())
- {
- suffix += cmSystemTools::UpperCase(config);
- }
- else
- {
- suffix += "NOCONFIG";
- }
-
- // How many repetitions are needed if this library has cyclic
- // dependencies?
- std::string propName = "LINK_INTERFACE_MULTIPLICITY";
- propName += suffix;
- if(const char* config_reps = thisTarget->GetProperty(propName))
- {
- sscanf(config_reps, "%u", &iface.Multiplicity);
- }
- else if(const char* reps =
- thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
- {
- sscanf(reps, "%u", &iface.Multiplicity);
- }
- }
-}
-
-//----------------------------------------------------------------------------
void cmTargetInternals::AddInterfaceEntries(
cmTarget const* thisTarget, std::string const& config,
std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
{
- if(cmTarget::LinkImplementationLibraries const* impl =
+ if(cmLinkImplementationLibraries const* impl =
thisTarget->GetLinkImplementationLibraries(config))
{
for (std::vector<cmLinkImplItem>::const_iterator
@@ -6178,7 +3439,7 @@ void cmTargetInternals::AddInterfaceEntries(
{
std::string genex =
"$<TARGET_PROPERTY:" + *it + "," + prop + ">";
- cmGeneratorExpression ge(&it->Backtrace);
+ cmGeneratorExpression ge(it->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
cge->SetEvaluateForBuildsystem(true);
entries.push_back(
@@ -6188,43 +3449,23 @@ void cmTargetInternals::AddInterfaceEntries(
}
}
-//----------------------------------------------------------------------------
-cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const std::string& config) const
+cmOptionalLinkImplementation&
+cmTarget::GetLinkImplMap(std::string const& config) const
{
- // There is no link implementation for imported targets.
- if(this->IsImported())
- {
- return 0;
- }
-
// Populate the link implementation for this configuration.
std::string CONFIG = cmSystemTools::UpperCase(config);
- cmTargetInternals::OptionalLinkImplementation&
- impl = this->Internal->LinkImplMap[CONFIG][this];
- if(!impl.LibrariesDone)
- {
- impl.LibrariesDone = true;
- this->Internal
- ->ComputeLinkImplementationLibraries(this, config, impl, this);
- }
- if(!impl.LanguagesDone)
- {
- impl.LanguagesDone = true;
- this->Internal->ComputeLinkImplementationLanguages(this, config, impl);
- }
- return &impl;
+ return Internal->LinkImplMap[CONFIG][this];
}
//----------------------------------------------------------------------------
-cmTarget::LinkImplementationLibraries const*
+cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibraries(const std::string& config) const
{
return this->GetLinkImplementationLibrariesInternal(config, this);
}
//----------------------------------------------------------------------------
-cmTarget::LinkImplementationLibraries const*
+cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const
{
@@ -6246,39 +3487,36 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
return &hm.begin()->second;
}
- cmTargetInternals::OptionalLinkImplementation& impl = hm[head];
+ cmOptionalLinkImplementation& impl = hm[head];
if(!impl.LibrariesDone)
{
impl.LibrariesDone = true;
- this->Internal
- ->ComputeLinkImplementationLibraries(this, config, impl, head);
+ this->ComputeLinkImplementationLibraries(config, impl, head);
}
return &impl;
}
//----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLibraries(
- cmTarget const* thisTarget,
+void cmTarget::ComputeLinkImplementationLibraries(
const std::string& config,
- OptionalLinkImplementation& impl,
+ cmOptionalLinkImplementation& impl,
cmTarget const* head) const
{
// Collect libraries directly linked in this configuration.
for (std::vector<cmValueWithOrigin>::const_iterator
- le = this->LinkImplementationPropertyEntries.begin(),
- end = this->LinkImplementationPropertyEntries.end();
+ le = this->Internal->LinkImplementationPropertyEntries.begin(),
+ end = this->Internal->LinkImplementationPropertyEntries.end();
le != end; ++le)
{
std::vector<std::string> llibs;
cmGeneratorExpressionDAGChecker dagChecker(
- thisTarget->GetName(),
+ this->GetName(),
"LINK_LIBRARIES", 0, 0);
- cmGeneratorExpression ge(&le->Backtrace);
+ cmGeneratorExpression ge(le->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(le->Value);
std::string const evaluated =
- cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker);
+ cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
cmSystemTools::ExpandListArgument(evaluated, llibs);
if(cge->GetHadHeadSensitiveCondition())
{
@@ -6289,15 +3527,15 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
li != llibs.end(); ++li)
{
// Skip entries that resolve to the target itself or are empty.
- std::string name = thisTarget->CheckCMP0004(*li);
- if(name == thisTarget->GetName() || name.empty())
+ std::string name = this->CheckCMP0004(*li);
+ if(name == this->GetName() || name.empty())
{
- if(name == thisTarget->GetName())
+ if(name == this->GetName())
{
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
std::ostringstream e;
- switch(thisTarget->GetPolicyStatusCMP0038())
+ switch(this->GetPolicyStatusCMP0038())
{
case cmPolicies::WARN:
{
@@ -6316,9 +3554,9 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
if(!noMessage)
{
- e << "Target \"" << thisTarget->GetName() << "\" links to itself.";
- thisTarget->Makefile->GetCMakeInstance()->IssueMessage(
- messageType, e.str(), thisTarget->GetBacktrace());
+ e << "Target \"" << this->GetName() << "\" links to itself.";
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->GetBacktrace());
if (messageType == cmake::FATAL_ERROR)
{
return;
@@ -6330,7 +3568,7 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
// The entry is meant for this configuration.
impl.Libraries.push_back(
- cmLinkImplItem(name, thisTarget->FindTargetToLink(name),
+ cmLinkImplItem(name, this->FindTargetToLink(name),
le->Backtrace, evaluated != le->Value));
}
@@ -6338,51 +3576,35 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
for (std::set<std::string>::const_iterator it = seenProps.begin();
it != seenProps.end(); ++it)
{
- if (!thisTarget->GetProperty(*it))
+ if (!this->GetProperty(*it))
{
- thisTarget->LinkImplicitNullProperties.insert(*it);
+ this->LinkImplicitNullProperties.insert(*it);
}
}
- cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards);
+ cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
}
- cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config);
+ cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
cmTarget::LinkLibraryVectorType const& oldllibs =
- thisTarget->GetOriginalLinkLibraries();
+ this->GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
li != oldllibs.end(); ++li)
{
if(li->second != cmTarget::GENERAL && li->second != linkType)
{
- std::string name = thisTarget->CheckCMP0004(li->first);
- if(name == thisTarget->GetName() || name.empty())
+ std::string name = this->CheckCMP0004(li->first);
+ if(name == this->GetName() || name.empty())
{
continue;
}
// Support OLD behavior for CMP0003.
impl.WrongConfigLibraries.push_back(
- cmLinkItem(name, thisTarget->FindTargetToLink(name)));
+ cmLinkItem(name, this->FindTargetToLink(name)));
}
}
}
//----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLanguages(
- cmTarget const* thisTarget,
- const std::string& config,
- OptionalLinkImplementation& impl) const
-{
- // This target needs runtime libraries for its source languages.
- std::set<std::string> languages;
- // Get languages used in our source files.
- thisTarget->GetLanguages(languages, config);
- // Copy the set of langauges to the link implementation.
- impl.Languages.insert(impl.Languages.begin(),
- languages.begin(), languages.end());
-}
-
-//----------------------------------------------------------------------------
cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
{
cmTarget const* tgt = this->Makefile->FindTargetToUse(name);
@@ -6433,7 +3655,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
if(lib != item)
{
cmake* cm = this->Makefile->GetCMakeInstance();
- switch(this->PolicyStatusCMP0004)
+ switch(this->GetPolicyStatusCMP0004())
{
case cmPolicies::WARN:
{
@@ -6470,382 +3692,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const
return lib;
}
-template<typename PropertyType>
-PropertyType getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType,
- PropertyType *);
-
-template<>
-bool getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType, bool *)
-{
- return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
-}
-
-template<>
-const char * getLinkInterfaceDependentProperty(cmTarget const* tgt,
- const std::string& prop,
- const std::string& config,
- CompatibleType t,
- const char **)
-{
- switch(t)
- {
- case BoolType:
- assert(0 && "String compatibility check function called for boolean");
- return 0;
- case StringType:
- return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
- case NumberMinType:
- return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
- case NumberMaxType:
- return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
- }
- assert(0 && "Unreachable!");
- return 0;
-}
-
-//----------------------------------------------------------------------------
-template<typename PropertyType>
-void checkPropertyConsistency(cmTarget const* depender,
- cmTarget const* dependee,
- const std::string& propName,
- std::set<std::string> &emitted,
- const std::string& config,
- CompatibleType t,
- PropertyType *)
-{
- const char *prop = dependee->GetProperty(propName);
- if (!prop)
- {
- return;
- }
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
- std::string pdir =
- dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
- pdir += "/Help/prop_tgt/";
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
- {
- std::string pname = cmSystemTools::HelpFileName(*pi);
- std::string pfile = pdir + pname + ".rst";
- if(cmSystemTools::FileExists(pfile.c_str(), true))
- {
- std::ostringstream 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,
- t, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
- }
-}
-
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2)
-{
- std::set<std::string> intersect;
- std::set_intersection(s1.begin(),s1.end(),
- s2.begin(),s2.end(),
- std::inserter(intersect,intersect.begin()));
- if (!intersect.empty())
- {
- return *intersect.begin();
- }
- return "";
-}
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2,
- const std::set<std::string> &s3)
-{
- std::string result;
- result = intersect(s1, s2);
- if (!result.empty())
- return result;
- result = intersect(s1, s3);
- if (!result.empty())
- return result;
- return intersect(s2, s3);
-}
-static std::string intersect(const std::set<std::string> &s1,
- const std::set<std::string> &s2,
- const std::set<std::string> &s3,
- const std::set<std::string> &s4)
-{
- std::string result;
- result = intersect(s1, s2);
- if (!result.empty())
- return result;
- result = intersect(s1, s3);
- if (!result.empty())
- return result;
- result = intersect(s1, s4);
- if (!result.empty())
- return result;
- return intersect(s2, s3, s4);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const std::string& config) const
-{
- const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
- std::set<std::string> emittedBools;
- static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
- std::set<std::string> emittedStrings;
- static std::string strString = "COMPATIBLE_INTERFACE_STRING";
- std::set<std::string> emittedMinNumbers;
- static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
- std::set<std::string> emittedMaxNumbers;
- static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
-
- for(cmComputeLinkInformation::ItemVector::const_iterator li =
- deps.begin();
- li != deps.end(); ++li)
- {
- if (!li->Target)
- {
- continue;
- }
-
- checkPropertyConsistency<bool>(this, li->Target,
- strBool,
- emittedBools, config, BoolType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strString,
- emittedStrings, config,
- StringType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strNumMin,
- emittedMinNumbers, config,
- NumberMinType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- checkPropertyConsistency<const char *>(this, li->Target,
- strNumMax,
- emittedMaxNumbers, config,
- NumberMaxType, 0);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
-
- std::string prop = intersect(emittedBools,
- emittedStrings,
- emittedMinNumbers,
- emittedMaxNumbers);
-
- if (!prop.empty())
- {
- // Use a sorted std::vector to keep the error message sorted.
- std::vector<std::string> props;
- std::set<std::string>::const_iterator i = emittedBools.find(prop);
- if (i != emittedBools.end())
- {
- props.push_back(strBool);
- }
- i = emittedStrings.find(prop);
- if (i != emittedStrings.end())
- {
- props.push_back(strString);
- }
- i = emittedMinNumbers.find(prop);
- if (i != emittedMinNumbers.end())
- {
- props.push_back(strNumMin);
- }
- i = emittedMaxNumbers.find(prop);
- if (i != emittedMaxNumbers.end())
- {
- props.push_back(strNumMax);
- }
- std::sort(props.begin(), props.end());
-
- std::string propsString = cmJoin(cmRange(props).retreat(1), ", ");
- propsString += " and the " + props.back();
-
- std::ostringstream e;
- e << "Property \"" << prop << "\" appears in both the "
- << propsString <<
- " property in the dependencies of target \"" << this->GetName() <<
- "\". This is not allowed. A property may only require compatibility "
- "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
- "string interpretation, but not a mixture.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
-}
-
-//----------------------------------------------------------------------------
-cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const std::string& config) const
-{
- // Lookup any existing information for this configuration.
- std::string key(cmSystemTools::UpperCase(config));
- cmTargetLinkInformationMap::iterator
- i = this->LinkInformation.find(key);
- if(i == this->LinkInformation.end())
- {
- // Compute information for this configuration.
- cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config);
- 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 std::string& config,
- bool rootDir) const
-{
- std::string fpath;
- fpath += this->GetOutputName(config, false);
- fpath += ".framework";
- if(!rootDir)
- {
- fpath += "/Versions/";
- fpath += this->GetFrameworkVersion();
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetCFBundleDirectory(const std::string& config,
- bool contentOnly) const
-{
- std::string fpath;
- fpath += this->GetOutputName(config, false);
- fpath += ".";
- const char *ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext)
- {
- if (this->IsXCTestOnApple())
- {
- ext = "xctest";
- }
- else
- {
- ext = "bundle";
- }
- }
- fpath += ext;
- fpath += "/Contents";
- if(!contentOnly)
- fpath += "/MacOS";
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetAppBundleDirectory(const std::string& config,
- bool contentOnly) const
-{
- std::string fpath = this->GetFullName(config, false);
- fpath += ".app/Contents";
- if(!contentOnly)
- fpath += "/MacOS";
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::BuildMacContentDirectory(const std::string& base,
- const std::string& config,
- bool contentOnly) const
-{
- std::string fpath = base;
- if(this->IsAppBundleOnApple())
- {
- fpath += this->GetAppBundleDirectory(config, contentOnly);
- }
- if(this->IsFrameworkOnApple())
- {
- fpath += this->GetFrameworkDirectory(config, contentOnly);
- }
- if(this->IsCFBundleOnApple())
- {
- fpath += this->GetCFBundleDirectory(config, contentOnly);
- }
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetMacContentDirectory(const std::string& config,
- bool implib) const
-{
- // Start with the output directory for the target.
- std::string fpath = this->GetDirectory(config, implib);
- fpath += "/";
- bool contentOnly = true;
- if(this->IsFrameworkOnApple())
- {
- // additional files with a framework go into the version specific
- // directory
- contentOnly = false;
- }
- fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
- return fpath;
-}
-
-//----------------------------------------------------------------------------
-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()
-{
- cmDeleteAll(*this);
-}
-
//----------------------------------------------------------------------------
cmTargetInternalPointer::cmTargetInternalPointer()
{
@@ -6865,10 +3711,6 @@ cmTargetInternalPointer
//----------------------------------------------------------------------------
cmTargetInternalPointer::~cmTargetInternalPointer()
{
- cmDeleteAll(this->Pointer->IncludeDirectoriesEntries);
- cmDeleteAll(this->Pointer->CompileOptionsEntries);
- cmDeleteAll(this->Pointer->CompileFeaturesEntries);
- cmDeleteAll(this->Pointer->CompileDefinitionsEntries);
cmDeleteAll(this->Pointer->SourceEntries);
delete this->Pointer;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3eb9e7e..c86ec24 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -16,6 +16,7 @@
#include "cmPropertyMap.h"
#include "cmPolicies.h"
#include "cmListFileCache.h"
+#include "cmLinkItem.h"
#include <cmsys/auto_ptr.hxx>
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -52,41 +53,6 @@ class cmTarget;
class cmGeneratorTarget;
class cmTargetTraceDependencies;
-// Basic information about each link item.
-class cmLinkItem: public std::string
-{
- typedef std::string std_string;
-public:
- cmLinkItem(): std_string(), Target(0) {}
- cmLinkItem(const std_string& n,
- cmTarget const* t): std_string(n), Target(t) {}
- cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
- cmTarget const* Target;
-};
-class cmLinkImplItem: public cmLinkItem
-{
-public:
- cmLinkImplItem(): cmLinkItem(), Backtrace(0), FromGenex(false) {}
- cmLinkImplItem(std::string const& n,
- cmTarget const* t,
- cmListFileBacktrace const& bt,
- bool fromGenex):
- cmLinkItem(n, t), Backtrace(bt), FromGenex(fromGenex) {}
- cmLinkImplItem(cmLinkImplItem const& r):
- cmLinkItem(r), Backtrace(r.Backtrace), FromGenex(r.FromGenex) {}
- cmListFileBacktrace Backtrace;
- bool FromGenex;
-};
-
-struct cmTargetLinkInformationMap:
- public std::map<std::string, cmComputeLinkInformation*>
-{
- typedef std::map<std::string, cmComputeLinkInformation*> derived;
- cmTargetLinkInformationMap() {}
- cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
- ~cmTargetLinkInformationMap();
-};
-
class cmTargetInternals;
class cmTargetInternalPointer
{
@@ -144,7 +110,7 @@ public:
#define DECLARE_TARGET_POLICY(POLICY) \
cmPolicies::PolicyStatus GetPolicyStatus ## POLICY () const \
- { return this->PolicyStatus ## POLICY; }
+ { return this->PolicyMap.Get(cmPolicies::POLICY); }
CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
@@ -171,8 +137,6 @@ public:
*/
void GetSourceFiles(std::vector<cmSourceFile*> &files,
const std::string& config) const;
- bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
-
/**
* Add sources to the target.
*/
@@ -261,98 +225,19 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
void CheckProperty(const std::string& prop, cmMakefile* context) const;
- const char* GetFeature(const std::string& feature,
- const std::string& config) const;
- bool GetFeatureAsBool(const std::string& feature,
- const std::string& config) const;
-
bool IsImported() const {return this->IsImportedTarget;}
void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
- /** The link interface specifies transitive library dependencies and
- other information needed by targets that link to this target. */
- struct LinkInterfaceLibraries
- {
- // Libraries listed in the interface.
- std::vector<cmLinkItem> Libraries;
- };
- struct LinkInterface: public LinkInterfaceLibraries
- {
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
-
- // Shared library dependencies needed for linking on some platforms.
- std::vector<cmLinkItem> SharedDeps;
-
- // Number of repetitions of a strongly connected component of two
- // or more static libraries.
- int Multiplicity;
-
- // Libraries listed for other configurations.
- // Needed only for OLD behavior of CMP0003.
- std::vector<cmLinkItem> WrongConfigLibraries;
-
- 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 std::string& config,
- cmTarget const* headTarget) const;
- LinkInterfaceLibraries const*
- GetLinkInterfaceLibraries(const std::string& config,
- cmTarget const* headTarget,
- bool usage_requirements_only) const;
-
- std::vector<cmTarget const*> const&
- GetLinkImplementationClosure(const std::string& config) const;
-
- struct CompatibleInterfaces
- {
- std::set<std::string> PropsBool;
- std::set<std::string> PropsString;
- std::set<std::string> PropsNumberMax;
- std::set<std::string> PropsNumberMin;
- };
- CompatibleInterfaces const&
- GetCompatibleInterfaces(std::string const& config) const;
-
- /** The link implementation specifies the direct library
- dependencies needed by the object files of the target. */
- struct LinkImplementationLibraries
- {
- // Libraries linked directly in this configuration.
- std::vector<cmLinkImplItem> Libraries;
-
- // Libraries linked directly in other configurations.
- // Needed only for OLD behavior of CMP0003.
- std::vector<cmLinkItem> WrongConfigLibraries;
- };
- struct LinkImplementation: public LinkImplementationLibraries
- {
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
- };
- LinkImplementation const*
- GetLinkImplementation(const std::string& config) const;
-
- LinkImplementationLibraries const*
+ cmLinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const;
- /** Link information from the transitive closure of the link
- implementation and the interfaces of its dependencies. */
- struct LinkClosure
- {
- // The preferred linker language.
- std::string LinkerLanguage;
+ void ComputeLinkImplementationLibraries(const std::string& config,
+ cmOptionalLinkImplementation& impl,
+ cmTarget const* head) const;
- // Languages whose runtime libraries must be linked.
- std::vector<std::string> Languages;
- };
- LinkClosure const* GetLinkClosure(const std::string& config) const;
+ cmOptionalLinkImplementation&
+ GetLinkImplMap(std::string const& config) const;
cmTarget const* FindTargetToLink(std::string const& name) const;
@@ -373,20 +258,7 @@ public:
pdb output directory is given. */
std::string GetPDBDirectory(const std::string& config) const;
- /** Get the directory in which to place the target compiler .pdb file.
- If the configuration name is given then the generator will add its
- subdirectory for that configuration. Otherwise just the canonical
- compiler pdb output directory is given. */
- std::string GetCompilePDBDirectory(const std::string& config = "") const;
-
- /** Get the location of the target in the build tree for the given
- configuration. */
- const char* GetLocation(const std::string& config) const;
-
- /** Get the location of the target in the build tree with a placeholder
- referencing the configuration in the native build system. This
- location is suitable for use as the LOCATION target property. */
- const char* GetLocationForBuild() const;
+ const char* ImportedGetLocation(const std::string& config) const;
/** Get the target major and minor version numbers interpreted from
the VERSION property. Version 0 is returned if the property is
@@ -399,33 +271,6 @@ public:
void
GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
- ///! Return the preferred linker language for this target
- std::string GetLinkerLanguage(const std::string& config = "") const;
-
- /** Get the full name of the target according to the settings in its
- makefile. */
- std::string GetFullName(const std::string& config="",
- bool implib = false) const;
- void GetFullNameComponents(std::string& prefix,
- std::string& base, std::string& suffix,
- const std::string& config="",
- bool implib = false) const;
-
- /** Get the name of the pdb file for the target. */
- std::string GetPDBName(const std::string& config) const;
-
- /** Get the name of the compiler pdb file for the target. */
- std::string GetCompilePDBName(const std::string& config="") const;
-
- /** Get the path for the MSVC /Fd option for this target. */
- std::string GetCompilePDBPath(const std::string& config="") const;
-
- /** Whether this library has soname enabled and platform supports it. */
- bool HasSOName(const std::string& config) const;
-
- /** Get the soname of the target. Allowed only for a shared library. */
- std::string GetSOName(const std::string& config) const;
-
/** Whether this library has \@rpath and platform supports it. */
bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
@@ -436,26 +281,6 @@ public:
no soname at all. */
bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
- /** Get the full path to the target according to the settings in its
- makefile and the configuration type. */
- std::string GetFullPath(const std::string& config="", bool implib = false,
- bool realname = false) const;
-
- /** Get the names of the library needed to generate a build rule
- that takes into account shared library version numbers. This
- should be called only on a library target. */
- void GetLibraryNames(std::string& name, std::string& soName,
- std::string& realName, std::string& impName,
- std::string& pdbName, const std::string& config) const;
-
- /** Get the names of the executable needed to generate a build rule
- that takes into account executable version numbers. This should
- be called only on an executable target. */
- void GetExecutableNames(std::string& name, std::string& realName,
- std::string& impName,
- std::string& pdbName,
- const std::string& config) const;
-
/** Does this target have a GNU implib to convert to MS format? */
bool HasImplibGNUtoMS() const;
@@ -464,29 +289,8 @@ public:
bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
const char* newExt = 0) const;
- /**
- * Compute whether this target must be relinked before installing.
- */
- bool NeedRelinkBeforeInstall(const std::string& config) const;
-
- bool HaveBuildTreeRPATH(const std::string& config) const;
bool HaveInstallTreeRPATH() const;
- /** Return true if builtin chrpath will work for this target */
- bool IsChrpathUsed(const std::string& config) const;
-
- /** Return the install name directory for the target in the
- * build tree. For example: "\@rpath/", "\@loader_path/",
- * or "/full/path/to/library". */
- std::string GetInstallNameDirForBuildTree(const std::string& config) const;
-
- /** Return the install name directory for the target in the
- * install tree. For example: "\@rpath/" or "\@loader_path/". */
- std::string GetInstallNameDirForInstallTree() const;
-
- cmComputeLinkInformation*
- GetLinkInformation(const std::string& config) const;
-
// Get the properties
cmPropertyMap &GetProperties() const { return this->Properties; }
@@ -499,18 +303,6 @@ public:
If no macro should be defined null is returned. */
const char* GetExportMacro() const;
- void GetCompileDefinitions(std::vector<std::string> &result,
- const std::string& config,
- const std::string& language) const;
-
- // 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
- // information to forward these property changes to the targets
- // until we have per-target object file properties.
- void GetLanguages(std::set<std::string>& languages,
- std::string const& config) const;
-
/** Return whether this target is an executable with symbol exports
enabled. */
bool IsExecutableWithExports() const;
@@ -537,10 +329,6 @@ public:
/** Return whether this target is an executable Bundle on Apple. */
bool IsAppBundleOnApple() const;
- /** Return whether this target is an executable Bundle, a framework
- or CFBundle on Apple. */
- bool IsBundleOnApple() const;
-
/** Return the framework version string. Undefined if
IsFrameworkOnApple returns false. */
std::string GetFrameworkVersion() const;
@@ -555,86 +343,50 @@ public:
directory. */
bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
- /** @return the mac content directory for this target. */
- std::string GetMacContentDirectory(const std::string& config,
- bool implib) const;
-
/** @return whether this target have a well defined output file name. */
bool HaveWellDefinedOutputFiles() const;
- /** @return the Mac framework directory without the base. */
- std::string GetFrameworkDirectory(const std::string& config,
- bool rootDir) const;
-
- /** @return the Mac CFBundle directory without the base */
- std::string GetCFBundleDirectory(const std::string& config,
- bool contentOnly) const;
-
- /** @return the Mac App directory without the base */
- std::string GetAppBundleDirectory(const std::string& config,
- bool contentOnly) const;
-
- std::vector<std::string> GetIncludeDirectories(
- const std::string& config,
- const std::string& language) const;
- void InsertInclude(const cmValueWithOrigin &entry,
+ void InsertInclude(std::string const& entry,
+ cmListFileBacktrace const& bt,
bool before = false);
- void InsertCompileOption(const cmValueWithOrigin &entry,
- bool before = false);
- void InsertCompileDefinition(const cmValueWithOrigin &entry);
+ void InsertCompileOption(std::string const& entry,
+ cmListFileBacktrace const& bt,
+ bool before = false);
+ void InsertCompileDefinition(std::string const& entry,
+ cmListFileBacktrace const& bt);
void AppendBuildInterfaceIncludes();
- void GetCompileOptions(std::vector<std::string> &result,
- const std::string& config,
- const std::string& language) const;
- void GetAutoUicOptions(std::vector<std::string> &result,
- const std::string& config) const;
- void GetCompileFeatures(std::vector<std::string> &features,
- const std::string& config) const;
-
bool IsNullImpliedByLinkLibraries(const std::string &p) const;
- bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
- const std::string& config) const;
- bool IsLinkInterfaceDependentStringProperty(const std::string &p,
- const std::string& config) const;
- bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
- const std::string& config) const;
- bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
- const std::string& config) const;
-
- bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
- const std::string& config) const;
-
- const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
- const std::string& config) const;
- const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p,
- const std::string& config) const;
- const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
- const std::string& config) const;
std::string GetDebugGeneratorExpressions(const std::string &value,
cmTarget::LinkLibraryType llt) const;
void AddSystemIncludeDirectories(const std::set<std::string> &incs);
- void AddSystemIncludeDirectories(const std::vector<std::string> &incs);
std::set<std::string> const & GetSystemIncludeDirectories() const
{ return this->SystemIncludeDirectories; }
bool LinkLanguagePropagatesToDependents() const
{ return this->TargetTypeValue == STATIC_LIBRARY; }
- void ReportPropertyOrigin(const std::string &p,
- const std::string &result,
- const std::string &report,
- const std::string &compatibilityType) const;
-
std::map<std::string, std::string> const&
GetMaxLanguageStandards() const
{
return this->MaxLanguageStandards;
}
+ cmStringRange GetIncludeDirectoriesEntries() const;
+ cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+
+ cmStringRange GetCompileOptionsEntries() const;
+ cmBacktraceRange GetCompileOptionsBacktraces() const;
+
+ cmStringRange GetCompileFeaturesEntries() const;
+ cmBacktraceRange GetCompileFeaturesBacktraces() const;
+
+ cmStringRange GetCompileDefinitionsEntries() const;
+ cmBacktraceRange GetCompileDefinitionsBacktraces() const;
+
#if defined(_WIN32) && !defined(__CYGWIN__)
const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
return this->LinkLibrariesForVS6;}
@@ -643,12 +395,6 @@ public:
private:
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
- // The set of include directories that are marked as system include
- // directories.
- std::set<std::string> SystemIncludeDirectories;
-
- std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
-
#if defined(_WIN32) && !defined(__CYGWIN__)
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -704,11 +450,6 @@ private:
const char* GetSuffixVariableInternal(bool implib) const;
const char* GetPrefixVariableInternal(bool implib) const;
- std::string GetFullNameInternal(const std::string& config,
- bool implib) const;
- void GetFullNameInternal(const std::string& config, bool implib,
- std::string& outPrefix, std::string& outBase,
- std::string& outSuffix) const;
// Use a makefile variable to set a default for the given property.
// If the variable is not defined use the given default instead.
@@ -718,65 +459,53 @@ private:
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
const char* GetOutputTargetType(bool implib) const;
- // Get the target base name.
- std::string GetOutputName(const std::string& config, bool implib) const;
-
std::string GetFullNameImported(const std::string& config,
bool implib) const;
std::string ImportedGetFullPath(const std::string& config,
bool implib) const;
- std::string NormalGetFullPath(const std::string& config, bool implib,
- bool realname) const;
-
- /** Get the real name of the target. Allowed only for non-imported
- targets. When a library or executable file is versioned this is
- the full versioned name. If the target is not versioned this is
- the same as GetFullName. */
- std::string NormalGetRealName(const std::string& config) const;
- /** Append to @a base the mac content directory and return it. */
- std::string BuildMacContentDirectory(const std::string& base,
- const std::string& config,
- bool contentOnly) const;
void GetSourceFiles(std::vector<std::string> &files,
const std::string& config) const;
private:
+ mutable cmPropertyMap Properties;
+ std::set<std::string> SystemIncludeDirectories;
+ std::set<std::string> LinkDirectoriesEmmitted;
+ std::set<std::string> Utilities;
+ mutable std::set<std::string> LinkImplicitNullProperties;
+ std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
+ mutable std::map<std::string, std::string> MaxLanguageStandards;
+ cmPolicies::PolicyMap PolicyMap;
std::string Name;
+ std::string InstallPath;
+ std::string RuntimeInstallPath;
+ mutable std::string ExportMacro;
+ std::vector<std::string> LinkDirectories;
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
- TargetType TargetTypeValue;
+ std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
LinkLibraryVectorType PrevLinkedLibraries;
+ LinkLibraryVectorType OriginalLinkLibraries;
#if defined(_WIN32) && !defined(__CYGWIN__)
LinkLibraryVectorType LinkLibrariesForVS6;
- bool LinkLibrariesForVS6Analyzed;
#endif
- std::vector<std::string> LinkDirectories;
- std::set<std::string> LinkDirectoriesEmmitted;
+ cmMakefile* Makefile;
+ cmTargetInternalPointer Internal;
+ TargetType TargetTypeValue;
bool HaveInstallRule;
- std::string InstallPath;
- std::string RuntimeInstallPath;
- mutable std::string ExportMacro;
- std::set<std::string> Utilities;
- std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
bool RecordDependencies;
- mutable cmPropertyMap Properties;
- LinkLibraryVectorType OriginalLinkLibraries;
bool DLLPlatform;
bool IsAndroid;
bool IsApple;
bool IsImportedTarget;
- mutable bool DebugIncludesDone;
- mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
- mutable bool DebugCompileOptionsDone;
- mutable bool DebugCompileDefinitionsDone;
- mutable bool DebugSourcesDone;
- mutable bool DebugCompileFeaturesDone;
- mutable std::set<std::string> LinkImplicitNullProperties;
- mutable std::map<std::string, std::string> MaxLanguageStandards;
bool BuildInterfaceIncludesAppended;
+ mutable bool DebugSourcesDone;
+ mutable bool LinkImplementationLanguageIsContextDependent;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ bool LinkLibrariesForVS6Analyzed;
+#endif
// Cache target output paths for each configuration.
struct OutputInfo;
@@ -788,35 +517,27 @@ private:
std::string& out) const;
// Cache import information from properties for each configuration.
- struct ImportInfo;
+ struct ImportInfo
+ {
+ ImportInfo(): NoSOName(false), Multiplicity(0) {}
+ bool NoSOName;
+ int Multiplicity;
+ std::string Location;
+ std::string SOName;
+ std::string ImportLibrary;
+ std::string Languages;
+ std::string Libraries;
+ std::string LibrariesProp;
+ std::string SharedDeps;
+ };
+
ImportInfo const* GetImportInfo(const std::string& config) const;
void ComputeImportInfo(std::string const& desired_config,
ImportInfo& info) const;
- // Cache target compile paths for each configuration.
- struct CompileInfo;
- CompileInfo const* GetCompileInfo(const std::string& config) const;
-
- mutable cmTargetLinkInformationMap LinkInformation;
- void CheckPropertyCompatibility(cmComputeLinkInformation *info,
- const std::string& config) const;
-
- LinkInterface const*
- GetImportLinkInterface(const std::string& config, cmTarget const* head,
- bool usage_requirements_only) const;
-
- LinkImplementationLibraries const*
+ cmLinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const;
- void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
-
- void ExpandLinkItems(std::string const& prop, std::string const& value,
- std::string const& config, cmTarget const* headTarget,
- bool usage_requirements_only,
- std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const;
- void LookupLinkItems(std::vector<std::string> const& names,
- std::vector<cmLinkItem>& items) const;
std::string ProcessSourceItemCMP0049(const std::string& s);
@@ -824,25 +545,10 @@ private:
void MaybeInvalidatePropertyCache(const std::string& prop);
- void ProcessSourceExpression(std::string const& expr);
-
- // The cmMakefile instance that owns this target. This should
- // always be set.
- cmMakefile* Makefile;
-
- // Policy status recorded when target was created.
-#define TARGET_POLICY_MEMBER(POLICY) \
- cmPolicies::PolicyStatus PolicyStatus ## POLICY;
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_MEMBER)
-
-#undef TARGET_POLICY_MEMBER
-
// Internal representation details.
friend class cmTargetInternals;
friend class cmGeneratorTarget;
friend class cmTargetTraceDependencies;
- cmTargetInternalPointer Internal;
void ComputeVersionedName(std::string& vName,
std::string const& prefix,
@@ -850,8 +556,6 @@ private:
std::string const& suffix,
std::string const& name,
const char* version) const;
-
- mutable bool LinkImplementationLanguageIsContextDependent;
};
#ifdef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index a85153d..8e86f0f 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -50,7 +50,6 @@ bool cmTargetCompileOptionsCommand
bool, bool)
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmValueWithOrigin entry(this->Join(content), lfbt);
- tgt->InsertCompileOption(entry);
+ tgt->InsertCompileOption(this->Join(content), lfbt);
return true;
}
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 1feb072..c5059ee 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -14,23 +14,24 @@
#include "cmStandardIncludes.h"
-class cmTarget;
+class cmGeneratorTarget;
/** One edge in the global target dependency graph.
It may be marked as a 'link' or 'util' edge or both. */
class cmTargetDepend
{
- cmTarget const* Target;
+ cmGeneratorTarget const* Target;
// The set order depends only on the Target, so we use
// mutable members to acheive a map with set syntax.
mutable bool Link;
mutable bool Util;
public:
- cmTargetDepend(cmTarget const* t): Target(t), Link(false), Util(false) {}
- operator cmTarget const*() const { return this->Target; }
- cmTarget const* operator->() const { return this->Target; }
- cmTarget const& operator*() const { return *this->Target; }
+ cmTargetDepend(cmGeneratorTarget const* t)
+ : Target(t), Link(false), Util(false) {}
+ operator cmGeneratorTarget const*() const { return this->Target; }
+ cmGeneratorTarget const* operator->() const { return this->Target; }
+ cmGeneratorTarget const& operator*() const { return *this->Target; }
friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r)
{ return l.Target < r.Target; }
void SetType(bool strong) const
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 24500db..7dfe9ca 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -72,11 +72,26 @@ bool cmTargetIncludeDirectoriesCommand
bool prepend, bool system)
{
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- cmValueWithOrigin entry(this->Join(content), lfbt);
- tgt->InsertInclude(entry, prepend);
+ tgt->InsertInclude(this->Join(content), lfbt, prepend);
if (system)
{
- tgt->AddSystemIncludeDirectories(content);
+ std::string prefix =
+ this->Makefile->GetCurrentSourceDirectory() + std::string("/");
+ std::set<std::string> sdirs;
+ for (std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ if (cmSystemTools::FileIsFullPath(it->c_str())
+ || cmGeneratorExpression::Find(*it) == 0)
+ {
+ sdirs.insert(*it);
+ }
+ else
+ {
+ sdirs.insert(prefix + *it);
+ }
+ }
+ tgt->AddSystemIncludeDirectories(sdirs);
}
return true;
}
@@ -92,7 +107,7 @@ void cmTargetIncludeDirectoriesCommand
if (system)
{
- std::string joined = cmJoin(content, ";");
+ std::string joined = this->Join(content);
tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
joined.c_str());
}
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index ff5d411..6fcd0dc 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -21,7 +21,6 @@ cmTest::cmTest(cmMakefile* mf)
{
this->Makefile = mf;
this->OldStyle = true;
- this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
}
//----------------------------------------------------------------------------
@@ -50,12 +49,15 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
//----------------------------------------------------------------------------
const char *cmTest::GetProperty(const std::string& prop) const
{
- bool chain = false;
- const char *retVal =
- this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain);
- if (chain)
+ const char *retVal = this->Properties.GetPropertyValue(prop);
+ if (!retVal)
{
- return this->Makefile->GetProperty(prop,cmProperty::TEST);
+ const bool chain = this->Makefile->GetState()->
+ IsPropertyChained(prop, cmProperty::TEST);
+ if (chain)
+ {
+ return this->Makefile->GetProperty(prop, chain);
+ }
}
return retVal;
}
@@ -69,12 +71,12 @@ bool cmTest::GetPropertyAsBool(const std::string& prop) const
//----------------------------------------------------------------------------
void cmTest::SetProperty(const std::string& prop, const char* value)
{
- this->Properties.SetProperty(prop, value, cmProperty::TEST);
+ this->Properties.SetProperty(prop, value);
}
//----------------------------------------------------------------------------
void cmTest::AppendProperty(const std::string& prop,
const char* value, bool asString)
{
- this->Properties.AppendProperty(prop, value, cmProperty::TEST, asString);
+ this->Properties.AppendProperty(prop, value, asString);
}
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 7e11d8c..9d85f5a 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -12,8 +12,9 @@
#include "cmTestGenerator.h"
#include "cmGeneratorExpression.h"
-#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
@@ -27,6 +28,7 @@ cmTestGenerator
{
this->ActionsPerConfig = !test->GetOldStyle();
this->TestGenerated = false;
+ this->LG = 0;
}
//----------------------------------------------------------------------------
@@ -35,6 +37,11 @@ cmTestGenerator
{
}
+void cmTestGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LG = lg;
+}
+
//----------------------------------------------------------------------------
void cmTestGenerator::GenerateScriptConfigs(std::ostream& os,
Indent const& indent)
@@ -70,7 +77,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
this->TestGenerated = true;
// Set up generator expression evaluation context.
- cmGeneratorExpression ge(&this->Test->GetBacktrace());
+ cmGeneratorExpression ge(this->Test->GetBacktrace());
// Start the test command.
os << indent << "add_test(" << this->Test->GetName() << " ";
@@ -81,8 +88,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Check whether the command executable is a target whose name is to
// be translated.
std::string exe = command[0];
- cmMakefile* mf = this->Test->GetMakefile();
- cmTarget* target = mf->FindTargetToUse(exe);
+ cmGeneratorTarget* target =
+ this->LG->GetMakefile()->FindGeneratorTargetToUse(exe);
if(target && target->GetType() == cmTarget::EXECUTABLE)
{
// Use the target file on disk.
@@ -97,30 +104,31 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
- os << cmLocalGenerator::EscapeForCMake(emulatorExe) << " ";
+ os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
for(std::vector<std::string>::const_iterator ei =
emulatorWithArgs.begin()+1;
ei != emulatorWithArgs.end();
++ei)
{
- os << cmLocalGenerator::EscapeForCMake(*ei) << " ";
+ os << cmOutputConverter::EscapeForCMake(*ei) << " ";
}
}
}
else
{
// Use the command name given.
- exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
+ exe = ge.Parse(exe.c_str())->Evaluate(this->LG->GetMakefile(), config);
cmSystemTools::ConvertToUnixSlashes(exe);
}
// Generate the command line with full escapes.
- os << cmLocalGenerator::EscapeForCMake(exe);
+ os << cmOutputConverter::EscapeForCMake(exe);
for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci)
{
- os << " " << cmLocalGenerator::EscapeForCMake(
- ge.Parse(*ci)->Evaluate(mf, config));
+ os << " " << cmOutputConverter::EscapeForCMake(
+ ge.Parse(*ci)->Evaluate(
+ this->LG->GetMakefile(), config));
}
// Finish the test command.
@@ -136,8 +144,9 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
i != pm.end(); ++i)
{
os << " " << i->first
- << " " << cmLocalGenerator::EscapeForCMake(
- ge.Parse(i->second.GetValue())->Evaluate(mf, config));
+ << " " << cmOutputConverter::EscapeForCMake(
+ ge.Parse(i->second.GetValue())->Evaluate(this->LG->GetMakefile(),
+ config));
}
os << ")" << std::endl;
}
@@ -206,7 +215,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
i != pm.end(); ++i)
{
fout << " " << i->first
- << " " << cmLocalGenerator::EscapeForCMake(i->second.GetValue());
+ << " " << cmOutputConverter::EscapeForCMake(i->second.GetValue());
}
fout << ")" << std::endl;
}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 5446553..de8ab78 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -15,6 +15,7 @@
#include "cmScriptGenerator.h"
class cmTest;
+class cmLocalGenerator;
/** \class cmTestGenerator
* \brief Support class for generating install scripts.
@@ -28,6 +29,8 @@ public:
configurations = std::vector<std::string>());
virtual ~cmTestGenerator();
+ void Compute(cmLocalGenerator* lg);
+
protected:
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
@@ -38,6 +41,7 @@ protected:
virtual bool NeedsScriptNoConfig() const;
void GenerateOldStyle(std::ostream& os, Indent const& indent);
+ cmLocalGenerator* LG;
cmTest* Test;
bool TestGenerated;
};
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 9473008..98a397c 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -49,30 +49,26 @@ static void cmVariableWatchCommandVariableAccessed(
newLFF.Arguments.clear();
newLFF.Arguments.push_back(
cmListFileArgument(variable, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(accessString, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(newValue?newValue:"", cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(currentListFile, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Arguments.push_back(
cmListFileArgument(stack, cmListFileArgument::Quoted,
- "unknown", 9999));
+ 9999));
newLFF.Name = data->Command;
- newLFF.FilePath = "Some weird path";
newLFF.Line = 9999;
cmExecutionStatus status;
if(!makefile->ExecuteCommand(newLFF,status))
{
- arg.FilePath = "Unknown";
- arg.Line = 0;
std::ostringstream error;
- error << "Error in cmake code at\n"
- << arg.FilePath << ":" << arg.Line << ":\n"
+ error << "Error in cmake code at\nUnknown:0:\n"
<< "A command failed during the invocation of callback \""
<< data->Command << "\".";
cmSystemTools::Error(error.str().c_str());
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 5dfdb14..4c380f7 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -176,9 +176,8 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
this->Makefile->GetConfigurations(this->Configurations);
this->LocalGenerator =
(cmLocalVisualStudio7Generator*)
- this->Makefile->GetLocalGenerator();
+ this->GeneratorTarget->GetLocalGenerator();
this->Name = this->Target->GetName();
- this->GlobalGenerator->CreateGUID(this->Name.c_str());
this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
this->Platform = gg->GetPlatformName();
this->NsightTegra = gg->IsNsightTegra();
@@ -325,12 +324,22 @@ void cmVisualStudio10TargetGenerator::Generate()
if(this->NsightTegra)
{
this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1);
- if(this->NsightTegraVersion[0] >= 2)
+ const int nsightTegraMajorVersion = this->NsightTegraVersion[0];
+ const int nsightTegraMinorVersion = this->NsightTegraVersion[1];
+ if (nsightTegraMajorVersion >= 2)
{
- // Nsight Tegra 2.0 uses project revision 9.
- this->WriteString("<NsightTegraProjectRevisionNumber>"
- "9"
- "</NsightTegraProjectRevisionNumber>\n", 2);
+ this->WriteString("<NsightTegraProjectRevisionNumber>", 2);
+ if (nsightTegraMajorVersion > 3 ||
+ (nsightTegraMajorVersion == 3 && nsightTegraMinorVersion >= 1))
+ {
+ (*this->BuildFileStream) << "11";
+ }
+ else
+ {
+ // Nsight Tegra 2.0 uses project revision 9.
+ (*this->BuildFileStream) << "9";
+ }
+ (*this->BuildFileStream) << "</NsightTegraProjectRevisionNumber>\n";
// Tell newer versions to upgrade silently when loading.
this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>"
"true"
@@ -788,6 +797,20 @@ void cmVisualStudio10TargetGenerator
(*this->BuildFileStream ) <<
"android-" << cmVS10EscapeXML(api) << "</AndroidTargetAPI>\n";
}
+
+ if(const char* cpuArch = this->Target->GetProperty("ANDROID_ARCH"))
+ {
+ this->WriteString("<AndroidArch>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(cpuArch) <<
+ "</AndroidArch>\n";
+ }
+
+ if(const char* stlType = this->Target->GetProperty("ANDROID_STL_TYPE"))
+ {
+ this->WriteString("<AndroidStlType>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(stlType) <<
+ "</AndroidStlType>\n";
+ }
}
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
@@ -867,7 +890,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile const* source,
i = this->Configurations.begin();
i != this->Configurations.end(); ++i)
{
- cmCustomCommandGenerator ccg(command, *i, this->Makefile);
+ cmCustomCommandGenerator ccg(command, *i, this->LocalGenerator);
std::string comment = lg->ConstructComment(ccg);
comment = cmVS10EscapeComment(comment);
std::string script =
@@ -923,10 +946,7 @@ cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path,
return forceRelative
? cmSystemTools::RelativePath(
this->Makefile->GetCurrentBinaryDirectory(), path.c_str())
- : this->LocalGenerator->Convert(path.c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED,
- /* optional = */ true);
+ : path.c_str();
}
void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
@@ -945,7 +965,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::vector<cmSourceGroup> sourceGroups =
this->Makefile->GetSourceGroups();
std::vector<cmSourceFile*> classes;
- if (!this->Target->GetConfigCommonSourceFiles(classes))
+ if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes))
{
return;
}
@@ -1084,7 +1104,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
(*this->BuildFileStream) << name << "\">\n";
std::string guidName = "SG_Filter_";
guidName += name;
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid
= this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1099,7 +1118,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
std::string guidName = "SG_Filter_Object Libraries";
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid =
this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1112,7 +1130,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
std::string guidName = "SG_Filter_Resource Files";
- this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid =
this->GlobalGenerator->GetGUID(guidName.c_str());
@@ -1610,7 +1627,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
this->GlobalGenerator->GetLanguageFromExtension
(sf.GetExtension().c_str());
std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
- const std::string& linkLanguage = this->Target->GetLinkerLanguage();
+ const std::string& linkLanguage = this->GeneratorTarget->GetLinkerLanguage();
bool needForceLang = false;
// source file does not match its extension language
if(lang != sourceLang)
@@ -1639,7 +1656,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// for the first time we need a new line if there is something
// produced here.
const char* firstString = ">\n";
- if(objectName.size())
+ if(!objectName.empty())
{
(*this->BuildFileStream ) << firstString;
firstString = "";
@@ -1658,7 +1675,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
defPropName += configUpper;
if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
{
- if(configDefines.size())
+ if(!configDefines.empty())
{
configDefines += ";";
}
@@ -1757,7 +1774,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
else
{
outDir = this->Target->GetDirectory(config->c_str()) + "/";
- targetNameFull = this->Target->GetFullName(config->c_str());
+ targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
}
this->ConvertToWindowsSlash(intermediateDir);
this->ConvertToWindowsSlash(outDir);
@@ -1871,7 +1888,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string flags;
const std::string& linkLanguage =
- this->Target->GetLinkerLanguage(configName.c_str());
+ this->GeneratorTarget->GetLinkerLanguage(configName.c_str());
if(linkLanguage.empty())
{
cmSystemTools::Error
@@ -1917,7 +1934,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
- this->Target->GetCompileDefinitions(targetDefines,
+ this->GeneratorTarget->GetCompileDefinitions(targetDefines,
configName.c_str(), "CXX");
clOptions.AddDefines(targetDefines);
if(this->MSTools)
@@ -1985,6 +2002,17 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
"\n", "CXX");
+ if(this->NsightTegra)
+ {
+ if(const char* processMax =
+ this->Target->GetProperty("ANDROID_PROCESS_MAX"))
+ {
+ this->WriteString("<ProcessMax>", 3);
+ *this->BuildFileStream << cmVS10EscapeXML(processMax) <<
+ "</ProcessMax>\n";
+ }
+ }
+
if(this->MSTools)
{
this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
@@ -1998,7 +2026,8 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
}
// Specify the compiler program database file if configured.
- std::string pdb = this->Target->GetCompilePDBPath(configName.c_str());
+ std::string pdb =
+ this->GeneratorTarget->GetCompilePDBPath(configName.c_str());
if(!pdb.empty())
{
this->ConvertToWindowsSlash(pdb);
@@ -2177,7 +2206,7 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
//----------------------------------------------------------------------------
void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
- std::string const&)
+ std::string const& configName)
{
// Look through the sources for AndroidManifest.xml and use
// its location as the root source directory.
@@ -2207,6 +2236,92 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
cmVS10EscapeXML(antBuildPath) << "</AntBuildPath>\n";
}
+ if (this->Target->GetPropertyAsBool("ANDROID_SKIP_ANT_STEP"))
+ {
+ this->WriteString("<SkipAntStep>true</SkipAntStep>\n", 3);
+ }
+
+ if (this->Target->GetPropertyAsBool("ANDROID_PROGUARD"))
+ {
+ this->WriteString("<EnableProGuard>true</EnableProGuard>\n", 3);
+ }
+
+ if (const char* proGuardConfigLocation =
+ this->Target->GetProperty("ANDROID_PROGUARD_CONFIG_PATH"))
+ {
+ this->WriteString("<ProGuardConfigLocation>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(proGuardConfigLocation) <<
+ "</ProGuardConfigLocation>\n";
+ }
+
+ if (const char* securePropertiesLocation =
+ this->Target->GetProperty("ANDROID_SECURE_PROPS_PATH"))
+ {
+ this->WriteString("<SecurePropertiesLocation>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(securePropertiesLocation) <<
+ "</SecurePropertiesLocation>\n";
+ }
+
+ if (const char* nativeLibDirectoriesExpression =
+ this->Target->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(nativeLibDirectoriesExpression);
+ std::string nativeLibDirs = cge->Evaluate(this->Makefile, configName);
+ this->WriteString("<NativeLibDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDirs) <<
+ "</NativeLibDirectories>\n";
+ }
+
+ if (const char* nativeLibDependenciesExpression =
+ this->Target->GetProperty("ANDROID_NATIVE_LIB_DEPENDENCIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(nativeLibDependenciesExpression);
+ std::string nativeLibDeps = cge->Evaluate(this->Makefile, configName);
+ this->WriteString("<NativeLibDependencies>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDeps) <<
+ "</NativeLibDependencies>\n";
+ }
+
+ if (const char* javaSourceDir =
+ this->Target->GetProperty("ANDROID_JAVA_SOURCE_DIR"))
+ {
+ this->WriteString("<JavaSourceDir>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(javaSourceDir) <<
+ "</JavaSourceDir>\n";
+ }
+
+ if (const char* jarDirectoriesExpression =
+ this->Target->GetProperty("ANDROID_JAR_DIRECTORIES"))
+ {
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(jarDirectoriesExpression);
+ std::string jarDirectories = cge->Evaluate(this->Makefile, configName);
+ this->WriteString("<JarDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(jarDirectories) <<
+ "</JarDirectories>\n";
+ }
+
+ if (const char* jarDeps =
+ this->Target->GetProperty("ANDROID_JAR_DEPENDENCIES"))
+ {
+ this->WriteString("<JarDependencies>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(jarDeps) <<
+ "</JarDependencies>\n";
+ }
+
+ if (const char* assetsDirectories =
+ this->Target->GetProperty("ANDROID_ASSETS_DIRECTORIES"))
+ {
+ this->WriteString("<AssetsDirectories>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(assetsDirectories) <<
+ "</AssetsDirectories>\n";
+ }
+
{
std::string manifest_xml = rootDir + "/AndroidManifest.xml";
this->ConvertToWindowsSlash(manifest_xml);
@@ -2215,6 +2330,14 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
cmVS10EscapeXML(manifest_xml) << "</AndroidManifestLocation>\n";
}
+ if (const char* antAdditionalOptions =
+ this->Target->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS"))
+ {
+ this->WriteString("<AdditionalOptions>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(antAdditionalOptions) <<
+ " %(AdditionalOptions)</AdditionalOptions>\n";
+ }
+
this->WriteString("</AntBuild>\n", 2);
}
@@ -2248,7 +2371,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
Options& linkOptions = *pOptions;
const std::string& linkLanguage =
- this->Target->GetLinkerLanguage(config.c_str());
+ this->GeneratorTarget->GetLinkerLanguage(config.c_str());
if(linkLanguage.empty())
{
cmSystemTools::Error
@@ -2299,7 +2422,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
// Remove trailing spaces from libs
std::string::size_type pos = libs.size()-1;
- if(libs.size() != 0)
+ if(!libs.empty())
{
while(libs[pos] == ' ')
{
@@ -2316,7 +2439,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
cmSystemTools::ExpandListArgument(libs, libVec);
cmComputeLinkInformation* pcli =
- this->Target->GetLinkInformation(config.c_str());
+ this->GeneratorTarget->GetLinkInformation(config.c_str());
if(!pcli)
{
cmSystemTools::Error
@@ -2349,13 +2472,14 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
std::string targetNamePDB;
if(this->Target->GetType() == cmTarget::EXECUTABLE)
{
- this->Target->GetExecutableNames(targetName, targetNameFull,
+ this->GeneratorTarget->GetExecutableNames(targetName, targetNameFull,
targetNameImport, targetNamePDB,
config.c_str());
}
else
{
- this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ this->GeneratorTarget->GetLibraryNames(targetName, targetNameSO,
+ targetNameFull,
targetNameImport, targetNamePDB,
config.c_str());
}
@@ -2473,6 +2597,15 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
"%(IgnoreSpecificDefaultLibraries)");
}
+ if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
+ }
+ }
+
this->LinkOptions[config] = pOptions.release();
return true;
}
@@ -2620,8 +2753,25 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
void
cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
{
- this->WriteEvent("PreLinkEvent",
- this->Target->GetPreLinkCommands(), configName);
+ bool addedPrelink = false;
+ if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+ {
+ addedPrelink = true;
+ std::vector<cmCustomCommand> commands =
+ this->Target->GetPreLinkCommands();
+ this->GlobalGenerator->AddSymbolExportCommand(
+ this->GeneratorTarget, commands, configName);
+ this->WriteEvent("PreLinkEvent", commands, configName);
+ }
+ }
+ if (!addedPrelink)
+ {
+ this->WriteEvent("PreLinkEvent",
+ this->Target->GetPreLinkCommands(), configName);
+ }
this->WriteEvent("PreBuildEvent",
this->Target->GetPreBuildCommands(), configName);
this->WriteEvent("PostBuildEvent",
@@ -2633,7 +2783,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
std::vector<cmCustomCommand> const& commands,
std::string const& configName)
{
- if(commands.size() == 0)
+ if(commands.empty())
{
return;
}
@@ -2646,7 +2796,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
- cmCustomCommandGenerator ccg(*i, configName, this->Makefile);
+ cmCustomCommandGenerator ccg(*i, configName, this->LocalGenerator);
comment += pre;
comment += lg->ConstructComment(ccg);
script += pre;
@@ -2667,7 +2817,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
void cmVisualStudio10TargetGenerator::WriteProjectReferences()
{
cmGlobalGenerator::TargetDependSet const& unordered
- = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);
+ = this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget);
typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
OrderedTargetDependSet;
OrderedTargetDependSet depends(unordered);
@@ -2675,7 +2825,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
for( OrderedTargetDependSet::const_iterator i = depends.begin();
i != depends.end(); ++i)
{
- cmTarget const* dt = *i;
+ cmTarget const* dt = (*i)->Target;
if(dt->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
@@ -2743,7 +2893,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
(*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) <<
"\\</AppxPackageArtifactsDir>\n";
this->WriteString("<ProjectPriFullPath>"
- "$(TargetDir)resources.pri</ProjectPriFullPath>", 2);
+ "$(TargetDir)resources.pri</ProjectPriFullPath>\n", 2);
// If we are missing files and we don't have a certificate and
// aren't targeting WP8.0, add a default certificate
@@ -2761,6 +2911,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
this->WriteString("<", 2);
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
<< pfxFile << "</PackageCertificateKeyFile>\n";
+ std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ if (!thumb.empty())
+ {
+ this->WriteString("<PackageCertificateThumbprint>", 2);
+ (*this->BuildFileStream) << thumb
+ << "</PackageCertificateThumbprint>\n";
+ }
this->WriteString("</PropertyGroup>\n", 1);
}
else if(!pfxFile.empty())
@@ -2769,6 +2926,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile()
this->WriteString("<", 2);
(*this->BuildFileStream) << "PackageCertificateKeyFile>"
<< pfxFile << "</PackageCertificateKeyFile>\n";
+ std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile);
+ if (!thumb.empty())
+ {
+ this->WriteString("<PackageCertificateThumbprint>", 2);
+ (*this->BuildFileStream) << thumb
+ << "</PackageCertificateThumbprint>\n";
+ }
this->WriteString("</PropertyGroup>\n", 1);
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 6512fc2..bd4eb69 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -1,6 +1,6 @@
#include "cmVisualStudioGeneratorOptions.h"
+#include "cmOutputConverter.h"
#include "cmSystemTools.h"
-#include <cmsys/System.h>
#include "cmVisualStudio10TargetGenerator.h"
static
@@ -246,10 +246,10 @@ void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
// This option is not known. Store it in the output flags.
this->FlagString += " ";
this->FlagString +=
- cmSystemTools::EscapeWindowsShellArgument(
+ cmOutputConverter::EscapeWindowsShellArgument(
flag,
- cmsysSystem_Shell_Flag_AllowMakeVariables |
- cmsysSystem_Shell_Flag_VSIDE);
+ cmOutputConverter::Shell_Flag_AllowMakeVariables |
+ cmOutputConverter::Shell_Flag_VSIDE);
}
//----------------------------------------------------------------------------
@@ -274,7 +274,7 @@ cmVisualStudioGeneratorOptions
{
// if there are configuration specific flags, then
// use the configuration specific tag for PreprocessorDefinitions
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
fout << prefix;
this->TargetGenerator->WritePlatformConfigTag(
@@ -346,7 +346,7 @@ cmVisualStudioGeneratorOptions
m != this->FlagMap.end(); ++m)
{
fout << indent;
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
this->TargetGenerator->WritePlatformConfigTag(
m->first.c_str(),
@@ -398,7 +398,7 @@ cmVisualStudioGeneratorOptions
if(this->Version >= cmGlobalVisualStudioGenerator::VS10)
{
fout << prefix;
- if(this->Configuration.size())
+ if(!this->Configuration.empty())
{
this->TargetGenerator->WritePlatformConfigTag(
"AdditionalOptions",
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index f30f700..3973540 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -22,7 +22,7 @@ cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
//----------------------------------------------------------------------------
void cmXCode21Object::PrintComment(std::ostream& out)
{
- if(this->Comment.size() == 0)
+ if(this->Comment.empty())
{
cmXCodeObject* n = this->GetObject("name");
if(n)
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index ba6e395..c59c360 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -243,7 +243,11 @@ void cmXCodeObject::PrintString(std::ostream& os,std::string String)
bool needQuote =
(String.empty() ||
String.find("//") != String.npos ||
- String.find_first_of(" <>+-*=@[](){},~") != String.npos);
+ String.find_first_not_of(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "$_./") != String.npos);
const char* quote = needQuote? "\"" : "";
// Print the string, quoted and escaped as necessary.
diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx
index 99f5625..4ad05ca 100644
--- a/Source/cmXMLSafe.cxx
+++ b/Source/cmXMLSafe.cxx
@@ -13,8 +13,8 @@
#include "cm_utf8.h"
-#include <cmsys/ios/iostream>
-#include <cmsys/ios/sstream>
+#include <iostream>
+#include <sstream>
#include <string.h>
#include <stdio.h>
@@ -45,13 +45,13 @@ cmXMLSafe& cmXMLSafe::Quotes(bool b)
//----------------------------------------------------------------------------
std::string cmXMLSafe::str()
{
- cmsys_ios::ostringstream ss;
+ std::ostringstream ss;
ss << *this;
return ss.str();
}
//----------------------------------------------------------------------------
-cmsys_ios::ostream& operator<<(cmsys_ios::ostream& os, cmXMLSafe const& self)
+std::ostream& operator<<(std::ostream& os, cmXMLSafe const& self)
{
char const* first = self.Data;
char const* last = self.Data + self.Size;
diff --git a/Source/cmXMLSafe.h b/Source/cmXMLSafe.h
index c23a90c..ead2e01 100644
--- a/Source/cmXMLSafe.h
+++ b/Source/cmXMLSafe.h
@@ -12,8 +12,9 @@
#ifndef cmXMLSafe_h
#define cmXMLSafe_h
-#include <cmsys/stl/string>
-#include <cmsys/ios/iosfwd>
+#include <cmsys/Configure.hxx>
+#include <string>
+#include <iosfwd>
/** \class cmXMLSafe
* \brief Write strings to XML with proper escapes
@@ -37,8 +38,7 @@ private:
char const* Data;
unsigned long Size;
bool DoQuotes;
- friend cmsys_ios::ostream& operator<<(cmsys_ios::ostream&,
- cmXMLSafe const&);
+ friend std::ostream& operator<<(std::ostream&, cmXMLSafe const&);
};
#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 23803ef..f069481 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -75,7 +75,9 @@
# include "cmGlobalWatcomWMakeGenerator.h"
#endif
#include "cmGlobalUnixMakefileGenerator3.h"
-#include "cmGlobalNinjaGenerator.h"
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmGlobalNinjaGenerator.h"
+#endif
#include "cmExtraCodeLiteGenerator.h"
#if !defined(CMAKE_BOOT_MINGW)
@@ -121,20 +123,18 @@ void cmWarnUnusedCliWarning(const std::string& variable,
cmake::cmake()
{
this->Trace = false;
+ this->TraceExpand = false;
this->WarnUninitialized = false;
this->WarnUnused = false;
this->WarnUnusedCli = true;
this->CheckSystemVars = false;
- this->SuppressDevWarnings = false;
- this->DoSuppressDevWarnings = false;
this->DebugOutput = false;
this->DebugTryCompile = false;
this->ClearBuildSystem = false;
this->FileComparison = new cmFileTimeComparison;
- this->Policies = new cmPolicies();
this->State = new cmState(this);
- this->CurrentSnapshot = this->State->CreateSnapshot(cmState::Snapshot());
+ this->CurrentSnapshot = this->State->CreateBaseSnapshot();
#ifdef __APPLE__
struct rlimit rlp;
@@ -170,7 +170,6 @@ cmake::cmake()
cmake::~cmake()
{
delete this->CacheManager;
- delete this->Policies;
delete this->State;
if (this->GlobalGenerator)
{
@@ -186,7 +185,7 @@ cmake::~cmake()
void cmake::CleanupCommandsAndMacros()
{
- this->State->Reset();
+ this->CurrentSnapshot = this->State->Reset();
this->State->RemoveUserDefinedCommands();
}
@@ -251,15 +250,70 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- else if(arg.find("-Wno-dev",0) == 0)
+ else if(cmHasLiteralPrefix(arg, "-W"))
{
- this->SuppressDevWarnings = true;
- this->DoSuppressDevWarnings = true;
+ std::string entry = arg.substr(2);
+ if (entry.empty())
+ {
+ ++i;
+ if (i < args.size())
+ {
+ entry = args[i];
+ }
+ else
+ {
+ cmSystemTools::Error(
+ "-W must be followed with [no-][error=]<name>.");
+ return false;
+ }
}
- else if(arg.find("-Wdev",0) == 0)
- {
- this->SuppressDevWarnings = false;
- this->DoSuppressDevWarnings = true;
+
+ std::string name;
+ bool foundNo = false;
+ bool foundError = false;
+ unsigned int nameStartPosition = 0;
+
+ if (entry.find("no-", nameStartPosition) == 0)
+ {
+ foundNo = true;
+ nameStartPosition += 3;
+ }
+
+ if (entry.find("error=", nameStartPosition) == 0)
+ {
+ foundError = true;
+ nameStartPosition += 6;
+ }
+
+ name = entry.substr(nameStartPosition);
+ if (name.empty())
+ {
+ cmSystemTools::Error("No warning name provided.");
+ return false;
+ }
+
+ if (!foundNo && !foundError)
+ {
+ // -W<name>
+ this->WarningLevels[name] = std::max(this->WarningLevels[name],
+ WARNING_LEVEL);
+ }
+ else if (foundNo && !foundError)
+ {
+ // -Wno<name>
+ this->WarningLevels[name] = IGNORE_LEVEL;
+ }
+ else if (!foundNo && foundError)
+ {
+ // -Werror=<name>
+ this->WarningLevels[name] = ERROR_LEVEL;
+ }
+ else
+ {
+ // -Wno-error=<name>
+ this->WarningLevels[name] = std::min(this->WarningLevels[name],
+ WARNING_LEVEL);
+ }
}
else if(arg.find("-U",0) == 0)
{
@@ -370,11 +424,14 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
// read in the list file to fill the cache
if(path)
{
+ this->CurrentSnapshot = this->State->Reset();
std::string homeDir = this->GetHomeDirectory();
std::string homeOutputDir = this->GetHomeOutputDirectory();
this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator());
+ cmState::Snapshot snapshot = this->GetCurrentSnapshot();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(gg, snapshot));
+ cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator(mf.get()));
lg->GetMakefile()->SetCurrentBinaryDirectory
(cmSystemTools::GetCurrentWorkingDirectory());
lg->GetMakefile()->SetCurrentSourceDirectory
@@ -414,9 +471,10 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
cmGlobalGenerator *gg = new cmGlobalGenerator(this);
this->SetGlobalGenerator(gg);
+ cmState::Snapshot snapshot = this->GetCurrentSnapshot();
// read in the list file to fill the cache
- cmsys::auto_ptr<cmLocalGenerator> lg(gg->MakeLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(gg, snapshot));
+ cmsys::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator(mf.get()));
mf->SetCurrentBinaryDirectory
(cmSystemTools::GetCurrentWorkingDirectory());
mf->SetCurrentSourceDirectory
@@ -482,7 +540,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string linkPath;
std::string flags;
std::string linkFlags;
- gg->CreateGeneratorTargets(mf);
+ gg->CreateGeneratorTargets(cmGlobalGenerator::AllTargets, lg.get());
cmGeneratorTarget *gtgt = gg->GetGeneratorTarget(tgt);
lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
gtgt, false);
@@ -587,11 +645,7 @@ void cmake::SetArgs(const std::vector<std::string>& args,
// skip for now
i++;
}
- else if(arg.find("-Wno-dev",0) == 0)
- {
- // skip for now
- }
- else if(arg.find("-Wdev",0) == 0)
+ else if(arg.find("-W",0) == 0)
{
// skip for now
}
@@ -616,10 +670,17 @@ void cmake::SetArgs(const std::vector<std::string>& args,
std::cout << "Running with debug output on.\n";
this->SetDebugOutputOn(true);
}
+ else if(arg.find("--trace-expand",0) == 0)
+ {
+ std::cout << "Running with expanded trace output on.\n";
+ this->SetTrace(true);
+ this->SetTraceExpand(true);
+ }
else if(arg.find("--trace",0) == 0)
{
std::cout << "Running with trace output on.\n";
this->SetTrace(true);
+ this->SetTraceExpand(false);
}
else if(arg.find("--warn-uninitialized",0) == 0)
{
@@ -1171,25 +1232,121 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
int cmake::Configure()
{
- if(this->DoSuppressDevWarnings)
+ WarningLevel warningLevel;
+
+ if (this->WarningLevels.count("deprecated") == 1)
+ {
+ warningLevel = this->WarningLevels["deprecated"];
+ if (warningLevel == IGNORE_LEVEL)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+ "Whether to issue deprecation warnings for"
+ " macros and functions.",
+ cmState::BOOL);
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+ "Whether to issue deprecation errors for macros"
+ " and functions.",
+ cmState::BOOL);
+ }
+ if (warningLevel == WARNING_LEVEL)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+ "Whether to issue deprecation warnings for"
+ " macros and functions.",
+ cmState::BOOL);
+ }
+ else if (warningLevel == ERROR_LEVEL)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEPRECATED", "TRUE",
+ "Whether to issue deprecation errors for macros"
+ " and functions.",
+ cmState::BOOL);
+ }
+ }
+
+ if (this->WarningLevels.count("dev") == 1)
{
- if(this->SuppressDevWarnings)
+ bool setDeprecatedVariables = false;
+
+ const char* cachedWarnDeprecated =
+ this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+ const char* cachedErrorDeprecated =
+ this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
+
+ // don't overwrite deprecated warning setting from a previous invocation
+ if (!cachedWarnDeprecated && !cachedErrorDeprecated)
+ {
+ setDeprecatedVariables = true;
+ }
+
+ warningLevel = this->WarningLevels["dev"];
+ if (warningLevel == IGNORE_LEVEL)
{
this->CacheManager->
AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
"Suppress Warnings that are meant for"
" the author of the CMakeLists.txt files.",
cmState::INTERNAL);
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEVELOPER_WARNINGS", "FALSE",
+ "Suppress errors that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmState::INTERNAL);
+
+ if (setDeprecatedVariables)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+ "Whether to issue deprecation warnings for"
+ " macros and functions.",
+ cmState::BOOL);
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+ "Whether to issue deprecation errors for macros"
+ " and functions.",
+ cmState::BOOL);
+ }
}
- else
+ else if (warningLevel == WARNING_LEVEL)
{
this->CacheManager->
AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
"Suppress Warnings that are meant for"
" the author of the CMakeLists.txt files.",
cmState::INTERNAL);
+
+ if (setDeprecatedVariables)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+ "Whether to issue deprecation warnings for"
+ " macros and functions.",
+ cmState::BOOL);
+ }
+ }
+ else if (warningLevel == ERROR_LEVEL)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEVELOPER_WARNINGS", "TRUE",
+ "Suppress errors that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmState::INTERNAL);
+
+ if (setDeprecatedVariables)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEPRECATED", "TRUE",
+ "Whether to issue deprecation errors for macros"
+ " and functions.",
+ cmState::BOOL);
+ }
}
}
+
int ret = this->ActualConfigure();
const char* delCacheVars = this->State
->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
@@ -1437,35 +1594,8 @@ int cmake::ActualConfigure()
cmState::PATH);
}
}
- if(!this->State
- ->GetInitializedCacheValue("CMAKE_USE_RELATIVE_PATHS"))
- {
- this->State->AddCacheEntry
- ("CMAKE_USE_RELATIVE_PATHS", "OFF",
- "If true, cmake will use relative paths in makefiles and projects.",
- cmState::BOOL);
- if (!this->State->GetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS",
- "ADVANCED"))
- {
- this->State->SetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS",
- "ADVANCED", "1");
- }
- }
- if(cmSystemTools::GetFatalErrorOccured())
- {
- const char* makeProgram =
- this->State->GetInitializedCacheValue("CMAKE_MAKE_PROGRAM");
- if (!makeProgram || cmSystemTools::IsOff(makeProgram))
- {
- // We must have a bad generator selection. Wipe the cache entry so the
- // user can select another.
- this->State->RemoveCacheEntry("CMAKE_GENERATOR");
- this->State->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR");
- }
- }
-
- cmMakefile* mf=this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+ cmMakefile* mf=this->GlobalGenerator->GetMakefiles()[0];
if (mf->IsOn("CTEST_USE_LAUNCHERS")
&& !this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE"))
{
@@ -1547,6 +1677,18 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
{
this->AddCMakePaths();
}
+
+ // don't turn dev warnings into errors by default, if no value has been
+ // specified for the flag, disable it
+ if (!this->State->GetCacheEntryValue("CMAKE_ERROR_DEVELOPER_WARNINGS"))
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_ERROR_DEVELOPER_WARNINGS", "FALSE",
+ "Suppress errors that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmState::INTERNAL);
+ }
+
// Add any cache args
if ( !this->SetCacheArgs(args) )
{
@@ -1625,7 +1767,11 @@ int cmake::Generate()
{
return -1;
}
- this->GlobalGenerator->DoGenerate();
+ if (!this->GlobalGenerator->Compute())
+ {
+ return -1;
+ }
+ this->GlobalGenerator->Generate();
if ( !this->GraphVizFile.empty() )
{
std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
@@ -1714,8 +1860,10 @@ void cmake::AddDefaultGenerators()
#endif
this->Generators.push_back(
cmGlobalUnixMakefileGenerator3::NewFactory());
+#if defined(CMAKE_BUILD_WITH_CMAKE)
this->Generators.push_back(
cmGlobalNinjaGenerator::NewFactory());
+#endif
#if defined(CMAKE_USE_WMAKE)
this->Generators.push_back(
cmGlobalWatcomWMakeGenerator::NewFactory());
@@ -1914,8 +2062,8 @@ int cmake::CheckBuildSystem()
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cmGlobalGenerator gg(&cm);
- cmsys::auto_ptr<cmLocalGenerator> lg(gg.MakeLocalGenerator());
- cmMakefile* mf = lg->GetMakefile();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator(mf.get()));
if(!mf->ReadListFile(this->CheckBuildSystemArgument.c_str()) ||
cmSystemTools::GetErrorOccuredFlag())
{
@@ -1944,8 +2092,11 @@ int cmake::CheckBuildSystem()
ggd(this->CreateGlobalGenerator(genName));
if(ggd.get())
{
- cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator());
- lgd->ClearDependencies(mf, verbose);
+ cmsys::auto_ptr<cmMakefile> mfd(new cmMakefile(ggd.get(),
+ cm.GetCurrentSnapshot()));
+ cmsys::auto_ptr<cmLocalGenerator> lgd(
+ ggd->CreateLocalGenerator(mfd.get()));
+ lgd->ClearDependencies(mfd.get(), verbose);
}
}
@@ -2445,20 +2596,17 @@ bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
{
msg << "CMake Deprecation Warning";
}
+ else if (t == cmake::AUTHOR_WARNING)
+ {
+ msg << "CMake Warning (dev)";
+ }
+ else if (t == cmake::AUTHOR_ERROR)
+ {
+ msg << "CMake Error (dev)";
+ }
else
{
msg << "CMake Warning";
- if(t == cmake::AUTHOR_WARNING)
- {
- // Allow suppression of these warnings.
- const char* suppress = this->State->GetCacheEntryValue(
- "CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- if(suppress && cmSystemTools::IsOn(suppress))
- {
- return false;
- }
- msg << " (dev)";
- }
}
return true;
}
@@ -2480,6 +2628,12 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
msg <<
"This warning is for project developers. Use -Wno-dev to suppress it.";
}
+ else if (t == cmake::AUTHOR_ERROR)
+ {
+ msg <<
+ "This error is for project developers. Use -Wno-error=dev to suppress "
+ "it.";
+ }
// Add a terminating blank line.
msg << "\n";
@@ -2503,7 +2657,8 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
// Output the message.
if(t == cmake::FATAL_ERROR
|| t == cmake::INTERNAL_ERROR
- || t == cmake::DEPRECATION_ERROR)
+ || t == cmake::DEPRECATION_ERROR
+ || t == cmake::AUTHOR_ERROR)
{
cmSystemTools::SetErrorOccured();
cmSystemTools::Message(msg.str().c_str(), "Error");
@@ -2519,7 +2674,6 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& bt)
{
cmListFileBacktrace backtrace = bt;
- backtrace.MakeRelative();
std::ostringstream msg;
if (!this->PrintMessagePreamble(t, msg))
@@ -2595,6 +2749,25 @@ int cmake::Build(const std::string& dir,
}
std::string cachePath = dir;
cmSystemTools::ConvertToUnixSlashes(cachePath);
+ std::string cacheFile = cachePath;
+ cacheFile += "/CMakeCache.txt";
+ if(!cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ // search in parent directories for cache
+ std::string cmakeFiles = cachePath;
+ cmakeFiles += "/CMakeFiles";
+ if(cmSystemTools::FileExists(cmakeFiles.c_str()))
+ {
+ std::string cachePathFound =
+ cmSystemTools::FileExistsInParentDirectories(
+ "CMakeCache.txt", cachePath.c_str(), "/");
+ if(!cachePathFound.empty())
+ {
+ cachePath = cmSystemTools::GetFilenamePath(cachePathFound);
+ }
+ }
+ }
+
if(!this->LoadCache(cachePath))
{
std::cerr << "Error: could not load cache\n";
@@ -2682,3 +2855,18 @@ void cmake::RunCheckForUnusedVariables()
}
#endif
}
+
+void cmake::SetSuppressDevWarnings(bool b)
+{
+ // equivalent to -Wno-dev
+ if (b)
+ {
+ this->WarningLevels["dev"] = IGNORE_LEVEL;
+ }
+ // equivalent to -Wdev
+ else
+ {
+ this->WarningLevels["dev"] = std::max(this->WarningLevels["dev"],
+ WARNING_LEVEL);
+ }
+}
diff --git a/Source/cmake.h b/Source/cmake.h
index 12b7e68..8ac8897 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -27,7 +27,6 @@ class cmVariableWatch;
class cmFileTimeComparison;
class cmExternalMakefileProjectGenerator;
class cmDocumentationSection;
-class cmPolicies;
class cmTarget;
class cmGeneratedFileStream;
@@ -60,6 +59,7 @@ class cmake
public:
enum MessageType
{ AUTHOR_WARNING,
+ AUTHOR_ERROR,
FATAL_ERROR,
INTERNAL_ERROR,
MESSAGE,
@@ -69,6 +69,12 @@ class cmake
DEPRECATION_WARNING
};
+ enum WarningLevel
+ {
+ IGNORE_LEVEL,
+ WARNING_LEVEL,
+ ERROR_LEVEL
+ };
/** \brief Describes the working modes of cmake */
enum WorkingMode
@@ -222,9 +228,6 @@ class cmake
///! this is called by generators to update the progress
void UpdateProgress(const char *msg, float prog);
- ///! get the cmake policies instance
- cmPolicies *GetPolicies() {return this->Policies;}
-
///! Get the variable watch object
cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
@@ -273,6 +276,9 @@ class cmake
// Do we want trace output during the cmake run.
bool GetTrace() { return this->Trace;}
void SetTrace(bool b) { this->Trace = b;}
+ bool GetTraceExpand() { return this->TraceExpand;}
+ void SetTraceExpand(bool b) { this->TraceExpand = b;}
+ void SetSuppressDevWarnings(bool b);
bool GetWarnUninitialized() { return this->WarnUninitialized;}
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b;}
bool GetWarnUnused() { return this->WarnUnused;}
@@ -293,15 +299,9 @@ class cmake
std::string const& GetCMakeEditCommand() const
{ return this->CMakeEditCommand; }
- void SetSuppressDevWarnings(bool v)
- {
- this->SuppressDevWarnings = v;
- this->DoSuppressDevWarnings = true;
- }
-
/** Display a message to the user. */
void IssueMessage(cmake::MessageType t, std::string const& text,
- cmListFileBacktrace const& backtrace = cmListFileBacktrace(NULL));
+ cmListFileBacktrace const& backtrace = cmListFileBacktrace());
void IssueMessage(cmake::MessageType t, std::string const& text,
cmListFileContext const& lfc);
@@ -339,11 +339,9 @@ protected:
void AddExtraGenerator(const std::string& name,
CreateExtraGeneratorFunctionType newFunction);
- cmPolicies *Policies;
cmGlobalGenerator *GlobalGenerator;
cmCacheManager *CacheManager;
- bool SuppressDevWarnings;
- bool DoSuppressDevWarnings;
+ std::map<std::string, WarningLevel> WarningLevels;
std::string GeneratorPlatform;
std::string GeneratorToolset;
@@ -381,6 +379,7 @@ private:
WorkingMode CurrentWorkingMode;
bool DebugOutput;
bool Trace;
+ bool TraceExpand;
bool WarnUninitialized;
bool WarnUnused;
bool WarnUnusedCli;
@@ -418,7 +417,15 @@ private:
{"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
{"-A <platform-name>", "Specify platform name if supported by generator."}, \
{"-Wno-dev", "Suppress developer warnings."},\
- {"-Wdev", "Enable developer warnings."}
+ {"-Wdev", "Enable developer warnings."},\
+ {"-Werror=dev", "Make developer warnings errors."},\
+ {"-Wno-error=dev", "Make developer warnings not errors."},\
+ {"-Wdeprecated", "Enable deprecated macro and function warnings."},\
+ {"-Wno-deprecated", "Suppress deprecated macro and function warnings."},\
+ {"-Werror=deprecated", "Make deprecated macro and function warnings " \
+ "errors."},\
+ {"-Wno-error=deprecated", "Make deprecated macro and function warnings " \
+ "not errors."}
#define FOR_EACH_C_FEATURE(F) \
F(c_function_prototypes) \
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index e5f4700..a06b26f 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -83,6 +83,7 @@ static const char * cmDocumentationOptions[][2] =
"useful on one try_compile at a time."},
{"--debug-output", "Put cmake in a debug mode."},
{"--trace", "Put cmake in trace mode."},
+ {"--trace-expand", "Put cmake in trace mode with variable expansion."},
{"--warn-uninitialized", "Warn about uninitialized values."},
{"--warn-unused-vars", "Warn about unused variables."},
{"--no-warn-unused-cli", "Don't warn about command line options."},
@@ -113,12 +114,7 @@ static cmMakefile* cmakemainGetMakefile(void *clientdata)
cmGlobalGenerator* gg=cm->GetGlobalGenerator();
if (gg)
{
- cmLocalGenerator* lg=gg->GetCurrentLocalGenerator();
- if (lg)
- {
- cmMakefile* mf = lg->GetMakefile();
- return mf;
- }
+ return gg->GetCurrentMakefile();
}
}
return 0;
@@ -425,7 +421,7 @@ static int do_build(int ac, char const* const* av)
switch (doing)
{
case DoingDir:
- dir = av[i];
+ dir = cmSystemTools::CollapseFullPath(av[i]);
doing = DoingNone;
break;
case DoingTarget:
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3ea2186..aa70aa0 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -34,6 +34,10 @@
#include <time.h>
#include <stdlib.h> // required for atoi
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+// defined in binexplib.cxx
+bool DumpFile(const char* filename, FILE *fout);
+#endif
void CMakeCommandUsage(const char* program)
{
@@ -211,6 +215,41 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0;
}
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+ else if(args[1] == "__create_def")
+ {
+ if(args.size() < 4)
+ {
+ std::cerr <<
+ "__create_def Usage: -E __create_def outfile.def objlistfile\n";
+ return 1;
+ }
+ FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+ if(!fout)
+ {
+ std::cerr << "could not open output .def file: " << args[2].c_str()
+ << "\n";
+ return 1;
+ }
+ cmsys::ifstream fin(args[3].c_str(),
+ std::ios::in | std::ios::binary);
+ if(!fin)
+ {
+ std::cerr << "could not open object list file: " << args[3].c_str()
+ << "\n";
+ return 1;
+ }
+ std::string objfile;
+ while(cmSystemTools::GetLineFromStream(fin, objfile))
+ {
+ if (!DumpFile(objfile.c_str(), fout))
+ {
+ return 1;
+ }
+ }
+ return 0;
+ }
+#endif
// run include what you use command and then run the compile
// command. This is an internal undocumented option and should
// only be used by CMake itself when running iwyu.
@@ -296,14 +335,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
// Echo string
else if (args[1] == "echo" )
{
- std::cout << cmJoin(cmRange(args).advance(2), " ") << std::endl;
+ std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl;
return 0;
}
// Echo string no new line
else if (args[1] == "echo_append" )
{
- std::cout << cmJoin(cmRange(args).advance(2), " ");
+ std::cout << cmJoin(cmMakeRange(args).advance(2), " ");
return 0;
}
@@ -472,7 +511,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
// Clock command
else if (args[1] == "time" && args.size() > 2)
{
- std::string command = cmJoin(cmRange(args).advance(2), " ");
+ std::string command = cmJoin(cmMakeRange(args).advance(2), " ");
clock_t clock_start, clock_finish;
time_t time_start, time_finish;
@@ -533,7 +572,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 1;
}
- std::string command = cmWrap('"', cmRange(args).advance(3), '"', " ");
+ std::string command =
+ cmWrap('"', cmMakeRange(args).advance(3), '"', " ");
int retval = 0;
int timeout = 0;
if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, 0, &retval,
@@ -728,7 +768,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen))
{
cm.SetGlobalGenerator(ggd);
- cmsys::auto_ptr<cmLocalGenerator> lgd(ggd->MakeLocalGenerator());
+ cmState::Snapshot snapshot = cm.GetCurrentSnapshot();
+ cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(ggd, snapshot));
+ cmsys::auto_ptr<cmLocalGenerator> lgd(
+ ggd->CreateLocalGenerator(mf.get()));
lgd->GetMakefile()->SetCurrentSourceDirectory(startDir);
lgd->GetMakefile()->SetCurrentBinaryDirectory(startOutDir);
@@ -1428,18 +1471,24 @@ bool cmcmd::RunCommand(const char* comment,
std::string output;
int retCode =0;
// use rc command to create .res file
- cmSystemTools::RunSingleCommand(command,
- &output, &output,
- &retCode, 0, cmSystemTools::OUTPUT_NONE);
+ bool res = cmSystemTools::RunSingleCommand(command,
+ &output, &output,
+ &retCode, 0,
+ cmSystemTools::OUTPUT_NONE);
// always print the output of the command, unless
// it is the dumb rc command banner, but if the command
// returned an error code then print the output anyway as
// the banner may be mixed with some other important information.
if(output.find("Resource Compiler Version") == output.npos
- || retCode !=0)
+ || !res || retCode)
{
std::cout << output;
}
+ if (!res)
+ {
+ std::cout << comment << " failed to run." << std::endl;
+ return false;
+ }
// if retCodeOut is requested then always return true
// and set the retCodeOut to retCode
if(retCodeOut)
@@ -1553,7 +1602,10 @@ int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
mtCommand.push_back(tempManifest);
// now run mt.exe to create the final manifest file
int mtRet =0;
- cmcmd::RunCommand("MT", mtCommand, verbose, &mtRet);
+ if(!cmcmd::RunCommand("MT", mtCommand, verbose, &mtRet))
+ {
+ return -1;
+ }
// if mt returns 0, then the manifest was not changed and
// we do not need to do another link step
if(mtRet == 0)
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index e784759..afcbd61 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -98,6 +98,7 @@ static const char * cmDocumentationOptions[][2] =
{"--test-command", "The test to run with the --build-and-test option."},
{"--test-timeout", "The time limit in seconds, internal use only."},
+ {"--test-load", "CPU load threshold for starting new parallel tests."},
{"--tomorrow-tag", "Nightly or experimental starts with next day tag."},
{"--ctest-config", "The configuration file used to initialize CTest state "
"when submitting dashboards."},
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index c88e888..017d619 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -786,6 +786,15 @@ IF(KWSYS_USE_SystemInformation)
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
ENDIF()
+
+ IF(UNIX AND NOT CYGWIN)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
+ "Checking whether CXX compiler has getloadavg" DIRECT)
+ IF(KWSYS_CXX_HAS_GETLOADAVG)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
+ ENDIF()
+ ENDIF()
ENDIF()
#-----------------------------------------------------------------------------
@@ -1228,7 +1237,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
IF(NOT CYGWIN)
SET(KWSYS_TEST_PROCESS_7 7)
ENDIF()
- FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7})
+ FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
@@ -1261,6 +1270,10 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
ENDIF()
+ # Set up ctest custom configuration file.
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+ ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
+
# Suppress known consistent failures on buggy systems.
IF(KWSYS_TEST_BOGUS_FAILURES)
SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst
index e097b76..960eea4 100644
--- a/Source/kwsys/CONTRIBUTING.rst
+++ b/Source/kwsys/CONTRIBUTING.rst
@@ -29,7 +29,7 @@ License
We do not require any formal copyright assignment or contributor license
agreement. Any contributions intentionally sent upstream are presumed
-to be offerred under terms of the OSI-approved BSD 3-clause License.
+to be offered under terms of the OSI-approved BSD 3-clause License.
See `Copyright.txt`_ for details.
.. _`Copyright.txt`: Copyright.txt
diff --git a/Source/kwsys/CTestCustom.cmake.in b/Source/kwsys/CTestCustom.cmake.in
new file mode 100644
index 0000000..d6f802e
--- /dev/null
+++ b/Source/kwsys/CTestCustom.cmake.in
@@ -0,0 +1,15 @@
+# kwsys.testProcess-10 involves sending SIGINT to a child process, which then
+# exits abnormally via a call to _exit(). (On Windows, a call to ExitProcess).
+# Naturally, this results in plenty of memory being "leaked" by this child
+# process - the memory check results are not meaningful in this case.
+#
+# kwsys.testProcess-9 also tests sending SIGINT to a child process. However,
+# normal operation of that test involves the child process timing out, and the
+# host process kills (SIGKILL) it as a result. Since it was SIGKILL'ed, the
+# resulting memory leaks are not logged by valgrind anyway. Therefore, we
+# don't have to exclude it.
+
+set(CTEST_CUSTOM_MEMCHECK_IGNORE
+ ${CTEST_CUSTOM_MEMCHECK_IGNORE}
+ kwsys.testProcess-10
+ )
diff --git a/Source/kwsys/EncodingC.c b/Source/kwsys/EncodingC.c
index ba2cec2..32b9bff 100644
--- a/Source/kwsys/EncodingC.c
+++ b/Source/kwsys/EncodingC.c
@@ -45,8 +45,11 @@ wchar_t* kwsysEncoding_DupToWide(const char* str)
if(length > 0)
{
ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
- ret[0] = 0;
- kwsysEncoding_mbstowcs(ret, str, length);
+ if(ret)
+ {
+ ret[0] = 0;
+ kwsysEncoding_mbstowcs(ret, str, length);
+ }
}
return ret;
}
@@ -72,8 +75,11 @@ char* kwsysEncoding_DupToNarrow(const wchar_t* str)
if(length > 0)
{
ret = (char*)malloc(length);
- ret[0] = 0;
- kwsysEncoding_wcstombs(ret, str, length);
+ if(ret)
+ {
+ ret[0] = 0;
+ kwsysEncoding_wcstombs(ret, str, length);
+ }
}
return ret;
}
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index e35939f..c5ebc97 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -23,58 +23,60 @@
# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
#endif
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-# define kwsysProcess kwsys_ns(Process)
-# define kwsysProcess_s kwsys_ns(Process_s)
-# define kwsysProcess_New kwsys_ns(Process_New)
-# define kwsysProcess_Delete kwsys_ns(Process_Delete)
-# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
-# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
-# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
-# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
-# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
-# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
-# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
-# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
-# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
-# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
-# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
-# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
-# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
-# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
-# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
-# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
-# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
-# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
-# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
-# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
-# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
-# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
-# define kwsysProcess_GetState kwsys_ns(Process_GetState)
-# define kwsysProcess_State_e kwsys_ns(Process_State_e)
-# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
-# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
-# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
-# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
-# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
-# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
-# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
-# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
-# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
-# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
-# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
-# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
-# define kwsysProcess_Execute kwsys_ns(Process_Execute)
-# define kwsysProcess_Disown kwsys_ns(Process_Disown)
-# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
-# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
-# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
-# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
-# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
-# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
-# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
-# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
-# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
-# define kwsysProcess_Kill kwsys_ns(Process_Kill)
+# define kwsysProcess kwsys_ns(Process)
+# define kwsysProcess_s kwsys_ns(Process_s)
+# define kwsysProcess_New kwsys_ns(Process_New)
+# define kwsysProcess_Delete kwsys_ns(Process_Delete)
+# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand)
+# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand)
+# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout)
+# define kwsysProcess_SetWorkingDirectory kwsys_ns(Process_SetWorkingDirectory)
+# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile)
+# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative)
+# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared)
+# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach)
+# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow)
+# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput)
+# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim)
+# define kwsysProcess_Option_CreateProcessGroup kwsys_ns(Process_Option_CreateProcessGroup)
+# define kwsysProcess_GetOption kwsys_ns(Process_GetOption)
+# define kwsysProcess_SetOption kwsys_ns(Process_SetOption)
+# define kwsysProcess_Option_e kwsys_ns(Process_Option_e)
+# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting)
+# define kwsysProcess_State_Error kwsys_ns(Process_State_Error)
+# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception)
+# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing)
+# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited)
+# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired)
+# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed)
+# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned)
+# define kwsysProcess_GetState kwsys_ns(Process_GetState)
+# define kwsysProcess_State_e kwsys_ns(Process_State_e)
+# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None)
+# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault)
+# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal)
+# define kwsysProcess_Exception_Interrupt kwsys_ns(Process_Exception_Interrupt)
+# define kwsysProcess_Exception_Numerical kwsys_ns(Process_Exception_Numerical)
+# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other)
+# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException)
+# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e)
+# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode)
+# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue)
+# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString)
+# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString)
+# define kwsysProcess_Execute kwsys_ns(Process_Execute)
+# define kwsysProcess_Disown kwsys_ns(Process_Disown)
+# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData)
+# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e)
+# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None)
+# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN)
+# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT)
+# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR)
+# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout)
+# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle)
+# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit)
+# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt)
+# define kwsysProcess_Kill kwsys_ns(Process_Kill)
#endif
#if defined(__cplusplus)
@@ -199,6 +201,15 @@ kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
* and ignore the rest of the arguments.
* 0 = No (default)
* 1 = Yes
+ *
+ * kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a
+ * new process group. This is
+ * useful if you want to send Ctrl+C
+ * to the process. On UNIX, also
+ * places the process in a new
+ * session.
+ * 0 = No (default)
+ * 1 = Yes
*/
kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId);
kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId,
@@ -208,7 +219,8 @@ enum kwsysProcess_Option_e
kwsysProcess_Option_HideWindow,
kwsysProcess_Option_Detach,
kwsysProcess_Option_MergeOutput,
- kwsysProcess_Option_Verbatim
+ kwsysProcess_Option_Verbatim,
+ kwsysProcess_Option_CreateProcessGroup
};
/**
@@ -363,6 +375,17 @@ enum kwsysProcess_Pipes_e
kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout);
/**
+ * Interrupt the process group for the child process that is currently
+ * running by sending it the appropriate operating-system specific signal.
+ * The caller should call WaitForExit after this returns to wait for the
+ * child to terminate.
+ *
+ * WARNING: If you didn't specify kwsysProcess_Option_CreateProcessGroup,
+ * you will interrupt your own process group.
+ */
+kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp);
+
+/**
* Forcefully terminate the child process that is currently running.
* The caller should call WaitForExit after this returns to wait for
* the child to terminate.
@@ -394,6 +417,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_Option_HideWindow
# undef kwsysProcess_Option_MergeOutput
# undef kwsysProcess_Option_Verbatim
+# undef kwsysProcess_Option_CreateProcessGroup
# undef kwsysProcess_GetOption
# undef kwsysProcess_SetOption
# undef kwsysProcess_Option_e
@@ -430,6 +454,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
# undef kwsysProcess_Pipe_Timeout
# undef kwsysProcess_Pipe_Handle
# undef kwsysProcess_WaitForExit
+# undef kwsysProcess_Interrupt
# undef kwsysProcess_Kill
# endif
#endif
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 0393a6d..6d9b109 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -88,7 +88,7 @@ typedef ssize_t kwsysProcess_ssize_t;
typedef int kwsysProcess_ssize_t;
#endif
-#if defined(__BEOS__) && !defined(__ZETA__)
+#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 kwsysProcess_usleep(unsigned int msec)
@@ -151,6 +151,7 @@ typedef struct kwsysProcessCreateInformation_s
} kwsysProcessCreateInformation;
/*--------------------------------------------------------------------------*/
+static void kwsysProcessVolatileFree(volatile void* p);
static int kwsysProcessInitialize(kwsysProcess* cp);
static void kwsysProcessCleanup(kwsysProcess* cp, int error);
static void kwsysProcessCleanupDescriptor(int* pfd);
@@ -197,7 +198,7 @@ struct kwsysProcess_s
{
/* The command lines to execute. */
char*** Commands;
- int NumberOfCommands;
+ volatile int NumberOfCommands;
/* Descriptors for the read ends of the child's output pipes and
the signal pipe. */
@@ -213,8 +214,10 @@ struct kwsysProcess_s
/* Buffer for pipe data. */
char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
- /* Process IDs returned by the calls to fork. */
- pid_t* ForkPIDs;
+ /* Process IDs returned by the calls to fork. Everything is volatile
+ because the signal handler accesses them. You must be very careful
+ when reaping PIDs or modifying this array to avoid race conditions. */
+ volatile pid_t* volatile ForkPIDs;
/* Flag for whether the children were terminated by a faild select. */
int SelectError;
@@ -237,6 +240,9 @@ struct kwsysProcess_s
/* Whether to merge stdout/stderr of the child. */
int MergeOutput;
+ /* Whether to create the process in a new process group. */
+ volatile sig_atomic_t CreateProcessGroup;
+
/* Time at which the child started. Negative for no timeout. */
kwsysProcessTime StartTime;
@@ -257,8 +263,9 @@ struct kwsysProcess_s
/* The number of children still executing. */
int CommandsLeft;
- /* The current status of the child process. */
- int State;
+ /* The current status of the child process. Must be atomic because
+ the signal handler checks this to avoid a race. */
+ volatile sig_atomic_t State;
/* The exceptional behavior that terminated the child process, if
* any. */
@@ -271,7 +278,7 @@ struct kwsysProcess_s
int ExitValue;
/* Whether the process was killed. */
- int Killed;
+ volatile sig_atomic_t Killed;
/* Buffer for error message in case of failure. */
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
@@ -649,6 +656,8 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
case kwsysProcess_Option_Detach: return cp->OptionDetach;
case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ case kwsysProcess_Option_CreateProcessGroup:
+ return cp->CreateProcessGroup;
default: return 0;
}
}
@@ -666,6 +675,8 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ case kwsysProcess_Option_CreateProcessGroup:
+ cp->CreateProcessGroup = value; break;
default: break;
}
}
@@ -1490,6 +1501,45 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+ int i;
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+ cp->Killed)
+ {
+ return;
+ }
+
+ /* Interrupt the children. */
+ if (cp->CreateProcessGroup)
+ {
+ if(cp->ForkPIDs)
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ /* Make sure the PID is still valid. */
+ if(cp->ForkPIDs[i])
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. */
+ kill(-cp->ForkPIDs[i], SIGINT);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No process group was created. Kill our own process group.
+ NOTE: While one could argue that we could call kill(cp->ForkPIDs[i],
+ SIGINT) as a way to still interrupt the process even though it's not in
+ a special group, this is not an option on Windows. Therefore, we kill
+ the current process group for consistency with Windows. */
+ kill(0, SIGINT);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
void kwsysProcess_Kill(kwsysProcess* cp)
{
int i;
@@ -1539,10 +1589,28 @@ void kwsysProcess_Kill(kwsysProcess* cp)
}
/*--------------------------------------------------------------------------*/
+/* Call the free() function with a pointer to volatile without causing
+ compiler warnings. */
+static void kwsysProcessVolatileFree(volatile void* p)
+{
+ /* clang has made it impossible to free memory that points to volatile
+ without first using special pragmas to disable a warning... */
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wcast-qual"
+#endif
+ free((void*)p); /* The cast will silence most compilers, but not clang. */
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
/* Initialize a process control structure for kwsysProcess_Execute. */
static int kwsysProcessInitialize(kwsysProcess* cp)
{
int i;
+ volatile pid_t* oldForkPIDs;
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
{
cp->PipeReadEnds[i] = -1;
@@ -1571,16 +1639,21 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->ErrorMessage[0] = 0;
strcpy(cp->ExitExceptionString, "No exception");
- if(cp->ForkPIDs)
+ oldForkPIDs = cp->ForkPIDs;
+ cp->ForkPIDs = (volatile pid_t*)malloc(
+ sizeof(volatile pid_t)*(size_t)(cp->NumberOfCommands));
+ if(oldForkPIDs)
{
- free(cp->ForkPIDs);
+ kwsysProcessVolatileFree(oldForkPIDs);
}
- cp->ForkPIDs = (pid_t*)malloc(sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
if(!cp->ForkPIDs)
{
return 0;
}
- memset(cp->ForkPIDs, 0, sizeof(pid_t)*(size_t)(cp->NumberOfCommands));
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
+ }
if(cp->CommandExitCodes)
{
@@ -1671,7 +1744,7 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
/* Free memory. */
if(cp->ForkPIDs)
{
- free(cp->ForkPIDs);
+ kwsysProcessVolatileFree(cp->ForkPIDs);
cp->ForkPIDs = 0;
}
if(cp->RealWorkingDirectory)
@@ -1758,15 +1831,49 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
kwsysProcessCreateInformation* si)
{
+ sigset_t mask, old_mask;
+ int pgidPipe[2];
+ char tmp;
+ ssize_t readRes;
+
/* Create the error reporting pipe. */
if(pipe(si->ErrorPipe) < 0)
{
return 0;
}
- /* Set close-on-exec flag on the error pipe's write end. */
- if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+ /* Create a pipe for detecting that the child process has created a process
+ group and session. */
+ if(pipe(pgidPipe) < 0)
{
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ return 0;
+ }
+
+ /* Set close-on-exec flag on the pipe's write end. */
+ if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 ||
+ fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+ {
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
+ return 0;
+ }
+
+ /* Block SIGINT / SIGTERM while we start. The purpose is so that our signal
+ handler doesn't get called from the child process after the fork and
+ before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+ {
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
return 0;
}
@@ -1774,13 +1881,19 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
#if defined(__VMS)
/* VMS needs vfork and execvp to be in the same function because
they use setjmp/longjmp to run the child startup code in the
- parent! TODO: OptionDetach. */
+ parent! TODO: OptionDetach. Also
+ TODO: CreateProcessGroup. */
cp->ForkPIDs[prIndex] = vfork();
#else
cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
#endif
if(cp->ForkPIDs[prIndex] < 0)
{
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
return 0;
}
@@ -1790,8 +1903,10 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Specify standard pipes for child process. */
decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
#else
- /* Close the read end of the error reporting pipe. */
+ /* Close the read end of the error reporting / process group
+ setup pipe. */
close(si->ErrorPipe[0]);
+ close(pgidPipe[0]);
/* Setup the stdin, stdout, and stderr pipes. */
if(si->StdIn > 0)
@@ -1819,11 +1934,25 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Restore all default signal handlers. */
kwsysProcessRestoreDefaultSignalHandlers();
+
+ /* Now that we have restored default signal handling and created the
+ process group, restore mask. */
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+
+ /* Create new process group. We use setsid instead of setpgid to avoid
+ the child getting hung up on signals like SIGTTOU. (In the real world,
+ this has been observed where "git svn" ends up calling the "resize"
+ program which opens /dev/tty. */
+ if(cp->CreateProcessGroup && setsid() < 0)
+ {
+ kwsysProcessChildErrorExit(si->ErrorPipe[1]);
+ }
#endif
/* Execute the real process. If successful, this does not return. */
execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]);
/* TODO: What does VMS do if the child fails to start? */
+ /* TODO: On VMS, how do we put the process in a new group? */
/* Failure. Report error to parent and terminate. */
kwsysProcessChildErrorExit(si->ErrorPipe[1]);
@@ -1834,12 +1963,34 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
decc$set_child_standard_streams(0, 1, 2);
#endif
+ /* We are done with the error reporting pipe and process group setup pipe
+ write end. */
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[1]);
+
+ /* Make sure the child is in the process group before we proceed. This
+ avoids race conditions with calls to the kill function that we make for
+ signalling process groups. */
+ while((readRes = read(pgidPipe[0], &tmp, 1)) > 0);
+ if(readRes < 0)
+ {
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+ return 0;
+ }
+ kwsysProcessCleanupDescriptor(&pgidPipe[0]);
+
+ /* Unmask signals. */
+ if(sigprocmask(SIG_SETMASK, &old_mask, 0) < 0)
+ {
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+ return 0;
+ }
+
/* A child has been created. */
++cp->CommandsLeft;
- /* We are done with the error reporting pipe write end. */
- kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]);
-
/* Block until the child's exec call succeeds and closes the error
pipe or writes data to the pipe to report an error. */
{
@@ -1877,6 +2028,17 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
/* A child process has terminated. Reap it if it is one handled by
this object. */
int i;
+ /* Temporarily disable signals that access ForkPIDs. We don't want them to
+ read a reaped PID, and writes to ForkPIDs are not atomic. */
+ sigset_t mask, old_mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ if(sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0)
+ {
+ return;
+ }
+
for(i=0; i < cp->NumberOfCommands; ++i)
{
if(cp->ForkPIDs[i])
@@ -1910,6 +2072,9 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
}
}
}
+
+ /* Re-enable signals. */
+ sigprocmask(SIG_SETMASK, &old_mask, 0);
}
/*--------------------------------------------------------------------------*/
@@ -1938,7 +2103,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
/* Assign the replacement descriptor. */
*p = fout;
- return 1;
+ return 1;
}
/*--------------------------------------------------------------------------*/
@@ -2582,19 +2747,23 @@ typedef struct kwsysProcessInstances_s
} kwsysProcessInstances;
static kwsysProcessInstances kwsysProcesses;
-/* The old SIGCHLD handler. */
+/* The old SIGCHLD / SIGINT / SIGTERM handlers. */
static struct sigaction kwsysProcessesOldSigChldAction;
+static struct sigaction kwsysProcessesOldSigIntAction;
+static struct sigaction kwsysProcessesOldSigTermAction;
/*--------------------------------------------------------------------------*/
static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
{
- /* Block SIGCHLD while we update the set of pipes to check.
+ /* Block signals while we update the set of pipes to check.
TODO: sigprocmask is undefined for threaded apps. See
pthread_sigmask. */
sigset_t newset;
sigset_t oldset;
sigemptyset(&newset);
sigaddset(&newset, SIGCHLD);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGTERM);
sigprocmask(SIG_BLOCK, &newset, &oldset);
/* Store the new set in that seen by the signal handler. */
@@ -2686,21 +2855,36 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
{
/* Install our handler for SIGCHLD. Repeat call until it is not
interrupted. */
- struct sigaction newSigChldAction;
- memset(&newSigChldAction, 0, sizeof(struct sigaction));
+ struct sigaction newSigAction;
+ memset(&newSigAction, 0, sizeof(struct sigaction));
#if KWSYSPE_USE_SIGINFO
- newSigChldAction.sa_sigaction = kwsysProcessesSignalHandler;
- newSigChldAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+ newSigAction.sa_sigaction = kwsysProcessesSignalHandler;
+ newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
# ifdef SA_RESTART
- newSigChldAction.sa_flags |= SA_RESTART;
+ newSigAction.sa_flags |= SA_RESTART;
# endif
#else
- newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
- newSigChldAction.sa_flags = SA_NOCLDSTOP;
+ newSigAction.sa_handler = kwsysProcessesSignalHandler;
+ newSigAction.sa_flags = SA_NOCLDSTOP;
#endif
- while((sigaction(SIGCHLD, &newSigChldAction,
+ sigemptyset(&newSigAction.sa_mask);
+ while((sigaction(SIGCHLD, &newSigAction,
&kwsysProcessesOldSigChldAction) < 0) &&
(errno == EINTR));
+
+ /* Install our handler for SIGINT / SIGTERM. Repeat call until
+ it is not interrupted. */
+ sigemptyset(&newSigAction.sa_mask);
+ sigaddset(&newSigAction.sa_mask, SIGTERM);
+ while((sigaction(SIGINT, &newSigAction,
+ &kwsysProcessesOldSigIntAction) < 0) &&
+ (errno == EINTR));
+
+ sigemptyset(&newSigAction.sa_mask);
+ sigaddset(&newSigAction.sa_mask, SIGINT);
+ while((sigaction(SIGTERM, &newSigAction,
+ &kwsysProcessesOldSigIntAction) < 0) &&
+ (errno == EINTR));
}
}
@@ -2734,10 +2918,14 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
/* If this was the last process, disable the signal handler. */
if(newProcesses.Count == 0)
{
- /* Restore the SIGCHLD handler. Repeat call until it is not
+ /* Restore the signal handlers. Repeat call until it is not
interrupted. */
while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
(errno == EINTR));
+ while((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
+ (errno == EINTR));
+ while((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
+ (errno == EINTR));
/* Free the table of process pointers since it is now empty.
This is safe because the signal handler has been removed. */
@@ -2763,39 +2951,108 @@ static void kwsysProcessesSignalHandler(int signum
#endif
)
{
- (void)signum;
+ int i, j, procStatus, old_errno = errno;
#if KWSYSPE_USE_SIGINFO
(void)info;
(void)ucontext;
#endif
/* Signal all process objects that a child has terminated. */
- {
- int i;
- for(i=0; i < kwsysProcesses.Count; ++i)
+ switch(signum)
{
- /* Set the pipe in a signalled state. */
- char buf = 1;
- 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;
+ case SIGCHLD:
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ /* Set the pipe in a signalled state. */
+ char buf = 1;
+ kwsysProcess* cp = kwsysProcesses.Processes[i];
+ kwsysProcess_ssize_t pipeStatus=
+ read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1);
+ (void)pipeStatus;
+ pipeStatus=write(cp->SignalPipe, &buf, 1);
+ (void)pipeStatus;
+ }
+ break;
+ case SIGINT:
+ case SIGTERM:
+ /* Signal child processes that are running in new process groups. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ kwsysProcess* cp = kwsysProcesses.Processes[i];
+ /* Check Killed to avoid data race condition when killing.
+ Check State to avoid data race condition in kwsysProcessCleanup
+ when there is an error (it leaves a reaped PID). */
+ if(cp->CreateProcessGroup && !cp->Killed &&
+ cp->State != kwsysProcess_State_Error && cp->ForkPIDs)
+ {
+ for(j=0; j < cp->NumberOfCommands; ++j)
+ {
+ /* Make sure the PID is still valid. */
+ if(cp->ForkPIDs[j])
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. */
+ kill(-cp->ForkPIDs[j], SIGINT);
+ }
+ }
+ }
+ }
+
+ /* Wait for all processes to terminate. */
+ while(wait(&procStatus) >= 0 || errno != ECHILD)
+ {
+ }
+
+ /* Terminate the process, which is now in an inconsistent state
+ because we reaped all the PIDs that it may have been reaping
+ or may have reaped in the future. Reraise the signal so that
+ the proper exit code is returned. */
+ {
+ /* Install default signal handler. */
+ struct sigaction defSigAction;
+ sigset_t unblockSet;
+ memset(&defSigAction, 0, sizeof(defSigAction));
+ defSigAction.sa_handler = SIG_DFL;
+ sigemptyset(&defSigAction.sa_mask);
+ while((sigaction(signum, &defSigAction, 0) < 0) &&
+ (errno == EINTR));
+ /* Unmask the signal. */
+ sigemptyset(&unblockSet);
+ sigaddset(&unblockSet, signum);
+ sigprocmask(SIG_UNBLOCK, &unblockSet, 0);
+ /* Raise the signal again. */
+ raise(signum);
+ /* We shouldn't get here... but if we do... */
+ _exit(1);
+ }
+ /* break omitted to silence unreachable code clang compiler warning. */
}
- }
#if !KWSYSPE_USE_SIGINFO
- /* Re-Install our handler for SIGCHLD. Repeat call until it is not
- interrupted. */
+ /* Re-Install our handler. Repeat call until it is not interrupted. */
{
- struct sigaction newSigChldAction;
- memset(&newSigChldAction, 0, sizeof(struct sigaction));
+ struct sigaction newSigAction;
+ struct sigaction &oldSigAction;
+ memset(&newSigAction, 0, sizeof(struct sigaction));
newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
newSigChldAction.sa_flags = SA_NOCLDSTOP;
- while((sigaction(SIGCHLD, &newSigChldAction,
- &kwsysProcessesOldSigChldAction) < 0) &&
+ sigemptyset(&newSigAction.sa_mask);
+ switch(signum)
+ {
+ case SIGCHLD: oldSigAction = &kwsysProcessesOldSigChldAction; break;
+ case SIGINT:
+ sigaddset(&newSigAction.sa_mask, SIGTERM);
+ oldSigAction = &kwsysProcessesOldSigIntAction; break;
+ case SIGTERM:
+ sigaddset(&newSigAction.sa_mask, SIGINT);
+ oldSigAction = &kwsysProcessesOldSigTermAction; break;
+ default: return 0;
+ }
+ while((sigaction(signum, &newSigAction,
+ oldSigAction) < 0) &&
(errno == EINTR));
}
#endif
+
+ errno = old_errno;
}
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index f630171..1f8749f 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -11,14 +11,12 @@
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Process.h)
-#include KWSYS_HEADER(System.h)
#include KWSYS_HEADER(Encoding.h)
/* Work-around CMake dependency scanning limitation. This must
duplicate the above list of headers. */
#if 0
# include "Process.h.in"
-# include "System.h.in"
# include "Encoding_c.h.in"
#endif
@@ -111,20 +109,16 @@ static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd);
static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp,
kwsysProcessPipeData* td);
static int kwsysProcessInitialize(kwsysProcess* cp);
-static int kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si);
+static DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+ kwsysProcessCreateInformation* si);
static void kwsysProcessDestroy(kwsysProcess* cp, int event);
-static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name);
+static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle,
+ const char* name);
static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle);
static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle);
static void kwsysProcessCleanupHandle(PHANDLE h);
-static void kwsysProcessCleanup(kwsysProcess* cp, int error);
+static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error);
static void kwsysProcessCleanErrorMessage(kwsysProcess* cp);
-static int kwsysProcessComputeCommandLength(kwsysProcess* cp,
- char const* const* command);
-static void kwsysProcessComputeCommandLine(kwsysProcess* cp,
- char const* const* command,
- char* cmd);
static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
@@ -140,6 +134,13 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
static void kwsysProcessKillTree(int pid);
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
+static int kwsysProcessesInitialize(void);
+static int kwsysTryEnterCreateProcessSection(void);
+static void kwsysLeaveCreateProcessSection(void);
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId,
+ int newProcessGroup);
+static void kwsysProcessesRemove(HANDLE hProcess);
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType);
/*--------------------------------------------------------------------------*/
/* A structure containing synchronization data for each thread. */
@@ -229,6 +230,9 @@ struct kwsysProcess_s
/* Whether to merge stdout/stderr of the child. */
int MergeOutput;
+ /* Whether to create the process in a new process group. */
+ int CreateProcessGroup;
+
/* Mutex to protect the shared index used by threads to report data. */
HANDLE SharedIndexMutex;
@@ -328,6 +332,16 @@ kwsysProcess* kwsysProcess_New(void)
/* Windows version number data. */
OSVERSIONINFO osv;
+ /* Initialize list of processes before we get any farther. It's especially
+ important that the console Ctrl handler be added BEFORE starting the
+ first process. This prevents the risk of an orphaned process being
+ started by the main thread while the default Ctrl handler is in
+ progress. */
+ if(!kwsysProcessesInitialize())
+ {
+ return 0;
+ }
+
/* Allocate a process control structure. */
cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
if(!cp)
@@ -602,37 +616,69 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
}
}
- /* We need to construct a single string representing the command
- and its arguments. We will surround each argument containing
- spaces with double-quotes. Inside a double-quoted argument, we
- need to escape double-quotes and all backslashes before them.
- We also need to escape backslashes at the end of an argument
- because they come before the closing double-quote for the
- argument. */
- {
- /* First determine the length of the final string. */
- int length = kwsysProcessComputeCommandLength(cp, command);
-
- /* Allocate enough space for the command. We do not need an extra
- byte for the terminating null because we allocated a space for
- the first argument that we will not use. */
- char* new_cmd = malloc(length);
- if(!new_cmd)
+ if (cp->Verbatim)
{
- /* Out of memory. */
+ /* Copy the verbatim command line into the buffer. */
+ newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command);
+ }
+ else
+ {
+ /* Encode the arguments so CommandLineToArgvW can decode
+ them from the command line string in the child. */
+ char buffer[32768]; /* CreateProcess max command-line length. */
+ char* end = buffer + sizeof(buffer);
+ char* out = buffer;
+ char const* const* a;
+ for (a = command; *a; ++a)
+ {
+ int quote = !**a; /* Quote the empty string. */
+ int slashes = 0;
+ char const* c;
+ if (a != command && out != end) { *out++ = ' '; }
+ for (c = *a; !quote && *c; ++c)
+ { quote = (*c == ' ' || *c == '\t'); }
+ if (quote && out != end) { *out++ = '"'; }
+ for (c = *a; *c; ++c)
+ {
+ if (*c == '\\')
+ {
+ ++slashes;
+ }
+ else
+ {
+ if (*c == '"')
+ {
+ // Add n+1 backslashes to total 2n+1 before internal '"'.
+ while(slashes-- >= 0 && out != end) { *out++ = '\\'; }
+ }
+ slashes = 0;
+ }
+ if (out != end) { *out++ = *c; }
+ }
+ if (quote)
+ {
+ // Add n backslashes to total 2n before ending '"'.
+ while (slashes-- > 0 && out != end) { *out++ = '\\'; }
+ if (out != end) { *out++ = '"'; }
+ }
+ }
+ if(out != end)
+ {
+ *out = '\0';
+ newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer);
+ }
+ else
+ {
+ newCommands[cp->NumberOfCommands] = 0;
+ }
+ }
+ if (!newCommands[cp->NumberOfCommands])
+ {
+ /* Out of memory or command line too long. */
free(newCommands);
return 0;
}
- /* Construct the command line in the allocated buffer. */
- kwsysProcessComputeCommandLine(cp, command,
- new_cmd);
-
- newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(new_cmd);
- free(new_cmd);
- }
-
-
/* Save the new array of commands. */
free(cp->Commands);
cp->Commands = newCommands;
@@ -811,6 +857,8 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
case kwsysProcess_Option_HideWindow: return cp->HideWindow;
case kwsysProcess_Option_MergeOutput: return cp->MergeOutput;
case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ case kwsysProcess_Option_CreateProcessGroup:
+ return cp->CreateProcessGroup;
default: return 0;
}
}
@@ -829,6 +877,8 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
case kwsysProcess_Option_MergeOutput: cp->MergeOutput = value; break;
case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ case kwsysProcess_Option_CreateProcessGroup:
+ cp->CreateProcessGroup = value; break;
default: break;
}
}
@@ -920,7 +970,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if(!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength,
cp->RealWorkingDirectory))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
SetCurrentDirectoryW(cp->WorkingDirectory);
@@ -932,14 +982,16 @@ void kwsysProcess_Execute(kwsysProcess* cp)
{
/* Create a handle to read a file for stdin. */
wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN);
+ DWORD error;
cp->PipeChildStd[0] =
CreateFileW(wstdin, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0, OPEN_EXISTING, 0, 0);
+ error = GetLastError(); /* Check now in case free changes this. */
free(wstdin);
if(cp->PipeChildStd[0] == INVALID_HANDLE_VALUE)
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, error);
return;
}
}
@@ -965,17 +1017,18 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read,
&cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
if(cp->PipeFileSTDOUT)
{
/* Use a file for stdout. */
- if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
- cp->PipeFileSTDOUT))
+ DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1],
+ cp->PipeFileSTDOUT);
+ if(error)
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, error);
return;
}
}
@@ -998,7 +1051,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
GetCurrentProcess(), &cp->PipeChildStd[1],
0, FALSE, DUPLICATE_SAME_ACCESS))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
}
@@ -1009,17 +1062,18 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if(!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read,
&cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
if(cp->PipeFileSTDERR)
{
/* Use a file for stderr. */
- if(!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
- cp->PipeFileSTDERR))
+ DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2],
+ cp->PipeFileSTDERR);
+ if(error)
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, error);
return;
}
}
@@ -1042,7 +1096,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
GetCurrentProcess(), &cp->PipeChildStd[2],
0, FALSE, DUPLICATE_SAME_ACCESS))
{
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, GetLastError());
return;
}
}
@@ -1081,11 +1135,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
HANDLE p[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
if (!CreatePipe(&p[0], &p[1], 0, 0))
{
+ DWORD error = GetLastError();
if (nextStdInput != cp->PipeChildStd[0])
{
kwsysProcessCleanupHandle(&nextStdInput);
}
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, error);
return;
}
nextStdInput = p[0];
@@ -1094,7 +1149,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
si.hStdError = cp->MergeOutput? cp->PipeChildStd[1] : cp->PipeChildStd[2];
{
- int res = kwsysProcessCreate(cp, i, &si);
+ DWORD error = kwsysProcessCreate(cp, i, &si);
/* Close our copies of pipes used between children. */
if (si.hStdInput != cp->PipeChildStd[0])
@@ -1109,7 +1164,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
{
kwsysProcessCleanupHandle(&si.hStdError);
}
- if (res)
+ if (!error)
{
cp->ProcessEvents[i+1] = cp->ProcessInformation[i].hProcess;
}
@@ -1119,7 +1174,7 @@ void kwsysProcess_Execute(kwsysProcess* cp)
{
kwsysProcessCleanupHandle(&nextStdInput);
}
- kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanup(cp, error);
return;
}
}
@@ -1435,6 +1490,52 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
}
/*--------------------------------------------------------------------------*/
+void kwsysProcess_Interrupt(kwsysProcess* cp)
+{
+ int i;
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired ||
+ cp->Killed)
+ {
+ KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n"));
+ return;
+ }
+
+ /* Skip actually interrupting the child if it has already terminated. */
+ if(cp->Terminated)
+ {
+ KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n"));
+ return;
+ }
+
+ /* Interrupt the children. */
+ if (cp->CreateProcessGroup)
+ {
+ if(cp->ProcessInformation)
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ /* Make sure the process handle isn't closed (e.g. from disowning). */
+ if(cp->ProcessInformation[i].hProcess)
+ {
+ /* The user created a process group for this process. The group ID
+ is the process ID for the original process in the group. Note
+ that we have to use Ctrl+Break: Ctrl+C is not allowed for process
+ groups. */
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
+ cp->ProcessInformation[i].dwProcessId);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No process group was created. Kill our own process group... */
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
void kwsysProcess_Kill(kwsysProcess* cp)
{
int i;
@@ -1462,7 +1563,8 @@ void kwsysProcess_Kill(kwsysProcess* cp)
for(i=0; i < cp->NumberOfCommands; ++i)
{
kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
- // close the handle if we kill it
+ /* Remove from global list of processes and close handles. */
+ kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
}
@@ -1661,7 +1763,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
}
/*--------------------------------------------------------------------------*/
-static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
+static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
{
DWORD flags;
@@ -1672,13 +1774,19 @@ static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
if (flags & HANDLE_FLAG_INHERIT)
{
*out = in;
- return 1;
+ return ERROR_SUCCESS;
}
/* Create an inherited copy of this handle. */
- return DuplicateHandle(GetCurrentProcess(), in,
- GetCurrentProcess(), out,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
+ if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out,
+ 0, TRUE, DUPLICATE_SAME_ACCESS))
+ {
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ return GetLastError();
+ }
}
else
{
@@ -1694,29 +1802,46 @@ static int kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn)
(GENERIC_WRITE | FILE_READ_ATTRIBUTES)),
FILE_SHARE_READ|FILE_SHARE_WRITE,
&sa, OPEN_EXISTING, 0, 0);
- return *out != INVALID_HANDLE_VALUE;
+ return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError();
}
-
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessCreate(kwsysProcess* cp, int index,
- kwsysProcessCreateInformation* si)
+DWORD kwsysProcessCreate(kwsysProcess* cp, int index,
+ kwsysProcessCreateInformation* si)
{
- int res =
+ DWORD creationFlags;
+ DWORD error = ERROR_SUCCESS;
- /* Create inherited copies the handles. */
- kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
- si->hStdInput, 1) &&
- kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
- si->hStdOutput, 0) &&
- kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
- si->hStdError, 0) &&
+ /* Check if we are currently exiting. */
+ if (!kwsysTryEnterCreateProcessSection())
+ {
+ /* The Ctrl handler is currently working on exiting our process. Rather
+ than return an error code, which could cause incorrect conclusions to be
+ reached by the caller, we simply hang. (For example, a CMake try_run
+ configure step might cause the project to configure wrong.) */
+ Sleep(INFINITE);
+ }
+
+ /* Create the child in a suspended state so we can wait until all
+ children have been created before running any one. */
+ creationFlags = CREATE_SUSPENDED;
+ if (cp->CreateProcessGroup)
+ {
+ creationFlags |= CREATE_NEW_PROCESS_GROUP;
+ }
- /* Create the child in a suspended state so we can wait until all
- children have been created before running any one. */
- CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
- 0, &si->StartupInfo, &cp->ProcessInformation[index]);
+ /* Create inherited copies of the handles. */
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput,
+ si->hStdInput, 1)) ||
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput,
+ si->hStdOutput, 0)) ||
+ (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError,
+ si->hStdError, 0)) ||
+ /* Create the process. */
+ (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0,
+ 0, &si->StartupInfo, &cp->ProcessInformation[index]) &&
+ (error = GetLastError()));
/* Close the inherited copies of the handles. */
if (si->StartupInfo.hStdInput != si->hStdInput)
@@ -1732,7 +1857,23 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
kwsysProcessCleanupHandle(&si->StartupInfo.hStdError);
}
- return res;
+ /* Add the process to the global list of processes. */
+ if (!error &&
+ !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess,
+ cp->ProcessInformation[index].dwProcessId, cp->CreateProcessGroup))
+ {
+ /* This failed for some reason. Kill the suspended process. */
+ TerminateProcess(cp->ProcessInformation[index].hProcess, 1);
+ /* And clean up... */
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
+ strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed");
+ error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason. */
+ }
+
+ /* If the console Ctrl handler is waiting for us, this will release it... */
+ kwsysLeaveCreateProcessSection();
+ return error;
}
/*--------------------------------------------------------------------------*/
@@ -1754,6 +1895,9 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
&cp->CommandExitCodes[index]);
+ /* Remove from global list of processes. */
+ kwsysProcessesRemove(cp->ProcessInformation[index].hProcess);
+
/* Close the process handle for the terminated process. */
kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
@@ -1788,13 +1932,14 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event)
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
+DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
{
HANDLE fout;
wchar_t* wname;
+ DWORD error;
if(!name)
{
- return 1;
+ return ERROR_INVALID_PARAMETER;
}
/* Close the existing handle. */
@@ -1804,15 +1949,16 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
wname = kwsysEncoding_DupToWide(name);
fout = CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0,
CREATE_ALWAYS, 0, 0);
+ error = GetLastError();
free(wname);
if(fout == INVALID_HANDLE_VALUE)
{
- return 0;
+ return error;
}
/* Assign the replacement handle. */
*phandle = fout;
- return 1;
+ return ERROR_SUCCESS;
}
/*--------------------------------------------------------------------------*/
@@ -1851,7 +1997,7 @@ void kwsysProcessCleanupHandle(PHANDLE h)
/*--------------------------------------------------------------------------*/
/* Close all handles created by kwsysProcess_Execute. */
-void kwsysProcessCleanup(kwsysProcess* cp, int error)
+void kwsysProcessCleanup(kwsysProcess* cp, DWORD error)
{
int i;
/* If this is an error case, report the error. */
@@ -1861,21 +2007,27 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
if(cp->ErrorMessage[0] == 0)
{
/* Format the error message. */
- DWORD original = GetLastError();
wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE];
DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
+ FORMAT_MESSAGE_IGNORE_INSERTS, 0, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
err_msg, KWSYSPE_PIPE_BUFFER_SIZE, 0);
- WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
- KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL);
if(length < 1)
{
/* FormatMessage failed. Use a default message. */
_snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
"Process execution failed with error 0x%X. "
"FormatMessage failed with error 0x%X",
- original, GetLastError());
+ error, GetLastError());
+ }
+ if(!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage,
+ KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL))
+ {
+ /* WideCharToMultiByte failed. Use a default message. */
+ _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE,
+ "Process execution failed with error 0x%X. "
+ "WideCharToMultiByte failed with error 0x%X",
+ error, GetLastError());
}
}
@@ -1898,6 +2050,8 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
}
for(i=0; i < cp->NumberOfCommands; ++i)
{
+ /* Remove from global list of processes and close handles. */
+ kwsysProcessesRemove(cp->ProcessInformation[i].hProcess);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
}
@@ -1962,66 +2116,6 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
}
/*--------------------------------------------------------------------------*/
-int kwsysProcessComputeCommandLength(kwsysProcess* cp,
- char const* const* command)
-{
- int length = 0;
- if(cp->Verbatim)
- {
- /* Treat the first argument as a verbatim command line. Use its
- length directly and add space for the null-terminator. */
- length = (int)strlen(*command)+1;
- }
- else
- {
- /* Compute the length of the command line when it is converted to
- a single string. Space for the null-terminator is allocated by
- the whitespace character allocated for the first argument that
- will not be used. */
- char const* const* arg;
- for(arg = command; *arg; ++arg)
- {
- /* Add the length of this argument. It already includes room
- for a separating space or terminating null. */
- length += kwsysSystem_Shell_GetArgumentSizeForWindows(*arg, 0);
- }
- }
-
- return length;
-}
-
-/*--------------------------------------------------------------------------*/
-void kwsysProcessComputeCommandLine(kwsysProcess* cp,
- char const* const* command,
- char* cmd)
-{
- if(cp->Verbatim)
- {
- /* Copy the verbatim command line into the buffer. */
- strcpy(cmd, *command);
- }
- else
- {
- /* Construct the command line in the allocated buffer. */
- char const* const* arg;
- for(arg = command; *arg; ++arg)
- {
- /* Add the separating space if this is not the first argument. */
- if(arg != command)
- {
- *cmd++ = ' ';
- }
-
- /* Add the current argument. */
- cmd = kwsysSystem_Shell_GetArgumentForWindows(*arg, cmd, 0);
- }
-
- /* Add the terminating null character to the command line. */
- *cmd = 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
/* Get the time at which either the process or user timeout will
expire. Returns 1 if the user timeout is first, and 0 otherwise. */
int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
@@ -2694,3 +2788,230 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
}
}
+
+/*--------------------------------------------------------------------------*/
+/* Global set of executing processes for use by the Ctrl handler.
+ This global instance will be zero-initialized by the compiler.
+
+ Note that the console Ctrl handler runs on a background thread and so
+ everything it does must be thread safe. Here, we track the hProcess
+ HANDLEs directly instead of kwsysProcess instances, so that we don't have
+ to make kwsysProcess thread safe. */
+typedef struct kwsysProcessInstance_s
+{
+ HANDLE hProcess;
+ DWORD dwProcessId;
+ int NewProcessGroup; /* Whether the process was created in a new group. */
+} kwsysProcessInstance;
+
+typedef struct kwsysProcessInstances_s
+{
+ /* Whether we have initialized key fields below, like critical sections. */
+ int Initialized;
+
+ /* Ctrl handler runs on a different thread, so we must sync access. */
+ CRITICAL_SECTION Lock;
+
+ int Exiting;
+ size_t Count;
+ size_t Size;
+ kwsysProcessInstance* Processes;
+} kwsysProcessInstances;
+static kwsysProcessInstances kwsysProcesses;
+
+/*--------------------------------------------------------------------------*/
+/* Initialize critial section and set up console Ctrl handler. You MUST call
+ this before using any other kwsysProcesses* functions below. */
+static int kwsysProcessesInitialize(void)
+{
+ /* Initialize everything if not done already. */
+ if(!kwsysProcesses.Initialized)
+ {
+ InitializeCriticalSection(&kwsysProcesses.Lock);
+
+ /* Set up console ctrl handler. */
+ if(!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE))
+ {
+ return 0;
+ }
+
+ kwsysProcesses.Initialized = 1;
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* The Ctrl handler waits on the global list of processes. To prevent an
+ orphaned process, do not create a new process if the Ctrl handler is
+ already running. Do so by using this function to check if it is ok to
+ create a process. */
+static int kwsysTryEnterCreateProcessSection(void)
+{
+ /* Enter main critical section; this means creating a process and the Ctrl
+ handler are mutually exclusive. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+ /* Indicate to the caller if they can create a process. */
+ if(kwsysProcesses.Exiting)
+ {
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Matching function on successful kwsysTryEnterCreateProcessSection return.
+ Make sure you called kwsysProcessesAdd if applicable before calling this.*/
+static void kwsysLeaveCreateProcessSection(void)
+{
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Add new process to global process list. The Ctrl handler will wait for
+ the process to exit before it returns. Do not close the process handle
+ until after calling kwsysProcessesRemove. The newProcessGroup parameter
+ must be set if the process was created with CREATE_NEW_PROCESS_GROUP. */
+static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid,
+ int newProcessGroup)
+{
+ if(!kwsysProcessesInitialize() || !hProcess ||
+ hProcess == INVALID_HANDLE_VALUE)
+ {
+ return 0;
+ }
+
+ /* Enter the critical section. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Make sure there is enough space for the new process handle. */
+ if(kwsysProcesses.Count == kwsysProcesses.Size)
+ {
+ size_t newSize;
+ kwsysProcessInstance *newArray;
+ /* Start with enough space for a small number of process handles
+ and double the size each time more is needed. */
+ newSize = kwsysProcesses.Size? kwsysProcesses.Size*2 : 4;
+
+ /* Try allocating the new block of memory. */
+ if(newArray = (kwsysProcessInstance*)malloc(
+ newSize*sizeof(kwsysProcessInstance)))
+ {
+ /* Copy the old process handles to the new memory. */
+ if(kwsysProcesses.Count > 0)
+ {
+ memcpy(newArray, kwsysProcesses.Processes,
+ kwsysProcesses.Count * sizeof(kwsysProcessInstance));
+ }
+ }
+ else
+ {
+ /* Failed to allocate memory for the new process handle set. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+ return 0;
+ }
+
+ /* Free original array. */
+ free(kwsysProcesses.Processes);
+
+ /* Update original structure with new allocation. */
+ kwsysProcesses.Size = newSize;
+ kwsysProcesses.Processes = newArray;
+ }
+
+ /* Append the new process information to the set. */
+ kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess;
+ kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid;
+ kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup =
+ newProcessGroup;
+
+ /* Leave critical section and return success. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Removes process to global process list. */
+static void kwsysProcessesRemove(HANDLE hProcess)
+{
+ size_t i;
+
+ if (!hProcess || hProcess == INVALID_HANDLE_VALUE)
+ {
+ return;
+ }
+
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Find the given process in the set. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ if(kwsysProcesses.Processes[i].hProcess == hProcess)
+ {
+ break;
+ }
+ }
+ if(i < kwsysProcesses.Count)
+ {
+ /* Found it! Remove the process from the set. */
+ --kwsysProcesses.Count;
+ for(; i < kwsysProcesses.Count; ++i)
+ {
+ kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i+1];
+ }
+
+ /* If this was the last process, free the array. */
+ if(kwsysProcesses.Count == 0)
+ {
+ kwsysProcesses.Size = 0;
+ free(kwsysProcesses.Processes);
+ kwsysProcesses.Processes = 0;
+ }
+ }
+
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+}
+
+/*--------------------------------------------------------------------------*/
+static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType)
+{
+ size_t i;
+ (void)dwCtrlType;
+ /* Enter critical section. */
+ EnterCriticalSection(&kwsysProcesses.Lock);
+
+ /* Set flag indicating that we are exiting. */
+ kwsysProcesses.Exiting = 1;
+
+ /* If some of our processes were created in a new process group, we must
+ manually interrupt them. They won't otherwise receive a Ctrl+C/Break. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ if(kwsysProcesses.Processes[i].NewProcessGroup)
+ {
+ DWORD groupId = kwsysProcesses.Processes[i].dwProcessId;
+ if(groupId)
+ {
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId);
+ }
+ }
+ }
+
+ /* Wait for each child process to exit. This is the key step that prevents
+ us from leaving several orphaned children processes running in the
+ background when the user presses Ctrl+C. */
+ for(i=0; i < kwsysProcesses.Count; ++i)
+ {
+ WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE);
+ }
+
+ /* Leave critical section. */
+ LeaveCriticalSection(&kwsysProcesses.Lock);
+
+ /* Continue on to default Ctrl handler (which calls ExitProcess). */
+ return FALSE;
+}
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index 1ee26fa..ccc7e81 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -20,8 +20,8 @@
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* malloc, free */
-#include <string.h> /* strlen */
-#include <ctype.h> /* isalpha */
+#include <string.h> /* memcpy */
+#include <ctype.h> /* isspace */
#include <stdio.h>
@@ -31,587 +31,6 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t;
typedef int kwsysSystem_ptrdiff_t;
#endif
-/*
-
-Notes:
-
-Make variable replacements open a can of worms. Sometimes they should
-be quoted and sometimes not. Sometimes their replacement values are
-already quoted.
-
-VS variables cause problems. In order to pass the referenced value
-with spaces the reference must be quoted. If the variable value ends
-in a backslash then it will escape the ending quote! In order to make
-the ending backslash appear we need this:
-
- "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
- "$(InputDir)"
-
-Make variable references are platform specific so we should probably
-just NOT quote them and let the listfile author deal with it.
-
-*/
-
-/*
-TODO: For windows echo:
-
-To display a pipe (|) or redirection character (< or >) when using the
-echo command, use a caret character immediately before the pipe or
-redirection character (for example, ^>, ^<, or ^| ). If you need to
-use the caret character itself (^), use two in a row (^^).
-*/
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsWhitespace(char c)
-{
- return ((c == ' ') || (c == '\t'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnUnix(char c)
-{
- return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
- (c == '&') || (c == '$') || (c == '(') || (c == ')') ||
- (c == '~') || (c == '<') || (c == '>') || (c == '|') ||
- (c == '*') || (c == '^') || (c == '\\'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotesOnWindows(char c)
-{
- return ((c == '\'') || (c == '#') || (c == '&') ||
- (c == '<') || (c == '>') || (c == '|') || (c == '^'));
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharNeedsQuotes(char c, int isUnix, int flags)
-{
- /* On Windows the built-in command shell echo never needs quotes. */
- if(!isUnix && (flags & kwsysSystem_Shell_Flag_EchoWindows))
- {
- return 0;
- }
-
- /* On all platforms quotes are needed to preserve whitespace. */
- if(kwsysSystem_Shell__CharIsWhitespace(c))
- {
- return 1;
- }
-
- if(isUnix)
- {
- /* On UNIX several special characters need quotes to preserve them. */
- if(kwsysSystem_Shell__CharNeedsQuotesOnUnix(c))
- {
- return 1;
- }
- }
- else
- {
- /* On Windows several special characters need quotes to preserve them. */
- if(kwsysSystem_Shell__CharNeedsQuotesOnWindows(c))
- {
- return 1;
- }
- }
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__CharIsMakeVariableName(char c)
-{
- return c && (c == '_' || isalpha(((int)c)));
-}
-
-/*--------------------------------------------------------------------------*/
-static const char* kwsysSystem_Shell__SkipMakeVariables(const char* c)
-{
- while(*c == '$' && *(c+1) == '(')
- {
- const char* skip = c+2;
- while(kwsysSystem_Shell__CharIsMakeVariableName(*skip))
- {
- ++skip;
- }
- if(*skip == ')')
- {
- c = skip+1;
- }
- else
- {
- break;
- }
- }
- return c;
-}
-
-/*
-Allowing make variable replacements opens a can of worms. Sometimes
-they should be quoted and sometimes not. Sometimes their replacement
-values are already quoted or contain escapes.
-
-Some Visual Studio variables cause problems. In order to pass the
-referenced value with spaces the reference must be quoted. If the
-variable value ends in a backslash then it will escape the ending
-quote! In order to make the ending backslash appear we need this:
-
- "$(InputDir)\"
-
-However if there is not a trailing backslash then this will put a
-quote in the value so we need:
-
- "$(InputDir)"
-
-This macro decides whether we quote an argument just because it
-contains a make variable reference. This should be replaced with a
-flag later when we understand applications of this better.
-*/
-#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
- int flags)
-{
- /* The empty string needs quotes. */
- if(!*in)
- {
- return 1;
- }
-
- /* Scan the string for characters that require quoting. */
- {
- const char* c;
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
-#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
- const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
- if(skip != c)
- {
- /* We need to quote make variable references to preserve the
- string with contents substituted in its place. */
- return 1;
- }
-#else
- /* Skip over the make variable references if any are present. */
- c = kwsysSystem_Shell__SkipMakeVariables(c);
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
-#endif
- }
-
- /* Check whether this character needs quotes. */
- if(kwsysSystem_Shell__CharNeedsQuotes(*c, isUnix, flags))
- {
- return 1;
- }
- }
- }
-
- /* On Windows some single character arguments need quotes. */
- if(!isUnix && *in && !*(in+1))
- {
- char c = *in;
- if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#'))
- {
- return 1;
- }
- }
-
- return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-static int kwsysSystem_Shell__GetArgumentSize(const char* in,
- int isUnix, int flags)
-{
- /* Start with the length of the original argument, plus one for
- either a terminating null or a separating space. */
- int size = (int)strlen(in) + 1;
-
- /* String iterator. */
- const char* c;
-
- /* Keep track of how many backslashes have been encountered in a row. */
- int windows_backslashes = 0;
-
- /* Scan the string for characters that require escaping or quoting. */
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
- /* Skip over the make variable references if any are present. */
- c = kwsysSystem_Shell__SkipMakeVariables(c);
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
- }
-
- /* Check whether this character needs escaping for the shell. */
- if(isUnix)
- {
- /* On Unix a few special characters need escaping even inside a
- quoted argument. */
- if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
- {
- /* This character needs a backslash to escape it. */
- ++size;
- }
- }
- else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
- {
- /* On Windows the built-in command shell echo never needs escaping. */
- }
- else
- {
- /* On Windows only backslashes and double-quotes need escaping. */
- if(*c == '\\')
- {
- /* Found a backslash. It may need to be escaped later. */
- ++windows_backslashes;
- }
- else if(*c == '"')
- {
- /* Found a double-quote. We need to escape it and all
- immediately preceding backslashes. */
- size += windows_backslashes + 1;
- windows_backslashes = 0;
- }
- else
- {
- /* Found another character. This eliminates the possibility
- that any immediately preceding backslashes will be
- escaped. */
- windows_backslashes = 0;
- }
- }
-
- /* Check whether this character needs escaping for a make tool. */
- if(*c == '$')
- {
- if(flags & kwsysSystem_Shell_Flag_Make)
- {
- /* In Makefiles a dollar is written $$ so we need one extra
- character. */
- ++size;
- }
- else if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a dollar is written "$" so we need two extra
- characters. */
- size += 2;
- }
- }
- else if(*c == '#')
- {
- if((flags & kwsysSystem_Shell_Flag_Make) &&
- (flags & kwsysSystem_Shell_Flag_WatcomWMake))
- {
- /* In Watcom WMake makefiles a pound is written $# so we need
- one extra character. */
- ++size;
- }
- }
- else if(*c == '%')
- {
- if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
- ((flags & kwsysSystem_Shell_Flag_Make) &&
- ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
- (flags & kwsysSystem_Shell_Flag_NMake))))
- {
- /* In the VS IDE, NMake, or MinGW make a percent is written %%
- so we need one extra characters. */
- size += 1;
- }
- }
- else if(*c == ';')
- {
- if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a semicolon is written ";" so we need two extra
- characters. */
- size += 2;
- }
- }
- }
-
- /* Check whether the argument needs surrounding quotes. */
- if(kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags))
- {
- /* Surrounding quotes are needed. Allocate space for them. */
- if((flags & kwsysSystem_Shell_Flag_WatcomQuote) && (isUnix))
- {
- size += 2;
- }
- size += 2;
-
- /* We must escape all ending backslashes when quoting on windows. */
- size += windows_backslashes;
- }
-
- return size;
-}
-
-/*--------------------------------------------------------------------------*/
-static char* kwsysSystem_Shell__GetArgument(const char* in, char* out,
- int isUnix, int flags)
-{
- /* String iterator. */
- const char* c;
-
- /* Keep track of how many backslashes have been encountered in a row. */
- int windows_backslashes = 0;
-
- /* Whether the argument must be quoted. */
- int needQuotes = kwsysSystem_Shell__ArgumentNeedsQuotes(in, isUnix, flags);
- if(needQuotes)
- {
- /* Add the opening quote for this argument. */
- if(flags & kwsysSystem_Shell_Flag_WatcomQuote)
- {
- if(isUnix)
- {
- *out++ = '"';
- }
- *out++ = '\'';
- }
- else
- {
- *out++ = '"';
- }
- }
-
- /* Scan the string for characters that require escaping or quoting. */
- for(c=in; *c; ++c)
- {
- /* Look for $(MAKEVAR) syntax if requested. */
- if(flags & kwsysSystem_Shell_Flag_AllowMakeVariables)
- {
- const char* skip = kwsysSystem_Shell__SkipMakeVariables(c);
- if(skip != c)
- {
- /* Copy to the end of the make variable references. */
- while(c != skip)
- {
- *out++ = *c++;
- }
-
- /* The make variable reference eliminates any escaping needed
- for preceding backslashes. */
- windows_backslashes = 0;
-
- /* Stop if we have reached the end of the string. */
- if(!*c)
- {
- break;
- }
- }
- }
-
- /* Check whether this character needs escaping for the shell. */
- if(isUnix)
- {
- /* On Unix a few special characters need escaping even inside a
- quoted argument. */
- if(*c == '\\' || *c == '"' || *c == '`' || *c == '$')
- {
- /* This character needs a backslash to escape it. */
- *out++ = '\\';
- }
- }
- else if(flags & kwsysSystem_Shell_Flag_EchoWindows)
- {
- /* On Windows the built-in command shell echo never needs escaping. */
- }
- else
- {
- /* On Windows only backslashes and double-quotes need escaping. */
- if(*c == '\\')
- {
- /* Found a backslash. It may need to be escaped later. */
- ++windows_backslashes;
- }
- else if(*c == '"')
- {
- /* Found a double-quote. Escape all immediately preceding
- backslashes. */
- while(windows_backslashes > 0)
- {
- --windows_backslashes;
- *out++ = '\\';
- }
-
- /* Add the backslash to escape the double-quote. */
- *out++ = '\\';
- }
- else
- {
- /* We encountered a normal character. This eliminates any
- escaping needed for preceding backslashes. */
- windows_backslashes = 0;
- }
- }
-
- /* Check whether this character needs escaping for a make tool. */
- if(*c == '$')
- {
- if(flags & kwsysSystem_Shell_Flag_Make)
- {
- /* In Makefiles a dollar is written $$. The make tool will
- replace it with just $ before passing it to the shell. */
- *out++ = '$';
- *out++ = '$';
- }
- else if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a dollar is written "$". If this is written in
- an un-quoted argument it starts a quoted segment, inserts
- the $ and ends the segment. If it is written in a quoted
- argument it ends quoting, inserts the $ and restarts
- quoting. Either way the $ is isolated from surrounding
- text to avoid looking like a variable reference. */
- *out++ = '"';
- *out++ = '$';
- *out++ = '"';
- }
- else
- {
- /* Otherwise a dollar is written just $. */
- *out++ = '$';
- }
- }
- else if(*c == '#')
- {
- if((flags & kwsysSystem_Shell_Flag_Make) &&
- (flags & kwsysSystem_Shell_Flag_WatcomWMake))
- {
- /* In Watcom WMake makefiles a pound is written $#. The make
- tool will replace it with just # before passing it to the
- shell. */
- *out++ = '$';
- *out++ = '#';
- }
- else
- {
- /* Otherwise a pound is written just #. */
- *out++ = '#';
- }
- }
- else if(*c == '%')
- {
- if((flags & kwsysSystem_Shell_Flag_VSIDE) ||
- ((flags & kwsysSystem_Shell_Flag_Make) &&
- ((flags & kwsysSystem_Shell_Flag_MinGWMake) ||
- (flags & kwsysSystem_Shell_Flag_NMake))))
- {
- /* In the VS IDE, NMake, or MinGW make a percent is written %%. */
- *out++ = '%';
- *out++ = '%';
- }
- else
- {
- /* Otherwise a percent is written just %. */
- *out++ = '%';
- }
- }
- else if(*c == ';')
- {
- if(flags & kwsysSystem_Shell_Flag_VSIDE)
- {
- /* In a VS IDE a semicolon is written ";". If this is written
- in an un-quoted argument it starts a quoted segment,
- inserts the ; and ends the segment. If it is written in a
- quoted argument it ends quoting, inserts the ; and restarts
- quoting. Either way the ; is isolated. */
- *out++ = '"';
- *out++ = ';';
- *out++ = '"';
- }
- else
- {
- /* Otherwise a semicolon is written just ;. */
- *out++ = ';';
- }
- }
- else
- {
- /* Store this character. */
- *out++ = *c;
- }
- }
-
- if(needQuotes)
- {
- /* Add enough backslashes to escape any trailing ones. */
- while(windows_backslashes > 0)
- {
- --windows_backslashes;
- *out++ = '\\';
- }
-
- /* Add the closing quote for this argument. */
- if(flags & kwsysSystem_Shell_Flag_WatcomQuote)
- {
- *out++ = '\'';
- if(isUnix)
- {
- *out++ = '"';
- }
- }
- else
- {
- *out++ = '"';
- }
- }
-
- /* Store a terminating null without incrementing. */
- *out = 0;
-
- return out;
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
- char* out,
- int flags)
-{
- return kwsysSystem_Shell__GetArgument(in, out, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
- char* out,
- int flags)
-{
- return kwsysSystem_Shell__GetArgument(in, out, 1, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in, int flags)
-{
- return kwsysSystem_Shell__GetArgumentSize(in, 0, flags);
-}
-
-/*--------------------------------------------------------------------------*/
-int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in, int flags)
-{
- return kwsysSystem_Shell__GetArgumentSize(in, 1, flags);
-}
-
/*--------------------------------------------------------------------------*/
static int kwsysSystem__AppendByte(char* local,
char** begin, char** end,
diff --git a/Source/kwsys/System.h.in b/Source/kwsys/System.h.in
index f21bf0d..3f3d3f4 100644
--- a/Source/kwsys/System.h.in
+++ b/Source/kwsys/System.h.in
@@ -24,28 +24,6 @@
#endif
#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define kwsysSystem_Parse_CommandForUnix kwsys_ns(System_Parse_CommandForUnix)
-# define kwsysSystem_Shell_GetArgumentForWindows kwsys_ns(System_Shell_GetArgumentForWindows)
-# define kwsysSystem_Shell_GetArgumentForUnix kwsys_ns(System_Shell_GetArgumentForUnix)
-# define kwsysSystem_Shell_GetArgumentSizeForWindows kwsys_ns(System_Shell_GetArgumentSizeForWindows)
-# define kwsysSystem_Shell_GetArgumentSizeForUnix kwsys_ns(System_Shell_GetArgumentSizeForUnix)
-# define kwsysSystem_Shell_Flag_e kwsys_ns(System_Shell_Flag_e)
-# define kwsysSystem_Shell_Flag_Make kwsys_ns(System_Shell_Flag_Make)
-# define kwsysSystem_Shell_Flag_VSIDE kwsys_ns(System_Shell_Flag_VSIDE)
-# define kwsysSystem_Shell_Flag_EchoWindows kwsys_ns(System_Shell_Flag_EchoWindows)
-# define kwsysSystem_Shell_Flag_WatcomWMake kwsys_ns(System_Shell_Flag_WatcomWMake)
-# define kwsysSystem_Shell_Flag_MinGWMake kwsys_ns(System_Shell_Flag_MinGWMake)
-# define kwsysSystem_Shell_Flag_NMake kwsys_ns(System_Shell_Flag_NMake)
-# define kwsysSystem_Shell_Flag_AllowMakeVariables kwsys_ns(System_Shell_Flag_AllowMakeVariables)
-# define kwsysSystem_Shell_Flag_WatcomQuote kwsys_ns(System_Shell_Flag_WatcomQuote)
-#endif
-
-#ifdef __VMS
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentForUnix \
- @KWSYS_NAMESPACE@System_Shell_UnixGA
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentSizeForUnix \
- @KWSYS_NAMESPACE@System_Shell_UnixGAS
-#define @KWSYS_NAMESPACE@System_Shell_GetArgumentForWindows \
- @KWSYS_NAMESPACE@System_Shell_WindowsGA
#endif
#if defined(__cplusplus)
@@ -54,69 +32,6 @@ extern "C"
#endif
/**
- * Transform the given command line argument for use in a Windows or
- * Unix shell. Returns a pointer to the end of the command line
- * argument in the provided output buffer. Flags may be passed to
- * modify the generated quoting and escape sequences to work under
- * alternative environments.
- */
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForWindows(const char* in,
- char* out,
- int flags);
-kwsysEXPORT char* kwsysSystem_Shell_GetArgumentForUnix(const char* in,
- char* out,
- int flags);
-
-/**
- * Compute the size of the buffer required to store the output from
- * kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix. The flags passed must be
- * identical between the two calls.
- */
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForWindows(const char* in,
- int flags);
-kwsysEXPORT int kwsysSystem_Shell_GetArgumentSizeForUnix(const char* in,
- int flags);
-
-/**
- * Flags to pass to kwsysSystem_Shell_GetArgumentForWindows or
- * kwsysSystem_Shell_GetArgumentForUnix. These modify the generated
- * quoting and escape sequences to work under alternative
- * environments.
- */
-enum kwsysSystem_Shell_Flag_e
-{
- /** The target shell is in a makefile. */
- kwsysSystem_Shell_Flag_Make = (1<<0),
-
- /** The target shell is in a VS project file. Do not use with
- Shell_Flag_Make. */
- kwsysSystem_Shell_Flag_VSIDE = (1<<1),
-
- /** In a windows shell the argument is being passed to "echo". */
- kwsysSystem_Shell_Flag_EchoWindows = (1<<2),
-
- /** The target shell is in a Watcom WMake makefile. */
- kwsysSystem_Shell_Flag_WatcomWMake = (1<<3),
-
- /** The target shell is in a MinGW Make makefile. */
- kwsysSystem_Shell_Flag_MinGWMake = (1<<4),
-
- /** The target shell is in a NMake makefile. */
- kwsysSystem_Shell_Flag_NMake = (1<<5),
-
- /** Make variable reference syntax $(MAKEVAR) should not be escaped
- to allow a build tool to replace it. Replacement values
- containing spaces, quotes, backslashes, or other
- non-alphanumeric characters that have significance to some makes
- or shells produce undefined behavior. */
- kwsysSystem_Shell_Flag_AllowMakeVariables = (1<<6),
-
- /** The target shell quoting uses extra single Quotes for Watcom tools. */
- kwsysSystem_Shell_Flag_WatcomQuote = (1<<7)
-};
-
-/**
* Parse a unix-style command line string into separate arguments.
*
* On success, returns a pointer to an array of pointers to individual
@@ -148,19 +63,6 @@ kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
# undef kwsysEXPORT
# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# undef kwsysSystem_Parse_CommandForUnix
-# undef kwsysSystem_Shell_GetArgumentForWindows
-# undef kwsysSystem_Shell_GetArgumentForUnix
-# undef kwsysSystem_Shell_GetArgumentSizeForWindows
-# undef kwsysSystem_Shell_GetArgumentSizeForUnix
-# undef kwsysSystem_Shell_Flag_e
-# undef kwsysSystem_Shell_Flag_Make
-# undef kwsysSystem_Shell_Flag_VSIDE
-# undef kwsysSystem_Shell_Flag_EchoWindows
-# undef kwsysSystem_Shell_Flag_WatcomWMake
-# undef kwsysSystem_Shell_Flag_MinGWMake
-# undef kwsysSystem_Shell_Flag_NMake
-# undef kwsysSystem_Shell_Flag_AllowMakeVariables
-# undef kwsysSystem_Shell_Flag_WatcomQuote
# endif
#endif
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index b0434f4..6e81b0b 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -81,6 +81,11 @@ typedef int siginfo_t;
# include <errno.h> // extern int errno;
#endif
+#if defined (__CYGWIN__) && !defined(_WIN32)
+# include <windows.h>
+# undef _WIN32
+#endif
+
#ifdef __FreeBSD__
# include <sys/sysctl.h>
# include <fenv.h>
@@ -366,6 +371,8 @@ public:
const char *procLimitEnvVarName);
LongLong GetProcMemoryUsed();
+ double GetLoadAverage();
+
// enable/disable stack trace signal handler.
static
void SetStackTraceOnError(int enable);
@@ -820,6 +827,11 @@ SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
return this->Implementation->GetProcMemoryUsed();
}
+double SystemInformation::GetLoadAverage()
+{
+ return this->Implementation->GetLoadAverage();
+}
+
SystemInformation::LongLong SystemInformation::GetProcessId()
{
return this->Implementation->GetProcessId();
@@ -1490,6 +1502,60 @@ void SymbolProperties::Initialize(void *address)
}
#endif // don't define this class if we're not using it
+// --------------------------------------------------------------------------
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(_MSC_VER) && _MSC_VER < 1310
+# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes
+#endif
+#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+double calculateCPULoad(unsigned __int64 idleTicks,
+ unsigned __int64 totalTicks)
+{
+ static double previousLoad = -0.0;
+ static unsigned __int64 previousIdleTicks = 0;
+ static unsigned __int64 previousTotalTicks = 0;
+
+ unsigned __int64 const idleTicksSinceLastTime =
+ idleTicks - previousIdleTicks;
+ unsigned __int64 const totalTicksSinceLastTime =
+ totalTicks - previousTotalTicks;
+
+ double load;
+ if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0)
+ {
+ // No new information. Use previous result.
+ load = previousLoad;
+ }
+ else
+ {
+ // Calculate load since last time.
+ load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime;
+
+ // Smooth if possible.
+ if (previousLoad > 0)
+ {
+ load = 0.25 * load + 0.75 * previousLoad;
+ }
+ }
+
+ previousLoad = load;
+ previousIdleTicks = idleTicks;
+ previousTotalTicks = totalTicks;
+
+ return load;
+}
+
+unsigned __int64 fileTimeToUInt64(FILETIME const& ft)
+{
+ LARGE_INTEGER out;
+ out.HighPart = ft.dwHighDateTime;
+ out.LowPart = ft.dwLowDateTime;
+ return out.QuadPart;
+}
+#endif
+
} // anonymous namespace
@@ -3612,6 +3678,38 @@ SystemInformationImplementation::GetProcMemoryUsed()
#endif
}
+double SystemInformationImplementation::GetLoadAverage()
+{
+#if defined(KWSYS_CXX_HAS_GETLOADAVG)
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ if (getloadavg(loadavg, 3) > 0)
+ {
+ return loadavg[0];
+ }
+ return -0.0;
+#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes)
+ // Old windows.h headers do not provide GetSystemTimes.
+ typedef BOOL (WINAPI *GetSystemTimesType)(LPFILETIME, LPFILETIME,
+ LPFILETIME);
+ static GetSystemTimesType pGetSystemTimes =
+ (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"),
+ "GetSystemTimes");
+ FILETIME idleTime, kernelTime, userTime;
+ if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime))
+ {
+ unsigned __int64 const idleTicks =
+ fileTimeToUInt64(idleTime);
+ unsigned __int64 const totalTicks =
+ fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime);
+ return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU();
+ }
+ return -0.0;
+#else
+ // Not implemented on this platform.
+ return -0.0;
+#endif
+}
+
/**
Get the process id of the running process.
*/
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index a9fd05d..4acdc4f 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -130,6 +130,10 @@ public:
// Get system RAM used by this process id in units of KiB.
LongLong GetProcMemoryUsed();
+ // Return the load average of the machine or -0.0 if it cannot
+ // be determined.
+ double GetLoadAverage();
+
// 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.
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index c834e34..0714344 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -385,6 +385,26 @@ class SystemToolsTranslationMap :
{
};
+#ifdef _WIN32
+struct SystemToolsPathCaseCmp
+{
+ bool operator()(kwsys_stl::string const& l, kwsys_stl::string const& r) const
+ {
+# ifdef _MSC_VER
+ return _stricmp(l.c_str(), r.c_str()) < 0;
+# elif defined(__GNUC__)
+ return strcasecmp(l.c_str(), r.c_str()) < 0;
+# else
+ return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+# endif
+ }
+};
+
+class SystemToolsPathCaseMap:
+ public kwsys_stl::map<kwsys_stl::string, kwsys_stl::string,
+ SystemToolsPathCaseCmp> {};
+#endif
+
// adds the elements of the env variable path to the arg passed in
void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char* env)
{
@@ -3178,8 +3198,16 @@ bool SystemTools::FileIsDirectory(const kwsys_stl::string& inName)
bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
{
#if defined( _WIN32 )
- (void)name;
- return false;
+ DWORD attr = GetFileAttributesW(
+ SystemTools::ConvertToWindowsExtendedPath(name).c_str());
+ if (attr != INVALID_FILE_ATTRIBUTES)
+ {
+ return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+ }
+ else
+ {
+ return false;
+ }
#else
struct stat fs;
if(lstat(name.c_str(), &fs) == 0)
@@ -3690,6 +3718,11 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
// Start with root component.
kwsys_stl::vector<kwsys_stl::string>::size_type idx = 0;
casePath = path_components[idx++];
+ // make sure drive letter is always upper case
+ if(casePath.size() > 1 && casePath[1] == ':')
+ {
+ casePath[0] = toupper(casePath[0]);
+ }
const char* sep = "";
// If network path, fill casePath with server/share so FindFirstFile
@@ -3745,27 +3778,21 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p)
#ifndef _WIN32
return p;
#else
- kwsys_stl::string casePath = p;
- // make sure drive letter is always upper case
- if(casePath.size() > 1 && casePath[1] == ':')
- {
- casePath[0] = toupper(casePath[0]);
- }
-
// Check to see if actual case has already been called
- // for this path, and the result is stored in the LongPathMap
- SystemToolsTranslationMap::iterator i =
- SystemTools::LongPathMap->find(casePath);
- if(i != SystemTools::LongPathMap->end())
+ // for this path, and the result is stored in the PathCaseMap
+ SystemToolsPathCaseMap::iterator i =
+ SystemTools::PathCaseMap->find(p);
+ if(i != SystemTools::PathCaseMap->end())
{
return i->second;
}
+ kwsys_stl::string casePath;
int len = GetCasePathName(p, casePath);
if(len == 0 || len > MAX_PATH+1)
{
return p;
}
- (*SystemTools::LongPathMap)[p] = casePath;
+ (*SystemTools::PathCaseMap)[p] = casePath;
return casePath;
#endif
}
@@ -4211,6 +4238,11 @@ SystemTools::DetectFileType(const char *filename,
return SystemTools::FileTypeUnknown;
}
+ if (SystemTools::FileIsDirectory(filename))
+ {
+ return SystemTools::FileTypeUnknown;
+ }
+
FILE *fp = Fopen(filename, "rb");
if (!fp)
{
@@ -4224,6 +4256,7 @@ SystemTools::DetectFileType(const char *filename,
fclose(fp);
if (read_length == 0)
{
+ delete [] buffer;
return SystemTools::FileTypeUnknown;
}
@@ -4408,7 +4441,7 @@ bool SystemTools::FileIsFullPath(const char* in_name, size_t len)
bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& shortPath)
{
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
const int size = int(path.size()) +1; // size of return
char *tempPath = new char[size]; // create a buffer
DWORD ret;
@@ -5139,7 +5172,9 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
// necessary.
static unsigned int SystemToolsManagerCount;
SystemToolsTranslationMap *SystemTools::TranslationMap;
-SystemToolsTranslationMap *SystemTools::LongPathMap;
+#ifdef _WIN32
+SystemToolsPathCaseMap *SystemTools::PathCaseMap;
+#endif
#ifdef __CYGWIN__
SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
#endif
@@ -5187,7 +5222,9 @@ void SystemTools::ClassInitialize()
#endif
// Allocate the translation map first.
SystemTools::TranslationMap = new SystemToolsTranslationMap;
- SystemTools::LongPathMap = new SystemToolsTranslationMap;
+#ifdef _WIN32
+ SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
+#endif
#ifdef __CYGWIN__
SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
#endif
@@ -5244,7 +5281,9 @@ void SystemTools::ClassInitialize()
void SystemTools::ClassFinalize()
{
delete SystemTools::TranslationMap;
- delete SystemTools::LongPathMap;
+#ifdef _WIN32
+ delete SystemTools::PathCaseMap;
+#endif
#ifdef __CYGWIN__
delete SystemTools::Cyg2Win32Map;
#endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 93cde02..7899141 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -54,6 +54,8 @@ namespace @KWSYS_NAMESPACE@
{
class SystemToolsTranslationMap;
+class SystemToolsPathCaseMap;
+
/** \class SystemToolsManager
* \brief Use to make sure SystemTools is initialized before it is used
* and is the last static object destroyed
@@ -944,7 +946,9 @@ private:
* Each time 'dir' will be found it will be replace by 'refdir'
*/
static SystemToolsTranslationMap *TranslationMap;
- static SystemToolsTranslationMap *LongPathMap;
+#ifdef _WIN32
+ static SystemToolsPathCaseMap *PathCaseMap;
+#endif
#ifdef __CYGWIN__
static SystemToolsTranslationMap *Cyg2Win32Map;
#endif
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index 82620da..1596fe4 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -452,6 +452,19 @@ int main()
}
#endif
+#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG
+// Match feature definitions from SystemInformation.cxx
+#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+int main()
+{
+ double loadavg[3] = { 0.0, 0.0, 0.0 };
+ return getloadavg(loadavg, 3);
+}
+#endif
+
#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64
# if defined(KWSYS_HAS_LFS)
# define _LARGEFILE_SOURCE
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 47c3fb0..d0e20c1 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -29,26 +29,48 @@
# include <windows.h>
#else
# include <unistd.h>
+# include <signal.h>
#endif
#if defined(__BORLANDC__)
# pragma warn -8060 /* possibly incorrect assignment */
#endif
+/* Platform-specific sleep functions. */
+
#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)
+static inline void testProcess_usleep(unsigned int usec)
+{
+ snooze(usec);
+}
+#elif defined(_WIN32)
+/* Windows can only sleep in millisecond intervals. */
+static void testProcess_usleep(unsigned int usec)
{
- snooze(msec);
+ Sleep(usec / 1000);
}
#else
# define testProcess_usleep usleep
#endif
+#if defined(_WIN32)
+static void testProcess_sleep(unsigned int sec)
+{
+ Sleep(sec*1000);
+}
+#else
+static void testProcess_sleep(unsigned int sec)
+{
+ sleep(sec);
+}
+#endif
+
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 repeat, int disown, int createNewGroup,
+ unsigned int interruptDelay);
static int test1(int argc, const char* argv[])
{
@@ -73,11 +95,7 @@ static int test3(int argc, const char* argv[])
fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
fflush(stdout);
fflush(stderr);
-#if defined(_WIN32)
- Sleep(15000);
-#else
- sleep(15);
-#endif
+ testProcess_sleep(15);
fprintf(stdout, "Output after sleep on stdout from timeout test.\n");
fprintf(stderr, "Output after sleep on stderr from timeout test.\n");
return 0;
@@ -102,7 +120,7 @@ static int test4(int argc, const char* argv[])
#endif
(void)argc; (void)argv;
fprintf(stdout, "Output before crash on stdout from crash test.\n");
- fprintf(stderr, "Output before crash on stderr from crash test.\n");
+ fprintf(stderr, "Output before crash on stderr from crash test.\n");
fflush(stdout);
fflush(stderr);
assert(invalidAddress); /* Quiet Clang scan-build. */
@@ -127,7 +145,7 @@ static int test5(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
r = runChild(cmd, kwsysProcess_State_Exception,
- kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0);
+ kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0, 0, 0);
fprintf(stdout, "Output on stdout after recursive test.\n");
fprintf(stderr, "Output on stderr after recursive test.\n");
fflush(stdout);
@@ -168,11 +186,7 @@ static int test7(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
/* Sleep for 1 second. */
-#if defined(_WIN32)
- Sleep(1000);
-#else
- sleep(1);
-#endif
+ testProcess_sleep(1);
fprintf(stdout, "Output on stdout after sleep.\n");
fprintf(stderr, "Output on stderr after sleep.\n");
fflush(stdout);
@@ -196,7 +210,7 @@ static int test8(int argc, const char* argv[])
fflush(stdout);
fflush(stderr);
r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None,
- 1, 1, 1, 0, 10, 0, 1, 1);
+ 1, 1, 1, 0, 10, 0, 1, 1, 0, 0);
fprintf(stdout, "Output on stdout after grandchild test.\n");
fprintf(stderr, "Output on stderr after grandchild test.\n");
fflush(stdout);
@@ -217,18 +231,137 @@ static int test8_grandchild(int argc, const char* argv[])
implemented. */
fclose(stdout);
fclose(stderr);
+ testProcess_sleep(15);
+ return 0;
+}
+
+static int test9(int argc, const char* argv[])
+{
+ /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+ process. Here, we start a child process that sleeps for a long time
+ while ignoring signals. The test is successful if this process waits
+ for the child to return before exiting from the Ctrl+C handler.
+
+ WARNING: This test will falsely pass if the share parameter of runChild
+ was set to 0 when invoking the test9 process. */
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "109";
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before grandchild test.\n");
+ fprintf(stderr, "Output on stderr before grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ r = runChild(cmd, kwsysProcess_State_Exited,
+ kwsysProcess_Exception_None,
+ 0, 1, 1, 0, 30, 0, 1, 0, 0, 0);
+ /* This sleep will avoid a race condition between this function exiting
+ normally and our Ctrl+C handler exiting abnormally after the process
+ exits. */
+ testProcess_sleep(1);
+ fprintf(stdout, "Output on stdout after grandchild test.\n");
+ fprintf(stderr, "Output on stderr after grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return r;
+}
+
#if defined(_WIN32)
- Sleep(15000);
+static BOOL WINAPI test9_grandchild_handler(DWORD dwCtrlType)
+{
+ /* Ignore all Ctrl+C/Break signals. We must use an actual handler function
+ instead of using SetConsoleCtrlHandler(NULL, TRUE) so that we can also
+ ignore Ctrl+Break in addition to Ctrl+C. */
+ (void)dwCtrlType;
+ return TRUE;
+}
+#endif
+
+static int test9_grandchild(int argc, const char* argv[])
+{
+ /* The grandchild just sleeps for a few seconds while ignoring signals. */
+ (void)argc; (void)argv;
+#if defined(_WIN32)
+ if(!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE))
+ {
+ return 1;
+ }
#else
- sleep(15);
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ if(sigaction(SIGINT, &sa, 0) < 0)
+ {
+ return 1;
+ }
#endif
+ fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ /* Sleep for 9 seconds. */
+ testProcess_sleep(9);
+ fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return 0;
+}
+
+static int test10(int argc, const char* argv[])
+{
+ /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this
+ process. Here, we start a child process that sleeps for a long time and
+ processes signals normally. However, this grandchild is created in a new
+ process group - ensuring that Ctrl+C we receive is sent to our process
+ groups. We make sure it exits anyway. */
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "110";
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before grandchild test.\n");
+ fprintf(stderr, "Output on stderr before grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ r = runChild(cmd, kwsysProcess_State_Exception,
+ kwsysProcess_Exception_Interrupt,
+ 0, 1, 1, 0, 30, 0, 1, 0, 1, 0);
+ fprintf(stdout, "Output on stdout after grandchild test.\n");
+ fprintf(stderr, "Output on stderr after grandchild test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return r;
+}
+
+static int test10_grandchild(int argc, const char* argv[])
+{
+ /* The grandchild just sleeps for a few seconds and handles signals. */
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild before sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ /* Sleep for 6 seconds. */
+ testProcess_sleep(6);
+ fprintf(stdout, "Output on stdout from grandchild after sleep.\n");
+ fprintf(stderr, "Output on stderr from grandchild after sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
return 0;
}
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)
+ int poll, int disown, int createNewGroup,
+ unsigned int interruptDelay)
{
int result = 0;
char* data = 0;
@@ -249,6 +382,10 @@ static int runChild2(kwsysProcess* kp,
{
kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1);
}
+ if(createNewGroup)
+ {
+ kwsysProcess_SetOption(kp, kwsysProcess_Option_CreateProcessGroup, 1);
+ }
kwsysProcess_Execute(kp);
if(poll)
@@ -256,6 +393,12 @@ static int runChild2(kwsysProcess* kp,
pUserTimeout = &userTimeout;
}
+ if(interruptDelay)
+ {
+ testProcess_sleep(interruptDelay);
+ kwsysProcess_Interrupt(kp);
+ }
+
if(!share && !disown)
{
int p;
@@ -286,17 +429,13 @@ static int runChild2(kwsysProcess* kp,
if(poll)
{
/* Delay to avoid busy loop during polling. */
-#if defined(_WIN32)
- Sleep(100);
-#else
testProcess_usleep(100000);
-#endif
}
if(delay)
{
/* Purposely sleeping only on Win32 to let pipe fill up. */
#if defined(_WIN32)
- Sleep(100);
+ testProcess_usleep(100000);
#endif
}
}
@@ -337,7 +476,7 @@ static int runChild2(kwsysProcess* kp,
printf("Error in administrating child process: [%s]\n",
kwsysProcess_GetErrorString(kp)); break;
};
-
+
if(result)
{
if(exception != kwsysProcess_GetExitException(kp))
@@ -353,7 +492,7 @@ static int runChild2(kwsysProcess* kp,
value, kwsysProcess_GetExitValue(kp));
}
}
-
+
if(kwsysProcess_GetState(kp) != state)
{
fprintf(stderr, "Mismatch in state. "
@@ -374,9 +513,37 @@ static int runChild2(kwsysProcess* kp,
return result;
}
+/**
+ * Runs a child process and blocks until it returns. Arguments as follows:
+ *
+ * cmd = Command line to run.
+ * state = Expected return value of kwsysProcess_GetState after exit.
+ * exception = Expected return value of kwsysProcess_GetExitException.
+ * value = Expected return value of kwsysProcess_GetExitValue.
+ * share = Whether to share stdout/stderr child pipes with our pipes
+ * by way of kwsysProcess_SetPipeShared. If false, new pipes
+ * are created.
+ * output = If !share && !disown, whether to write the child's stdout
+ * and stderr output to our stdout.
+ * delay = If !share && !disown, adds an additional short delay to
+ * the pipe loop to allow the pipes to fill up; Windows only.
+ * timeout = Non-zero to sets a timeout in seconds via
+ * kwsysProcess_SetTimeout.
+ * poll = If !share && !disown, we count the number of 0.1 second
+ * intervals where the child pipes had no new data. We fail
+ * if not in the bounds of MINPOLL/MAXPOLL.
+ * repeat = Number of times to run the process.
+ * disown = If set, the process is disowned.
+ * createNewGroup = If set, the process is created in a new process group.
+ * interruptDelay = If non-zero, number of seconds to delay before
+ * interrupting the process. Note that this delay will occur
+ * BEFORE any reading/polling of pipes occurs and before any
+ * detachment occurs.
+ */
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 poll, int repeat, int disown, int createNewGroup,
+ unsigned int interruptDelay)
{
int result = 1;
kwsysProcess* kp = kwsysProcess_New();
@@ -388,7 +555,8 @@ int runChild(const char* cmd[], int state, int exception, int value,
while(repeat-- > 0)
{
result = runChild2(kp, cmd, state, exception, value, share,
- output, delay, timeout, poll, disown);
+ output, delay, timeout, poll, disown, createNewGroup,
+ interruptDelay);
}
kwsysProcess_Delete(kp);
return result;
@@ -435,7 +603,7 @@ int main(int argc, const char* argv[])
n = atoi(argv[2]);
}
/* Check arguments. */
- if(((n >= 1 && n <= 8) || n == 108) && argc == 3)
+ if(((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3)
{
/* This is the child process for a requested test number. */
switch (n)
@@ -448,15 +616,19 @@ int main(int argc, const char* argv[])
case 6: test6(argc, argv); return 0;
case 7: return test7(argc, argv);
case 8: return test8(argc, argv);
+ case 9: return test9(argc, argv);
+ case 10: return test10(argc, argv);
case 108: return test8_grandchild(argc, argv);
+ case 109: return test9_grandchild(argc, argv);
+ case 110: return test10_grandchild(argc, argv);
}
fprintf(stderr, "Invalid test number %d.\n", n);
return 1;
}
- else if(n >= 1 && n <= 8)
+ else if(n >= 1 && n <= 10)
{
/* This is the parent process for a requested test number. */
- int states[8] =
+ int states[10] =
{
kwsysProcess_State_Exited,
kwsysProcess_State_Exited,
@@ -465,9 +637,11 @@ int main(int argc, const char* argv[])
kwsysProcess_State_Exited,
kwsysProcess_State_Expired,
kwsysProcess_State_Exited,
- kwsysProcess_State_Exited
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Expired, /* Ctrl+C handler test */
+ kwsysProcess_State_Exception /* Process group test */
};
- int exceptions[8] =
+ int exceptions[10] =
{
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
@@ -476,14 +650,19 @@ int main(int argc, const char* argv[])
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
kwsysProcess_Exception_None,
- kwsysProcess_Exception_None
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_Interrupt
};
- int values[8] = {0, 123, 1, 1, 0, 0, 0, 0};
- int outputs[8] = {1, 1, 1, 1, 1, 0, 1, 1};
- int delays[8] = {0, 0, 0, 0, 0, 1, 0, 0};
- double timeouts[8] = {10, 10, 10, 30, 30, 10, -1, 10};
- int polls[8] = {0, 0, 0, 0, 0, 0, 1, 0};
- int repeat[8] = {2, 1, 1, 1, 1, 1, 1, 1};
+ int values[10] = {0, 123, 1, 1, 0, 0, 0, 0, 1, 1};
+ int shares[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+ int outputs[10] = {1, 1, 1, 1, 1, 0, 1, 1, 1, 1};
+ int delays[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
+ double timeouts[10] = {10, 10, 10, 30, 30, 10, -1, 10, 6, 4};
+ int polls[10] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};
+ int repeat[10] = {2, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+ int createNewGroups[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
+ unsigned int interruptDelays[10] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 2};
int r;
const char* cmd[4];
#ifdef _WIN32
@@ -515,9 +694,10 @@ int main(int argc, const char* argv[])
fprintf(stderr, "Output on stderr before test %d.\n", n);
fflush(stdout);
fflush(stderr);
- r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0,
+ r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], shares[n-1],
outputs[n-1], delays[n-1], timeouts[n-1],
- polls[n-1], repeat[n-1], 0);
+ polls[n-1], repeat[n-1], 0, createNewGroups[n-1],
+ interruptDelays[n-1]);
fprintf(stdout, "Output on stdout after test %d.\n", n);
fprintf(stderr, "Output on stderr after test %d.\n", n);
fflush(stdout);
@@ -536,7 +716,8 @@ int main(int argc, const char* argv[])
int exception = kwsysProcess_Exception_None;
int value = 0;
double timeout = 0;
- int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0);
+ int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout,
+ 0, 1, 0, 0, 0);
return r;
}
else
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 53d51ac..fc8ea55 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -87,6 +87,7 @@ int testSystemInformation(int, char*[])
printMethod3(info, GetProcMemoryAvailable("KWSHL","KWSPL"), "KiB");
printMethod3(info, GetHostMemoryUsed(), "KiB");
printMethod3(info, GetProcMemoryUsed(), "KiB");
+ printMethod(info, GetLoadAverage);
for (long int i = 0; i <= 31; i++)
{
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 15d8eab..7b5c025 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -98,6 +98,10 @@ static bool CheckEscapeChars(kwsys_stl::string input,
static bool CheckFileOperations()
{
bool res = true;
+ const kwsys_stl::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/testSystemToolsNonExistingFile");
+ const kwsys_stl::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/.");
const kwsys_stl::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR
"/testSystemTools.bin");
const kwsys_stl::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR
@@ -106,6 +110,24 @@ static bool CheckFileOperations()
"/testSystemToolsNewDir");
const kwsys_stl::string testNewFile(testNewDir + "/testNewFile.txt");
+ if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) !=
+ kwsys::SystemTools::FileTypeUnknown)
+ {
+ kwsys_ios::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << testNonExistingFile << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) !=
+ kwsys::SystemTools::FileTypeUnknown)
+ {
+ kwsys_ios::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << testDotFile << kwsys_ios::endl;
+ res = false;
+ }
+
if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) !=
kwsys::SystemTools::FileTypeBinary)
{