From 5c013a4f0d083f35ae17fa491ff187e69412a4de Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Sun, 4 Aug 2024 16:49:44 +0200 Subject: [PATCH] ci: add GDK SDL2 port of 31b3f5ea79cf47ec838aa46071445355b3b5f4d0 --- .github/actions/setup-gdk-desktop/action.yml | 82 +++++ .github/actions/setup-ninja/action.yml | 6 +- .github/workflows/msvc.yml | 26 +- .../testgamecontroller.vcxproj.filters | 2 +- VisualC-GDK/tests/testgdk/testgdk.vcxproj | 6 +- .../tests/testgdk/testgdk.vcxproj.filters | 2 +- .../tests/testsprite2/testsprite2.vcxproj | 6 +- .../testsprite2/testsprite2.vcxproj.filters | 2 +- build-scripts/setup-gdk-desktop.py | 303 ++++++++++++++++++ 9 files changed, 418 insertions(+), 17 deletions(-) create mode 100644 .github/actions/setup-gdk-desktop/action.yml create mode 100644 build-scripts/setup-gdk-desktop.py diff --git a/.github/actions/setup-gdk-desktop/action.yml b/.github/actions/setup-gdk-desktop/action.yml new file mode 100644 index 0000000000..10427ace3c --- /dev/null +++ b/.github/actions/setup-gdk-desktop/action.yml @@ -0,0 +1,82 @@ +name: 'Setup GDK (Game Development Kit) for Windows Desktop' +description: 'Download GDK and install into MSBuild' +inputs: + # Keep edition and ref in sync! + edition: + description: 'GDK edition' + default: '240601' # YYMMUU (Year Month Update) + ref: + description: 'Git reference' + default: 'June_2024_Update_1' + folder: + description: 'Folder where to create Directory.Build.props' + required: true + default: '${{ github.workspace }}' +runs: + using: 'composite' + steps: + - uses: actions/setup-python@main + with: + python-version: 3.x + - name: 'Calculate variables' + id: calc + shell: pwsh + run: | + $vs_folder=@(vswhere -latest -property installationPath) + echo "vs-folder=${vs_folder}" >> $Env:GITHUB_OUTPUT + + echo "gdk-path=${{ runner.temp }}\GDK-${{ inputs.edition }}" >> $Env:GITHUB_OUTPUT + + echo "cache-key=gdk-${{ inputs.ref }}-${{ inputs.edition }}" >> $Env:GITHUB_OUTPUT + - name: 'Restore cached GDK' + id: cache-restore + uses: actions/cache/restore@v4 + with: + path: '${{ steps.calc.outputs.gdk-path }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Download GDK' + if: ${{ !steps.cache-restore.outputs.cache-hit }} + shell: pwsh + run: | + python build-scripts/setup-gdk-desktop.py ` + --download ` + --temp-folder "${{ runner.temp }}" ` + --gdk-path="${{ steps.calc.outputs.gdk-path }}" ` + --ref-edition "${{ inputs.ref }},${{ inputs.edition }}" ` + --vs-folder="${{ steps.calc.outputs.vs-folder }}" ` + --no-user-props + - name: 'Extract GDK' + if: ${{ !steps.cache-restore.outputs.cache-hit }} + shell: pwsh + run: | + python build-scripts/setup-gdk-desktop.py ` + --extract ` + --ref-edition "${{ inputs.ref }},${{ inputs.edition }}" ` + --temp-folder "${{ runner.temp }}" ` + --gdk-path="${{ steps.calc.outputs.gdk-path }}" ` + --vs-folder="${{ steps.calc.outputs.vs-folder }}" ` + --no-user-props + - name: 'Cache GDK' + if: ${{ !steps.cache-restore.outputs.cache-hit }} + uses: actions/cache/save@v4 + with: + path: '${{ steps.calc.outputs.gdk-path }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Copy MSBuild files into GDK' + shell: pwsh + run: | + python build-scripts/setup-gdk-desktop.py ` + --ref-edition "${{ inputs.ref }},${{ inputs.edition }}" ` + --gdk-path="${{ steps.calc.outputs.gdk-path }}" ` + --vs-folder="${{ steps.calc.outputs.vs-folder }}" ` + --copy-msbuild ` + --no-user-props + - name: 'Write user props' + shell: pwsh + run: | + python build-scripts/setup-gdk-desktop.py ` + --ref-edition "${{ inputs.ref }},${{ inputs.edition }}" ` + --temp-folder "${{ runner.temp }}" ` + --vs-folder="${{ steps.calc.outputs.vs-folder }}" ` + --gdk-path="${{ steps.calc.outputs.gdk-path }}" ` + "--props-folder=${{ inputs.folder }}" diff --git a/.github/actions/setup-ninja/action.yml b/.github/actions/setup-ninja/action.yml index bf638eabae..b9283598d7 100644 --- a/.github/actions/setup-ninja/action.yml +++ b/.github/actions/setup-ninja/action.yml @@ -1,5 +1,5 @@ name: 'Setup ninja' -description: 'Setup ninja' +description: 'Download ninja and add it to the PATH environment variable' inputs: version: description: 'Ninja version' @@ -36,7 +36,7 @@ runs: echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT} - name: 'Restore cached ${{ steps.calc.outputs.archive }}' id: cache-restore - uses: actions/cache/restore@main + uses: actions/cache/restore@v4 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} @@ -47,7 +47,7 @@ runs: Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v${{ inputs.version }}/${{ steps.calc.outputs.archive }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" - name: 'Cache ${{ steps.calc.outputs.archive }}' if: ${{ !steps.cache-restore.outputs.cache-hit }} - uses: actions/cache/save@main + uses: actions/cache/save@v4 with: path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' key: ${{ steps.calc.outputs.cache-key }} diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index 0243eaff3f..c5034d2f94 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -21,16 +21,25 @@ jobs: - { name: 'Windows (ARM64)', vcvars: 'x64_arm64', artifact: 'SDL-VC-arm64', } - { name: 'UWP (x64)', vcvars: 'x64', artifact: 'SDL-VC-UWP', cmake-args: '-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DSDL_TESTS=OFF', project: 'VisualC-WinRT/SDL-UWP.sln', projectflags: '/p:Platform=x64 /p:WindowsTargetPlatformVersion=10.0.17763.0', } + - { name: 'GDK (x64)', vcvars: 'x64', artifact: '', no-cmake: true, gdk: true, + project: 'VisualC-GDK/SDL.sln', projectflags: '/p:Platform=Gaming.Desktop.x64', } steps: - uses: actions/checkout@v4 - name: Set up ninja + if: ${{ !matrix.platform.no-cmake }} uses: ./.github/actions/setup-ninja - uses: ilammy/msvc-dev-cmd@v1 with: arch: ${{ matrix.platform.vcvars }} + - name: 'Set up Windows GDK Desktop' + uses: ./.github/actions/setup-gdk-desktop + if: ${{ matrix.platform.gdk }} + with: + folder: '${{ github.workspace }}/VisualC-GDK' - name: Create CMake project using SDL as a subproject shell: python + if: ${{ !matrix.platform.no-cmake }} run: | import os import textwrap @@ -50,6 +59,8 @@ jobs: add_subdirectory("{ srcdir }" SDL) """)) - name: Configure (CMake) + id: cmake-configure + if: ${{ !matrix.platform.no-cmake }} run: cmake -S build -B build -GNinja ` -DCMAKE_BUILD_TYPE=Release ` -DSDL_WERROR=ON ` @@ -66,20 +77,24 @@ jobs: ${{ matrix.platform.cmake-args }} ` -DCMAKE_INSTALL_PREFIX=prefix - name: Build (CMake) + id: cmake-build + if: ${{ steps.cmake-configure.outcome == 'success' }} run: | cmake --build build/ --config Release --verbose --parallel -- -k0 - name: Run build-time tests - id: tests - if: ${{ !contains(matrix.platform.name, 'ARM') && !contains(matrix.platform.name, 'UWP') }} + id: cmake-test + if: ${{ steps.cmake-build.outcome == 'success' && !contains(matrix.platform.name, 'ARM') && !contains(matrix.platform.name, 'UWP') }} run: | $env:SDL_TESTS_QUICK=1 ctest -VV --test-dir build/ -C Release -j2 - name: Install (CMake) + id: cmake-install + if: ${{ steps.cmake-build.outcome == 'success' }} run: | echo "SDL2_DIR=$Env:GITHUB_WORKSPACE/prefix" >> $Env:GITHUB_ENV cmake --install build/ - name: Verify CMake configuration files - if: ${{ !contains(matrix.platform.name, 'UWP') }} + if: ${{ steps.cmake-install.outcome == 'success' && !contains(matrix.platform.name, 'UWP') }} run: | cmake -S cmake/test -B cmake_config_build -GNinja ` -DCMAKE_BUILD_TYPE=Release ` @@ -96,9 +111,10 @@ jobs: uses: microsoft/setup-msbuild@v2 - name: Build msbuild if: ${{ matrix.platform.project != '' }} - run: msbuild ${{ matrix.platform.project }} /m /p:BuildInParallel=true /p:Configuration=Release ${{ matrix.platform.projectflags }} + run: | + msbuild ${{ matrix.platform.project }} /m /p:BuildInParallel=true /p:Configuration=Release ${{ matrix.platform.projectflags }} - uses: actions/upload-artifact@v4 - if: ${{ always() && steps.tests.outcome == 'failure' }} + if: ${{ always() && steps.cmake-test.outcome == 'failure' }} with: if-no-files-found: ignore name: '${{ matrix.platform.artifact }}-minidumps' diff --git a/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters b/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters index 1124f2c6e6..5f744f1685 100644 --- a/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters +++ b/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters @@ -21,7 +21,7 @@ logos - + wingdk diff --git a/VisualC-GDK/tests/testgdk/testgdk.vcxproj b/VisualC-GDK/tests/testgdk/testgdk.vcxproj index f024a89a56..a78a22741c 100644 --- a/VisualC-GDK/tests/testgdk/testgdk.vcxproj +++ b/VisualC-GDK/tests/testgdk/testgdk.vcxproj @@ -139,7 +139,7 @@ Windows - xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) @@ -223,7 +223,7 @@ true Windows - xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) @@ -352,7 +352,7 @@ copy "%(FullPath)" "$(OutDir)\" - + Document true true diff --git a/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters b/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters index b82a989857..436bd53ea7 100644 --- a/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters +++ b/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters @@ -18,7 +18,7 @@ logos - + wingdk diff --git a/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj b/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj index 651a346e53..54401dcab2 100644 --- a/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj +++ b/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj @@ -139,7 +139,7 @@ Windows - xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) @@ -223,7 +223,7 @@ true Windows - xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) @@ -352,7 +352,7 @@ copy "%(FullPath)" "$(OutDir)\" - + Document true true diff --git a/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters b/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters index e945fe5489..83c26bf212 100644 --- a/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters +++ b/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters @@ -18,7 +18,7 @@ logos - + wingdk diff --git a/build-scripts/setup-gdk-desktop.py b/build-scripts/setup-gdk-desktop.py new file mode 100644 index 0000000000..d2309a0e31 --- /dev/null +++ b/build-scripts/setup-gdk-desktop.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python + +import argparse +import functools +import logging +import os +from pathlib import Path +import re +import shutil +import subprocess +import tempfile +import textwrap +import urllib.request +import zipfile + +# Update both variables when updating the GDK +GIT_REF = "June_2024_Update_1" +GDK_EDITION = "240601" # YYMMUU + +logger = logging.getLogger(__name__) + +class GdDesktopConfigurator: + def __init__(self, gdk_path, arch, vs_folder, vs_version=None, vs_toolset=None, temp_folder=None, git_ref=None, gdk_edition=None): + self.git_ref = git_ref or GIT_REF + self.gdk_edition = gdk_edition or GDK_EDITION + self.gdk_path = gdk_path + self.temp_folder = temp_folder or Path(tempfile.gettempdir()) + self.dl_archive_path = Path(self.temp_folder) / f"{ self.git_ref }.zip" + self.gdk_extract_path = Path(self.temp_folder) / f"GDK-{ self.git_ref }" + self.arch = arch + self.vs_folder = vs_folder + self._vs_version = vs_version + self._vs_toolset = vs_toolset + + def download_archive(self) -> None: + gdk_url = f"https://github.com/microsoft/GDK/archive/refs/tags/{ GIT_REF }.zip" + logger.info("Downloading %s to %s", gdk_url, self.dl_archive_path) + urllib.request.urlretrieve(gdk_url, self.dl_archive_path) + assert self.dl_archive_path.is_file() + + def extract_zip_archive(self) -> None: + extract_path = self.gdk_extract_path.parent + assert self.dl_archive_path.is_file() + logger.info("Extracting %s to %s", self.dl_archive_path, extract_path) + with zipfile.ZipFile(self.dl_archive_path) as zf: + zf.extractall(extract_path) + assert self.gdk_extract_path.is_dir(), f"{self.gdk_extract_path} must exist" + + def extract_development_kit(self) -> None: + extract_dks_cmd = self.gdk_extract_path / "SetupScripts/ExtractXboxOneDKs.cmd" + assert extract_dks_cmd.is_file() + logger.info("Extracting GDK Development Kit: running %s", extract_dks_cmd) + cmd = ["cmd.exe", "/C", str(extract_dks_cmd), str(self.gdk_extract_path), str(self.gdk_path)] + logger.debug("Running %r", cmd) + subprocess.check_call(cmd) + + def detect_vs_version(self) -> str: + vs_regex = re.compile("VS([0-9]{4})") + supported_vs_versions = [] + for p in self.gaming_grdk_build_path.iterdir(): + if not p.is_dir(): + continue + if m := vs_regex.match(p.name): + supported_vs_versions.append(m.group(1)) + logger.info(f"Supported Visual Studio versions: {supported_vs_versions}") + vs_versions = set(self.vs_folder.parts).intersection(set(supported_vs_versions)) + if not vs_versions: + raise RuntimeError("Visual Studio version is incompatible") + if len(vs_versions) > 1: + raise RuntimeError(f"Too many compatible VS versions found ({vs_versions})") + vs_version = vs_versions.pop() + logger.info(f"Used Visual Studio version: {vs_version}") + return vs_version + + def detect_vs_toolset(self) -> str: + toolset_paths = [] + for ts_path in self.gdk_toolset_parent_path.iterdir(): + if not ts_path.is_dir(): + continue + ms_props = ts_path / "Microsoft.Cpp.props" + if not ms_props.is_file(): + continue + toolset_paths.append(ts_path.name) + logger.info("Detected Visual Studio toolsets: %s", toolset_paths) + assert toolset_paths, "Have we detected at least one toolset?" + + def toolset_number(toolset: str) -> int: + if m:= re.match("[^0-9]*([0-9]+).*", toolset): + return int(m.group(1)) + return -9 + + return max(toolset_paths, key=toolset_number) + + @property + def vs_version(self) -> str: + if self._vs_version is None: + self._vs_version = self.detect_vs_version() + return self._vs_version + + @property + def vs_toolset(self) -> str: + if self._vs_toolset is None: + self._vs_toolset = self.detect_vs_toolset() + return self._vs_toolset + + @staticmethod + def copy_files_and_merge_into(srcdir: Path, dstdir: Path) -> None: + logger.info(f"Copy {srcdir} to {dstdir}") + for root, _, files in os.walk(srcdir): + dest_root = dstdir / Path(root).relative_to(srcdir) + if not dest_root.is_dir(): + dest_root.mkdir() + for file in files: + srcfile = Path(root) / file + dstfile = dest_root / file + shutil.copy(srcfile, dstfile) + + def copy_msbuild(self) -> None: + vc_toolset_parent_path = self.vs_folder / "MSBuild/Microsoft/VC" + if 1: + logger.info(f"Detected compatible Visual Studio version: {self.vs_version}") + srcdir = vc_toolset_parent_path + dstdir = self.gdk_toolset_parent_path + assert srcdir.is_dir(), "Source directory must exist" + assert dstdir.is_dir(), "Destination directory must exist" + + self.copy_files_and_merge_into(srcdir=srcdir, dstdir=dstdir) + + @property + def game_dk_path(self) -> Path: + return self.gdk_path / "Microsoft GDK" + + @property + def game_dk_latest_path(self) -> Path: + return self.game_dk_path / self.gdk_edition + + @property + def windows_sdk_path(self) -> Path: + return self.gdk_path / "Windows Kits/10" + + @property + def gaming_grdk_build_path(self) -> Path: + return self.game_dk_latest_path / "GRDK" + + @property + def gdk_toolset_parent_path(self) -> Path: + return self.gaming_grdk_build_path / f"VS{self.vs_version}/flatDeployment/MSBuild/Microsoft/VC" + + @property + def env(self) -> dict[str, str]: + game_dk = self.game_dk_path + game_dk_latest = self.game_dk_latest_path + windows_sdk_dir = self.windows_sdk_path + gaming_grdk_build = self.gaming_grdk_build_path + + return { + "GRDKEDITION": f"{self.gdk_edition}", + "GameDK": f"{game_dk}\\", + "GameDKLatest": f"{ game_dk_latest }\\", + "WindowsSdkDir": f"{ windows_sdk_dir }\\", + "GamingGRDKBuild": f"{ gaming_grdk_build }\\", + "VSInstallDir": f"{ self.vs_folder }\\", + } + + def create_user_props(self, path: Path) -> None: + vc_targets_path = self.gaming_grdk_build_path / f"VS{ self.vs_version }/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + vc_targets_path16 = self.gaming_grdk_build_path / f"VS2019/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + vc_targets_path17 = self.gaming_grdk_build_path / f"VS2022/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + additional_include_directories = ";".join(str(p) for p in self.gdk_include_paths) + additional_library_directories = ";".join(str(p) for p in self.gdk_library_paths) + durango_xdk_install_path = self.gdk_path / "Microsoft GDK" + with path.open("w") as f: + f.write(textwrap.dedent(f"""\ + + + + { vc_targets_path }\\ + { vc_targets_path16 }\\ + { vc_targets_path17 }\\ + { self.gaming_grdk_build_path }\\ + Gaming.Desktop.x64 + Debug + { self.gdk_edition } + { durango_xdk_install_path } + + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + + true + true + true + + + + { additional_include_directories };%(AdditionalIncludeDirectories) + + + { additional_library_directories };%(AdditionalLibraryDirectories) + + + + """)) + + @property + def gdk_include_paths(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / "gamekit/include", + ] + + @property + def gdk_library_paths(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / f"gamekit/lib/{self.arch}", + ] + + @property + def gdk_binary_path(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / "bin", + self.game_dk_path / "bin", + ] + + @property + def build_env(self) -> dict[str, str]: + gdk_include = ";".join(str(p) for p in self.gdk_include_paths) + gdk_lib = ";".join(str(p) for p in self.gdk_library_paths) + gdk_path = ";".join(str(p) for p in self.gdk_binary_path) + return { + "GDK_INCLUDE": gdk_include, + "GDK_LIB": gdk_lib, + "GDK_PATH": gdk_path, + } + + def print_env(self) -> None: + for k, v in self.env.items(): + print(f"set \"{k}={v}\"") + print() + for k, v in self.build_env.items(): + print(f"set \"{k}={v}\"") + print() + print(f"set \"PATH=%GDK_PATH%;%PATH%\"") + print(f"set \"LIB=%GDK_LIB%;%LIB%\"") + print(f"set \"INCLUDE=%GDK_INCLUDE%;%INCLUDE%\"") + + +def main(): + logging.basicConfig(level=logging.INFO) + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("--arch", choices=["amd64"], default="amd64", help="Architecture") + parser.add_argument("--download", action="store_true", help="Download GDK") + parser.add_argument("--extract", action="store_true", help="Extract downloaded GDK") + parser.add_argument("--copy-msbuild", action="store_true", help="Copy MSBuild files") + parser.add_argument("--temp-folder", help="Temporary folder where to download and extract GDK") + parser.add_argument("--gdk-path", required=True, type=Path, help="Folder where to store the GDK") + parser.add_argument("--ref-edition", type=str, help="Git ref and GDK edition separated by comma") + parser.add_argument("--vs-folder", required=True, type=Path, help="Installation folder of Visual Studio") + parser.add_argument("--vs-version", required=False, type=int, help="Visual Studio version") + parser.add_argument("--vs-toolset", required=False, help="Visual Studio toolset (e.g. v150)") + parser.add_argument("--props-folder", required=False, type=Path, default=Path(), help="Visual Studio toolset (e.g. v150)") + parser.add_argument("--no-user-props", required=False, dest="user_props", action="store_false", help="Don't ") + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + git_ref = None + gdk_edition = None + if args.ref_edition is not None: + git_ref, gdk_edition = args.ref_edition.split(",", 1) + try: + int(gdk_edition) + except ValueError: + parser.error("Edition should be an integer (YYMMUU) (Y=year M=month U=update)") + + configurator = GdDesktopConfigurator( + arch=args.arch, + git_ref=git_ref, + gdk_edition=gdk_edition, + vs_folder=args.vs_folder, + vs_version=args.vs_version, + vs_toolset=args.vs_toolset, + gdk_path=args.gdk_path, + temp_folder=args.temp_folder, + ) + + if args.download: + configurator.download_archive() + + if args.extract: + configurator.extract_zip_archive() + + configurator.extract_development_kit() + + if args.copy_msbuild: + configurator.copy_msbuild() + + if args.user_props: + configurator.print_env() + configurator.create_user_props(args.props_folder / "Directory.Build.props") + +if __name__ == "__main__": + raise SystemExit(main())