SDL: Add cmake-toolchain-file input

From c624a333e58cbce5761f556140ee8becfc1d9e54 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Sun, 18 Jun 2023 21:54:15 +0200
Subject: [PATCH] Add cmake-toolchain-file input

---
 action.yml      |  2 ++
 packed/index.js | 53 +++++++++++++++++++++++++++++++++++++-----
 src/main.ts     | 62 +++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 104 insertions(+), 13 deletions(-)

diff --git a/action.yml b/action.yml
index 2d44136fd264..baf14904eedb 100644
--- a/action.yml
+++ b/action.yml
@@ -13,6 +13,8 @@ inputs:
     description: "CMake build type (Release/Debug/RelWithDebInfo/MinSizeRel)"
     default: "Release"
     required: true
+  cmake-toolchain-file:
+    description: "Path of a CMake toolchain file"
   ninja:
     description: "Use Ninja make files"
     default: "true"
diff --git a/packed/index.js b/packed/index.js
index 05cf48b69838..553f7d9469eb 100644
--- a/packed/index.js
+++ b/packed/index.js
@@ -83,8 +83,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 const child_process = __importStar(__nccwpck_require__(2081));
 const crypto = __importStar(__nccwpck_require__(6113));
-const os = __importStar(__nccwpck_require__(2037));
 const fs = __importStar(__nccwpck_require__(7147));
+const os = __importStar(__nccwpck_require__(2037));
+const path = __importStar(__nccwpck_require__(1017));
 const cache = __importStar(__nccwpck_require__(7799));
 const core = __importStar(__nccwpck_require__(2186));
 const constants_1 = __nccwpck_require__(7077);
@@ -167,7 +168,12 @@ function calculate_state_hash(args) {
     for (const key of ENV_KEYS) {
         env_state.push(`${key}=${process.env[key]}`);
     }
-    const ACTION_KEYS = ["build-type", "discriminator", "ninja"];
+    const ACTION_KEYS = [
+        "build-type",
+        "cmake-toolchain-file",
+        "discriminator",
+        "ninja",
+    ];
     const inputs_state = [];
     for (const key of ACTION_KEYS) {
         const v = core.getInput(key);
@@ -178,6 +184,16 @@ function calculate_state_hash(args) {
         `build_platform=${args.build_platform}`,
         `shell=${args.shell}`,
     ];
+    if (args.cmake_toolchain_file) {
+        const toolchain_contents = fs.readFileSync(args.cmake_toolchain_file, {
+            encoding: "utf8",
+        });
+        const cmake_toolchain_file_hash = crypto
+            .createHash("sha256")
+            .update(toolchain_contents)
+            .digest("hex");
+        misc_state.push(`cmake_toolchain_file_hash=${cmake_toolchain_file_hash}`);
+    }
     const complete_state = [
         "ENVIRONMENT",
         ...env_state,
@@ -190,6 +206,20 @@ function calculate_state_hash(args) {
     core.debug(`state_string=${state_string}`);
     return crypto.createHash("sha256").update(state_string).digest("hex");
 }
+function get_cmake_toolchain_path() {
+    const in_cmake_toolchain_file = core.getInput("cmake-toolchain-file");
+    if (!in_cmake_toolchain_file) {
+        return in_cmake_toolchain_file;
+    }
+    if (fs.existsSync(in_cmake_toolchain_file)) {
+        return path.resolve(in_cmake_toolchain_file);
+    }
+    const workspace_cmake_toolchain_file = path.resolve(`${process.env.GITHUB_WORKSPACE}`, in_cmake_toolchain_file);
+    if (fs.existsSync(workspace_cmake_toolchain_file)) {
+        return workspace_cmake_toolchain_file;
+    }
+    throw new util_1.SetupSdlError(`Cannot find CMake toolchain file: ${in_cmake_toolchain_file}`);
+}
 async function run() {
     const SDL_BUILD_PLATFORM = (0, platform_1.get_sdl_build_platform)();
     core.info(`build platform=${SDL_BUILD_PLATFORM}`);
@@ -201,7 +231,6 @@ async function run() {
         shell_in = "";
     }
     const SHELL = shell_in;
-    const USE_NINJA = core.getBooleanInput("ninja");
     const REQUESTED_VERSION_TYPE = (0, version_1.parse_requested_sdl_version)(core.getInput("version"));
     const CMAKE_BUILD_TYPE = core.getInput("build-type");
     const CMAKE_BUILD_TYPES = [
@@ -239,10 +268,12 @@ async function run() {
         }
     }
     const GIT_HASH = await convert_git_branch_tag_to_hash(git_branch_hash);
+    const CMAKE_TOOLCHAIN_FILE = get_cmake_toolchain_path();
     const STATE_HASH = calculate_state_hash({
         git_hash: GIT_HASH,
         build_platform: SDL_BUILD_PLATFORM,
         shell: SHELL,
+        cmake_toolchain_file: CMAKE_TOOLCHAIN_FILE,
     });
     core.info(`setup-sdl state = ${STATE_HASH}`);
     const PACKAGE_DIR = `${SETUP_SDL_ROOT}/${STATE_HASH}/package`;
@@ -255,6 +286,7 @@ async function run() {
         const SOURCE_DIR = `${SETUP_SDL_ROOT}/${STATE_HASH}/source`;
         const BUILD_DIR = `${SETUP_SDL_ROOT}/${STATE_HASH}/build`;
         await checkout_sdl_git_hash(GIT_HASH, SOURCE_DIR);
+        const USE_NINJA = core.getBooleanInput("ninja");
         if (USE_NINJA) {
             await core.group(`Configuring Ninja`, async () => {
                 await (0, ninja_1.configure_ninja_build_tool)(SDL_BUILD_PLATFORM);
@@ -266,8 +298,8 @@ async function run() {
             "-DCMAKE_INSTALL_INCLUDEDIR=include",
             "-DCMAKE_INSTALL_LIBDIR=lib",
         ];
-        if (USE_NINJA) {
-            cmake_args.push("-GNinja");
+        if (CMAKE_TOOLCHAIN_FILE) {
+            cmake_args.push(`-DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}"`);
         }
         await cmake_configure_build({
             source_dir: SOURCE_DIR,
@@ -290,7 +322,16 @@ async function run() {
     core.setOutput("prefix", PACKAGE_DIR);
     core.setOutput("version", SDL_VERSION.toString());
 }
-run();
+try {
+    run();
+}
+catch (e) {
+    if (e instanceof Error) {
+        core.error(e.message);
+        core.setFailed(e.message);
+    }
+    throw e;
+}
 
 
 /***/ }),
diff --git a/src/main.ts b/src/main.ts
index dc303ac55623..98ba44c586b1 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,7 +1,8 @@
 import * as child_process from "child_process";
 import * as crypto from "crypto";
-import * as os from "os";
 import * as fs from "fs";
+import * as os from "os";
+import * as path from "path";
 
 import * as cache from "@actions/cache";
 import * as core from "@actions/core";
@@ -117,6 +118,7 @@ function calculate_state_hash(args: {
   git_hash: string;
   build_platform: SdlBuildPlatform;
   shell: string;
+  cmake_toolchain_file: string;
 }) {
   const ENV_KEYS = [
     "AR",
@@ -137,7 +139,12 @@ function calculate_state_hash(args: {
     env_state.push(`${key}=${process.env[key]}`);
   }
 
-  const ACTION_KEYS = ["build-type", "discriminator", "ninja"];
+  const ACTION_KEYS = [
+    "build-type",
+    "cmake-toolchain-file",
+    "discriminator",
+    "ninja",
+  ];
   const inputs_state: string[] = [];
   for (const key of ACTION_KEYS) {
     const v = core.getInput(key);
@@ -150,6 +157,17 @@ function calculate_state_hash(args: {
     `shell=${args.shell}`,
   ];
 
+  if (args.cmake_toolchain_file) {
+    const toolchain_contents = fs.readFileSync(args.cmake_toolchain_file, {
+      encoding: "utf8",
+    });
+    const cmake_toolchain_file_hash = crypto
+      .createHash("sha256")
+      .update(toolchain_contents)
+      .digest("hex");
+    misc_state.push(`cmake_toolchain_file_hash=${cmake_toolchain_file_hash}`);
+  }
+
   const complete_state: string[] = [
     "ENVIRONMENT",
     ...env_state,
@@ -166,6 +184,26 @@ function calculate_state_hash(args: {
   return crypto.createHash("sha256").update(state_string).digest("hex");
 }
 
+function get_cmake_toolchain_path(): string {
+  const in_cmake_toolchain_file = core.getInput("cmake-toolchain-file");
+  if (!in_cmake_toolchain_file) {
+    return in_cmake_toolchain_file;
+  }
+  if (fs.existsSync(in_cmake_toolchain_file)) {
+    return path.resolve(in_cmake_toolchain_file);
+  }
+  const workspace_cmake_toolchain_file = path.resolve(
+    `${process.env.GITHUB_WORKSPACE}`,
+    in_cmake_toolchain_file
+  );
+  if (fs.existsSync(workspace_cmake_toolchain_file)) {
+    return workspace_cmake_toolchain_file;
+  }
+  throw new SetupSdlError(
+    `Cannot find CMake toolchain file: ${in_cmake_toolchain_file}`
+  );
+}
+
 async function run() {
   const SDL_BUILD_PLATFORM = get_sdl_build_platform();
   core.info(`build platform=${SDL_BUILD_PLATFORM}`);
@@ -180,8 +218,6 @@ async function run() {
   }
   const SHELL = shell_in;
 
-  const USE_NINJA = core.getBooleanInput("ninja");
-
   const REQUESTED_VERSION_TYPE = parse_requested_sdl_version(
     core.getInput("version")
   );
@@ -231,10 +267,13 @@ async function run() {
     git_branch_hash
   );
 
+  const CMAKE_TOOLCHAIN_FILE = get_cmake_toolchain_path();
+
   const STATE_HASH = calculate_state_hash({
     git_hash: GIT_HASH,
     build_platform: SDL_BUILD_PLATFORM,
     shell: SHELL,
+    cmake_toolchain_file: CMAKE_TOOLCHAIN_FILE,
   });
   core.info(`setup-sdl state = ${STATE_HASH}`);
 
@@ -256,6 +295,7 @@ async function run() {
 
     await checkout_sdl_git_hash(GIT_HASH, SOURCE_DIR);
 
+    const USE_NINJA = core.getBooleanInput("ninja");
     if (USE_NINJA) {
       await core.group(`Configuring Ninja`, async () => {
         await configure_ninja_build_tool(SDL_BUILD_PLATFORM);
@@ -268,8 +308,8 @@ async function run() {
       "-DCMAKE_INSTALL_INCLUDEDIR=include",
       "-DCMAKE_INSTALL_LIBDIR=lib",
     ];
-    if (USE_NINJA) {
-      cmake_args.push("-GNinja");
+    if (CMAKE_TOOLCHAIN_FILE) {
+      cmake_args.push(`-DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}"`);
     }
 
     await cmake_configure_build({
@@ -299,4 +339,12 @@ async function run() {
   core.setOutput("version", SDL_VERSION.toString());
 }
 
-run();
+try {
+  run();
+} catch (e) {
+  if (e instanceof Error) {
+    core.error(e.message);
+    core.setFailed(e.message);
+  }
+  throw e;
+}