Browse Source

Merge topic 'ninja-swift'

a9180ccf9a Tests: add a check for the Swift compiler
d745551fb6 Help: add some initial documentation for Swift support
9a182c9e5b Auxiliary: update vim syntax highlighting
e9b0063e8e Modules: add build rules for Swift Ninja support
b6412e3e38 Ninja: add placeholders to support Swift build
7d7f31161d Ninja: add support for Swift's output-file-map.json
d688c4c19d Swift: remove unnecessary unreleased Ninja infrastructure
0723582208 Swift: Detect compiler version
...

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3297
Brad King 6 years ago
parent
commit
a9fb9a8774

+ 6 - 0
Auxiliary/vim/syntax/cmake.vim

@@ -96,6 +96,7 @@ syn keyword cmakeProperty contained
             \ CMAKE_CONFIGURE_DEPENDS
             \ CMAKE_CXX_KNOWN_FEATURES
             \ CMAKE_C_KNOWN_FEATURES
+            \ CMAKE_Swift_MODULE_DIRECTORY
             \ COMMON_LANGUAGE_RUNTIME
             \ COMPATIBLE_INTERFACE_BOOL
             \ COMPATIBLE_INTERFACE_NUMBER_MAX
@@ -287,6 +288,11 @@ syn keyword cmakeProperty contained
             \ STRINGS
             \ SUBDIRECTORIES
             \ SUFFIX
+            \ Swift_DEPENDENCIES_FILE
+            \ Swift_DIAGNOSTICS_FILE
+            \ Swift_MODULE
+            \ Swift_MODULE_DIRECTORY
+            \ Swift_MODULE_NAME
             \ SYMBOLIC
             \ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
             \ TARGET_MESSAGES

+ 11 - 0
Help/envvar/SWIFTC.rst

@@ -0,0 +1,11 @@
+SWIFTC
+------
+
+.. include:: ENV_VAR.txt
+
+Preferred executable for compiling ``Swift`` language files. Will only be used by
+CMake on the first configuration to determine ``Swift`` compiler, after which the
+value for ``SWIFTC`` is stored in the cache as
+:variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
+(including the first), the environment variable will be ignored if the
+:variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.

+ 1 - 0
Help/manual/cmake-env-variables.7.rst

@@ -52,6 +52,7 @@ Environment Variables for Languages
    /envvar/FFLAGS
    /envvar/RC
    /envvar/RCFLAGS
+   /envvar/SWIFTC
 
 Environment Variables for CTest
 ===============================

+ 5 - 0
Help/manual/cmake-properties.7.rst

@@ -315,6 +315,9 @@ Properties on Targets
    /prop_tgt/STATIC_LIBRARY_FLAGS
    /prop_tgt/STATIC_LIBRARY_OPTIONS
    /prop_tgt/SUFFIX
+   /prop_tgt/Swift_DEPENDENCIES_FILE
+   /prop_tgt/Swift_MODULE_DIRECTORY
+   /prop_tgt/Swift_MODULE_NAME
    /prop_tgt/TYPE
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
@@ -439,6 +442,8 @@ Properties on Source Files
    /prop_sf/SKIP_AUTOMOC
    /prop_sf/SKIP_AUTORCC
    /prop_sf/SKIP_AUTOUIC
+   /prop_sf/Swift_DEPENDENCIES_FILE
+   /prop_sf/Swift_DIAGNOSTICS_FILE
    /prop_sf/SYMBOLIC
    /prop_sf/VS_COPY_TO_OUT_DIR
    /prop_sf/VS_CSHARP_tagname

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -97,6 +97,7 @@ Variables that Provide Information
    /variable/CMAKE_SOURCE_DIR
    /variable/CMAKE_STATIC_LIBRARY_PREFIX
    /variable/CMAKE_STATIC_LIBRARY_SUFFIX
+   /variable/CMAKE_Swift_MODULE_DIRECTORY
    /variable/CMAKE_TOOLCHAIN_FILE
    /variable/CMAKE_TWEAK_VERSION
    /variable/CMAKE_VERBOSE_MAKEFILE

+ 5 - 0
Help/prop_sf/Swift_DEPENDENCIES_FILE.rst

@@ -0,0 +1,5 @@
+Swift_DEPENDENCIES_FILE
+-----------------------
+
+This property sets the path for the Swift dependency file (swiftdeps) for the
+source.

+ 4 - 0
Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst

@@ -0,0 +1,4 @@
+Swift_DIAGNOSTICS_FILE
+----------------------
+
+This property controls where the Swift diagnostics are serialized.

+ 5 - 0
Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst

@@ -0,0 +1,5 @@
+Swift_DEPENDENCIES_FILE
+-----------------------
+
+This property sets the path for the Swift dependency file (swiftdep) for the
+target.

+ 10 - 0
Help/prop_tgt/Swift_MODULE_DIRECTORY.rst

@@ -0,0 +1,10 @@
+Swift_MODULE_DIRECTORY
+----------------------
+
+Specify output directory for Swift modules provided by the target.
+
+If the target contains Swift source files, this specifies the directory in which
+the modules will be placed.  When this property is not set, the modules will be
+placed in the build directory corresponding to the target's source directory.
+If the variable :variable:`CMAKE_Swift_MODULE_DIRECTORY` is set when a target is
+created its value is used to initialise this property.

+ 5 - 0
Help/prop_tgt/Swift_MODULE_NAME.rst

@@ -0,0 +1,5 @@
+Swift_MODULE_NAME
+-----------------
+
+This property specifies the name of the Swift module.  It is defaulted to the
+name of the target.

+ 23 - 0
Help/release/dev/swift-support.rst

@@ -0,0 +1,23 @@
+Swift Language Support
+----------------------
+
+* Preliminary support for the Swift language with the :generator:`Ninja`
+  generator was added.  Use the :envvar:`SWIFTC` environment variable to
+  specify a compiler.
+
+* Support to emit an output file map was added to enable Swift compilation.
+
+* A target property :prop_tgt:`Swift_DEPENDENCIES_FILE` was added to targets to
+  indicate where to save the target swift dependencies file.  If one is not
+  specified, it will default to `<TARGET>.swiftdeps`.
+
+* A target property :prop_tgt:`Swift_MODULE_NAME` was added to targets to
+  indicate the Swift module name.  If it is not specified, it will default to
+  the name of the target.
+
+* A source property :prop_sf:`Swift_DEPENDENCIES_FILE` was added to sources to
+  indicate where to save the target swift dependencies file.  If one is not
+  specified, it will default to `<OBJECT>.swiftdeps`.
+
+* A source property :prop_sf:`Swift_DIAGNOSTICS_FILE` was added to sources to
+  indicate where to write the serialised Swift diagnostics.

+ 8 - 0
Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst

@@ -0,0 +1,8 @@
+CMAKE_Swift_MODULE_DIRECTORY
+----------------------------
+
+Swift module output directory.
+
+This variable is used to initialise the :prop_tgt:`Swift_MODULE_DIRECTORY`
+property on all the targets.  See the target property for additional
+information.

+ 32 - 7
Modules/CMakeDetermineCompilerId.cmake

@@ -46,6 +46,14 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     endif()
   endforeach()
 
+  # Check if compiler id detection gave us the compiler tool.
+  if(CMAKE_${lang}_COMPILER_ID_TOOL)
+    set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}")
+    set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
+  elseif(NOT CMAKE_${lang}_COMPILER)
+    set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
+  endif()
+
   # If the compiler is still unknown, try to query its vendor.
   if(CMAKE_${lang}_COMPILER AND NOT CMAKE_${lang}_COMPILER_ID)
     foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
@@ -76,6 +84,30 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     endif()
   endif()
 
+  # For Swift we need to explicitly query the version.
+  if(lang STREQUAL "Swift"
+     AND CMAKE_${lang}_COMPILER
+     AND NOT CMAKE_${lang}_COMPILER_VERSION)
+    execute_process(
+      COMMAND "${CMAKE_${lang}_COMPILER}"
+      -version
+      OUTPUT_VARIABLE output ERROR_VARIABLE output
+      RESULT_VARIABLE result
+      TIMEOUT 10
+    )
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n"
+      "${output}\n"
+      )
+
+    if(output MATCHES [[Swift version ([0-9]+\.[0-9]+(\.[0-9]+)?)]])
+      set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}")
+      if(NOT CMAKE_${lang}_COMPILER_ID)
+        set(CMAKE_Swift_COMPILER_ID "Apple")
+      endif()
+    endif()
+  endif()
+
   if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
     execute_process(
       COMMAND "${CMAKE_${lang}_COMPILER}"
@@ -124,13 +156,6 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     message(STATUS "The ${lang} compiler identification is unknown")
   endif()
 
-  # Check if compiler id detection gave us the compiler tool.
-  if(CMAKE_${lang}_COMPILER_ID_TOOL)
-    set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
-  elseif(NOT CMAKE_${lang}_COMPILER)
-    set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
-  endif()
-
   set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
   set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
   set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)

+ 41 - 8
Modules/CMakeDetermineSwiftCompiler.cmake

@@ -1,15 +1,46 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-
 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
 
+# Local system-specific compiler preferences for this language.
+include(Platform/${CMAKE_SYSTEM_NAME}-Determine-Swift OPTIONAL)
+include(Platform/${CMAKE_SYSTEM_NAME}-Swift OPTIONAL)
+if(NOT CMAKE_Swift_COMPILER_NAMES)
+  set(CMAKE_Swift_COMPILER_NAMES swiftc)
+endif()
+
 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)
+elseif("${CMAKE_GENERATOR}" STREQUAL "Ninja")
+  if(CMAKE_Swift_COMPILER)
+    _cmake_find_compiler_path(Swift)
+  else()
+    set(CMAKE_Swift_COMPILER_INIT NOTFOUND)
+
+    if(NOT $ENV{SWIFTC} STREQUAL "")
+      get_filename_component(CMAKE_Swift_COMPILER_INIT $ENV{SWIFTC} PROGRAM
+        PROGRAM_ARGS CMAKE_Swift_FLAGS_ENV_INIT)
+      if(CMAKE_Swift_FLAGS_ENV_INIT)
+        set(CMAKE_Swift_COMPILER_ARG1 "${CMAKE_Swift_FLAGS_ENV_INIT}" CACHE
+          STRING "First argument to the Swift compiler")
+      endif()
+      if(NOT EXISTS ${CMAKE_Swift_COMPILER_INIT})
+        message(FATAL_ERROR "Could not find compiler set in environment variable SWIFTC\n$ENV{SWIFTC}.\n${CMAKE_Swift_COMPILER_INIT}")
+      endif()
+    endif()
+
+    if(NOT CMAKE_Swift_COMPILER_INIT)
+      set(CMAKE_Swift_COMPILER_LIST swiftc ${_CMAKE_TOOLCHAIN_PREFIX}swiftc)
+    endif()
+
+    _cmake_find_compiler(Swift)
+  endif()
+  mark_as_advanced(CMAKE_Swift_COMPILER)
 else()
   message(FATAL_ERROR "Swift language not supported by \"${CMAKE_GENERATOR}\" generator")
 endif()
@@ -18,11 +49,13 @@ endif()
 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")
+  if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
+    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)
+    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)
+  endif()
 
   # Try to identify the compiler.
   set(CMAKE_Swift_COMPILER_ID)
@@ -40,6 +73,6 @@ unset(_CMAKE_PROCESSING_LANGUAGE)
 
 # 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
-  )
+               ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake @ONLY)
+
+set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")

+ 9 - 0
Modules/CMakeSwiftCompiler.cmake.in

@@ -1,5 +1,14 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
 set(CMAKE_Swift_COMPILER "@CMAKE_Swift_COMPILER@")
 set(CMAKE_Swift_COMPILER_ID "@CMAKE_Swift_COMPILER_ID@")
+set(CMAKE_Swift_COMPILER_VERSION "@CMAKE_Swift_COMPILER_VERSION@")
+
+set(CMAKE_Swift_COMPILER_LOADED 1)
+set(CMAKE_Swift_COMPILER_WORKS "@CMAKE_Swift_COMPILER_WORKS@")
+
+set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")
 
 set(CMAKE_Swift_COMPILER_ID_RUN 1)
 set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)

+ 43 - 14
Modules/CMakeSwiftInformation.cmake

@@ -1,32 +1,61 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-
-set(CMAKE_Swift_OUTPUT_EXTENSION .o)
-set(CMAKE_INCLUDE_FLAG_Swift "-I")
+if(UNIX)
+  set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+else()
+  set(CMAKE_Swift_OUTPUT_EXTENSION .obj)
+endif()
 
 # 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_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
   endif()
   include(Platform/${CMAKE_EFFECTIVE_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})
+set(CMAKE_INCLUDE_FLAG_Swift "-I")
+set(CMAKE_INCLUDE_FLAG_SEP_Swift " ")
+set(CMAKE_Swift_DEFINE_FLAG -D)
+set(CMAKE_Swift_COMPILE_OPTIONS_TARGET "-target ")
+set(CMAKE_Swift_COMPILER_ARG1 -frontend)
+
+set(CMAKE_Swift_FLAGS_DEBUG_INIT "-g")
+set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+
+# NOTE(compnerd) we do not have an object compile rule since we build the objects as part of the link step
+if(NOT CMAKE_Swift_COMPILE_OBJECT)
+  set(CMAKE_Swift_COMPILE_OBJECT ":")
 endif()
 
-include(CMakeCommonLanguageInclude)
+if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
+  if(CMAKE_Swift_COMPILER_TARGET)
+    set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+  else()
+    set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+  endif()
+endif()
+
+if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
+  set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
+endif()
+
+if(NOT CMAKE_Swift_LINK_EXECUTABLE)
+  if(CMAKE_Swift_COMPILER_TARGET)
+    set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+  else()
+    set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <FLAGS> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
+  endif()
+endif()
+
+if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
+  set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>")
+  set(CMAKE_Swift_ARCHIVE_FINISH "")
+endif()
 
 set(CMAKE_Swift_INFORMATION_LOADED 1)

+ 5 - 2
Modules/CMakeTestSwiftCompiler.cmake

@@ -1,7 +1,6 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-
 if(CMAKE_Swift_COMPILER_FORCED)
   # The compiler configuration was forced by the user.
   # Assume the user has configured all compiler information.
@@ -23,7 +22,6 @@ unset(CMAKE_Swift_COMPILER_WORKS CACHE)
 if(NOT CMAKE_Swift_COMPILER_WORKS)
   PrintTestCompilerStatus("Swift" "")
   file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
-    "import Foundation\n"
     "print(\"CMake\")\n")
   try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
     ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
@@ -51,6 +49,11 @@ else()
       "Determining if the Swift compiler works passed with "
       "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
   endif()
+
+  # Re-configure to save learned information.
+  configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
+                 ${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake @ONLY)
+  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake)
 endif()
 
 unset(__CMAKE_Swift_COMPILER_OUTPUT)

+ 76 - 26
Source/cmNinjaNormalTargetGenerator.cxx

@@ -281,10 +281,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
       cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
 
     vars.Language = this->TargetLinkLanguage.c_str();
+
     if (this->TargetLinkLanguage == "Swift") {
-      vars.SwiftPartialModules = "$SWIFT_PARTIAL_MODULES";
-      vars.TargetSwiftModule = "$TARGET_SWIFT_MODULE";
-      vars.TargetSwiftDoc = "$TARGET_SWIFT_DOC";
+      vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
+      vars.SwiftModule = "$SWIFT_MODULE";
+      vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
+      vars.SwiftOutputFileMap = "$SWIFT_OUTPUT_FILE_MAP";
+      vars.SwiftSources = "$SWIFT_SOURCES";
     }
 
     std::string responseFlag;
@@ -805,35 +808,82 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   outputs.push_back(targetOutputReal);
 
   if (this->TargetLinkLanguage == "Swift") {
-    if (const char* name = gt.GetProperty("SWIFT_MODULE_NAME")) {
-      vars["TARGET_SWIFT_DOC"] = std::string(name) + ".swiftdoc";
-      vars["TARGET_SWIFT_MODULE"] = std::string(name) + ".swiftmodule";
-    } else {
-      vars["TARGET_SWIFT_DOC"] = gt.GetName() + ".swiftdoc";
-      vars["TARGET_SWIFT_MODULE"] = gt.GetName() + ".swiftmodule";
-    }
-    outputs.push_back(vars["TARGET_SWIFT_DOC"]);
-    outputs.push_back(vars["TARGET_SWIFT_MODULE"]);
+    vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
+      cmGeneratorTarget::Names targetNames =
+        this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+      return targetNames.Base;
+    }();
+
+    vars["SWIFT_MODULE"] = [this]() -> std::string {
+      cmGeneratorTarget::Names targetNames =
+        this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+
+      std::string directory =
+        this->GetLocalGenerator()->GetCurrentBinaryDirectory();
+      if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+            "Swift_MODULE_DIRECTORY")) {
+        directory = prop;
+      }
+
+      std::string name = targetNames.Base + ".swiftmodule";
+      if (const char* prop =
+            this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
+        name = prop;
+      }
 
-    cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
+      return this->GetLocalGenerator()->ConvertToOutputFormat(
+        this->ConvertToNinjaPath(directory + "/" + name),
+        cmOutputConverter::SHELL);
+    }();
 
-    std::string partials;
-    std::vector<cmSourceFile const*> sources;
-    gt.GetObjectSources(sources, this->GetConfigName());
-    for (cmSourceFile const* source : sources) {
-      partials += " ";
-      if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
-        partials += partial;
-      } else {
-        partials += localGen.GetTargetDirectory(&gt) + "/" +
-          gt.GetObjectName(source) + ".swiftmodule";
+    vars["SWIFT_MODULE_NAME"] = [this]() -> std::string {
+      if (const char* name =
+            this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) {
+        return name;
       }
-    }
-    vars["SWIFT_PARTIAL_MODULES"] = partials;
+      return this->GetGeneratorTarget()->GetName();
+    }();
+
+    vars["SWIFT_OUTPUT_FILE_MAP"] =
+      this->GetLocalGenerator()->ConvertToOutputFormat(
+        this->ConvertToNinjaPath(gt.GetSupportDirectory() +
+                                 "/output-file-map.json"),
+        cmOutputConverter::SHELL);
+
+    vars["SWIFT_SOURCES"] = [this]() -> std::string {
+      std::vector<cmSourceFile const*> sources;
+      std::stringstream oss;
+
+      this->GetGeneratorTarget()->GetObjectSources(sources,
+                                                   this->GetConfigName());
+      cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
+      for (const auto& source : sources) {
+        oss << " "
+            << LocalGen->ConvertToOutputFormat(
+                 this->ConvertToNinjaPath(this->GetSourceFilePath(source)),
+                 cmOutputConverter::SHELL);
+      }
+      return oss.str();
+    }();
   }
 
   // Compute specific libraries to link with.
-  cmNinjaDeps explicitDeps = this->GetObjects();
+  cmNinjaDeps explicitDeps;
+  if (this->TargetLinkLanguage == "Swift") {
+    std::vector<cmSourceFile const*> sources;
+    this->GetGeneratorTarget()->GetObjectSources(sources,
+                                                 this->GetConfigName());
+    for (const auto& source : sources) {
+      outputs.push_back(
+        this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
+      explicitDeps.push_back(
+        this->ConvertToNinjaPath(this->GetSourceFilePath(source)));
+    }
+
+    outputs.push_back(vars["SWIFT_MODULE"]);
+  } else {
+    explicitDeps = this->GetObjects();
+  }
   cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
 
   if (!this->DeviceLinkObject.empty()) {

+ 76 - 49
Source/cmNinjaTargetGenerator.cxx

@@ -19,7 +19,6 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalNinjaGenerator.h"
-#include "cmListFileCache.h" // for BT
 #include "cmLocalGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmMakefile.h"
@@ -455,13 +454,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
   vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
   vars.ObjectDir = "$OBJECT_DIR";
   vars.ObjectFileDir = "$OBJECT_FILE_DIR";
-  if (lang == "Swift") {
-    vars.SwiftAuxiliarySources = "$SWIFT_AUXILIARY_SOURCES";
-    vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
-    vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
-    vars.SwiftPartialModule = "$SWIFT_PARTIAL_MODULE";
-    vars.SwiftPartialDoc = "$SWIFT_PARTIAL_DOC";
-  }
 
   // For some cases we do an explicit preprocessor invocation.
   bool const explicitPP = this->NeedExplicitPreprocessing(lang);
@@ -924,6 +916,28 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
   }
 
   this->GetBuildFileStream() << "\n";
+
+  if (!this->SwiftOutputMap.empty()) {
+    std::string const mapFilePath = this->ConvertToNinjaPath(
+      this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json");
+    std::string const targetSwiftDepsPath = [this]() -> std::string {
+      cmGeneratorTarget const* target = this->GeneratorTarget;
+      if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+        return name;
+      }
+      return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
+                                      target->GetName() + ".swiftdeps");
+    }();
+
+    // build the global target dependencies
+    // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+    Json::Value deps(Json::objectValue);
+    deps["swift-dependencies"] = targetSwiftDepsPath;
+    this->SwiftOutputMap[""] = deps;
+
+    cmGeneratedFileStream output(mapFilePath);
+    output << this->SwiftOutputMap;
+  }
 }
 
 void cmNinjaTargetGenerator::WriteObjectBuildStatement(
@@ -948,43 +962,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
   vars["DEFINES"] = this->ComputeDefines(source, language);
   vars["INCLUDES"] = this->ComputeIncludes(source, language);
-  if (language == "Swift") {
-    // The swift compiler needs all the sources besides the one being compiled
-    // in order to do the type checking.  List all these "auxiliary" sources.
-    std::string aux_sources;
-    cmGeneratorTarget::KindedSources const& sources =
-      this->GeneratorTarget->GetKindedSources(this->GetConfigName());
-    for (cmGeneratorTarget::SourceAndKind const& src : sources.Sources) {
-      if (src.Source.Value == source) {
-        continue;
-      }
-      aux_sources += " " + this->GetSourceFilePath(src.Source.Value);
-    }
-    vars["SWIFT_AUXILIARY_SOURCES"] = aux_sources;
-
-    if (const char* name =
-          this->GeneratorTarget->GetProperty("SWIFT_MODULE_NAME")) {
-      vars["SWIFT_MODULE_NAME"] = name;
-    } else {
-      vars["SWIFT_MODULE_NAME"] = this->GeneratorTarget->GetName();
-    }
-
-    cmGeneratorTarget::Names targetNames =
-      this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
-    vars["SWIFT_LIBRARY_NAME"] = targetNames.Base;
-
-    if (const char* partial = source->GetProperty("SWIFT_PARTIAL_MODULE")) {
-      vars["SWIFT_PARTIAL_MODULE"] = partial;
-    } else {
-      vars["SWIFT_PARTIAL_MODULE"] = objectFileName + ".swiftmodule";
-    }
-
-    if (const char* partial = source->GetProperty("SWIFT_PARTIAL_DOC")) {
-      vars["SWIFT_PARTIAL_DOC"] = partial;
-    } else {
-      vars["SWIFT_PARTIAL_DOC"] = objectFileName + ".swiftdoc";
-    }
-  }
 
   if (!this->NeedDepTypeMSVC(language)) {
     bool replaceExt(false);
@@ -1177,10 +1154,14 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 
   std::string const rspfile = objectFileName + ".rsp";
 
-  this->GetGlobalGenerator()->WriteBuild(
-    this->GetBuildFileStream(), comment, rule, outputs,
-    /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps,
-    vars, rspfile, commandLineLengthLimit);
+  if (language == "Swift") {
+    this->EmitSwiftDependencyInfo(source);
+  } else {
+    this->GetGlobalGenerator()->WriteBuild(
+      this->GetBuildFileStream(), comment, rule, outputs,
+      /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps,
+      orderOnlyDeps, vars, rspfile, commandLineLengthLimit);
+  }
 
   if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
     std::vector<std::string> outputList;
@@ -1239,6 +1220,52 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
   tdif << tdi;
 }
 
+void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
+  cmSourceFile const* source)
+{
+  std::string const sourceFilePath =
+    this->ConvertToNinjaPath(this->GetSourceFilePath(source));
+  std::string const objectFilePath =
+    this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+  std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
+    if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
+      return name;
+    }
+    return objectFilePath + ".swiftdeps";
+  }();
+  std::string const swiftDiaPath = [source, objectFilePath]() -> std::string {
+    if (const char* name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
+      return name;
+    }
+    return objectFilePath + ".dia";
+  }();
+  std::string const makeDepsPath = [this, source]() -> std::string {
+    cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
+    std::string const objectFileName =
+      this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+    std::string const objectFileDir =
+      cmSystemTools::GetFilenamePath(objectFileName);
+
+    if (this->Makefile->IsOn("CMAKE_Swift_DEPFLE_EXTNSION_REPLACE")) {
+      std::string dependFileName =
+        cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
+      return local->ConvertToOutputFormat(objectFileDir + "/" + dependFileName,
+                                          cmOutputConverter::SHELL);
+    }
+    return local->ConvertToOutputFormat(objectFileName + ".d",
+                                        cmOutputConverter::SHELL);
+  }();
+
+  // build the source file mapping
+  // https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
+  Json::Value entry = Json::Value(Json::objectValue);
+  entry["object"] = objectFilePath;
+  entry["dependencies"] = makeDepsPath;
+  entry["swift-dependencies"] = swiftDepsPath;
+  entry["diagnostics"] = swiftDiaPath;
+  SwiftOutputMap[sourceFilePath] = entry;
+}
+
 void cmNinjaTargetGenerator::ExportObjectCompileCommand(
   std::string const& language, std::string const& sourceFileName,
   std::string const& objectDir, std::string const& objectFileName,

+ 7 - 0
Source/cmNinjaTargetGenerator.h

@@ -5,6 +5,8 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include "cm_jsoncpp_value.h"
+
 #include "cmCommonTargetGenerator.h"
 #include "cmGlobalNinjaGenerator.h"
 #include "cmNinjaTypes.h"
@@ -128,6 +130,8 @@ protected:
   void WriteObjectBuildStatement(cmSourceFile const* source);
   void WriteTargetDependInfo(std::string const& lang);
 
+  void EmitSwiftDependencyInfo(cmSourceFile const* source);
+
   void ExportObjectCompileCommand(
     std::string const& language, std::string const& sourceFileName,
     std::string const& objectDir, std::string const& objectFileName,
@@ -171,7 +175,10 @@ private:
   cmLocalNinjaGenerator* LocalGenerator;
   /// List of object files for this target.
   cmNinjaDeps Objects;
+  // Fortran Support
   std::map<std::string, cmNinjaDeps> DDIFiles;
+  // Swift Support
+  Json::Value SwiftOutputMap;
   std::vector<cmCustomCommand const*> CustomCommands;
   cmNinjaDeps ExtraFiles;
 };

+ 25 - 40
Source/cmRulePlaceholderExpander.cxx

@@ -91,6 +91,31 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
   if (replaceValues.Includes && variable == "INCLUDES") {
     return replaceValues.Includes;
   }
+  if (replaceValues.SwiftLibraryName) {
+    if (variable == "SWIFT_LIBRARY_NAME") {
+      return replaceValues.SwiftLibraryName;
+    }
+  }
+  if (replaceValues.SwiftModule) {
+    if (variable == "SWIFT_MODULE") {
+      return replaceValues.SwiftModule;
+    }
+  }
+  if (replaceValues.SwiftModuleName) {
+    if (variable == "SWIFT_MODULE_NAME") {
+      return replaceValues.SwiftModuleName;
+    }
+  }
+  if (replaceValues.SwiftOutputFileMap) {
+    if (variable == "SWIFT_OUTPUT_FILE_MAP") {
+      return replaceValues.SwiftOutputFileMap;
+    }
+  }
+  if (replaceValues.SwiftSources) {
+    if (variable == "SWIFT_SOURCES") {
+      return replaceValues.SwiftSources;
+    }
+  }
   if (replaceValues.TargetPDB) {
     if (variable == "TARGET_PDB") {
       return replaceValues.TargetPDB;
@@ -162,46 +187,6 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
       }
     }
   }
-  if (replaceValues.SwiftAuxiliarySources) {
-    if (variable == "SWIFT_AUXILIARY_SOURCES") {
-      return replaceValues.SwiftAuxiliarySources;
-    }
-  }
-  if (replaceValues.SwiftModuleName) {
-    if (variable == "SWIFT_MODULE_NAME") {
-      return replaceValues.SwiftModuleName;
-    }
-  }
-  if (replaceValues.SwiftLibraryName) {
-    if (variable == "SWIFT_LIBRARY_NAME") {
-      return replaceValues.SwiftLibraryName;
-    }
-  }
-  if (replaceValues.SwiftPartialDoc) {
-    if (variable == "SWIFT_PARTIAL_DOC") {
-      return replaceValues.SwiftPartialDoc;
-    }
-  }
-  if (replaceValues.SwiftPartialModule) {
-    if (variable == "SWIFT_PARTIAL_MODULE") {
-      return replaceValues.SwiftPartialModule;
-    }
-  }
-  if (replaceValues.SwiftPartialModules) {
-    if (variable == "SWIFT_PARTIAL_MODULES") {
-      return replaceValues.SwiftPartialModules;
-    }
-  }
-  if (replaceValues.TargetSwiftDoc) {
-    if (variable == "TARGET_SWIFT_DOC") {
-      return replaceValues.TargetSwiftDoc;
-    }
-  }
-  if (replaceValues.TargetSwiftModule) {
-    if (variable == "TARGET_SWIFT_MODULE") {
-      return replaceValues.TargetSwiftModule;
-    }
-  }
   if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
       variable == "TARGET_INSTALLNAME_DIR") {
     // All these variables depend on TargetSOName

+ 4 - 7
Source/cmRulePlaceholderExpander.h

@@ -58,14 +58,11 @@ public:
     const char* Includes;
     const char* DependencyFile;
     const char* FilterPrefix;
-    const char* SwiftAuxiliarySources;
-    const char* SwiftModuleName;
     const char* SwiftLibraryName;
-    const char* SwiftPartialModule;
-    const char* SwiftPartialDoc;
-    const char* TargetSwiftModule;
-    const char* TargetSwiftDoc;
-    const char* SwiftPartialModules;
+    const char* SwiftModule;
+    const char* SwiftModuleName;
+    const char* SwiftOutputFileMap;
+    const char* SwiftSources;
   };
 
   // Expand rule variables in CMake of the type found in language rules

+ 1 - 0
Source/cmTarget.cxx

@@ -335,6 +335,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     InitProperty("LINK_SEARCH_START_STATIC", nullptr);
     InitProperty("LINK_SEARCH_END_STATIC", nullptr);
     InitProperty("FOLDER", nullptr);
+    InitProperty("Swift_MODULE_DIRECTORY", nullptr);
     InitProperty("VS_JUST_MY_CODE_DEBUGGING", nullptr);
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {

+ 8 - 2
Tests/CMakeLists.txt

@@ -22,6 +22,7 @@ macro(ADD_TEST_MACRO NAME)
 endmacro()
 
 include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
+include(${CMAKE_CURRENT_SOURCE_DIR}/CheckSwift.cmake)
 
 # Fake a user home directory to avoid polluting the real one.
 if(DEFINED ENV{HOME} AND NOT CTEST_NO_TEST_HOME)
@@ -365,11 +366,16 @@ if(BUILD_TESTING)
        ((NOT CMAKE_OSX_SDKPRODUCT STREQUAL "Mac OS X") OR
         (NOT CMAKE_OSX_SDKVERSION VERSION_LESS 10.10)))
       if(CMAKE_GENERATOR STREQUAL "Xcode")
-        ADD_TEST_MACRO(SwiftMix SwiftMix)
-        ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+        set(CMake_TEST_XCODE_SWIFT 1)
       endif()
     endif()
   endif()
+  if(CMAKE_Swift_COMPILER OR CMake_TEST_XCODE_SWIFT)
+    ADD_TEST_MACRO(SwiftOnly SwiftOnly)
+    if(CMake_TEST_XCODE_SWIFT)
+      ADD_TEST_MACRO(SwiftMix SwiftMix)
+    endif()
+  endif()
   if(CMAKE_Fortran_COMPILER)
     ADD_TEST_MACRO(FortranOnly FortranOnly)
   endif()

+ 61 - 0
Tests/CheckSwift.cmake

@@ -0,0 +1,61 @@
+if(NOT CMAKE_GENERATOR MATCHES "Xcode|Ninja")
+  set(CMAKE_Swift_COMPILER "")
+  return()
+endif()
+
+if(NOT DEFINED CMAKE_Swift_COMPILER)
+  set(_desc "Looking for a Swift compiler")
+  message(STATUS ${_desc})
+
+  file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift)
+
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift/CMakeLists.txt"
+  "cmake_minimum_required(VERSION 3.14)
+project(CheckSwift Swift)
+file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
+  \"set(CMAKE_Swift_COMPILER \\\"\${CMAKE_Swift_COMPILER}\\\")\\n\"
+  \"set(CMAKE_Swift_FLAGS \\\"\${CMAKE_Swift_FLAGS}\\\")\\n\")
+")
+
+  if(CMAKE_GENERATOR_INSTANCE)
+    set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
+  else()
+    set(_D_CMAKE_GENERATOR_INSTANCE "")
+  endif()
+
+  execute_process(WORKING_DIRECTORY
+                    ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift
+                  COMMAND
+                    ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+                                       -A "${CMAKE_GENERATOR_PLATFORM}"
+                                       -T "${CMAKE_GENERATOR_TOOLSET}"
+                                       ${_D_CMAKE_GENERATOR_INSTANCE}
+                  TIMEOUT
+                    60
+                  OUTPUT_VARIABLE
+                    output
+                  ERROR_VARIABLE
+                    output
+                  RESULT_VARIABLE
+                    result)
+
+  include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckSwift/result.cmake
+    OPTIONAL)
+  if(CMAKE_Swift_COMPILER AND "${result}" STREQUAL "0")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "${_desc} passed with the following output:\n"
+      "${output}\n")
+  else()
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "${_desc} failed with the following output:\n"
+      "${output}\n")
+  endif()
+
+  message(STATUS "${_desc} - ${CMAKE_Swift_COMPILER}")
+
+  set(CMAKE_Swift_COMPILER "${CMAKE_Swift_COMPILER}" CACHE FILEPATH "Swift compiler")
+  set(CMAKE_Swift_FLAGS "${CMAKE_Swift_FLAGS}" CACHE STRING "Swift flags")
+
+  mark_as_advanced(CMAKE_Swift_COMPILER)
+  mark_as_advanced(CMAKE_Swift_FLAGS)
+endif()

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -205,7 +205,7 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STRE
   add_RunCMake_test(RuntimePath)
 endif()
 add_RunCMake_test(ScriptMode)
-add_RunCMake_test(Swift)
+add_RunCMake_test(Swift -DCMAKE_Swift_COMPILER=${CMAKE_Swift_COMPILER})
 add_RunCMake_test(TargetObjects)
 add_RunCMake_test(TargetSources)
 add_RunCMake_test(ToolchainFile)

+ 4 - 0
Tests/RunCMake/Swift/RunCMakeTest.cmake

@@ -4,6 +4,10 @@ if(RunCMake_GENERATOR STREQUAL Xcode)
   if(XCODE_BELOW_6_1)
     run_cmake(XcodeTooOld)
   endif()
+elseif(RunCMake_GENERATOR STREQUAL Ninja)
+  if(CMAKE_Swift_COMPILER)
+    # Add Ninja-specific Swift tests here.
+  endif()
 else()
   run_cmake(NotSupported)
 endif()