Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding tools.microsoft:winsdk_version conf #15272

Merged
merged 8 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions conan/tools/cmake/toolchain/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ def context(self):
check_type=bool)
if android_ndk_path and (cxxflags or cflags) and android_legacy_toolchain is not False:
self._conanfile.output.warning("tools.build:cxxflags or cflags are defined, but Android NDK toolchain may be overriding "
"the values. Consider setting tools.android:cmake_legacy_toolchain to False.")
"the values. Consider setting tools.android:cmake_legacy_toolchain to False.")

return {
"cxxflags": cxxflags,
Expand Down Expand Up @@ -641,6 +641,9 @@ def context(self):

class GenericSystemBlock(Block):
template = textwrap.dedent("""
########## generic_system block #############
# Definition of system, platform and toolset
#############################################
{% if cmake_sysroot %}
set(CMAKE_SYSROOT {{ cmake_sysroot }})
{% endif %}
Expand All @@ -656,10 +659,24 @@ class GenericSystemBlock(Block):
set(CMAKE_SYSTEM_PROCESSOR {{ cmake_system_processor }})
{% endif %}

{% if generator_platform %}
{% if generator_platform and not winsdk_version %}
set(CMAKE_GENERATOR_PLATFORM "{{ generator_platform }}" CACHE STRING "" FORCE)
{% elif winsdk_version %}
if(POLICY CMP0149)
cmake_policy(GET CMP0149 _POLICY_WINSDK_VERSION)
endif()
if(_POLICY_WINSDK_VERSION STREQUAL "NEW")
message(STATUS "Conan toolchain: CMAKE_GENERATOR_PLATFORM={{gen_platform_sdk_version}}")
memsharded marked this conversation as resolved.
Show resolved Hide resolved
set(CMAKE_GENERATOR_PLATFORM "{{ gen_platform_sdk_version }}" CACHE STRING "" FORCE)
else()
# winsdk_version will be taken from above CMAKE_SYSTEM_VERSION
message(STATUS "Conan toolchain: CMAKE_GENERATOR_PLATFORM={{generator_platform}}")
set(CMAKE_GENERATOR_PLATFORM "{{ generator_platform }}" CACHE STRING "" FORCE)
endif()
{% endif %}

{% if toolset %}
message(STATUS "Conan toolchain: CMAKE_GENERATOR_TOOLSET={{ toolset }}")
set(CMAKE_GENERATOR_TOOLSET "{{ toolset }}" CACHE STRING "" FORCE)
{% endif %}
""")
Expand Down Expand Up @@ -771,6 +788,32 @@ def _get_cross_build(self):

return system_name, system_version, system_processor

def _get_winsdk_version(self, system_version, generator_platform):
compiler = self._conanfile.settings.get_safe("compiler")
if compiler not in ("msvc", "clang") or "Visual" not in str(self._toolchain.generator):
# Ninja will get it from VCVars, not from toolchain
return system_version, None, None

winsdk_version = self._conanfile.conf.get("tools.microsoft:winsdk_version", check_type=str)
if winsdk_version:
if system_version:
self._conanfile.output.warning("Both cmake_system_version and winsdk_version confs"
" defined, prioritizing winsdk_version")
system_version = winsdk_version
elif "Windows" in self._conanfile.settings.get_safe("os", ""):
winsdk_version = self._conanfile.settings.get_safe("os.version")
if system_version:
if winsdk_version:
self._conanfile.output.warning("Both cmake_system_version conf and os.version"
" defined, prioritizing cmake_system_version")
winsdk_version = system_version

gen_platform_sdk_version = [generator_platform,
f"version={winsdk_version}" if winsdk_version else None]
gen_platform_sdk_version = ",".join(d for d in gen_platform_sdk_version if d)

return system_version, winsdk_version, gen_platform_sdk_version

def context(self):
generator = self._toolchain.generator
generator_platform = self._get_generator_platform(generator)
Expand All @@ -781,12 +824,17 @@ def context(self):
cmake_sysroot = self._conanfile.conf.get("tools.build:sysroot")
cmake_sysroot = cmake_sysroot.replace("\\", "/") if cmake_sysroot is not None else None

result = self._get_winsdk_version(system_version, generator)
Copy link

@mocabe mocabe Dec 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@memsharded
Forgive me if I'm wrong: should this be self._get_winsdk_version(system_version, generator_platform) instead?
I have following conf in profile:

tools.cmake.cmaketoolchain:generator=Visual Studio 17 2022
tools.cmake.cmaketoolchain:system_version=10.0.22000

and now I get set(CMAKE_GENERATOR_PLATFORM "Visual Studio 17 2022,version=10.0.22000" CACHE STRING "" FORCE) in conan_toolchain.cmake, which seems incorrect.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mocabe

Thanks very much for reporting this. Lets have a look.
As a general hint, it is better to create a new ticket (issue) that links to this, that comments in closed PRs, because these might pass unnoticed. (I'll create a ticket for this)

system_version, winsdk_version, gen_platform_sdk_version = result

return {"toolset": toolset,
"generator_platform": generator_platform,
"cmake_system_name": system_name,
"cmake_system_version": system_version,
"cmake_system_processor": system_processor,
"cmake_sysroot": cmake_sysroot}
"cmake_sysroot": cmake_sysroot,
"winsdk_version": winsdk_version,
"gen_platform_sdk_version": gen_platform_sdk_version}


class OutputDirsBlock(Block):
Expand Down
8 changes: 8 additions & 0 deletions conan/tools/microsoft/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class MSBuildToolchain(object):
</ResourceCompile>
</ItemDefinitionGroup>
<PropertyGroup Label="Configuration">
{% if winsdk_version %}
<WindowsTargetPlatformVersion>{{ winsdk_version}}</WindowsTargetPlatformVersion>
{% endif %}
<PlatformToolset>{{ toolset }}</PlatformToolset>
{% for k, v in properties.items() %}
<{{k}}>{{ v }}</{{k}}>
Expand Down Expand Up @@ -149,6 +152,10 @@ def format_macro(key, value):
"\n <ProcessorNumber>{}</ProcessorNumber>".format(njobs)])
compile_options = "".join("\n <{k}>{v}</{k}>".format(k=k, v=v)
for k, v in self.compile_options.items())

winsdk_version = self._conanfile.conf.get("tools.microsoft:winsdk_version", check_type=str)
winsdk_version = winsdk_version or self._conanfile.settings.get_safe("os.version")

return {
'defines': defines,
'compiler_flags': " ".join(self.cxxflags + self.cflags),
Expand All @@ -159,6 +166,7 @@ def format_macro(key, value):
"compile_options": compile_options,
"parallel": parallel,
"properties": self.properties,
"winsdk_version": winsdk_version
}

def _write_config_toolchain(self, config_filename):
Expand Down
8 changes: 5 additions & 3 deletions conan/tools/microsoft/visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,23 @@ def generate(self, scope="build"):
vcvars_ver = _vcvars_vers(conanfile, compiler, vs_version)
vcvarsarch = _vcvars_arch(conanfile)

winsdk_version = conanfile.conf.get("tools.microsoft:winsdk_version", check_type=str)
winsdk_version = winsdk_version or conanfile.settings.get_safe("os.version")
# The vs_install_path is like
# C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
# C:\Program Files (x86)\Microsoft Visual Studio\2017\Community
# C:\Program Files (x86)\Microsoft Visual Studio 14.0
vcvars = vcvars_command(vs_version, architecture=vcvarsarch, platform_type=None,
winsdk_version=None, vcvars_ver=vcvars_ver,
winsdk_version=winsdk_version, vcvars_ver=vcvars_ver,
vs_install_path=vs_install_path)

content = textwrap.dedent("""\
@echo off
set __VSCMD_ARG_NO_LOGO=1
set VSCMD_SKIP_SENDTELEMETRY=1
echo conanvcvars.bat: Activating environment Visual Studio {} - {} - vcvars_ver={}
echo conanvcvars.bat: Activating environment Visual Studio {} - {} - winsdk_version={} - vcvars_ver={}
{}
""".format(vs_version, vcvarsarch, vcvars_ver, vcvars))
""".format(vs_version, vcvarsarch, winsdk_version, vcvars_ver, vcvars))
from conan.tools.env.environment import create_env_script
create_env_script(conanfile, content, CONAN_VCVARS_FILE, scope)

Expand Down
1 change: 1 addition & 0 deletions conans/model/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"tools.google.bazel:bazelrc_path": "List of paths to bazelrc files to be used as 'bazel --bazelrc=rcpath1 ... build'",
"tools.meson.mesontoolchain:backend": "Any Meson backend: ninja, vs, vs2010, vs2012, vs2013, vs2015, vs2017, vs2019, xcode",
"tools.meson.mesontoolchain:extra_machine_files": "List of paths for any additional native/cross file references to be appended to the existing Conan ones",
"tools.microsoft:winsdk_version": "Use this winsdk_version in vcvars",
"tools.microsoft.msbuild:vs_version": "Defines the IDE version (15, 16, 17) when using the msvc compiler. Necessary if compiler.version specifies a toolset that is not the IDE default",
"tools.microsoft.msbuild:max_cpu_count": "Argument for the /m when running msvc to build parallel projects",
"tools.microsoft.msbuild:installation_path": "VS install path, to avoid auto-detect via vswhere, like C:/Program Files (x86)/Microsoft Visual Studio/2019/Community. Use empty string to disable",
Expand Down
18 changes: 18 additions & 0 deletions conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,24 @@ def test_cmake_toolchain_runtime_types_cmake_older_than_3_15():
assert "LIBCMTD" in client.out


@pytest.mark.skipif(platform.system() != "Windows", reason="Only for windows")
# @pytest.mark.tool("cmake", "3.28")
def test_cmake_toolchain_winsdk_version():
client = TestClient(path_with_spaces=False)
client.run("new cmake_lib -d name=hello -d version=0.1")
cmake = client.load("CMakeLists.txt")
# TODO: when we have CMake 3.27 in CI
# cmake = cmake.replace("cmake_minimum_required(VERSION 3.15)",
# "cmake_minimum_required(VERSION 3.27)")
cmake += 'message(STATUS "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION = ' \
'${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")'
client.save({"CMakeLists.txt": cmake})
client.run("create . -s arch=x86_64 -s compiler.version=193 "
"-c tools.microsoft:winsdk_version=8.1")
assert "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION = 8.1" in client.out
assert "Conan toolchain: CMAKE_GENERATOR_PLATFORM=x64" in client.out
memsharded marked this conversation as resolved.
Show resolved Hide resolved


@pytest.mark.tool("cmake", "3.23")
def test_cmake_presets_missing_option():
client = TestClient(path_with_spaces=False)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
import platform
import sys
import textwrap
import os

import pytest
try:
from unittest.mock import MagicMock
except:
from mock import MagicMock

from conan.tools.files import replace_in_file
from conans.test.utils.tools import TestClient

toolchain_props = """
<ImportGroup Label="PropertySheets">
<Import Project="conan\\conantoolchain_release_x64.props" />
"""


@pytest.mark.skipif(sys.version_info.major == 2, reason="Meson not supported in Py2")
@pytest.mark.skipif(platform.system() not in ["Windows"], reason="Requires Windows")
@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
def test_msbuildtoolchain_props_with_extra_flags():
"""
Real test which is injecting some compiler/linker options and other dummy defines and
Expand All @@ -39,14 +26,25 @@ def test_msbuildtoolchain_props_with_extra_flags():
""")
client = TestClient(path_with_spaces=False)
client.run("new msbuild_exe -d name=hello -d version=0.1")
client.save({
"myprofile": profile
})
# Let's import manually the created conantoolchain_release_x64.props
replace_in_file(MagicMock(), os.path.join(client.current_folder, "hello.vcxproj"),
r' <ImportGroup Label="PropertySheets">', toolchain_props)
client.run("create . -pr myprofile -tf=\"\"")
client.save({"myprofile": profile})
# conantoolchain.props is already imported in the msbuild_exe tempalte
client.run("create . -pr myprofile -tf=")
assert "/analyze:quiet /doc src/hello.cpp" in client.out
assert r"/VERBOSE:UNUSEDLIBS /PDB:mypdbfile x64\Release\hello.obj" in client.out
assert "/D DEF1 /D DEF2" in client.out
assert "Build succeeded." in client.out


@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
def test_msbuildtoolchain_winsdk_version():
"""
Configure sdk_version
"""
client = TestClient(path_with_spaces=False)
client.run("new msbuild_lib -d name=hello -d version=0.1")
# conantoolchain.props is already imported in the msbuild_exe tempalte
client.run("create . -s arch=x86_64 -s compiler.version=193 "
"-c tools.microsoft:winsdk_version=8.1")
# I have verified also opening VS IDE that the setting is correctly configured
# because the test always run over vcvars that already activates it
assert "amd64 - winsdk_version=8.1 - vcvars_ver=14.3" in client.out
19 changes: 19 additions & 0 deletions conans/test/integration/toolchains/microsoft/vcvars_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,22 @@ class TestConan(ConanFile):
vcvars = client.load("conanvcvars.bat")
assert 'vcvarsall.bat" x86_amd64' in vcvars
assert "-vcvars_ver" not in vcvars


@pytest.mark.skipif(platform.system() != "Windows", reason="Requires Windows")
def test_vcvars_winsdk_version():
client = TestClient(path_with_spaces=False)

conanfile = textwrap.dedent("""
from conan import ConanFile
class TestConan(ConanFile):
generators = "VCVars"
settings = "os", "compiler", "arch", "build_type"
""")
client.save({"conanfile.py": conanfile})
client.run('install . -s os=Windows -s compiler=msvc -s compiler.version=193 '
'-s compiler.cppstd=14 -s compiler.runtime=static '
'-c tools.microsoft:winsdk_version=8.1')

vcvars = client.load("conanvcvars.bat")
assert 'vcvarsall.bat" amd64 8.1 -vcvars_ver=14.3' in vcvars