浏览代码

Visual Studio: Add Android support

Kyle Edwards 5 年之前
父节点
当前提交
6051a49c78
共有 34 个文件被更改,包括 479 次插入63 次删除
  1. 7 0
      Help/release/dev/visual-studio-android.rst
  2. 25 4
      Modules/CMakeDetermineCompilerId.cmake
  3. 2 2
      Modules/CompilerId/VS-10.vcxproj.in
  4. 3 0
      Modules/Platform/Android-Clang.cmake
  5. 59 2
      Modules/Platform/Android-Determine.cmake
  6. 1 1
      Modules/Platform/Android-Initialize.cmake
  7. 38 0
      Modules/Platform/Android/VCXProjInspect.vcxproj.in
  8. 82 18
      Source/cmGlobalVisualStudio10Generator.cxx
  9. 16 0
      Source/cmGlobalVisualStudio10Generator.h
  10. 6 0
      Source/cmGlobalVisualStudio14Generator.cxx
  11. 6 0
      Source/cmGlobalVisualStudio14Generator.h
  12. 38 0
      Source/cmGlobalVisualStudioVersionedGenerator.cxx
  13. 2 0
      Source/cmGlobalVisualStudioVersionedGenerator.h
  14. 51 8
      Source/cmVisualStudio10TargetGenerator.cxx
  15. 2 0
      Source/cmVisualStudio10TargetGenerator.h
  16. 45 16
      Tests/CMakeLists.txt
  17. 44 9
      Tests/RunCMake/Android/RunCMakeTest.cmake
  18. 7 0
      Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt
  19. 7 0
      Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt
  20. 7 0
      Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt
  21. 7 0
      Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt
  22. 7 0
      Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt
  23. 7 0
      Tests/RunCMake/Android/ndk-x86-stderr.txt
  24. 7 0
      Tests/RunCMake/Android/ndk-x86_64-stderr.txt
  25. 2 2
      Tests/RunCMake/CMakeLists.txt
  26. 0 0
      Tests/VSAndroid/AndroidManifest.xml
  27. 1 1
      Tests/VSAndroid/CMakeLists.txt
  28. 0 0
      Tests/VSAndroid/build.xml
  29. 0 0
      Tests/VSAndroid/jni/first.c
  30. 0 0
      Tests/VSAndroid/jni/first.h
  31. 0 0
      Tests/VSAndroid/jni/second.c
  32. 0 0
      Tests/VSAndroid/proguard-android.txt
  33. 0 0
      Tests/VSAndroid/res/values/strings.xml
  34. 0 0
      Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java

+ 7 - 0
Help/release/dev/visual-studio-android.rst

@@ -0,0 +1,7 @@
+visual-studio-android
+---------------------
+
+* The :ref:`Visual Studio Generators` for Visual Studio 2015 and above gained
+  support for the Visual Studio Tools for Android. This allows you to set
+  :variable:`CMAKE_SYSTEM_NAME` to `Android` to generate `.vcxproj` files for
+  the Android tools.

+ 25 - 4
Modules/CMakeDetermineCompilerId.cmake

@@ -248,7 +248,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
     set(id_PostBuildEvent_Command "")
     if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
       set(id_cl_var "ClangClExecutable")
-    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg][Cc][Ll]$")
+    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
       set(id_cl "$(CLToolExe)")
     elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
       set(id_cl clang.exe)
@@ -310,17 +310,36 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
       set(id_PreferredToolArchitecture "")
     endif()
     if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
     elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Store</ApplicationType>")
+    elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
+      set(id_keyword "Android")
+      set(id_system "<ApplicationType>Android</ApplicationType>")
     else()
+      set(id_keyword "Win32Proj")
       set(id_system "")
     endif()
-    if(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
+    if(id_keyword STREQUAL "Android")
+      if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+        set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
+      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+        set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
+      else()
+        set(id_system_version "")
+      endif()
+    elseif(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
       set(id_system_version "<ApplicationTypeRevision>${CMAKE_MATCH_1}</ApplicationTypeRevision>")
     else()
       set(id_system_version "")
     endif()
+    if(id_keyword STREQUAL "Android")
+      set(id_config_type "DynamicLibrary")
+    else()
+      set(id_config_type "Application")
+    endif()
     if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
       set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
     endif()
@@ -333,9 +352,11 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
         string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n    ")
       endif()
     endforeach()
-    if(id_platform STREQUAL ARM64)
+    if(id_keyword STREQUAL "Android")
+      set(id_WindowsSDKDesktopARMSupport "")
+    elseif(id_platform STREQUAL "ARM64")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
-    elseif(id_platform STREQUAL ARM)
+    elseif(id_platform STREQUAL "ARM")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
     else()
       set(id_WindowsSDKDesktopARMSupport "")

+ 2 - 2
Modules/CompilerId/VS-10.vcxproj.in

@@ -9,7 +9,7 @@
   <PropertyGroup Label="Globals">
     <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
     <RootNamespace>CompilerId@id_lang@</RootNamespace>
-    <Keyword>Win32Proj</Keyword>
+    <Keyword>@id_keyword@</Keyword>
     @id_system@
     @id_system_version@
     @id_WindowsTargetPlatformVersion@
@@ -24,7 +24,7 @@
     @id_PreferredToolArchitecture@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>@id_config_type@</ConfigurationType>
     @id_toolset@
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>

+ 3 - 0
Modules/Platform/Android-Clang.cmake

@@ -53,4 +53,7 @@ macro(__android_compiler_clang lang)
     endif()
     list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
   endif()
+  if(CMAKE_GENERATOR MATCHES "Visual Studio")
+    set(_ANDROID_STL_NOSTDLIBXX 1)
+  endif()
 endmacro()

+ 59 - 2
Modules/Platform/Android-Determine.cmake

@@ -7,8 +7,8 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
-if(CMAKE_GENERATOR MATCHES "Visual Studio")
+# that functionality for now.
+if(CMAKE_GENERATOR_PLATFORM STREQUAL "Tegra-Android")
   return()
 endif()
 
@@ -27,6 +27,63 @@ endif()
 cmake_policy(PUSH)
 cmake_policy(SET CMP0057 NEW) # if IN_LIST
 
+# If using Android tools for Visual Studio, compile a sample project to get the
+# sysroot.
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+  if(NOT CMAKE_SYSROOT)
+    set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]")
+      set(vcx_sysroot_var "Sysroot")
+    else()
+      set(vcx_sysroot_var "SysrootLink")
+    endif()
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+      set(vcx_revision "2.0")
+    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+      set(vcx_revision "3.0")
+    else()
+      set(vcx_revision "")
+    endif()
+    configure_file(${CMAKE_ROOT}/Modules/Platform/Android/VCXProjInspect.vcxproj.in
+      ${CMAKE_PLATFORM_INFO_DIR}/VCXProjInspect.vcxproj @ONLY)
+    execute_process(
+      COMMAND "${CMAKE_VS_MSBUILD_COMMAND}" "VCXProjInspect.vcxproj"
+        "/p:Configuration=Debug" "/p:Platform=${vcx_platform}"
+      WORKING_DIRECTORY ${CMAKE_PLATFORM_INFO_DIR}
+      OUTPUT_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      ERROR_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      RESULT_VARIABLE VCXPROJ_INSPECT_RESULT
+      )
+    if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]")
+      # Strip VS diagnostic output from the end of the line.
+      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}")
+      if(EXISTS "${_sysroot}")
+        file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT)
+      endif()
+    endif()
+    if(VCXPROJ_INSPECT_RESULT)
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Determining the sysroot for the Android NDK failed.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    else()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining the sysroot for the Android NDK succeeded.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    endif()
+  endif()
+  if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION)
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang")
+  endif()
+endif()
+
 # If the user provided CMAKE_SYSROOT for us, extract information from it.
 set(_ANDROID_SYSROOT_NDK "")
 set(_ANDROID_SYSROOT_API "")

+ 1 - 1
Modules/Platform/Android-Initialize.cmake

@@ -6,7 +6,7 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
+# that functionality for now.
 if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
   return()
 endif()

+ 38 - 0
Modules/Platform/Android/VCXProjInspect.vcxproj.in

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|@vcx_platform@">
+      <Configuration>Debug</Configuration>
+      <Platform>@vcx_platform@</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{14D44772-ECF7-47BD-9E29-BC62FAF940A5}</ProjectGuid>
+    <RootNamespace>VCXProjInspect</RootNamespace>
+    <Keyword>Android</Keyword>
+    <ApplicationType>Android</ApplicationType>
+    <ApplicationTypeRevision>@vcx_revision@</ApplicationTypeRevision>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">
+    <PostBuildEvent>
+      <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 82 - 18
Source/cmGlobalVisualStudio10Generator.cxx

@@ -508,18 +508,16 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
       mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
       return false;
     }
-    std::string v = this->GetInstalledNsightTegraVersion();
-    if (v.empty()) {
-      mf->IssueMessage(MessageType::FATAL_ERROR,
-                       "CMAKE_SYSTEM_NAME is 'Android' but "
-                       "'NVIDIA Nsight Tegra Visual Studio Edition' "
-                       "is not installed.");
-      return false;
+    if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") == "Tegra-Android") {
+      if (!this->InitializeTegraAndroid(mf)) {
+        return false;
+      }
+    } else {
+      this->SystemIsAndroid = true;
+      if (!this->InitializeAndroid(mf)) {
+        return false;
+      }
     }
-    this->DefaultPlatformName = "Tegra-Android";
-    this->DefaultPlatformToolset = "Default";
-    this->NsightTegraVersion = v;
-    mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
   }
 
   return true;
@@ -561,6 +559,31 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf)
   return false;
 }
 
+bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
+{
+  std::string v = this->GetInstalledNsightTegraVersion();
+  if (v.empty()) {
+    mf->IssueMessage(MessageType::FATAL_ERROR,
+                     "CMAKE_SYSTEM_NAME is 'Android' but "
+                     "'NVIDIA Nsight Tegra Visual Studio Edition' "
+                     "is not installed.");
+    return false;
+  }
+  this->DefaultPlatformName = "Tegra-Android";
+  this->DefaultPlatformToolset = "Default";
+  this->NsightTegraVersion = v;
+  mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
+  return true;
+}
+
+bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf)
+{
+  std::ostringstream e;
+  e << this->GetName() << " does not support Android.";
+  mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  return false;
+}
+
 bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
   std::string& toolset) const
 {
@@ -595,6 +618,28 @@ void cmGlobalVisualStudio10Generator::Generate()
 {
   this->LongestSource = LongestSourcePath();
   this->cmGlobalVisualStudio8Generator::Generate();
+  if (!this->AndroidExecutableWarnings.empty() &&
+      !this->CMakeInstance->GetIsInTryCompile()) {
+    std::ostringstream e;
+    /* clang-format off */
+    e <<
+      "You are using Visual Studio tools for Android, which does not support "
+      "standalone executables. However, the following executable targets do "
+      "not have the ANDROID_GUI property set, and thus will not be built as "
+      "expected. They will be built as shared libraries with executable "
+      "filenames:\n"
+      "  ";
+    /* clang-format on */
+    bool first = true;
+    for (auto const& name : this->AndroidExecutableWarnings) {
+      if (!first) {
+        e << ", ";
+      }
+      first = false;
+      e << name;
+    }
+    this->CMakeInstance->IssueMessage(MessageType::WARNING, e.str());
+  }
   if (this->LongestSource.Length > 0) {
     cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
     std::ostringstream e;
@@ -661,8 +706,14 @@ std::string const& cmGlobalVisualStudio10Generator::GetPlatformToolsetString()
   if (!this->GeneratorToolset.empty()) {
     return this->GeneratorToolset;
   }
-  if (!this->DefaultPlatformToolset.empty()) {
-    return this->DefaultPlatformToolset;
+  if (this->SystemIsAndroid) {
+    if (!this->DefaultAndroidToolset.empty()) {
+      return this->DefaultAndroidToolset;
+    }
+  } else {
+    if (!this->DefaultPlatformToolset.empty()) {
+      return this->DefaultPlatformToolset;
+    }
   }
   static std::string const empty;
   return empty;
@@ -876,7 +927,10 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
       epg.Attribute("Label", "Globals");
       cmXMLElement(epg, "ProjectGuid")
         .Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
-      cmXMLElement(epg, "Keyword").Content("Win32Proj");
+      cmXMLElement(epg, "Keyword")
+        .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"
+                   ? "Android"
+                   : "Win32Proj");
       cmXMLElement(epg, "Platform").Content(this->GetPlatformName());
       if (this->GetSystemName() == "WindowsPhone") {
         cmXMLElement(epg, "ApplicationType").Content("Windows Phone");
@@ -886,15 +940,21 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
         cmXMLElement(epg, "ApplicationType").Content("Windows Store");
         cmXMLElement(epg, "ApplicationTypeRevision")
           .Content(this->GetApplicationTypeRevision());
+      } else if (this->GetSystemName() == "Android") {
+        cmXMLElement(epg, "ApplicationType").Content("Android");
+        cmXMLElement(epg, "ApplicationTypeRevision")
+          .Content(this->GetApplicationTypeRevision());
       }
       if (!this->WindowsTargetPlatformVersion.empty()) {
         cmXMLElement(epg, "WindowsTargetPlatformVersion")
           .Content(this->WindowsTargetPlatformVersion);
       }
-      if (this->GetPlatformName() == "ARM64") {
-        cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
-      } else if (this->GetPlatformName() == "ARM") {
-        cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+      if (this->GetSystemName() != "Android") {
+        if (this->GetPlatformName() == "ARM64") {
+          cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
+        } else if (this->GetPlatformName() == "ARM") {
+          cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+        }
       }
     }
     cmXMLElement(eprj, "Import")
@@ -1206,6 +1266,10 @@ std::string cmGlobalVisualStudio10Generator::GetInstalledNsightTegraVersion()
 
 std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const
 {
+  if (this->GetSystemName() == "Android") {
+    return this->GetAndroidApplicationTypeRevision();
+  }
+
   // Return the first two '.'-separated components of the Windows version.
   std::string::size_type end1 = this->SystemVersion.find('.');
   std::string::size_type end2 =

+ 16 - 0
Source/cmGlobalVisualStudio10Generator.h

@@ -4,6 +4,7 @@
 #define cmGlobalVisualStudio10Generator_h
 
 #include <memory>
+#include <set>
 
 #include "cmGlobalVisualStudio8Generator.h"
 #include "cmVisualStudio10ToolsetOptions.h"
@@ -43,6 +44,11 @@ public:
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
                       bool optional) override;
 
+  void AddAndroidExecutableWarning(const std::string& name)
+  {
+    this->AndroidExecutableWarnings.insert(name);
+  }
+
   bool IsCudaEnabled() const { return this->CudaEnabled; }
 
   /** Generating for Nsight Tegra VS plugin?  */
@@ -100,6 +106,9 @@ public:
   /** Return true if building for WindowsStore */
   bool TargetsWindowsStore() const { return this->SystemIsWindowsStore; }
 
+  /** Return true if building for Android */
+  bool TargetsAndroid() const { return this->SystemIsAndroid; }
+
   const char* GetCMakeCFGIntDir() const override { return "$(Configuration)"; }
   bool Find64BitTools(cmMakefile* mf);
 
@@ -128,6 +137,8 @@ public:
   /** Return the first two components of CMAKE_SYSTEM_VERSION.  */
   std::string GetApplicationTypeRevision() const;
 
+  virtual const char* GetAndroidApplicationTypeRevision() const { return ""; }
+
   cmIDEFlagTable const* GetClFlagTable() const;
   cmIDEFlagTable const* GetCSharpFlagTable() const;
   cmIDEFlagTable const* GetRcFlagTable() const;
@@ -148,6 +159,8 @@ protected:
   virtual bool InitializeWindowsCE(cmMakefile* mf);
   virtual bool InitializeWindowsPhone(cmMakefile* mf);
   virtual bool InitializeWindowsStore(cmMakefile* mf);
+  virtual bool InitializeTegraAndroid(cmMakefile* mf);
+  virtual bool InitializeAndroid(cmMakefile* mf);
 
   virtual bool ProcessGeneratorToolsetField(std::string const& key,
                                             std::string const& value);
@@ -171,6 +184,7 @@ protected:
   std::string GeneratorToolsetCudaCustomDir;
   std::string DefaultPlatformToolset;
   std::string DefaultPlatformToolsetHostArchitecture;
+  std::string DefaultAndroidToolset;
   std::string WindowsTargetPlatformVersion;
   std::string SystemName;
   std::string SystemVersion;
@@ -188,6 +202,7 @@ protected:
   bool SystemIsWindowsCE = false;
   bool SystemIsWindowsPhone = false;
   bool SystemIsWindowsStore = false;
+  bool SystemIsAndroid = false;
 
 private:
   class Factory;
@@ -211,6 +226,7 @@ private:
   std::string MSBuildCommand;
   bool MSBuildCommandInitialized;
   cmVisualStudio10ToolsetOptions ToolsetOptions;
+  std::set<std::string> AndroidExecutableWarnings;
   virtual std::string FindMSBuildCommand();
   std::string FindDevEnvCommand() override;
   std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }

+ 6 - 0
Source/cmGlobalVisualStudio14Generator.cxx

@@ -109,6 +109,7 @@ cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
     "ProductDir",
     vc14Express, cmSystemTools::KeyWOW64_32);
   this->DefaultPlatformToolset = "v140";
+  this->DefaultAndroidToolset = "Clang_3_8";
   this->DefaultCLFlagTableName = "v140";
   this->DefaultCSharpFlagTableName = "v140";
   this->DefaultLibFlagTableName = "v14";
@@ -159,6 +160,11 @@ bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf)
   return true;
 }
 
+bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
+{
+  return true;
+}
+
 bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
                                                          bool required)
 {

+ 6 - 0
Source/cmGlobalVisualStudio14Generator.h

@@ -23,12 +23,18 @@ public:
 
   bool MatchesGeneratorName(const std::string& name) const override;
 
+  const char* GetAndroidApplicationTypeRevision() const override
+  {
+    return "2.0";
+  }
+
 protected:
   cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name,
                                   std::string const& platformInGeneratorName);
 
   bool InitializeWindows(cmMakefile* mf) override;
   bool InitializeWindowsStore(cmMakefile* mf) override;
+  bool InitializeAndroid(cmMakefile* mf) override;
   bool SelectWindowsStoreToolset(std::string& toolset) const override;
 
   // These aren't virtual because we need to check if the selected version

+ 38 - 0
Source/cmGlobalVisualStudioVersionedGenerator.cxx

@@ -100,6 +100,24 @@ static const char* VSVersionToToolset(
   return "";
 }
 
+static const char* VSVersionToAndroidToolset(
+  cmGlobalVisualStudioGenerator::VSVersion v)
+{
+  switch (v) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "Clang_3_8";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "Clang_5_0";
+  }
+  return "";
+}
+
 static const char vs15generatorName[] = "Visual Studio 15 2017";
 
 // Map generator name without year to name with year.
@@ -284,6 +302,7 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
   this->Version = version;
   this->ExpressEdition = false;
   this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
+  this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version);
   this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
@@ -408,6 +427,25 @@ bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
           vsInstanceVersion > vsInstanceVersion16_7_P2);
 }
 
+const char*
+cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
+  const
+{
+  switch (this->Version) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "2.0";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "3.0";
+  }
+  return "";
+}
+
 std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
 {
   const char* version = this->GetPlatformToolsetVersion();

+ 2 - 0
Source/cmGlobalVisualStudioVersionedGenerator.h

@@ -36,6 +36,8 @@ public:
 
   bool IsStdOutEncodingSupported() const override;
 
+  const char* GetAndroidApplicationTypeRevision() const override;
+
 protected:
   cmGlobalVisualStudioVersionedGenerator(
     VSVersion version, cmake* cm, const std::string& name,

+ 51 - 8
Source/cmVisualStudio10TargetGenerator.cxx

@@ -234,13 +234,14 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
 {
   this->Makefile->GetConfigurations(this->Configurations);
   this->NsightTegra = gg->IsNsightTegra();
+  this->Android = gg->TargetsAndroid();
   for (int i = 0; i < 4; ++i) {
     this->NsightTegraVersion[i] = 0;
   }
   sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
          &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
          &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
-  this->MSTools = !this->NsightTegra;
+  this->MSTools = !this->NsightTegra && !this->Android;
   this->Managed = false;
   this->TargetCompileAsWinRT = false;
   this->IsMissingFiles = false;
@@ -333,6 +334,13 @@ void cmVisualStudio10TargetGenerator::Generate()
     this->ProjectType = csproj;
     this->Managed = true;
   }
+
+  if (this->Android &&
+      this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+      !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
+    this->GlobalGenerator->AddAndroidExecutableWarning(this->Name);
+  }
+
   // Tell the global generator the name of the project file
   this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
                                              this->Name);
@@ -427,7 +435,7 @@ void cmVisualStudio10TargetGenerator::Generate()
       e1.Attribute("Label", "Globals");
       e1.Element("ProjectGuid", "{" + this->GUID + "}");
 
-      if (this->MSTools &&
+      if ((this->MSTools || this->Android) &&
           this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
         this->WriteApplicationTypeSettings(e1);
         this->VerifyNecessaryFiles();
@@ -469,7 +477,11 @@ void cmVisualStudio10TargetGenerator::Generate()
       cmProp vsGlobalKeyword =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
       if (!vsGlobalKeyword) {
-        e1.Element("Keyword", "Win32Proj");
+        if (this->GlobalGenerator->TargetsAndroid()) {
+          e1.Element("Keyword", "Android");
+        } else {
+          e1.Element("Keyword", "Win32Proj");
+        }
       } else {
         e1.Element("Keyword", *vsGlobalKeyword);
       }
@@ -1137,6 +1149,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
                 !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
               // Android executables are .so too.
               configType = "DynamicLibrary";
+            } else if (this->Android) {
+              configType = "DynamicLibrary";
             } else {
               configType = "Application";
             }
@@ -1166,6 +1180,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
       }
     } else if (this->NsightTegra) {
       this->WriteNsightTegraConfigurationValues(e1, c);
+    } else if (this->Android) {
+      this->WriteAndroidConfigurationValues(e1, c);
     }
   }
 }
@@ -1324,6 +1340,24 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
   }
 }
 
+void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues(
+  Elem& e1, std::string const&)
+{
+  cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+  if (cmProp projectToolsetOverride =
+        this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+    e1.Element("PlatformToolset", *projectToolsetOverride);
+  } else if (const char* toolset = gg->GetPlatformToolset()) {
+    e1.Element("PlatformToolset", toolset);
+  }
+  if (cmProp stlType =
+        this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
+    if (*stlType != "none") {
+      e1.Element("UseOfStl", *stlType);
+    }
+  }
+}
+
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 {
   this->CSharpCustomCommandNames.clear();
@@ -2909,7 +2943,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
     }
   }
 
-  if (this->MSTools) {
+  if (this->Android) {
+    e2.Element("ObjectFileName", "$(IntDir)%(filename).o");
+  } else if (this->MSTools) {
     cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*");
     const char* toolset = this->GlobalGenerator->GetPlatformToolset();
     if (toolset && clangToolset.find(toolset)) {
@@ -4347,6 +4383,7 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
   bool isAppContainer = false;
   bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
   bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+  bool const isAndroid = this->GlobalGenerator->TargetsAndroid();
   std::string const& rev = this->GlobalGenerator->GetApplicationTypeRevision();
   if (isWindowsPhone || isWindowsStore) {
     e1.Element("ApplicationType",
@@ -4384,13 +4421,19 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
                    this->Name + "_$(Configuration)_$(Platform).xap");
       }
     }
+  } else if (isAndroid) {
+    e1.Element("ApplicationType", "Android");
+    e1.Element("ApplicationTypeRevision",
+               gg->GetAndroidApplicationTypeRevision());
   }
   if (isAppContainer) {
     e1.Element("AppContainerApplication", "true");
-  } else if (this->Platform == "ARM64") {
-    e1.Element("WindowsSDKDesktopARM64Support", "true");
-  } else if (this->Platform == "ARM") {
-    e1.Element("WindowsSDKDesktopARMSupport", "true");
+  } else if (!isAndroid) {
+    if (this->Platform == "ARM64") {
+      e1.Element("WindowsSDKDesktopARM64Support", "true");
+    } else if (this->Platform == "ARM") {
+      e1.Element("WindowsSDKDesktopARMSupport", "true");
+    }
   }
   std::string const& targetPlatformVersion =
     gg->GetWindowsTargetPlatformVersion();

+ 2 - 0
Source/cmVisualStudio10TargetGenerator.h

@@ -70,6 +70,7 @@ private:
   void WriteExtraSource(Elem& e1, cmSourceFile const* sf);
   void WriteNsightTegraConfigurationValues(Elem& e1,
                                            std::string const& config);
+  void WriteAndroidConfigurationValues(Elem& e1, std::string const& config);
   void WriteSource(Elem& e2, cmSourceFile const* sf);
   void WriteExcludeFromBuild(Elem& e2,
                              std::vector<size_t> const& exclude_configs);
@@ -215,6 +216,7 @@ private:
   bool MSTools;
   bool Managed;
   bool NsightTegra;
+  bool Android;
   unsigned int NsightTegraVersion[4];
   bool TargetCompileAsWinRT;
   std::set<std::string> IPOEnabledConfigurations;

+ 45 - 16
Tests/CMakeLists.txt

@@ -206,6 +206,26 @@ if(BUILD_TESTING)
         set(${reg} 0)
       endif()
     endforeach()
+    if(COMMAND cmake_host_system_information)
+      set(info_vs15 "VS_15_DIR")
+      set(info_vs16 "VS_16_DIR")
+      set(vs_versions)
+      if(WIN32)
+        if(NOT CMAKE_VERSION VERSION_LESS 3.14)
+          set(vs_versions vs15 vs16)
+        elseif(NOT CMAKE_VERSION VERSION_LESS 3.8)
+          set(vs_versions vs15)
+        endif()
+      endif()
+      foreach(info ${vs_versions})
+        cmake_host_system_information(RESULT found QUERY "${info_${info}}")
+        if(found)
+          set(${info} 1)
+        else()
+          set(${info} 0)
+        endif()
+      endforeach()
+    endif()
   endif()
 
   #---------------------------------------------------------------------------
@@ -2316,32 +2336,41 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
     endforeach()
   endif()
 
+  macro(add_test_VSAndroid name generator platform)
+    add_test(NAME "VSAndroid.${name}.${platform}" COMMAND ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/VSAndroid"
+      "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}/${platform}"
+      --build-generator "${generator}"
+      --build-project VSAndroid
+      --build-config $<CONFIGURATION>
+      --build-options -DCMAKE_SYSTEM_NAME=Android "-A${platform}"
+      )
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}")
+  endmacro()
   if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
-    macro(add_test_VSNsightTegra name generator)
-      add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND}
-        --build-and-test
-        "${CMake_SOURCE_DIR}/Tests/VSNsightTegra"
-        "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}"
-        --build-generator "${generator}"
-        --build-project VSNsightTegra
-        --build-config $<CONFIGURATION>
-        --build-options -DCMAKE_SYSTEM_NAME=Android
-        )
-      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}")
-    endmacro()
     if(vs10)
-      add_test_VSNsightTegra(vs10 "Visual Studio 10 2010")
+      add_test_VSAndroid(vs10 "Visual Studio 10 2010" "Tegra-Android")
     endif()
     if(vs11)
-      add_test_VSNsightTegra(vs11 "Visual Studio 11 2012")
+      add_test_VSAndroid(vs11 "Visual Studio 11 2012" "Tegra-Android")
     endif()
     if(vs12)
-      add_test_VSNsightTegra(vs12 "Visual Studio 12 2013")
+      add_test_VSAndroid(vs12 "Visual Studio 12 2013" "Tegra-Android")
     endif()
     if(vs14)
-      add_test_VSNsightTegra(vs14 "Visual Studio 14 2015")
+      add_test_VSAndroid(vs14 "Visual Studio 14 2015" "Tegra-Android")
     endif()
   endif()
+  if(vs14 AND CMake_TEST_ANDROID_VS14)
+    add_test_VSAndroid(vs14 "Visual Studio 14 2015" "ARM")
+  endif()
+  if(vs15 AND CMake_TEST_ANDROID_VS15)
+    add_test_VSAndroid(vs15 "Visual Studio 15 2017" "ARM")
+  endif()
+  if(vs16 AND CMake_TEST_ANDROID_VS16)
+    add_test_VSAndroid(vs16 "Visual Studio 16 2019" "ARM")
+  endif()
 
   if (APPLE)
     if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")

+ 44 - 9
Tests/RunCMake/Android/RunCMakeTest.cmake

@@ -33,12 +33,18 @@ function(run_Android case)
   endforeach()
 endfunction()
 
+set(RunCMake_GENERATOR_PLATFORM_OLD "${RunCMake_GENERATOR_PLATFORM}")
+
+if(RunCMake_GENERATOR MATCHES "Visual Studio")
+  set(RunCMake_GENERATOR_PLATFORM "ARM")
+endif()
 set(RunCMake_TEST_OPTIONS
   -DCMAKE_SYSTEM_NAME=Android
   -DCMAKE_SYSROOT=${CMAKE_CURRENT_SOURCE_DIR}
   )
 run_cmake(BadSYSROOT)
 unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
 foreach(ndk IN LISTS TEST_ANDROID_NDK)
   # Load available toolchain versions and abis.
@@ -82,6 +88,9 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
   if(_versions MATCHES "clang")
     set(_versions "clang" ${_versions})
   endif()
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(_versions "clang")
+  endif()
   list(REMOVE_DUPLICATES _versions)
   list(SORT _versions)
   set(_versions ";${_versions}")
@@ -89,44 +98,58 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
     list(REMOVE_DUPLICATES _abis_${vers})
   endforeach()
 
+  set(ndk_arg -DCMAKE_ANDROID_NDK=${ndk})
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(ndk_arg)
+  endif()
+
   # Test failure cases.
   message(STATUS "ndk='${ndk}'")
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=badabi
     )
   run_cmake(ndk-badabi)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "x86")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=x86
     -DCMAKE_ANDROID_ARM_MODE=0
     )
   run_cmake(ndk-badarm)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   if("armeabi" IN_LIST _abis_)
     set(RunCMake_TEST_OPTIONS
       -DCMAKE_SYSTEM_NAME=Android
-      -DCMAKE_ANDROID_NDK=${ndk}
+      ${ndk_arg}
       -DCMAKE_ANDROID_ARM_NEON=0
       )
     run_cmake(ndk-badneon)
   endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=badver
     )
   run_cmake(ndk-badver)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=1.0
     )
   run_cmake(ndk-badvernum)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_STL_TYPE=badstl
     )
   run_cmake(ndk-badstl)
@@ -143,6 +166,7 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
     run_cmake(ndk-sysroot-armeabi)
     unset(RunCMake_TEST_OPTIONS)
   endif()
+  set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
   # Find available STLs.
   set(stl_types
@@ -169,11 +193,18 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
     armeabi-v6
     armeabi-v7a
     arm64-v8a
-    mips
-    mips64
     x86
     x86_64
     )
+  if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+    list(APPEND abi_names mips mips64)
+  endif()
+  set(abi_to_arch_armeabi ARM)
+  set(abi_to_arch_armeabi-v6 ARM)
+  set(abi_to_arch_armeabi-v7a ARM)
+  set(abi_to_arch_arm64-v8a ARM64)
+  set(abi_to_arch_x86 x86)
+  set(abi_to_arch_x86_64 x64)
 
   # Test all combinations.
   foreach(vers IN LISTS _versions)
@@ -193,7 +224,7 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
         endif()
         message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}'${config_status}")
         set(RunCMake_TEST_OPTIONS
-          -DCMAKE_ANDROID_NDK=${ndk}
+          ${ndk_arg}
           -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${vers}
           -DCMAKE_ANDROID_STL_TYPE=${stl}
           "${build_type_arg}"
@@ -205,6 +236,9 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
           endif()
 
           # Run the tests for this combination.
+          if(RunCMake_GENERATOR MATCHES "Visual Studio")
+            set(RunCMake_GENERATOR_PLATFORM "${abi_to_arch_${abi}}")
+          endif()
           if("${abi}" STREQUAL "armeabi")
             run_Android(ndk-armeabi-thumb) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi -DCMAKE_ANDROID_ARM_MODE=0
             run_Android(ndk-armeabi-arm -DCMAKE_ANDROID_ARM_MODE=1) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi
@@ -214,6 +248,7 @@ foreach(ndk IN LISTS TEST_ANDROID_NDK)
               run_Android(ndk-${abi}-neon -DCMAKE_ANDROID_ARCH_ABI=${abi} -DCMAKE_ANDROID_ARM_NEON=1)
             endif()
           endif()
+          set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
         endforeach()
         unset(RunCMake_TEST_OPTIONS)
       endforeach()

+ 7 - 0
Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-x86-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 7 - 0
Tests/RunCMake/Android/ndk-x86_64-stderr.txt

@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$

+ 2 - 2
Tests/RunCMake/CMakeLists.txt

@@ -683,8 +683,8 @@ add_RunCMake_test(AutoExportDll
 add_RunCMake_test(AndroidMK)
 
 if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
-  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
-    message(FATAL_ERROR "Android tests supported only by Makefile and Ninja generators")
+  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|Visual Studio 1[456]")
+    message(FATAL_ERROR "Android tests supported only by Makefile, Ninja, and Visual Studio >= 14 generators")
   endif()
   foreach(v TEST_ANDROID_NDK TEST_ANDROID_STANDALONE_TOOLCHAIN)
     if(CMake_${v})

+ 0 - 0
Tests/VSNsightTegra/AndroidManifest.xml → Tests/VSAndroid/AndroidManifest.xml


+ 1 - 1
Tests/VSNsightTegra/CMakeLists.txt → Tests/VSAndroid/CMakeLists.txt

@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.3)
-project(VSNsightTegra C CXX)
+project(VSAndroid C CXX)
 
 set(CMAKE_ANDROID_ARCH armv7-a)
 set(CMAKE_ANDROID_STL_TYPE stlport_shared)

+ 0 - 0
Tests/VSNsightTegra/build.xml → Tests/VSAndroid/build.xml


+ 0 - 0
Tests/VSNsightTegra/jni/first.c → Tests/VSAndroid/jni/first.c


+ 0 - 0
Tests/VSNsightTegra/jni/first.h → Tests/VSAndroid/jni/first.h


+ 0 - 0
Tests/VSNsightTegra/jni/second.c → Tests/VSAndroid/jni/second.c


+ 0 - 0
Tests/VSNsightTegra/proguard-android.txt → Tests/VSAndroid/proguard-android.txt


+ 0 - 0
Tests/VSNsightTegra/res/values/strings.xml → Tests/VSAndroid/res/values/strings.xml


+ 0 - 0
Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java → Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java