Visual Studio: Add Android support

This commit is contained in:
Kyle Edwards 2020-06-12 15:11:04 -04:00 committed by Brad King
parent bbcaf9689e
commit 6051a49c78
34 changed files with 479 additions and 63 deletions

View File

@ -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.

View File

@ -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 "")

View File

@ -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>

View File

@ -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()

View File

@ -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 "")

View File

@ -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()

View File

@ -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>

View File

@ -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 =

View File

@ -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(); }

View File

@ -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)
{

View File

@ -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

View File

@ -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();

View File

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

View File

@ -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();

View File

@ -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;

View File

@ -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")

View File

@ -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()

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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)?$

View File

@ -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})

View File

@ -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)