Skip to content

Commit a790d77

Browse files
authored
Merge pull request #399 from oneclick/arm64
Add arm64 architecture
2 parents 7a72381 + ff96dd3 commit a790d77

21 files changed

+395
-114
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ Check the [wiki on how to use](https://github.com/oneclick/rubyinstaller2/wiki/F
109109
| | | | "installer-inno" => executable installer file
110110
| | | '------- "msvcrt" => older type of C standard library
111111
| | | "ucrt" => new type of C standard library
112-
| | '------- "x86" => 32 bit ruby and MSYS2 version
113-
| | "x64" => 64 bit version
112+
| | '------- "x86" => 32 bit x86 ruby and MSYS2 version
113+
| | "x64" => 64 bit x86_64 version
114+
| | "arm" => ARM64 version
114115
| '------ "x.x.x" => ruby version to build
115116
| "head" => latest development snapshot of ruby
116117
'------ "ri" => RubyInstaller without Devkit

lib/ruby_installer/build.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module Build
55
autoload :ComponentsInstaller, 'ruby_installer/build/components_installer'
66
autoload :DllDirectory, 'ruby_installer/build/dll_directory'
77
autoload :ErbCompiler, 'ruby_installer/build/erb_compiler'
8+
autoload :ManifestUpdater, 'ruby_installer/build/manifest_updater'
89
autoload :Msys2Installation, 'ruby_installer/build/msys2_installation'
910
autoload :GEM_VERSION, 'ruby_installer/build/gem_version'
1011
autoload :Task, 'ruby_installer/build/task'

lib/ruby_installer/build/components/03_dev_tools.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def description
5252
'mingw32' => PACKAGES_MINGW32,
5353
'mingw64' => PACKAGES_MINGW64,
5454
'ucrt64' => PACKAGES_MINGW64,
55+
'clangarm64' => PACKAGES_MINGW64,
5556
}
5657

5758
def execute(args)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module RubyInstaller
2+
module Build
3+
class ManifestUpdater
4+
def self.update_file(from_fname, manifest_xml_string, to_fname)
5+
image = File.binread(from_fname)
6+
update_blob(image, manifest_xml_string, filename: from_fname)
7+
File.binwrite(to_fname, image)
8+
end
9+
10+
def self.update_blob(dll_or_exe_data, manifest_xml_string, filename: nil)
11+
# There are two regular options to add a custom manifest:
12+
# 1. Change a given exe file per Microsofts "mt.exe" after the build
13+
# 2. Specify a the manifest while linking with the MINGW toolchain
14+
#
15+
# Since we don't want to depend on particular Microsoft tools and want to avoid additional patching of the ruby build, we do a nifty trick here.
16+
# We patch the exe file manually.
17+
# Removing unnecessary spaces and comments from the embedded XML manifest gives us enough space to add the above XML elements.
18+
# Then the default MINGW manifest gets replaced by our custom XML content.
19+
# The rest of the available bytes is simply padded with spaces, so that we don't change positions within the EXE image.
20+
success = false
21+
dll_or_exe_data.gsub!(/<\?xml.*?<assembly.*?<\/assembly>\n/m) do |m|
22+
success = true
23+
newm = m.gsub(/^\s*<\/assembly>\s*$/, manifest_xml_string + "</assembly>")
24+
.gsub(/<!--.*?-->/m, "")
25+
.gsub(/^ +/, "")
26+
.gsub(/\n+/m, "\n")
27+
28+
raise "replacement manifest too big #{m.bytesize} < #{newm.bytesize}" if m.bytesize < newm.bytesize
29+
newm + " " * (m.bytesize - newm.bytesize)
30+
end
31+
raise "no manifest found#{ "in #{filename}" if filename}" unless success
32+
end
33+
end
34+
end
35+
end

lib/ruby_installer/build/msys2_installation.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def initialize(msys_path: nil, mingwarch: nil, mingw_package_prefix: nil, ruby_b
2626
when /x64.*ucrt/ then 'ucrt64'
2727
when /x64.*mingw32/ then 'mingw64'
2828
when /i386.*mingw32/ then 'mingw32'
29+
when /aarch64-mingw-ucrt/ then 'clangarm64'
2930
else raise "unsupported ruby platform #{RUBY_PLATFORM.inspect}"
3031
end
3132
)
@@ -34,6 +35,7 @@ def initialize(msys_path: nil, mingwarch: nil, mingw_package_prefix: nil, ruby_b
3435
when 'mingw32' then "mingw-w64-i686"
3536
when 'mingw64' then "mingw-w64-x86_64"
3637
when 'ucrt64' then "mingw-w64-ucrt-x86_64"
38+
when 'clangarm64' then "mingw-w64-clang-aarch64"
3739
else raise "unknown mingwarch #{@mingwarch.inspect}"
3840
end
3941
end
@@ -128,6 +130,9 @@ def mingw_prefix
128130
def enable_dll_search_paths
129131
@mingwdir ||= begin
130132
DllDirectory.set_defaults
133+
# Add bundled dll directory for libcrypto.dll loading zlib.dll and legacy.dll loading libcrypto.dll
134+
DllDirectory.new(RbConfig::CONFIG["rubyarchdir"])
135+
# Add MSYS2-MINGW DLL directory for user-installed gems
131136
path = mingw_bin_path
132137
DllDirectory.new(path) if File.directory?(path)
133138
rescue MsysNotFound
@@ -182,6 +187,12 @@ def disable_dll_search_paths
182187
vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32'
183188
vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST']
184189
vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX']
190+
when 'clangarm64'
191+
vars['MSYSTEM_PREFIX'] = '/clangarm64'
192+
vars['MSYSTEM_CARCH'] = 'aarch64'
193+
vars['MSYSTEM_CHOST'] = 'aarch64-w64-mingw32'
194+
vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST']
195+
vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX']
185196
else raise "unknown mingwarch #{@mingwarch.inspect}"
186197
end
187198

packages/ri-msys/Rakefile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ class RubyPackage < RubyInstaller::Build::Openstruct
3939
self.mingwdir = "mingw32"
4040
self.packagenamearch = "x86"
4141
self.default_instdir = "C:\\Ruby#{rubyver2.gsub(".","")}"
42+
when 'arm-ucrt'
43+
self.pacman_arch = "mingw-w64-clang-aarch64"
44+
self.ruby_arch = "aarch64-mingw-ucrt"
45+
self.msys_arch = "x86_64"
46+
self.msysdir = "msys64"
47+
self.mingwdir = "clangarm64"
48+
self.packagenamearch = "arm"
49+
self.default_instdir = "C:\\Ruby#{rubyver2.gsub(".","")}-arm"
4250
else
4351
raise "invalid arch #{arch}"
4452
end
@@ -50,13 +58,13 @@ end
5058

5159
ovl_glob('recipes/*/task.rake').each{|f| load(ovl_expand_file(f)) }
5260

53-
ruby_arch_packages = %w[x64-ucrt].map do |arch|
61+
ruby_arch_packages = %w[x64-ucrt x86-msvcrt].map do |arch|
5462
%w[3.1.6-1 3.2.6-1 3.3.6-2 3.4.1-1 head].map do |packagever|
5563
RubyPackage.new( packagever: packagever, arch: arch, rootdir: __dir__ ).freeze
5664
end
5765
end
58-
ruby_arch_packages += %w[x86-msvcrt].map do |arch|
59-
%w[3.1.6-1 3.2.6-1 3.3.6-2 3.4.1-1 head].map do |packagever|
66+
ruby_arch_packages += %w[arm-ucrt].map do |arch|
67+
%w[3.4.1-1 head].map do |packagever|
6068
RubyPackage.new( packagever: packagever, arch: arch, rootdir: __dir__ ).freeze
6169
end
6270
end

packages/ri/Rakefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ class RubyPackage < RubyInstaller::Build::Openstruct
3434
self.mingwdir = "mingw32"
3535
self.default_instdir = "C:\\Ruby#{rubyver2.gsub(".","")}"
3636
self.packagenamearch = "x86"
37+
when 'arm-ucrt'
38+
self.pacman_arch = "mingw-w64-clang-aarch64"
39+
self.ruby_arch = "aarch64-mingw-ucrt"
40+
self.mingwdir = "clangarm64"
41+
self.default_instdir = "C:\\Ruby#{rubyver2.gsub(".","")}-arm"
42+
self.packagenamearch = "arm"
3743
else
3844
raise "invalid arch #{arch}"
3945
end
@@ -45,13 +51,13 @@ end
4551

4652
ovl_glob('recipes/*/task.rake').each{|f| load(ovl_expand_file(f)) }
4753

48-
ruby_arch_packages = %w[x64-ucrt].map do |arch|
54+
ruby_arch_packages = %w[x64-ucrt x86-msvcrt].map do |arch|
4955
%w[3.1.6-1 3.2.6-1 3.3.6-2 3.4.1-1 head].map do |packagever|
5056
RubyPackage.new( packagever: packagever, arch: arch, rootdir: __dir__ ).freeze
5157
end
5258
end
53-
ruby_arch_packages += %w[x86-msvcrt].map do |arch|
54-
%w[3.1.6-1 3.2.6-1 3.3.6-2 3.4.1-1 head].map do |packagever|
59+
ruby_arch_packages += %w[arm-ucrt].map do |arch|
60+
%w[3.4.1-1 head].map do |packagever|
5561
RubyPackage.new( packagever: packagever, arch: arch, rootdir: __dir__ ).freeze
5662
end
5763
end

recipes/installer-inno/events.iss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ begin
2626
ModifyRubyopt(['-Eutf-8']);
2727
#endif
2828

29-
if IsComponentSelected('msys2') then
29+
if WizardIsComponentSelected('msys2') then
3030
DeleteRubyMsys2Directory();
3131

3232
end else

recipes/installer-inno/ri_gui.iss

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,23 @@ begin
103103

104104
if update then
105105
if msysdir <> '' then
106-
if IsComponentSelected('msys2') then
106+
if WizardIsComponentSelected('msys2') then
107107
CompLabel.Caption := 'ATTENTION: MSYS2 is already present in ' + msysdir + '. It will be deleted now and then re-installed. Additional installed pacman packages will be removed. Some gems might not work afterwards and must be re-installed.'
108108
else
109109
CompLabel.Caption := 'Ruby in ' + ExpandConstant('{app}') + ' will be updated. MSYS2 seems to be already present in ' + msysdir + ' . It will kept untouched and will be reused for this Ruby installation. Optionally it can be updated per `ridk install` on the last page of the installer.'
110110
else
111-
if IsComponentSelected('msys2') then
111+
if WizardIsComponentSelected('msys2') then
112112
CompLabel.Caption := 'Ruby in ' + ExpandConstant('{app}') + ' will be updated and MSYS2 will be installed into ' + ExpandConstant('{app}\{#MsysDir}') + '. Please run `ridk install` on the last installer page to initialize it. It can be updated later per `ridk install` as well.'
113113
else
114114
CompLabel.Caption := 'Ruby in ' + ExpandConstant('{app}') + ' will be updated. It''s possible to install MSYS2 at the last page of the installer or to reuse an existing MSYS2 installation.'
115115
else
116116
if msysdir <> '' then
117-
if IsComponentSelected('msys2') then
117+
if WizardIsComponentSelected('msys2') then
118118
CompLabel.Caption := 'ATTENTION: MSYS2 is already present in ' + msysdir + '. It will be deleted now and then re-installed. Additional installed pacman packages will be removed. Some gems might not work afterwards and must be re-installed.'
119119
else
120120
CompLabel.Caption := 'Ruby will be installed into ' + ExpandConstant('{app}') + '. MSYS2 seems to be already present in ' + msysdir + ' . It will kept untouched and will be re-used for this Ruby installation. Optionally it can be updated per `ridk install` on the last page of the installer.'
121121
else
122-
if IsComponentSelected('msys2') then
122+
if WizardIsComponentSelected('msys2') then
123123
CompLabel.Caption := 'Ruby will be installed into ' + ExpandConstant('{app}') + ' and MSYS2 will be installed into ' + ExpandConstant('{app}\{#MsysDir}') + '. Please run `ridk install` on the last installer page to initialize it. It can be updated later per `ridk install` as well.'
124124
else
125125
CompLabel.Caption := 'Ruby will be installed into ' + ExpandConstant('{app}') + ' without MSYS2. It''s possible to install MSYS2 at the last page of the installer or to reuse an existing MSYS2 installation.';
@@ -129,9 +129,10 @@ end;
129129

130130
procedure EnableMsys2Component(enable: Boolean);
131131
begin
132-
{* InnoSetup doesn't provide corresponding setter for IsComponentSelected, so that we alter the ComponentsList directly. *}
133-
if WizardForm.ComponentsList.Items.Count > 2 then
134-
WizardForm.ComponentsList.Checked[2] := enable;
132+
if enable then
133+
WizardSelectComponents('msys2')
134+
else
135+
WizardSelectComponents('!msys2');
135136
end;
136137

137138
procedure InitializeGUI;

recipes/installer-inno/rubyinstaller.iss.erb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ en.SelectDirDesc=
8383
en.SelectDirLabel3=Setup will install [name] into the following folder. Click Install to continue or click Browse to use a different one.
8484
en.SelectDirBrowseLabel=Please avoid any folder name that contains spaces (e.g. Program Files).
8585
en.DiskSpaceMBLabel=Required free disk space: ~[mb] MB
86-
en.DirExists=The folder:%n%n%1%n%nalready exists. Would you like to install to that folder anyway?%n%nOverwriting a Ruby version with the same major and minor version usually works, but for example Ruby-2.5.0 over 2.4.0 doesn't.
86+
en.DirExists=The folder:%n%n%1%n%nalready exists. Would you like to install to that folder anyway?%n%nOverwriting a Ruby version with the same major and minor version usually works, but for example Ruby-3.4.0 over 3.3.0 doesn't.
8787

8888
[CustomMessages]
8989
AddPath=Add Ruby executables to your PATH
@@ -133,11 +133,16 @@ Root: <%= regroot %>; Subkey: Software\Classes\<%= rubyname %>File\shell\open\co
133133
; So use Innosetup to add described permissions and icacls to disable unwanted inheritance.
134134
[Dirs]
135135
Name: {app}; Permissions: creatorowner-full users-readexec admins-full
136+
Name: "{app}/<%= package.rubyver2 =~ /^3\.[23]$/ ? "bin/etc" : "lib/ruby/#{ package.rubylibver }/etc" %>"
137+
136138
[Run]
139+
; Set permissions on install directories
137140
Filename: "icacls.exe"; Parameters: """{app}"" /inheritancelevel:r "; WorkingDir: "{app}"; StatusMsg: "Changing install Directory Permissions"; Flags: runhidden
138141
<% if with_msys %>
139142
Filename: "icacls.exe"; Parameters: """{app}\<%= package.msysdir %>\tmp"" /inheritancelevel:r /grant *S-1-5-32-545:(CI)(WD,AD,WEA,WA) /grant *S-1-3-0:(OI)(CI)(IO)(F) /grant *S-1-5-32-544:(OI)(CI)(F) /grant *S-1-5-32-545:(NP)(RX) "; WorkingDir: "{app}"; StatusMsg: "Changing MSYS2 /tmp Directory Permissions"; Flags: runhidden; Components: msys2
140143
<% end %>
144+
; Add link to SSL CA certs so that OpenSSL finds them based on the libssl.dll location
145+
Filename: "{cmd}"; Parameters: "/c mklink /j <%= package.rubyver2 =~ /^3\.[23]$/ ? "bin" : "lib\\ruby\\#{package.rubylibver}" %>\etc\ssl ssl"; WorkingDir: "{app}"; StatusMsg: "Add link to SSL CA certs"; Flags: runhidden
141146

142147
[Icons]
143148
Name: {autoprograms}\{#InstallerName}\{cm:InteractiveRubyTitle}; Filename: {app}\bin\irb.<%= package.rubyver2 < '3.1' ? "cmd" : "bat" %>; IconFilename: {app}\bin\ruby.exe

0 commit comments

Comments
 (0)