Merge pull request #1070 from wsobolewski/arm64

Arm64
This commit is contained in:
Corey Butler
2024-11-12 11:44:13 -06:00
committed by GitHub
6 changed files with 139 additions and 45 deletions

View File

@@ -3,8 +3,9 @@ SET INNOSETUP=%CD%\nvm.iss
SET ORIG=%CD% SET ORIG=%CD%
REM SET GOPATH=%CD%\src REM SET GOPATH=%CD%\src
SET GOBIN=%CD%\bin SET GOBIN=%CD%\bin
SET GOBINS=%CD%\bins
REM Support for older architectures REM Support for older architectures
SET GOARCH=386 rem SET GOARCH=386
REM Cleanup existing build if it exists REM Cleanup existing build if it exists
if exist src\nvm.exe ( if exist src\nvm.exe (
@@ -16,19 +17,28 @@ echo ----------------------------
echo Building nvm.exe echo Building nvm.exe
echo ---------------------------- echo ----------------------------
cd .\src cd .\src
go build nvm.go SET GOARCH=386
go build -o %GOBINS%\nvm.exe nvm.go
SET GOARCH=amd64
go build -o %GOBINS%\nvm-64.exe nvm.go
SET GOARCH=arm64
go build -o %GOBINS%\nvm-arm64.exe nvm.go
REM Group the file with the helper binaries REM Group the file with the helper binaries
move nvm.exe "%GOBIN%" rem move nvm.exe "%GOBIN%"
cd ..\ cd ..\
REM Codesign the executable REM Codesign the executable
echo ---------------------------- echo ----------------------------
echo Sign the nvm executable... echo Sign the nvm executable...
echo ---------------------------- echo ----------------------------
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%GOBIN%\nvm.exe" buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%GOBINS%\nvm.exe"
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%GOBINS%\nvm-64.exe"
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%GOBINS%\nvm-arm64.exe"
for /f %%i in ('"%GOBIN%\nvm.exe" version') do set AppVersion=%%i for /f %%i in ('"%GOBINS%\nvm.exe" version') do set AppVersion=%%i
for /f %%i in ('"%GOBINS%\nvm-64.exe" version') do set AppVersion=%%i
for /f %%i in ('"%GOBINS%\nvm-arm64.exe" version') do set AppVersion=%%i
echo nvm.exe v%AppVersion% built. echo nvm.exe v%AppVersion% built.
REM Create the distribution folder REM Create the distribution folder
@@ -46,15 +56,20 @@ REM Create the distribution directory
mkdir "%DIST%" mkdir "%DIST%"
REM Create the "no install" zip version REM Create the "no install" zip version
for %%a in ("%GOBIN%") do (buildtools\zip -j -9 -r "%DIST%\nvm-noinstall.zip" "%CD%\LICENSE" %%a\* -x "%GOBIN%\nodejs.ico") for %%a in ("%GOBIN%" "%GOBINS%") do (buildtools\zip -j -9 -r "%DIST%\nvm-noinstall.zip" "%CD%\LICENSE" %%a\* -x "%GOBIN%\nodejs.ico")
REM Generate update utility REM Generate update utility
echo ---------------------------- echo ----------------------------
echo Generating update utility... echo Generating update utility...
echo ---------------------------- echo ----------------------------
cd .\updater cd .\updater
go build nvm-update.go SET GOARCH=386
move nvm-update.exe "%DIST%" go build -o %DIST%\nvm-update.exe nvm-update.go
SET GOARCH=amd64
go build -o %DIST%\nvm-update-64.exe nvm-update.go
SET GOARCH=arm64
go build -o %DIST%\nvm-update-arm64.exe nvm-update.go
rem move nvm-update.exe "%DIST%"
cd ..\ cd ..\
REM Generate the installer (InnoSetup) REM Generate the installer (InnoSetup)
@@ -72,6 +87,8 @@ echo ----------------------------
echo Sign the updater... echo Sign the updater...
echo ---------------------------- echo ----------------------------
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%DIST%\nvm-update.exe" buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%DIST%\nvm-update.exe"
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%DIST%\nvm-update-64.exe"
buildtools\signtool.exe sign /debug /tr http://timestamp.sectigo.com /td sha256 /fd sha256 /a "%DIST%\nvm-update-arm64.exe"
echo ---------------------------- echo ----------------------------
echo Bundle the installer... echo Bundle the installer...
@@ -82,9 +99,11 @@ buildtools\zip -j -9 -r "%DIST%\nvm-setup.zip" "%DIST%\nvm-setup.exe"
echo ---------------------------- echo ----------------------------
echo Bundle the updater... echo Bundle the updater...
echo ---------------------------- echo ----------------------------
buildtools\zip -j -9 -r "%DIST%\nvm-update.zip" "%DIST%\nvm-update.exe" buildtools\zip -j -9 -r "%DIST%\nvm-update.zip" "%DIST%\nvm-update.exe" "%DIST%\nvm-update-64.exe" "%DIST%\nvm-update-arm64.exe"
del "%DIST%\nvm-update.exe" del "%DIST%\nvm-update.exe"
del "%DIST%\nvm-update-64.exe"
del "%DIST%\nvm-update-arm64.exe"
del "%DIST%\nvm-setup.exe" del "%DIST%\nvm-setup.exe"
REM Generate checksums REM Generate checksums
@@ -97,7 +116,9 @@ echo complete
echo ---------------------------- echo ----------------------------
echo Cleaning up... echo Cleaning up...
echo ---------------------------- echo ----------------------------
del "%GOBIN%\nvm.exe" del "%GOBINS%\nvm.exe"
del "%GOBINS%\nvm-64.exe"
del "%GOBINS%\nvm-arm64.exe"
echo complete echo complete
@REM del %GOBIN%\nvm-update.exe @REM del %GOBIN%\nvm-update.exe
@REM del %GOBIN%\nvm-setup.exe @REM del %GOBIN%\nvm-setup.exe

22
nvm.iss
View File

@@ -37,7 +37,7 @@ Compression=lzma
SolidCompression=yes SolidCompression=yes
ChangesEnvironment=yes ChangesEnvironment=yes
DisableProgramGroupPage=yes DisableProgramGroupPage=yes
ArchitecturesInstallIn64BitMode=x64 ia64 ArchitecturesInstallIn64BitMode=x64 ia64 arm64
UninstallDisplayIcon={app}\{#MyIcon} UninstallDisplayIcon={app}\{#MyIcon}
VersionInfoVersion={#MyAppVersion} VersionInfoVersion={#MyAppVersion}
VersionInfoCopyright=Copyright (C) 2018-2022 Ecor Ventures LLC, Corey Butler, and contributors. VersionInfoCopyright=Copyright (C) 2018-2022 Ecor Ventures LLC, Corey Butler, and contributors.
@@ -53,13 +53,31 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
[Files] [Files]
Source: "{#ProjectRoot}\bin\*"; DestDir: "{app}"; BeforeInstall: PreInstall; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "{#ProjectRoot}\bin\install.cmd" Source: "{#ProjectRoot}\bin\*"; DestDir: "{app}"; BeforeInstall: PreInstall; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "{#ProjectRoot}\bin\install.cmd {#ProjectRoot}\bin\nvm-arm64.exe {#ProjectRoot}\bin\nvm-64.exe {#ProjectRoot}\bin\nvm.exe"
Source: "{#ProjectRoot}\bins\nvm-arm64.exe"; DestDir: "{app}"; DestName: "nvm.exe"; Check: InstallARM64; Flags: solidbreak
Source: "{#ProjectRoot}\bins\nvm-64.exe"; DestDir: "{app}"; DestName: "nvm.exe"; Check: InstallX64; Flags: solidbreak
Source: "{#ProjectRoot}\bins\nvm.exe"; DestDir: "{app}"; DestName: "nvm.exe"; Check: InstallOtherArch;
[Icons] [Icons]
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{#MyIcon}" Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{#MyIcon}"
Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}" Name: "{group}\Uninstall {#MyAppShortName}"; Filename: "{uninstallexe}"
[Code] [Code]
function InstallX64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
end;
function InstallARM64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paARM64);
end;
function InstallOtherArch: Boolean;
begin
Result := not InstallX64 and not InstallARM64;
end;
var var
SymlinkPage: TInputDirWizardPage; SymlinkPage: TInputDirWizardPage;

View File

@@ -1,12 +1,12 @@
package arch package arch
import ( import (
//"regexp" //"regexp"
"os" "os"
//"os/exec" //"os/exec"
"strings" "strings"
//"fmt" //"fmt"
"encoding/hex" "encoding/hex"
) )
func SearchBytesInFile( path string, match string, limit int) bool { func SearchBytesInFile( path string, match string, limit int) bool {
@@ -47,9 +47,12 @@ func SearchBytesInFile( path string, match string, limit int) bool {
} }
func Bit(path string) string { func Bit(path string) string {
isarm64 := SearchBytesInFile(path, "5045000064AA", 400)
is64 := SearchBytesInFile(path, "504500006486", 400); is64 := SearchBytesInFile(path, "504500006486", 400);
is32 := SearchBytesInFile(path, "504500004C", 400); is32 := SearchBytesInFile(path, "504500004C", 400);
if is64 { if isarm64 {
return "arm64";
} else if is64 {
return "64"; return "64";
} else if is32 { } else if is32 {
return "32"; return "32";
@@ -59,11 +62,13 @@ func Bit(path string) string {
func Validate(str string) (string){ func Validate(str string) (string){
if str == "" { if str == "" {
str = os.Getenv("PROCESSOR_ARCHITECTURE") str = strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE"))
} }
if strings.ContainsAny("64",str) { if strings.Contains(str, "arm64") {
return "arm64"
}
if strings.Contains(str, "64") {
return "64" return "64"
} else { }
return "32" return "32"
}
} }

View File

@@ -34,6 +34,8 @@ func GetCurrentVersion() (string, string) {
if err == nil { if err == nil {
if string(str) == "x64" { if string(str) == "x64" {
bit = "64" bit = "64"
} else if string(str) == "arm64" {
bit = "arm64"
} else { } else {
bit = "32" bit = "32"
} }

View File

@@ -56,7 +56,7 @@ var env = &Environment{
settings: home, settings: home,
root: "", root: "",
symlink: symlink, symlink: symlink,
arch: os.Getenv("PROCESSOR_ARCHITECTURE"), arch: strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE")),
node_mirror: "", node_mirror: "",
npm_mirror: "", npm_mirror: "",
proxy: "none", proxy: "none",
@@ -80,7 +80,7 @@ func main() {
detail = args[2] detail = args[2]
} }
if len(args) > 3 { if len(args) > 3 {
if args[3] == "32" || args[3] == "64" { if args[3] == "32" || args[3] == "arm64" || args[3] == "64" {
procarch = args[3] procarch = args[3]
} }
} }
@@ -128,8 +128,8 @@ func main() {
case "arch": case "arch":
if strings.Trim(detail, " \r\n") != "" { if strings.Trim(detail, " \r\n") != "" {
detail = strings.Trim(detail, " \r\n") detail = strings.Trim(detail, " \r\n")
if detail != "32" && detail != "64" { if detail != "32" && detail != "64" && detail != "arm64" {
fmt.Println("\"" + detail + "\" is an invalid architecture. Use 32 or 64.") fmt.Println("\"" + detail + "\" is an invalid architecture. Use 32 or 64 or arm64.")
return return
} }
env.arch = detail env.arch = detail
@@ -301,8 +301,8 @@ func getVersion(version string, cpuarch string, localInstallsOnly ...bool) (stri
cpuarch = strings.ToLower(cpuarch) cpuarch = strings.ToLower(cpuarch)
if cpuarch != "" { if cpuarch != "" {
if cpuarch != "32" && cpuarch != "64" && cpuarch != "all" { if cpuarch != "32" && cpuarch != "arm64" && cpuarch != "64" && cpuarch != "all" {
return version, cpuarch, errors.New("\"" + cpuarch + "\" is not a valid CPU architecture. Must be 32 or 64.") return version, cpuarch, errors.New("\"" + cpuarch + "\" is not a valid CPU architecture. Must be 32 or 64 or arm64.")
} }
} else { } else {
cpuarch = env.arch cpuarch = env.arch
@@ -335,7 +335,7 @@ func getVersion(version string, cpuarch string, localInstallsOnly ...bool) (stri
version = installed[0] version = installed[0]
} }
if version == "32" || version == "64" { if version == "32" || version == "arm64" || version == "64" {
cpuarch = version cpuarch = version
v, _ := node.GetCurrentVersion() v, _ := node.GetCurrentVersion()
version = v version = v
@@ -433,6 +433,11 @@ func install(version string, cpuarch string) {
return return
} }
if cpuarch == "arm64" && !web.IsNodeArm64bitAvailable(version) {
fmt.Println("Node.js v" + version + " is only available in 64 and 32-bit.")
return
}
// Check to see if the version is already installed // Check to see if the version is already installed
if !node.IsVersionInstalled(env.root, version, cpuarch) { if !node.IsVersionInstalled(env.root, version, cpuarch) {
if !node.IsVersionAvailable(version) { if !node.IsVersionAvailable(version) {
@@ -451,22 +456,31 @@ func install(version string, cpuarch string) {
} }
// Download node // Download node
append32 := node.IsVersionInstalled(env.root, version, "64") if (cpuarch == "arm64") && !node.IsVersionInstalled(env.root, version, "arm64") {
append64 := node.IsVersionInstalled(env.root, version, "32") success := web.GetNodeJS(env.root, version, "arm64", false)
if (cpuarch == "32" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "32") {
success := web.GetNodeJS(env.root, version, "32", append32)
if !success { if !success {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules")) os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " 32-bit executable.") fmt.Println("Could not download node.js v" + version + " arm64-bit executable.")
return return
} }
} } else {
if (cpuarch == "64" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "64") { append32 := node.IsVersionInstalled(env.root, version, "64")
success := web.GetNodeJS(env.root, version, "64", append64) append64 := node.IsVersionInstalled(env.root, version, "32")
if !success { if (cpuarch == "32" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "32") {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules")) success := web.GetNodeJS(env.root, version, "32", append32)
fmt.Println("Could not download node.js v" + version + " 64-bit executable.") if !success {
return os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " 32-bit executable.")
return
}
}
if (cpuarch == "64" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "64") {
success := web.GetNodeJS(env.root, version, "64", append64)
if !success {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " 64-bit executable.")
return
}
} }
} }
@@ -585,7 +599,7 @@ func uninstall(version string) {
version = cleanVersion(version) version = cleanVersion(version)
// Determine if the version exists and skip if it doesn't // Determine if the version exists and skip if it doesn't
if node.IsVersionInstalled(env.root, version, "32") || node.IsVersionInstalled(env.root, version, "64") { if node.IsVersionInstalled(env.root, version, "32") || node.IsVersionInstalled(env.root, version, "64") || node.IsVersionInstalled(env.root, version, "arm64") {
fmt.Printf("Uninstalling node v" + version + "...") fmt.Printf("Uninstalling node v" + version + "...")
v, _ := node.GetCurrentVersion() v, _ := node.GetCurrentVersion()
if v == version { if v == version {
@@ -838,7 +852,11 @@ func useArchitecture(a string) {
fmt.Println("This computer only supports 32-bit processing.") fmt.Println("This computer only supports 32-bit processing.")
return return
} }
if a == "32" || a == "64" { if strings.Contains("arm64",strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE"))) {
fmt.Println("This computer only supports arm64-bit processing.")
return
}
if a == "32" || a == "64" || a == "arm64" {
env.arch = a env.arch = a
saveSettings() saveSettings()
fmt.Println("Set to " + a + "-bit mode") fmt.Println("Set to " + a + "-bit mode")

View File

@@ -231,6 +231,12 @@ func GetNodeJS(root string, v string, a string, append bool) bool {
} else { } else {
vpre = "x64/" vpre = "x64/"
} }
} else if a == "arm64" {
if main > 0 {
vpre = "win-arm64/"
} else {
vpre = "arm64/"
}
} }
url := getNodeUrl(v, vpre, a, append) url := getNodeUrl(v, vpre, a, append)
@@ -354,8 +360,32 @@ func IsNode64bitAvailable(v string) bool {
return true return true
} }
func IsNodeArm64bitAvailable(v string) bool {
if v == "latest" {
return true
}
// Anything below version 19.9 doesn't have a arm64 bit version
vers := strings.Fields(strings.Replace(v, ".", " ", -1))
main, _ := strconv.ParseInt(vers[0], 0, 0)
minor, _ := strconv.ParseInt(vers[1], 0, 0)
fmt.Println("main "+ strconv.FormatInt(main,10) + " minor "+strconv.FormatInt(minor,10))
if main < 19 {
return false
}
if main == 19 && minor < 9{
return false
}
// TODO: fixme. Assume a 64 bit version exists
return true
}
func getNodeUrl(v string, vpre string, arch string, append bool) string { func getNodeUrl(v string, vpre string, arch string, append bool) string {
a := "x86" a := "x86"
if arch == "arm64" {
a = "arm64"
}
if arch == "64" { if arch == "64" {
a = "x64" a = "x64"
} }