summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst18
-rw-r--r--Help/release/dev/ExternalProject-USES_TERMINAL.rst7
-rw-r--r--Help/release/dev/add-apple-swift-language.rst9
-rw-r--r--Help/release/dev/auto_export_dll_symbols.rst6
-rw-r--r--Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst6
-rw-r--r--Modules/CMakeDetermineSwiftCompiler.cmake53
-rw-r--r--Modules/CMakeSwiftCompiler.cmake.in5
-rw-r--r--Modules/CMakeSwiftInformation.cmake41
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake15
-rw-r--r--Modules/CompilerId/main.swift.in1
-rw-r--r--Modules/ExternalProject.cmake83
-rw-r--r--Modules/FindPythonLibs.cmake39
-rw-r--r--Modules/Platform/Windows-MSVC.cmake2
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx10
-rw-r--r--Source/bindexplib.cxx428
-rw-r--r--Source/cmArchiveWrite.cxx11
-rw-r--r--Source/cmArchiveWrite.h1
-rw-r--r--Source/cmCTest.cxx14
-rw-r--r--Source/cmCTest.h1
-rw-r--r--Source/cmDependsFortran.cxx2
-rw-r--r--Source/cmFunctionCommand.cxx1
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx70
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx4
-rw-r--r--Source/cmLinkedTree.h18
-rw-r--r--Source/cmListFileCache.cxx39
-rw-r--r--Source/cmListFileCache.h29
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx31
-rw-r--r--Source/cmMacroCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx143
-rw-r--r--Source/cmMakefile.h27
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx53
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx54
-rw-r--r--Source/cmState.cxx140
-rw-r--r--Source/cmState.h37
-rw-r--r--Source/cmTarget.cxx5
-rw-r--r--Source/cmVariableWatchCommand.cxx1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx30
-rw-r--r--Source/cmcmd.cxx39
-rw-r--r--Tests/CMakeLists.txt6
-rw-r--r--Tests/Fortran/CMakeLists.txt2
-rw-r--r--Tests/Fortran/test_preprocess.F902
-rw-r--r--Tests/Fortran/test_preprocess_module.F905
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExport.cmake7
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt1
-rw-r--r--Tests/RunCMake/AutoExportDll/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake26
-rw-r--r--Tests/RunCMake/AutoExportDll/foo.c15
-rw-r--r--Tests/RunCMake/AutoExportDll/hello.cxx13
-rw-r--r--Tests/RunCMake/AutoExportDll/hello.h18
-rw-r--r--Tests/RunCMake/AutoExportDll/say.cxx37
-rw-r--r--Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/AutoExportDll/sub/sub.cxx4
-rw-r--r--Tests/RunCMake/AutoExportDll/world.cxx6
-rw-r--r--Tests/RunCMake/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake97
-rw-r--r--Tests/RunCMake/ExternalProject/UsesTerminal.cmake45
-rw-r--r--Tests/RunCMake/Swift/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Swift/Enable-stdout.txt1
-rw-r--r--Tests/RunCMake/Swift/Enable.cmake1
-rw-r--r--Tests/RunCMake/Swift/NotSupported-result.txt1
-rw-r--r--Tests/RunCMake/Swift/NotSupported-stderr.txt5
-rw-r--r--Tests/RunCMake/Swift/NotSupported.cmake1
-rw-r--r--Tests/RunCMake/Swift/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld-result.txt1
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld-stderr.txt5
-rw-r--r--Tests/RunCMake/Swift/XcodeTooOld.cmake1
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/ParenInENV-stderr.txt4
-rw-r--r--Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt12
-rw-r--r--Tests/RunCMake/Syntax/StringNoSpace-stderr.txt8
-rw-r--r--Tests/SwiftMix/CMain.c4
-rw-r--r--Tests/SwiftMix/CMakeLists.txt5
-rw-r--r--Tests/SwiftMix/ObjC-Swift.h0
-rw-r--r--Tests/SwiftMix/ObjCMain.m4
-rw-r--r--Tests/SwiftMix/SwiftMain.swift10
-rw-r--r--Tests/SwiftOnly/CMakeLists.txt4
-rw-r--r--Tests/SwiftOnly/main.swift1
92 files changed, 1797 insertions, 110 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 9a60a10..b767ed6 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -251,6 +251,7 @@ Properties on Targets
/prop_tgt/VS_WINRT_EXTENSIONS
/prop_tgt/VS_WINRT_REFERENCES
/prop_tgt/WIN32_EXECUTABLE
+ /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
/prop_tgt/XCODE_ATTRIBUTE_an-attribute
/prop_tgt/XCTEST
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index adbc40b..f54436a 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -275,6 +275,7 @@ Variables that Control the Build
/variable/CMAKE_USE_RELATIVE_PATHS
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN
/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+ /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
/variable/CMAKE_WIN32_EXECUTABLE
/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
/variable/EXECUTABLE_OUTPUT_PATH
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..3f48af8
--- /dev/null
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,18 @@
+WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------
+
+This property is implemented only for MS-compatible tools on Windows.
+
+Enable this boolean property to automatically create a module definition
+(``.def``) file with all global symbols found in the input ``.obj`` files
+for a ``SHARED`` library on Windows. The module definition file will be
+passed to the linker causing all symbols to be exported from the ``.dll``.
+For global *data* symbols, ``__declspec(dllimport)`` must still be used when
+compiling against the code in the ``.dll``. All other function symbols will
+be automatically exported and imported by callers. This simplifies porting
+projects to Windows by reducing the need for explicit ``dllexport`` markup,
+even in ``C++`` classes.
+
+This property is initialized by the value of
+the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/release/dev/ExternalProject-USES_TERMINAL.rst b/Help/release/dev/ExternalProject-USES_TERMINAL.rst
new file mode 100644
index 0000000..415540d
--- /dev/null
+++ b/Help/release/dev/ExternalProject-USES_TERMINAL.rst
@@ -0,0 +1,7 @@
+ExternalProject-USES_TERMINAL
+-----------------------------
+
+* The :module:`ExternalProject` module learned new ``USES_TERMINAL``
+ arguments for giving steps exclusive terminal access. Especially
+ useful with the :generator:`Ninja` generator to monitor CMake
+ superbuild progress and prevent CPU oversubscription.
diff --git a/Help/release/dev/add-apple-swift-language.rst b/Help/release/dev/add-apple-swift-language.rst
new file mode 100644
index 0000000..60ce5d8
--- /dev/null
+++ b/Help/release/dev/add-apple-swift-language.rst
@@ -0,0 +1,9 @@
+add-apple-swift-language
+------------------------
+
+* CMake learned rudimentary support for the Apple Swift language. When using
+ the :generator:`Xcode` generator with Xcode 6.1 or higher, one may enable
+ the ``Swift`` language with the :command:`enable_language` command or the
+ :command:`project` command (this is an error with other generators or when
+ Xcode is too old). Then one may list ``.swift`` source files in targets
+ for compilation.
diff --git a/Help/release/dev/auto_export_dll_symbols.rst b/Help/release/dev/auto_export_dll_symbols.rst
new file mode 100644
index 0000000..9db2b5e
--- /dev/null
+++ b/Help/release/dev/auto_export_dll_symbols.rst
@@ -0,0 +1,6 @@
+auto_export_dll_symbols
+-----------------------
+
+* On Windows with MS-compatible tools, CMake learned to optionally
+ generate a module definition (``.def``) file for ``SHARED`` libraries.
+ See the :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..1636842
--- /dev/null
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------------
+
+Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
new file mode 100644
index 0000000..bff1ae9
--- /dev/null
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -0,0 +1,53 @@
+
+#=============================================================================
+# Copyright 2002-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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+
+if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
+ if(XCODE_VERSION VERSION_LESS 6.1)
+ message(FATAL_ERROR "Swift language not supported by Xcode ${XCODE_VERSION}")
+ endif()
+ set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift)
+ _cmake_find_compiler_path(Swift)
+else()
+ message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator")
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_Swift_COMPILER_ID_RUN)
+ set(CMAKE_Swift_COMPILER_ID_RUN 1)
+
+ list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple)
+ set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler")
+
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift")
+ set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+ # Try to identify the compiler.
+ set(CMAKE_Swift_COMPILER_ID)
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+ CMAKE_DETERMINE_COMPILER_ID(Swift "" CompilerId/main.swift)
+endif()
+
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+ get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH)
+endif ()
+
+include(CMakeFindBinUtils)
+
+# configure variables set in this file for fast reload later on
+configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
+ ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake
+ @ONLY
+ )
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
new file mode 100644
index 0000000..45f0a31
--- /dev/null
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -0,0 +1,5 @@
+set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@")
+set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@")
+
+set(CMAKE_Swift_COMPILER_ID_RUN 1)
+set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
new file mode 100644
index 0000000..61ad928
--- /dev/null
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -0,0 +1,41 @@
+
+#=============================================================================
+# 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+
+# Load compiler-specific information.
+if(CMAKE_Swift_COMPILER_ID)
+ include(Compiler/${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# load the system- and compiler specific files
+if(CMAKE_Swift_COMPILER_ID)
+ # load a hardware specific file, mostly useful for embedded compilers
+ if(CMAKE_SYSTEM_PROCESSOR)
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+ endif()
+ include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
+endif()
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+ set(CMAKE_SHARED_MODULE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_Swift_FLAGS})
+ set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Swift_FLAGS})
+endif()
+
+include(CMakeCommonLanguageInclude)
+
+set(CMAKE_Swift_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
new file mode 100644
index 0000000..9186426
--- /dev/null
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -0,0 +1,15 @@
+
+#=============================================================================
+# Copyright 2003-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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+set(CMAKE_Swift_COMPILER_WORKS 1)
diff --git a/Modules/CompilerId/main.swift.in b/Modules/CompilerId/main.swift.in
new file mode 100644
index 0000000..962e857
--- /dev/null
+++ b/Modules/CompilerId/main.swift.in
@@ -0,0 +1 @@
+println("CMakeSwiftCompilerId")
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index eee1841..f6844be 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -175,6 +175,23 @@ Create custom targets to build projects in external trees
``LOG_INSTALL 1``
Wrap install in script to log output
+ Steps can be given direct access to the terminal if possible. With
+ the :generator:`Ninja` generator, this places the steps in the
+ ``console`` :prop_gbl:`pool <JOB_POOLS>`. Options are:
+
+ ``USES_TERMINAL_DOWNLOAD 1``
+ Give download terminal access.
+ ``USES_TERMINAL_UPDATE 1``
+ Give update terminal access.
+ ``USES_TERMINAL_CONFIGURE 1``
+ Give configure terminal access.
+ ``USES_TERMINAL_BUILD 1``
+ Give build terminal access.
+ ``USES_TERMINAL_TEST 1``
+ Give test terminal access.
+ ``USES_TERMINAL_INSTALL 1``
+ Give install terminal access.
+
Other options are:
``STEP_TARGETS <step-target>...``
@@ -256,6 +273,8 @@ Create custom targets to build projects in external trees
Working directory for command
``LOG 1``
Wrap step in script to log output
+ ``USES_TERMINAL 1``
+ Give the step direct access to the terminal if possible.
The command line, comment, working directory, and byproducts of every
standard and custom step are processed to replace tokens ``<SOURCE_DIR>``,
@@ -1463,6 +1482,14 @@ function(ExternalProject_Add_Step name step)
get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT)
endif()
+ # Uses terminal?
+ get_property(uses_terminal TARGET ${name} PROPERTY _EP_${step}_USES_TERMINAL)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL)
+ else()
+ set(uses_terminal "")
+ endif()
+
# Run every time?
get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS)
if(always)
@@ -1505,6 +1532,7 @@ function(ExternalProject_Add_Step name step)
DEPENDS ${depends}
WORKING_DIRECTORY ${work_dir}
VERBATIM
+ ${uses_terminal}
)
set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
@@ -1890,6 +1918,14 @@ function(_ep_add_download_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_DOWNLOAD)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} download
COMMENT ${comment}
COMMAND ${cmd}
@@ -1897,6 +1933,7 @@ function(_ep_add_download_command name)
DEPENDS ${depends}
DEPENDEES mkdir
${log}
+ ${uses_terminal}
)
endfunction()
@@ -2001,6 +2038,14 @@ Update to Mercurial >= 2.1.1.
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_UPDATE)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} update
COMMENT ${comment}
COMMAND ${cmd}
@@ -2009,6 +2054,7 @@ Update to Mercurial >= 2.1.1.
WORKING_DIRECTORY ${work_dir}
DEPENDEES download
${log}
+ ${uses_terminal}
)
if(always AND update_disconnected)
@@ -2021,6 +2067,7 @@ Update to Mercurial >= 2.1.1.
WORKING_DIRECTORY ${work_dir}
DEPENDEES download
${log}
+ ${uses_terminal}
)
set_property(SOURCE ${skip-update_stamp_file} PROPERTY SYMBOLIC 1)
endif()
@@ -2149,6 +2196,14 @@ function(_ep_add_configure_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_CONFIGURE)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
if(update_disconnected_set)
get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
@@ -2167,6 +2222,7 @@ function(_ep_add_configure_command name)
DEPENDEES ${update_dep} patch
DEPENDS ${file_deps}
${log}
+ ${uses_terminal}
)
endfunction()
@@ -2188,6 +2244,14 @@ function(_ep_add_build_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_BUILD)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
get_property(build_always TARGET ${name} PROPERTY _EP_BUILD_ALWAYS)
if(build_always)
set(always 1)
@@ -2204,6 +2268,7 @@ function(_ep_add_build_command name)
DEPENDEES configure
ALWAYS ${always}
${log}
+ ${uses_terminal}
)
endfunction()
@@ -2225,11 +2290,20 @@ function(_ep_add_install_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_INSTALL)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} install
COMMAND ${cmd}
WORKING_DIRECTORY ${binary_dir}
DEPENDEES build
${log}
+ ${uses_terminal}
)
endfunction()
@@ -2277,6 +2351,14 @@ function(_ep_add_test_command name)
set(log "")
endif()
+ get_property(uses_terminal TARGET ${name} PROPERTY
+ _EP_USES_TERMINAL_TEST)
+ if(uses_terminal)
+ set(uses_terminal USES_TERMINAL 1)
+ else()
+ set(uses_terminal "")
+ endif()
+
ExternalProject_Add_Step(${name} test
COMMAND ${cmd}
WORKING_DIRECTORY ${binary_dir}
@@ -2284,6 +2366,7 @@ function(_ep_add_test_command name)
${dependers_args}
${exclude_args}
${log}
+ ${uses_terminal}
)
endif()
endfunction()
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index cc875ad..b80d3ce 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -53,6 +53,15 @@ include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
# Search for the python framework on Apple.
CMAKE_FIND_FRAMEWORKS(Python)
+# Save CMAKE_FIND_FRAMEWORK
+if(DEFINED CMAKE_FIND_FRAMEWORK)
+ set(_PythonLibs_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
+else()
+ unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+endif()
+# To avoid picking up the system Python.h pre-maturely.
+set(CMAKE_FIND_FRAMEWORK LAST)
+
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
set(_PYTHON3_VERSIONS 3.4 3.3 3.2 3.1 3.0)
@@ -111,14 +120,22 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
)
endif()
+ set(PYTHON_FRAMEWORK_LIBRARIES)
+ if(Python_FRAMEWORKS AND NOT PYTHON_LIBRARY)
+ foreach(dir ${Python_FRAMEWORKS})
+ list(APPEND PYTHON_FRAMEWORK_LIBRARIES
+ ${dir}/Versions/${_CURRENT_VERSION}/lib)
+ endforeach()
+ endif()
find_library(PYTHON_LIBRARY
NAMES
- python${_CURRENT_VERSION_NO_DOTS}
- python${_CURRENT_VERSION}mu
- python${_CURRENT_VERSION}m
- python${_CURRENT_VERSION}u
- python${_CURRENT_VERSION}
+ python${_CURRENT_VERSION_NO_DOTS}
+ python${_CURRENT_VERSION}mu
+ python${_CURRENT_VERSION}m
+ python${_CURRENT_VERSION}u
+ python${_CURRENT_VERSION}
PATHS
+ ${PYTHON_FRAMEWORK_LIBRARIES}
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
# Avoid finding the .dll in the PATH. We want the .lib.
@@ -143,8 +160,8 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
set(PYTHON_FRAMEWORK_INCLUDES)
if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
foreach(dir ${Python_FRAMEWORKS})
- set(PYTHON_FRAMEWORK_INCLUDES ${PYTHON_FRAMEWORK_INCLUDES}
- ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION})
+ list(APPEND PYTHON_FRAMEWORK_INCLUDES
+ ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION})
endforeach()
endif()
@@ -201,6 +218,14 @@ SELECT_LIBRARY_CONFIGURATIONS(PYTHON)
# for historical reasons.
unset(PYTHON_FOUND)
+# Restore CMAKE_FIND_FRAMEWORK
+if(DEFINED _PythonLibs_CMAKE_FIND_FRAMEWORK)
+ set(CMAKE_FIND_FRAMEWORK ${_PythonLibs_CMAKE_FIND_FRAMEWORK})
+ unset(_PythonLibs_CMAKE_FIND_FRAMEWORK)
+else()
+ unset(CMAKE_FIND_FRAMEWORK)
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs
REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 2537e39..f72a7f2 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -46,8 +46,10 @@ else()
set(_PLATFORM_LINK_FLAGS "")
endif()
+set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
set (CMAKE_NO_BUILD_TYPE 1)
+ set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 0) # not implemented for VS6
endif()
if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
set (CMAKE_NO_BUILD_TYPE 1)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index aa3f675..6940187 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -430,6 +430,7 @@ if (WIN32)
set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h
+ bindexplib.cxx
)
if(NOT UNIX)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index d573101..1348c2789 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 20150707)
+set(CMake_VERSION_PATCH 20150708)
#set(CMake_VERSION_RC 1)
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/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/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 72818f5..44d0d4e 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -84,7 +84,8 @@ cmArchiveWrite::cmArchiveWrite(
Stream(os),
Archive(archive_write_new()),
Disk(archive_read_disk_new()),
- Verbose(false)
+ Verbose(false),
+ Format(format)
{
switch (c)
{
@@ -282,6 +283,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: ";
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/cmCTest.cxx b/Source/cmCTest.cxx
index 5887ba8..5676dda 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -1220,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))
@@ -1236,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
@@ -1252,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);
@@ -3101,6 +3101,7 @@ static const char* cmCTestStringLogType[] =
"DEBUG",
"OUTPUT",
"HANDLER_OUTPUT",
+ "HANDLER_PROGRESS_OUTPUT",
"HANDLER_VERBOSE_OUTPUT",
"WARNING",
"ERROR_MESSAGE",
@@ -3139,6 +3140,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 47245ae..73c2807 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -382,6 +382,7 @@ public:
DEBUG = 0,
OUTPUT,
HANDLER_OUTPUT,
+ HANDLER_PROGRESS_OUTPUT,
HANDLER_VERBOSE_OUTPUT,
WARNING,
ERROR_MESSAGE,
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index f12116e..1b2586c 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -143,7 +143,7 @@ cmDependsFortran
std::vector<std::string> definitions;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
if(const char* c_defines =
- mf->GetDefinition("CMAKE_TARGET_DEFINITIONS"))
+ mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran"))
{
cmSystemTools::ExpandListArgument(c_defines, definitions);
}
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index b3576c3..78853ce 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -95,6 +95,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass
}
cmMakefile::FunctionPushPop functionScope(this->Makefile,
+ this->FilePath,
this->Policies);
// set the value of argc
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 438d60e..1d583eb 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)
@@ -896,3 +898,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 41843b3..8e2d6a4 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -103,6 +103,10 @@ 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();
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 505929e..21075bb 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -843,6 +843,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext,
{
sourcecode += ".c.objc";
}
+ else if (ext == "swift")
+ {
+ sourcecode += ".swift";
+ }
else if(ext == "plist")
{
sourcecode += ".text.plist";
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index d2339c4..df00b30 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -87,6 +87,24 @@ public:
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);
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 006ca4c..1097dc2 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -251,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;
@@ -399,40 +398,50 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
}
}
-void cmListFileBacktrace::Append(cmListFileContext const& context)
-{
- this->push_back(context);
-}
-
void cmListFileBacktrace::PrintTitle(std::ostream& out)
{
- if (this->empty())
+ if (!this->Snapshot.IsValid())
{
return;
}
-
cmOutputConverter converter(this->Snapshot);
- cmListFileContext lfc = this->front();
+ 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::PrintCallStack(std::ostream& out)
{
- if (size() <= 1)
+ if (!this->Snapshot.IsValid())
+ {
+ return;
+ }
+ cmState::Snapshot parent = this->Snapshot.GetCallStackParent();
+ if (!parent.IsValid() || parent.GetExecutionListFile().empty())
{
return;
}
cmOutputConverter converter(this->Snapshot);
- const_iterator i = this->begin() + 1;
+ 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 lfc = *i;
- lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+ 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 f5859ec..aa8a34c 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -25,6 +25,13 @@
class cmMakefile;
+struct cmCommandContext
+{
+ std::string Name;
+ long Line;
+ cmCommandContext(): Name(), Line(0) {}
+};
+
struct cmListFileArgument
{
enum Delimiter
@@ -57,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&);
@@ -64,24 +81,24 @@ 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(cmState::Snapshot snapshot = cmState::Snapshot())
- : Snapshot(snapshot)
+ cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(),
+ cmCommandContext const& cc = cmCommandContext())
+ : Context(cc), Snapshot(snapshot)
{
}
- void Append(cmListFileContext const& context);
-
void PrintTitle(std::ostream& out);
void PrintCallStack(std::ostream& out);
private:
+ cmCommandContext Context;
cmState::Snapshot Snapshot;
};
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index dc3a16d..a0e9e4d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1081,6 +1081,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
+ 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:
@@ -2015,7 +2023,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())
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 0b945b2..6d3054a 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -97,6 +97,7 @@ bool cmMacroHelperCommand::InvokeInitialPass
}
cmMakefile::MacroPushPop macroScope(this->Makefile,
+ this->FilePath,
this->Policies);
// set the value of argc
@@ -131,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
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index cdcf88c..94c77e1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -247,11 +247,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());
}
@@ -275,33 +275,29 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
//----------------------------------------------------------------------------
cmListFileBacktrace cmMakefile::GetBacktrace() const
{
- cmListFileBacktrace backtrace(this->StateSnapshot);
- 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(cmListFileContext const& lfc) const
+cmMakefile::GetBacktrace(cmCommandContext const& cc) const
{
- cmListFileBacktrace backtrace(this->StateSnapshot);
- backtrace.Append(lfc);
- for(CallStackType::const_reverse_iterator i = this->CallStack.rbegin();
- i != this->CallStack.rend(); ++i)
- {
- backtrace.Append(*i->Context);
- }
- return backtrace;
+ 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());
}
//----------------------------------------------------------------------------
@@ -461,11 +457,22 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
this->Makefile->PushPolicyBarrier();
this->Makefile->ListFileStack.push_back(filenametoread);
this->Makefile->PushFunctionBlockerBarrier();
+
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateCallStackSnapshot(
+ this->Makefile->StateSnapshot,
+ this->Makefile->ContextStack.back()->Name,
+ this->Makefile->ContextStack.back()->Line,
+ filenametoread);
}
//----------------------------------------------------------------------------
cmMakefile::IncludeScope::~IncludeScope()
{
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
+ assert(this->Makefile->StateSnapshot.IsValid());
+
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
// Enforce matching policy scopes inside the included file.
this->Makefile->PopPolicyBarrier(this->ReportError);
@@ -534,6 +541,25 @@ void cmMakefile::IncludeScope::EnforceCMP0011()
}
}
+class cmParseFileScope
+{
+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* filename, bool noPolicyScope)
{
this->AddDefinition("CMAKE_PARENT_LIST_FILE",
@@ -545,10 +571,14 @@ bool cmMakefile::ReadDependentFile(const char* filename, bool noPolicyScope)
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())
{
@@ -565,11 +595,27 @@ public:
{
this->Makefile->ListFileStack.push_back(filenametoread);
this->Makefile->PushPolicyBarrier();
+
+ 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->StateSnapshot =
+ this->Makefile->GetState()->Pop(this->Makefile->StateSnapshot);
+ assert(this->Makefile->StateSnapshot.IsValid());
+
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
this->Makefile->PopPolicyBarrier(this->ReportError);
this->Makefile->ListFileStack.pop_back();
@@ -590,10 +636,13 @@ bool cmMakefile::ReadListFile(const char* filename)
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())
@@ -1571,8 +1620,16 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
this->ImportedTargets = parent->ImportedTargets;
}
-void cmMakefile::PushFunctionScope(const cmPolicies::PolicyMap& pm)
+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->Internal->PushDefinitions();
this->PushLoopBlockBarrier();
@@ -1592,6 +1649,9 @@ void cmMakefile::PopFunctionScope(bool reportError)
this->PopPolicyBarrier(reportError);
this->PopPolicy();
+ this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+ assert(this->StateSnapshot.IsValid());
+
this->PopFunctionBlockerBarrier(reportError);
#if defined(CMAKE_BUILD_WITH_CMAKE)
@@ -1605,8 +1665,16 @@ void cmMakefile::PopFunctionScope(bool reportError)
this->Internal->PopDefinitions();
}
-void cmMakefile::PushMacroScope(const cmPolicies::PolicyMap& pm)
+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);
@@ -1618,6 +1686,9 @@ void cmMakefile::PopMacroScope(bool reportError)
this->PopPolicyBarrier(reportError);
this->PopPolicy();
+ this->StateSnapshot = this->GetState()->Pop(this->StateSnapshot);
+ assert(this->StateSnapshot.IsValid());
+
this->PopFunctionBlockerBarrier(reportError);
}
@@ -1635,6 +1706,7 @@ public:
std::string currentStart =
this->Makefile->StateSnapshot.GetCurrentSourceDirectory();
currentStart += "/CMakeLists.txt";
+ this->Makefile->StateSnapshot.SetListFile(currentStart);
this->Makefile->ListFileStack.push_back(currentStart);
this->Makefile->PushPolicyBarrier();
this->Makefile->PushFunctionBlockerBarrier();
@@ -1686,11 +1758,14 @@ void cmMakefile::Configure()
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())
{
@@ -1778,7 +1853,9 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
}
cmState::Snapshot newSnapshot = this->GetState()
- ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot);
+ ->CreateBuildsystemDirectorySnapshot(this->StateSnapshot,
+ this->ContextStack.back()->Name,
+ this->ContextStack.back()->Line);
// create a new local generator and set its parent
cmLocalGenerator *lg2 = this->GetGlobalGenerator()
@@ -1996,7 +2073,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;
@@ -3360,11 +3437,12 @@ bool cmMakefile::IsLoopBlock() const
std::string cmMakefile::GetExecutionFilePath() const
{
- if (this->CallStack.empty())
+ if (this->ContextStack.empty())
{
return std::string();
}
- return this->CallStack.back().Context->FilePath;
+ assert(this->StateSnapshot.IsValid());
+ return this->StateSnapshot.GetExecutionListFile();
}
//----------------------------------------------------------------------------
@@ -3455,7 +3533,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());
@@ -3488,11 +3566,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());
}
@@ -5476,10 +5556,11 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const
cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
+ const std::string& fileName,
cmPolicies::PolicyMap const& pm)
: Makefile(mf), ReportError(true)
{
- this->Makefile->PushFunctionScope(pm);
+ this->Makefile->PushFunctionScope(fileName, pm);
}
cmMakefile::FunctionPushPop::~FunctionPushPop()
@@ -5489,10 +5570,11 @@ cmMakefile::FunctionPushPop::~FunctionPushPop()
cmMakefile::MacroPushPop::MacroPushPop(cmMakefile* mf,
+ const std::string& fileName,
const cmPolicies::PolicyMap& pm)
: Makefile(mf), ReportError(true)
{
- this->Makefile->PushMacroScope(pm);
+ this->Makefile->PushMacroScope(fileName, pm);
}
cmMakefile::MacroPushPop::~MacroPushPop()
@@ -5500,14 +5582,15 @@ cmMakefile::MacroPushPop::~MacroPushPop()
this->Makefile->PopMacroScope(this->ReportError);
}
-cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmListFileContext& lfc,
+cmMakefileCall::cmMakefileCall(cmMakefile* mf, const cmCommandContext& lfc,
cmExecutionStatus& status): Makefile(mf)
{
- cmMakefile::CallStackEntry entry = {&lfc, &status};
- this->Makefile->CallStack.push_back(entry);
+ this->Makefile->ContextStack.push_back(&lfc);
+ this->Makefile->ExecutionStatusStack.push_back(&status);
}
cmMakefileCall::~cmMakefileCall()
{
- this->Makefile->CallStack.pop_back();
+ this->Makefile->ExecutionStatusStack.pop_back();
+ this->Makefile->ContextStack.pop_back();
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index aa70c72..82a2279 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -547,7 +547,7 @@ public:
* Get the current context backtrace.
*/
cmListFileBacktrace GetBacktrace() const;
- cmListFileBacktrace GetBacktrace(cmListFileContext const& lfc) const;
+ cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const;
cmListFileContext GetExecutionContext() const;
/**
@@ -720,7 +720,7 @@ public:
class FunctionPushPop
{
public:
- FunctionPushPop(cmMakefile* mf,
+ FunctionPushPop(cmMakefile* mf, std::string const& fileName,
cmPolicies::PolicyMap const& pm);
~FunctionPushPop();
@@ -733,8 +733,8 @@ public:
class MacroPushPop
{
public:
- MacroPushPop(cmMakefile* mf,
- cmPolicies::PolicyMap const& pm);
+ MacroPushPop(cmMakefile* mf, std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
~MacroPushPop();
void Quiet() { this->ReportError = false; }
@@ -743,9 +743,11 @@ public:
bool ReportError;
};
- void PushFunctionScope(cmPolicies::PolicyMap const& pm);
+ void PushFunctionScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
void PopFunctionScope(bool reportError);
- void PushMacroScope(cmPolicies::PolicyMap const& pm);
+ void PushMacroScope(std::string const& fileName,
+ cmPolicies::PolicyMap const& pm);
void PopMacroScope(bool reportError);
void PushScope();
void PopScope();
@@ -935,15 +937,10 @@ private:
// stack of list files being read
std::vector<std::string> ListFileStack;
- // 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;
@@ -1058,7 +1055,7 @@ class cmMakefileCall
{
public:
cmMakefileCall(cmMakefile* mf,
- cmListFileContext const& lfc,
+ cmCommandContext const& lfc,
cmExecutionStatus& status);
~cmMakefileCall();
private:
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 660027c..696dcc4 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmSourceFile.h"
#include "cmTarget.h"
#include "cmake.h"
+#include "cmAlgorithms.h"
//----------------------------------------------------------------------------
cmMakefileLibraryTargetGenerator
@@ -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();
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 2fe53bf..88da09b 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -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);
@@ -600,6 +616,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/cmState.cxx b/Source/cmState.cxx
index 58500cc..d918f65 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -20,10 +20,14 @@
struct cmState::SnapshotDataType
{
+ cmState::PositionType CallStackParent;
cmState::PositionType DirectoryParent;
cmState::SnapshotType SnapshotType;
+ cmLinkedTree<std::string>::iterator ExecutionListFile;
cmLinkedTree<cmState::BuildsystemDirectoryStateType>::iterator
BuildSystemDirectory;
+ std::string EntryPointCommand;
+ long EntryPointLine;
};
struct cmState::BuildsystemDirectoryStateType
@@ -226,6 +230,7 @@ cmState::Snapshot cmState::Reset()
this->BuildsystemDirectory.Truncate();
PositionType pos = this->SnapshotData.Truncate();
+ this->ExecutionListFiles.Truncate();
this->DefineProperty
("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY,
@@ -682,22 +687,113 @@ cmState::Snapshot cmState::CreateBaseSnapshot()
pos->SnapshotType = BuildsystemDirectoryType;
pos->BuildSystemDirectory =
this->BuildsystemDirectory.Extend(this->BuildsystemDirectory.Root());
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Extend(this->ExecutionListFiles.Root());
return cmState::Snapshot(this, pos);
}
cmState::Snapshot
-cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot)
+cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine)
{
assert(originSnapshot.IsValid());
PositionType pos = this->SnapshotData.Extend(originSnapshot.Position);
+ pos->CallStackParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
pos->DirectoryParent = originSnapshot.Position;
pos->SnapshotType = BuildsystemDirectoryType;
pos->BuildSystemDirectory =
this->BuildsystemDirectory.Extend(
originSnapshot.Position->BuildSystemDirectory);
+ pos->ExecutionListFile =
+ this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile);
return cmState::Snapshot(this, pos);
}
+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->CallStackParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = FunctionCallType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ return cmState::Snapshot(this, pos);
+}
+
+
+cmState::Snapshot
+cmState::CreateMacroCallSnapshot(cmState::Snapshot originSnapshot,
+ std::string const& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName)
+{
+ PositionType pos = this->SnapshotData.Extend(originSnapshot.Position,
+ *originSnapshot.Position);
+ pos->CallStackParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = MacroCallType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ 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->CallStackParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = CallStackType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ 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->CallStackParent = originSnapshot.Position;
+ pos->EntryPointLine = entryPointLine;
+ pos->EntryPointCommand = entryPointCommand;
+ pos->SnapshotType = InlineListFileType;
+ pos->ExecutionListFile = this->ExecutionListFiles.Extend(
+ originSnapshot.Position->ExecutionListFile, fileName);
+ return cmState::Snapshot(this, pos);
+}
+
+cmState::Snapshot cmState::Pop(cmState::Snapshot originSnapshot)
+{
+ PositionType pos = originSnapshot.Position;
+ PositionType prevPos = pos;
+ ++prevPos;
+ if (prevPos == this->SnapshotData.Root())
+ {
+ return Snapshot(this, prevPos);
+ }
+ return Snapshot(this, originSnapshot.Position->CallStackParent);
+}
+
cmState::Snapshot::Snapshot(cmState* state, PositionType position)
: State(state),
Position(position)
@@ -742,6 +838,11 @@ void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
this->ComputeRelativePathTopBinary();
}
+void cmState::Snapshot::SetListFile(const std::string& listfile)
+{
+ *this->Position->ExecutionListFile = listfile;
+}
+
std::vector<std::string> const&
cmState::Snapshot::GetCurrentSourceDirectoryComponents() const
{
@@ -776,6 +877,21 @@ void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
this->Position->BuildSystemDirectory->RelativePathTopBinary = dir;
}
+std::string cmState::Snapshot::GetExecutionListFile() const
+{
+ return *this->Position->ExecutionListFile;
+}
+
+std::string cmState::Snapshot::GetEntryPointCommand() const
+{
+ return this->Position->EntryPointCommand;
+}
+
+long cmState::Snapshot::GetEntryPointLine() const
+{
+ return this->Position->EntryPointLine;
+}
+
bool cmState::Snapshot::IsValid() const
{
return this->State && this->Position.IsValid()
@@ -799,6 +915,28 @@ cmState::Snapshot cmState::Snapshot::GetBuildsystemDirectoryParent() const
return snapshot;
}
+cmState::Snapshot cmState::Snapshot::GetCallStackParent() const
+{
+ assert(this->State);
+ assert(this->Position != this->State->SnapshotData.Root());
+
+ Snapshot snapshot;
+ if (this->Position->SnapshotType == cmState::BuildsystemDirectoryType)
+ {
+ return snapshot;
+ }
+
+ PositionType parentPos = this->Position;
+ ++parentPos;
+ if (parentPos == this->State->SnapshotData.Root())
+ {
+ return snapshot;
+ }
+
+ snapshot = Snapshot(this->State, parentPos);
+ return snapshot;
+}
+
cmState* cmState::Snapshot::GetState() const
{
return this->State;
diff --git a/Source/cmState.h b/Source/cmState.h
index 9c7574f..473a194 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -31,7 +31,11 @@ public:
enum SnapshotType
{
- BuildsystemDirectoryType
+ BuildsystemDirectoryType,
+ FunctionCallType,
+ MacroCallType,
+ CallStackType,
+ InlineListFileType
};
class Snapshot {
@@ -43,6 +47,8 @@ public:
const char* GetCurrentBinaryDirectory() const;
void SetCurrentBinaryDirectory(std::string const& dir);
+ void SetListFile(std::string const& listfile);
+
std::vector<std::string> const&
GetCurrentSourceDirectoryComponents() const;
std::vector<std::string> const&
@@ -53,8 +59,13 @@ public:
void SetRelativePathTopSource(const char* dir);
void SetRelativePathTopBinary(const char* dir);
+ std::string GetExecutionListFile() const;
+ std::string GetEntryPointCommand() const;
+ long GetEntryPointLine() const;
+
bool IsValid() const;
Snapshot GetBuildsystemDirectoryParent() const;
+ Snapshot GetCallStackParent() const;
cmState* GetState() const;
@@ -69,7 +80,27 @@ public:
};
Snapshot CreateBaseSnapshot();
- Snapshot CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot);
+ 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 CreateInlineListFileSnapshot(Snapshot originSnapshot,
+ const std::string& entryPointCommand,
+ long entryPointLine,
+ std::string const& fileName);
+ Snapshot Pop(Snapshot originSnapshot);
enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
UNINITIALIZED };
@@ -175,6 +206,8 @@ private:
struct BuildsystemDirectoryStateType;
cmLinkedTree<BuildsystemDirectoryStateType> BuildsystemDirectory;
+ cmLinkedTree<std::string> ExecutionListFiles;
+
cmLinkedTree<SnapshotDataType> SnapshotData;
std::vector<std::string> SourceDirectoryComponents;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4b031bc..d309927 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -429,6 +429,11 @@ 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);
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 6521c04..98a397c 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -63,7 +63,6 @@ static void cmVariableWatchCommandVariableAccessed(
cmListFileArgument(stack, cmListFileArgument::Quoted,
9999));
newLFF.Name = data->Command;
- newLFF.FilePath = "unknown";
newLFF.Line = 9999;
cmExecutionStatus status;
if(!makefile->ExecuteCommand(newLFF,status))
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 591c2db..a2f9bca 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2466,6 +2466,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;
}
@@ -2613,8 +2622,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",
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3ea2186..63838b4 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.
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 8865063..8de1c79 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -260,6 +260,12 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
set_tests_properties(MissingSourceFile PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
+ if(CMake_TEST_XCODE_VERSION AND NOT CMake_TEST_XCODE_VERSION VERSION_LESS 6.1)
+ if(CMAKE_GENERATOR STREQUAL "Xcode")
+ ADD_TEST_MACRO(SwiftMix SwiftMix)
+ ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+ endif()
+ endif()
if(CMAKE_Fortran_COMPILER)
ADD_TEST_MACRO(FortranOnly FortranOnly)
endif()
diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt
index 8700c94..753ce27 100644
--- a/Tests/Fortran/CMakeLists.txt
+++ b/Tests/Fortran/CMakeLists.txt
@@ -168,7 +168,7 @@ if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
add_definitions(-DFOO -DBAR=1)
include_directories(${testf_SOURCE_DIR}/include)
- add_executable(test_preprocess test_preprocess.F90)
+ add_executable(test_preprocess test_preprocess.F90 test_preprocess_module.F90)
set(TEST_MODULE_DEPENDS 1)
endif()
diff --git a/Tests/Fortran/test_preprocess.F90 b/Tests/Fortran/test_preprocess.F90
index e4f1fbe..3a09976 100644
--- a/Tests/Fortran/test_preprocess.F90
+++ b/Tests/Fortran/test_preprocess.F90
@@ -46,6 +46,8 @@ PROGRAM PPTEST
#endif
! 0 ; <empty>
+USE PPAvailable
+
#include "test_preprocess.h"
END PROGRAM
diff --git a/Tests/Fortran/test_preprocess_module.F90 b/Tests/Fortran/test_preprocess_module.F90
new file mode 100644
index 0000000..5849b62
--- /dev/null
+++ b/Tests/Fortran/test_preprocess_module.F90
@@ -0,0 +1,5 @@
+#ifdef FOO
+MODULE PPAvailable
+! no conent
+END MODULE
+#endif
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
new file mode 100644
index 0000000..3b2b2c5
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -0,0 +1,7 @@
+project(autoexport)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
+add_subdirectory(sub)
+add_library(autoexport SHARED hello.cxx world.cxx foo.c)
+add_executable(say say.cxx)
+target_link_libraries(say autoexport autoexport2)
diff --git a/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
new file mode 100644
index 0000000..d483c2c
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
@@ -0,0 +1 @@
+^.*$
diff --git a/Tests/RunCMake/AutoExportDll/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
new file mode 100644
index 0000000..3784a6a
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+set(RunCMake_TEST_NO_CLEAN TRUE)
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build")
+# start by cleaning up because we don't clean up along the way
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+# configure the AutoExport test
+run_cmake(AutoExport)
+unset(RunCMake_TEST_OPTIONS)
+# don't run this test on VS 6 as it is not supported
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 6|Watcom WMake|Borland Makefiles")
+ return()
+endif()
+# we build debug so the say.exe will be found in Debug/say.exe for
+# Visual Studio generators
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+ set(INTDIR "Debug/")
+endif()
+# build AutoExport
+run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build
+ ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first)
+# run the executable that uses symbols from the dll
+if(WIN32)
+ set(EXE_EXT ".exe")
+endif()
+run_cmake_command(AutoExportRun
+ ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT})
diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c
new file mode 100644
index 0000000..4b1318b
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/foo.c
@@ -0,0 +1,15 @@
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+int WINAPI foo()
+{
+ return 10;
+}
+
+int bar()
+{
+ return 5;
+}
diff --git a/Tests/RunCMake/AutoExportDll/hello.cxx b/Tests/RunCMake/AutoExportDll/hello.cxx
new file mode 100644
index 0000000..3933fc1
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.cxx
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "hello.h"
+int Hello::Data = 0;
+void Hello::real()
+{
+ return;
+}
+void hello()
+{
+ printf("hello");
+}
+void Hello::operator delete[](void*) {};
+void Hello::operator delete(void*) {};
diff --git a/Tests/RunCMake/AutoExportDll/hello.h b/Tests/RunCMake/AutoExportDll/hello.h
new file mode 100644
index 0000000..3749b97
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.h
@@ -0,0 +1,18 @@
+#ifndef _MSC_VER
+#define winexport
+#else
+#ifdef autoexport_EXPORTS
+#define winexport
+#else
+#define winexport __declspec(dllimport)
+#endif
+#endif
+
+class Hello
+{
+public:
+ static winexport int Data;
+ void real();
+ static void operator delete[](void*);
+ static void operator delete(void*);
+};
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
new file mode 100644
index 0000000..655b3c2
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "hello.h"
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+extern "C"
+{
+// test __cdecl stuff
+ int WINAPI foo();
+// test regular C
+ int bar();
+}
+
+// test c++ functions
+// forward declare hello and world
+void hello();
+void world();
+
+int main()
+{
+ // test static data (needs declspec to work)
+ Hello::Data = 120;
+ Hello h;
+ h.real();
+ hello();
+ printf(" ");
+ world();
+ printf("\n");
+ foo();
+ printf("\n");
+ bar();
+ printf("\n");
+ return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
new file mode 100644
index 0000000..8b70e7d
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(autoexport2 SHARED sub.cxx)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ # Try msvc "big" object format.
+ target_compile_options(autoexport2 PRIVATE /bigobj)
+endif()
diff --git a/Tests/RunCMake/AutoExportDll/sub/sub.cxx b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
new file mode 100644
index 0000000..9766b41
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
@@ -0,0 +1,4 @@
+int sub()
+{
+ return 10;
+}
diff --git a/Tests/RunCMake/AutoExportDll/world.cxx b/Tests/RunCMake/AutoExportDll/world.cxx
new file mode 100644
index 0000000..3a54df3
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/world.cxx
@@ -0,0 +1,6 @@
+#include "stdio.h"
+
+void world()
+{
+ printf("world");
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index bc706d3..c0ac5c8 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -59,6 +59,10 @@ function(add_RunCMake_test_group test types)
endforeach()
endfunction()
+if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 6.1)
+ set(Swift_ARGS -DXCODE_BELOW_6_1=1)
+endif()
+
if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3)
set(GeneratorToolset_ARGS -DXCODE_BELOW_3=1)
endif()
@@ -132,6 +136,7 @@ add_RunCMake_test(GNUInstallDirs)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(ObjectLibrary)
+add_RunCMake_test(Swift)
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
add_RunCMake_test(find_dependency)
@@ -266,3 +271,6 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
endif()
add_RunCMake_test_group(CPack "DEB;RPM")
+# add a test to make sure symbols are exported from a shared library
+# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
+add_RunCMake_test(AutoExportDll)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index e038409..47d6129 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -11,3 +11,4 @@ run_cmake(Add_StepDependencies)
run_cmake(Add_StepDependencies_iface)
run_cmake(Add_StepDependencies_iface_step)
run_cmake(Add_StepDependencies_no_target)
+run_cmake(UsesTerminal)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
new file mode 100644
index 0000000..201d822
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
@@ -0,0 +1,97 @@
+cmake_minimum_required(VERSION 3.3)
+
+# If we are using the Ninja generator, we can check and verify that the
+# USES_TERMINAL option actually works by examining the Ninja build file.
+# This is the only way, since CMake doesn't offer a way to examine the
+# options on a custom command after it has been added. Furthermore,
+# there isn't an easy way to test for this by actually running Ninja.
+#
+# Other generators don't currently support USES_TERMINAL at this time.
+# This file can be improved to support them if they do. Until then, we
+# simply assume success for new generator types.
+#
+# For Ninja, there is a complication. If the Ninja generator detects a
+# version of Ninja < 1.5, it won't actually emit the console pool command,
+# because those Ninja versions don't yet support the console pool. In
+# that case, we also have to assume success.
+
+# Check Ninja build output to verify whether or not a target step is in the
+# console pool.
+macro(CheckNinjaStep _target _step _require)
+ if("${_build}" MATCHES
+" DESC = Performing ${_step} step for '${_target}'
+ pool = console"
+ )
+ if(NOT ${_require})
+ set(RunCMake_TEST_FAILED "${_target} ${_step} step is in console pool")
+ return()
+ endif()
+ else()
+ if(${_require})
+ set(RunCMake_TEST_FAILED "${_target} ${_step} step not in console pool")
+ return()
+ endif()
+ endif()
+endmacro()
+
+# Check Ninja build output to verify whether each target step is in the
+# console pool.
+macro(CheckNinjaTarget _target
+ _download _update _configure _build _test _install
+ )
+ CheckNinjaStep(${_target} download ${_download})
+ CheckNinjaStep(${_target} update ${_update})
+ CheckNinjaStep(${_target} configure ${_configure})
+ CheckNinjaStep(${_target} build ${_build})
+ CheckNinjaStep(${_target} test ${_test})
+ CheckNinjaStep(${_target} install ${_install})
+endmacro()
+
+# Load build/make file, depending on generator
+if(RunCMake_GENERATOR STREQUAL Ninja)
+ # Check the Ninja version. If < 1.5, console pool isn't supported and
+ # so the generator would not emit console pool usage. That would cause
+ # this test to fail.
+ execute_process(COMMAND ${RunCMake_MAKE_PROGRAM} --version
+ RESULT_VARIABLE _version_result
+ OUTPUT_VARIABLE _version
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(_version_result OR _version VERSION_EQUAL "0")
+ set(RunCMake_TEST_FAILED "Failed to get Ninja version")
+ return()
+ endif()
+ if(_version VERSION_LESS "1.5")
+ return() # console pool not supported on Ninja < 1.5
+ endif()
+
+ # Read the Ninja build file
+ set(_build_file "${RunCMake_TEST_BINARY_DIR}/build.ninja")
+
+ if(NOT EXISTS "${_build_file}")
+ set(RunCMake_TEST_FAILED "Ninja build file not created")
+ return()
+ endif()
+
+ file(READ "${_build_file}" _build)
+
+ set(_target_check_macro CheckNinjaTarget)
+elseif((RunCMake_GENERATOR STREQUAL "") OR NOT DEFINED RunCMake_GENERATOR)
+ # protection in case somebody renamed RunCMake_GENERATOR
+ set(RunCMake_TEST_FAILED "Unknown generator")
+ return()
+else()
+ # We don't yet know how to test USES_TERMINAL on this generator.
+ return()
+endif()
+
+# Actual tests:
+CheckNinjaTarget(TerminalTest1
+ true true true true true true )
+CheckNinjaTarget(TerminalTest2
+ true false true false true false)
+CheckNinjaTarget(TerminalTest3
+ false true false true false true )
+CheckNinjaTarget(TerminalTest4
+ false false false false false false)
diff --git a/Tests/RunCMake/ExternalProject/UsesTerminal.cmake b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
new file mode 100644
index 0000000..cd87403
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/UsesTerminal.cmake
@@ -0,0 +1,45 @@
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+include(ExternalProject)
+
+# Test various combinations of USES_TERMINAL with ExternalProject_Add.
+
+macro(DoTerminalTest _target)
+ ExternalProject_Add(${_target}
+ DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download"
+ UPDATE_COMMAND "${CMAKE_COMMAND}" -E echo "update"
+ CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E echo "configure"
+ BUILD_COMMAND "${CMAKE_COMMAND}" -E echo "build"
+ TEST_COMMAND "${CMAKE_COMMAND}" -E echo "test"
+ INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "install"
+ ${ARGN}
+ )
+endmacro()
+
+# USES_TERMINAL on all steps
+DoTerminalTest(TerminalTest1
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_BUILD 1
+ USES_TERMINAL_TEST 1
+ USES_TERMINAL_INSTALL 1
+ )
+
+# USES_TERMINAL on every other step, starting with download
+DoTerminalTest(TerminalTest2
+ USES_TERMINAL_DOWNLOAD 1
+ USES_TERMINAL_CONFIGURE 1
+ USES_TERMINAL_TEST 1
+ )
+
+# USES_TERMINAL on every other step, starting with update
+DoTerminalTest(TerminalTest3
+ USES_TERMINAL_UPDATE 1
+ USES_TERMINAL_BUILD 1
+ USES_TERMINAL_INSTALL 1
+ )
+
+# USES_TERMINAL on no step
+DoTerminalTest(TerminalTest4)
diff --git a/Tests/RunCMake/Swift/CMakeLists.txt b/Tests/RunCMake/Swift/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Swift/Enable-stdout.txt b/Tests/RunCMake/Swift/Enable-stdout.txt
new file mode 100644
index 0000000..39e133f
--- /dev/null
+++ b/Tests/RunCMake/Swift/Enable-stdout.txt
@@ -0,0 +1 @@
+-- The Swift compiler identification is Apple
diff --git a/Tests/RunCMake/Swift/Enable.cmake b/Tests/RunCMake/Swift/Enable.cmake
new file mode 100644
index 0000000..19f297a
--- /dev/null
+++ b/Tests/RunCMake/Swift/Enable.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Swift/NotSupported-result.txt b/Tests/RunCMake/Swift/NotSupported-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/NotSupported-stderr.txt b/Tests/RunCMake/Swift/NotSupported-stderr.txt
new file mode 100644
index 0000000..9a9c23f
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+ Swift language not supported by "[^"]*" generator
+Call Stack \(most recent call first\):
+ NotSupported.cmake:[0-9]+ \(enable_language\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/NotSupported.cmake b/Tests/RunCMake/Swift/NotSupported.cmake
new file mode 100644
index 0000000..19f297a
--- /dev/null
+++ b/Tests/RunCMake/Swift/NotSupported.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
new file mode 100644
index 0000000..0a57121
--- /dev/null
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR STREQUAL Xcode)
+ if(XCODE_BELOW_6_1)
+ run_cmake(XcodeTooOld)
+ else()
+ run_cmake(Enable)
+ endif()
+else()
+ run_cmake(NotSupported)
+endif()
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-result.txt b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
new file mode 100644
index 0000000..8d18f29
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineSwiftCompiler.cmake:[0-9]+ \(message\):
+ Swift language not supported by Xcode [0-9.]+
+Call Stack \(most recent call first\):
+ XcodeTooOld.cmake:[0-9]+ \(enable_language\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Swift/XcodeTooOld.cmake b/Tests/RunCMake/Swift/XcodeTooOld.cmake
new file mode 100644
index 0000000..19f297a
--- /dev/null
+++ b/Tests/RunCMake/Swift/XcodeTooOld.cmake
@@ -0,0 +1 @@
+enable_language(Swift)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
index b3f1e47..a845ffb 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-16-BE.cmake:
File
.*/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
index c08c902..cc4244b 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-16-LE.cmake:
File
.*/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
index 5dde4e3..5f851bf 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-32-BE.cmake:
File
.*/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
index eb054ec..d8fafd0 100644
--- a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
+++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BOM-UTF-32-LE.cmake:
File
.*/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake
starts with a Byte-Order-Mark that is not UTF-8.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
index afd91f9..a288280 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace0.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace0.cmake:1:27
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
index 826e511..391e11b 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace1.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace1.cmake:1:24
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
index 23ecdcd..acaf7fe 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace2.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace2.cmake:1:44
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
index 906d6fc..f12b2e5 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace3.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace3.cmake:1:45
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
index a461e93..7157763 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace4.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace4.cmake:1:44
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
index ff8bf1c..c13969d 100644
--- a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
+++ b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt
@@ -1,6 +1,8 @@
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in BracketNoSpace5.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/BracketNoSpace5.cmake:1:45
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/ParenInENV-stderr.txt b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
index 7ecfe11..37c5d6e 100644
--- a/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
+++ b/Tests/RunCMake/Syntax/ParenInENV-stderr.txt
@@ -1,9 +1,11 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenInENV.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/ParenInENV.cmake:2:21
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Error at ParenInENV.cmake:2 \(message\):
diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
index 64ef8b1..45b2e6a 100644
--- a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
+++ b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt
@@ -1,22 +1,28 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:1:26
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in ParenNoSpace1.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:2:26
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
-CMake Error at CMakeLists.txt:3 \(include\):
+CMake Error in ParenNoSpace1.cmake:
Syntax Error in cmake code at
.*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:3:29
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
index 89c2d2a..a4ec6e7 100644
--- a/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
+++ b/Tests/RunCMake/Syntax/StringNoSpace-stderr.txt
@@ -1,17 +1,21 @@
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:28
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
-CMake Warning \(dev\) at CMakeLists.txt:3 \(include\):
+CMake Warning \(dev\) in StringNoSpace.cmake:
Syntax Warning in cmake code at
.*/Tests/RunCMake/Syntax/StringNoSpace.cmake:2:31
Argument not separated from preceding token by whitespace.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
\[1 \${var} \\n 4\]
diff --git a/Tests/SwiftMix/CMain.c b/Tests/SwiftMix/CMain.c
new file mode 100644
index 0000000..13e2f8c
--- /dev/null
+++ b/Tests/SwiftMix/CMain.c
@@ -0,0 +1,4 @@
+extern int ObjCMain(int argc, char const* const argv[]);
+int main(int argc, char* argv[]) {
+ return ObjCMain(argc, argv);
+}
diff --git a/Tests/SwiftMix/CMakeLists.txt b/Tests/SwiftMix/CMakeLists.txt
new file mode 100644
index 0000000..5e50470
--- /dev/null
+++ b/Tests/SwiftMix/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftMix C Swift)
+
+add_executable(SwiftMix CMain.c ObjCMain.m SwiftMain.swift ObjC-Swift.h)
+set_property(TARGET SwiftMix PROPERTY XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "ObjC-Swift.h")
diff --git a/Tests/SwiftMix/ObjC-Swift.h b/Tests/SwiftMix/ObjC-Swift.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/SwiftMix/ObjC-Swift.h
diff --git a/Tests/SwiftMix/ObjCMain.m b/Tests/SwiftMix/ObjCMain.m
new file mode 100644
index 0000000..7fa90ae
--- /dev/null
+++ b/Tests/SwiftMix/ObjCMain.m
@@ -0,0 +1,4 @@
+#import "SwiftMix-Swift.h"
+int ObjCMain(int argc, char const* const argv[]) {
+ return [SwiftMainClass SwiftMain:argc argv:argv];
+}
diff --git a/Tests/SwiftMix/SwiftMain.swift b/Tests/SwiftMix/SwiftMain.swift
new file mode 100644
index 0000000..9af9883
--- /dev/null
+++ b/Tests/SwiftMix/SwiftMain.swift
@@ -0,0 +1,10 @@
+@objc class SwiftMainClass {
+ class func SwiftMain(argc:Int, argv:UnsafePointer<UnsafePointer<CChar>>) -> Int32 {
+ println("argc: \(argc)")
+ for (var i = 0; i < argc; ++i) {
+ var argi = String.fromCString(argv[i])
+ println("arg[\(i)]: \(argi)");
+ }
+ return 0;
+ }
+}
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
new file mode 100644
index 0000000..5cb9739
--- /dev/null
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.3)
+project(SwiftOnly Swift)
+
+add_executable(SwiftOnly main.swift)
diff --git a/Tests/SwiftOnly/main.swift b/Tests/SwiftOnly/main.swift
new file mode 100644
index 0000000..67be986
--- /dev/null
+++ b/Tests/SwiftOnly/main.swift
@@ -0,0 +1 @@
+println("SwiftOnly")