From 0132490ba82f699a44778870ad8bc6c2a3553861 Mon Sep 17 00:00:00 2001 From: memsharded Date: Fri, 5 Apr 2024 11:57:02 +0200 Subject: [PATCH 1/2] msvc package --- examples/dev_flow.rst | 1 + examples/dev_flow/msvc_package.rst | 94 ++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 examples/dev_flow/msvc_package.rst diff --git a/examples/dev_flow.rst b/examples/dev_flow.rst index f32ec7428bd..6491aaae03b 100644 --- a/examples/dev_flow.rst +++ b/examples/dev_flow.rst @@ -7,3 +7,4 @@ Developer tools and flows :maxdepth: 2 dev_flow/debug/step_into_dependencies + dev_flow/msvc_package diff --git a/examples/dev_flow/msvc_package.rst b/examples/dev_flow/msvc_package.rst new file mode 100644 index 00000000000..a59ec879dc7 --- /dev/null +++ b/examples/dev_flow/msvc_package.rst @@ -0,0 +1,94 @@ +Packaging Visual Studio as a Conan package +========================================== + +It is possible to package the Visual Studio tools into a Conan package and use it later as a ``tool_requires``. +This can be convenient in some scenarios, for example in CI, or in some developer setups. + +In this example we are going to start with a standard Visual Studio 16 2019 installation on disk. The first +thing we'll do is to rename the folder ``C:/Program Files (x86)/Microsoft Visual Studio/2019`` to +``C:/Program Files (x86)/Microsoft Visual Studio/2019_2``. This is not strictly necessary, but in this way +we make sure that CMake or vswhere are not able to locate it, and we can validate better that the consumer +project is using VS from the Conan package and not from the system. + +This is the recipe to package VS 2019: + +.. code-block:: python + :caption: conanfile.py + + from conan import ConanFile + from conan.tools.files import copy, save + import os + + class x86_64_windows_msvc2017Conan(ConanFile): + name = "msvc" + version = "16" + settings = "os", "arch" + + def package(self): + # toolchain + version_vs = "16.11.34601.136" # This must be tuned, might be automatically obtained too + toolchain = f'set(CMAKE_GENERATOR_INSTANCE "$ENV{{CONAN_MSVC_16_FOLDER}},version={version_vs}" CACHE INTERNAL "")' + save(self, os.path.join(self.package_folder, "msvc_toolchain.cmake"), toolchain) + # packaging + vs_path = "C:/Program Files (x86)/Microsoft Visual Studio/2019_2/Community" + copy(self, "*", src=vs_path, dst=self.package_folder) + + def package_info(self): + f = os.path.join(self.package_folder, "msvc_toolchain.cmake") + self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", f) + pf = self.package_folder.replace("\\", "/") + self.buildenv_info.define("CONAN_MSVC_16_FOLDER", pf) + + +Note a few important things: + +- The ``package()`` method is creating a ``msvc_toolchain.cmake`` that defines the ``CMAKE_GENERATOR_INSTANCE``. +- The ``CMAKE_GENERATOR_INSTANCE`` should point to the location of VS, which is inside the Conan package. But this location + will change from machine to machine, so it needs to be generalized. +- The ``version_vs = "16.11.34601.136"`` needs to match your installation. It can be obtained with ``vswhere``. It is possible + to automate that in the recipe, but it is hardcoded for simplicity, like the ``vs_path``. +- A ``CONAN_MSVC_16_FOLDER`` environment variable, which value is defined in the ``package_info()`` method is used to + generalize the package folder location. +- The generated ``msvc_toolchain.cmake`` is passed to consumers with the ``tools.cmake.cmaketoolchain:user_toolchain`` configuration + + +We can use ``conan create .`` to create the Conan package containing a copy of the VS 2019 installation. + +Then, we can define a profile like (assuming the ``default`` profile is a Windows-MSVC one): + +.. code-block:: + :caption: msvc16_profile + + include(default) + + [settings] + # Note that we need to align the settings with the tool-require + compiler.version=192 + + [tool_requires] + msvc/16 + +And we can now use it to build a CMake package: + +.. code-block:: bash + + $ conan new cmake_lib -d name=mypkg -d version=0.1 + $ conan create . -pr=msvc16_profile + ... + -- Check for working CXX compiler: C:/Users/mysuser/.conan2/p/b/msvcfa3a5055acf54/p/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped + ... + mypkg/0.1 (test package): RUN: Release\example + mypkg/0.1: _MSC_VER1929 + +And it will use the compiler from within the ``msvc/16`` Conan package. + + + +.. note:: + + - This example is far from optimal. The whole IDE installation is packaged, which is very large. Most likely + it is not necessary to package everything and packaging just a subset (MSBuild, compiler and tools) would be + enough, be faster to package and use less space. + - Please make sure to comply with the VS licenses while using their tools. + - This example works only for CMake consumers. For other build systems, it might be necessary to improve the + ``msvc`` recipe. From 196f2df14ecbae642ccdcb1050c221a6a96a2ec8 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 5 Apr 2024 13:17:28 +0200 Subject: [PATCH 2/2] Update examples/dev_flow/msvc_package.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rubén Rincón Blanco --- examples/dev_flow/msvc_package.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dev_flow/msvc_package.rst b/examples/dev_flow/msvc_package.rst index a59ec879dc7..6b47c3d7915 100644 --- a/examples/dev_flow/msvc_package.rst +++ b/examples/dev_flow/msvc_package.rst @@ -47,7 +47,7 @@ Note a few important things: will change from machine to machine, so it needs to be generalized. - The ``version_vs = "16.11.34601.136"`` needs to match your installation. It can be obtained with ``vswhere``. It is possible to automate that in the recipe, but it is hardcoded for simplicity, like the ``vs_path``. -- A ``CONAN_MSVC_16_FOLDER`` environment variable, which value is defined in the ``package_info()`` method is used to +- A ``CONAN_MSVC_16_FOLDER`` environment variable, whose value is defined in the ``package_info()`` method is used to generalize the package folder location. - The generated ``msvc_toolchain.cmake`` is passed to consumers with the ``tools.cmake.cmaketoolchain:user_toolchain`` configuration