1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Runtime . CompilerServices ;
5+ using System . Runtime . InteropServices ;
6+ using System . Threading . Tasks ;
7+ using Microsoft . CodeAnalysis ;
8+ using Nuke . Common ;
9+ using Nuke . Common . IO ;
10+ using Nuke . Common . Tooling ;
11+ using Nuke . Common . Tools . PowerShell ;
12+ using Nuke . Common . Utilities ;
13+ using Serilog ;
14+ using static Nuke . Cola . Cola ;
15+
16+ namespace Nuke . Cola . Tooling ;
17+
18+ /// <summary>
19+ /// CMake is a versatile build tool for C and C++ (in 99% of cases)
20+ /// </summary>
21+ public static class CMakeTasks
22+ {
23+ public const string LatestVersion = "4.1.2" ;
24+ internal static string GetArchiveName ( string version = LatestVersion )
25+ => ( plat : EnvironmentInfo . Platform , arch : RuntimeInformation . OSArchitecture ) switch
26+ {
27+ ( PlatformFamily . Windows , Architecture . X64 ) => $ "cmake-{ version } -windows-x86_64.zip",
28+ ( PlatformFamily . Windows , Architecture . X86 ) => $ "cmake-{ version } -windows-i386.zip",
29+ ( PlatformFamily . Windows , Architecture . Arm64 ) => $ "cmake-{ version } -windows-arm64.zip",
30+ ( PlatformFamily . Linux , Architecture . X64 ) => $ "cmake-{ version } -linux-x86_64.tar.gz",
31+ ( PlatformFamily . Linux , Architecture . Arm64 ) => $ "cmake-{ version } -linux-aarch64.tar.gz",
32+ ( PlatformFamily . OSX , _ ) => $ "cmake-{ version } -macos-universal.tar.gz",
33+ var other => throw new Exception ( $ "Trying to use CMake on an unsupported platform: { other . plat } { other . arch } ")
34+ } ;
35+
36+ public static AbsolutePath GetLocalCMakeBin ( string version = LatestVersion )
37+ {
38+ var archiveName = GetArchiveName ( version ) ;
39+ var subfolderName = archiveName
40+ . Replace ( ".zip" , "" )
41+ . Replace ( ".tar.gz" , "" ) ;
42+
43+ var localPath = NukeBuild . TemporaryDirectory / "cmake" ;
44+ return EnvironmentInfo . Platform == PlatformFamily . OSX
45+ ? localPath / subfolderName
46+ : localPath / subfolderName / "bin" ;
47+ }
48+
49+ /// <summary>
50+ /// Get CMake or an error if downloading it has failed.
51+ /// </summary>
52+ public static ValueOrError < Tool > TryGetCMake ( string version = LatestVersion ) => ErrorHandling . TryGet ( ( ) =>
53+ {
54+ var archiveName = GetArchiveName ( version ) ;
55+ var subfolderName = archiveName
56+ . Replace ( ".zip" , "" )
57+ . Replace ( ".tar.gz" , "" ) ;
58+
59+ var localPath = NukeBuild . TemporaryDirectory / "cmake" ;
60+ if ( ! ( localPath / subfolderName ) . DirectoryExists ( ) )
61+ {
62+ var downloadPath = localPath / archiveName ;
63+ Log . Information ( "Downloading CMake {0}" , archiveName ) ;
64+ HttpTasks . HttpDownloadFile (
65+ $ "https://github.com/Kitware/CMake/releases/download/v{ LatestVersion } /{ archiveName } ",
66+ downloadPath
67+ ) ;
68+
69+ Log . Information ( "Extracting CMake {0}" , subfolderName ) ;
70+ if ( archiveName . EndsWithOrdinalIgnoreCase ( ".zip" ) )
71+ {
72+ downloadPath . UnZipTo ( localPath ) ;
73+ }
74+ else if ( archiveName . EndsWithOrdinalIgnoreCase ( ".tar.gz" ) )
75+ {
76+ downloadPath . UnTarGZipTo ( localPath ) ;
77+ }
78+ }
79+ var programPath = EnvironmentInfo . Platform switch
80+ {
81+ PlatformFamily . Windows => localPath / subfolderName / "bin" / "cmake.exe" ,
82+ PlatformFamily . Linux => localPath / subfolderName / "bin" / "cmake" ,
83+ PlatformFamily . OSX => localPath / subfolderName / "CMake.app" ,
84+ var other => throw new Exception ( $ "Trying to use CMake on an unsupported platform: { other } ")
85+ } ;
86+ return ToolResolver . GetTool ( programPath ) ;
87+ } ) ;
88+
89+ public static ValueOrError < Tool > EnsureCMake => TryGetCMake ( ) ;
90+
91+ /// <summary>
92+ /// Get CMake. It throws an exception if setup has failed.
93+ /// </summary>
94+ public static Tool CMake => EnsureCMake . Get ( ) ;
95+ }
0 commit comments