tebako 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,31 +55,47 @@ module Tebako
55
55
  # So we have to use \"xxx\"
56
56
  @cfg_options ||=
57
57
  "-DCMAKE_BUILD_TYPE=Release -DRUBY_VER:STRING=\"#{ruby_ver}\" -DRUBY_HASH:STRING=\"#{ruby_hash}\" " \
58
- "-DDEPS:STRING=\"#{deps}\" -G \"#{m_files}\" -B \"#{output}\" -S \"#{source}\""
58
+ "-DDEPS:STRING=\"#{deps}\" -G \"#{m_files}\" -B \"#{output_folder}\" -S \"#{source}\""
59
59
  end
60
60
 
61
61
  def clean_cache
62
62
  puts "Cleaning tebako packaging environment"
63
63
  # Using File.join(deps, "") to ensure that the slashes are appropriate
64
- FileUtils.rm_rf([File.join(deps, ""), File.join(output, "")], secure: true)
64
+ FileUtils.rm_rf([File.join(deps, ""), File.join(output_folder, "")], secure: true)
65
65
  end
66
66
 
67
67
  def clean_output
68
68
  puts "Cleaning CMake cache and Ruby build files"
69
- # Using File.join(output, "") to ensure that the slashes are appropriate
70
69
 
71
70
  nmr = "src/_ruby_*"
72
71
  nms = "stash_*"
73
72
  FileUtils.rm_rf(Dir.glob(File.join(deps, nmr)), secure: true)
74
73
  FileUtils.rm_rf(Dir.glob(File.join(deps, nms)), secure: true)
75
74
 
76
- FileUtils.rm_rf(File.join(output, ""), secure: true)
75
+ # Using File.join(output_folder, "") to ensure that the slashes are appropriate
76
+ FileUtils.rm_rf(File.join(output_folder, ""), secure: true)
77
77
  end
78
78
 
79
79
  def deps
80
80
  @deps ||= File.join(prefix, "deps")
81
81
  end
82
82
 
83
+ def do_press
84
+ cfg_cmd = "cmake -DSETUP_MODE:BOOLEAN=OFF #{cfg_options} #{press_options}"
85
+ build_cmd = "cmake --build #{output_folder} --target tebako --parallel #{Etc.nprocessors}"
86
+ merged_env = ENV.to_h.merge(b_env)
87
+ Tebako.packaging_error(103) unless system(merged_env, cfg_cmd)
88
+ Tebako.packaging_error(104) unless system(merged_env, build_cmd)
89
+ end
90
+
91
+ def do_setup
92
+ cfg_cmd = "cmake -DSETUP_MODE:BOOLEAN=ON #{cfg_options}"
93
+ build_cmd = "cmake --build \"#{output_folder}\" --target setup --parallel #{Etc.nprocessors}"
94
+ merged_env = ENV.to_h.merge(b_env)
95
+ Tebako.packaging_error(101) unless system(merged_env, cfg_cmd)
96
+ Tebako.packaging_error(102) unless system(merged_env, build_cmd)
97
+ end
98
+
83
99
  def ensure_version_file
84
100
  version_file_path = File.join(deps, E_VERSION_FILE)
85
101
 
@@ -121,15 +137,27 @@ module Tebako
121
137
  "MinGW Makefiles"
122
138
  else
123
139
  raise Tebako::Error.new(
124
- "#{RUBY_PLATFORM} is not supported yet, exiting",
140
+ "#{RUBY_PLATFORM} is not supported, exiting",
125
141
  254
126
142
  )
127
143
  end
128
144
  end
129
145
  # rubocop:enable Metrics/MethodLength
130
146
 
131
- def output
132
- @output ||= File.join(prefix, "o")
147
+ def options_from_tebafile(tebafile)
148
+ ::YAML.load_file(tebafile)["options"] || {}
149
+ rescue Psych::SyntaxError => e
150
+ puts "Warning: The tebafile '#{tebafile}' contains invalid YAML syntax."
151
+ puts e.message
152
+ {}
153
+ rescue StandardError => e
154
+ puts "An unexpected error occurred while loading the tebafile '#{tebafile}'."
155
+ puts e.message
156
+ {}
157
+ end
158
+
159
+ def output_folder
160
+ @output_folder ||= File.join(prefix, "o")
133
161
  end
134
162
 
135
163
  def package
@@ -167,20 +195,28 @@ module Tebako
167
195
  end
168
196
 
169
197
  def press_announce
198
+ cwd_announce = options["cwd"].nil? ? "<Host current directory>" : options["cwd"]
170
199
  @press_announce ||= <<~ANN
171
200
  Running tebako press at #{prefix}
172
- Ruby version: '#{extend_ruby_version[0]}'
173
- Project root: '#{root}'
174
- Application entry point: '#{options["entry-point"]}'
175
- Package file name: '#{package}'
176
- Loging level: '#{l_level}'
201
+ Ruby version: '#{extend_ruby_version[0]}'
202
+ Project root: '#{root}'
203
+ Application entry point: '#{options["entry-point"]}'
204
+ Package file name: '#{package}'
205
+ Loging level: '#{l_level}'
206
+ Package working directory: '#{cwd_announce}'
177
207
  ANN
178
208
  end
179
209
 
180
210
  def press_options
211
+ cwd_option = if options["cwd"].nil?
212
+ "-DPACKAGE_NEEDS_CWD:BOOL=OFF"
213
+ else
214
+ "-DPACKAGE_NEEDS_CWD:BOOL=ON -DPACKAGE_CWD:STRING='#{options["cwd"]}'"
215
+ end
181
216
  @press_options ||=
182
217
  "-DROOT:STRING='#{root}' -DENTRANCE:STRING='#{options["entry-point"]}' " \
183
- "-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{options["log-level"]}' "
218
+ "-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{options["log-level"]}' " \
219
+ "#{cwd_option}"
184
220
  end
185
221
 
186
222
  def relative?(path)
@@ -42,25 +42,27 @@ module Tebako
42
42
  "3.0.7" => "2a3411977f2850431136b0fab8ad53af09fb74df2ee2f4fb7f11b378fe034388",
43
43
  "3.1.6" => "0d0dafb859e76763432571a3109d1537d976266be3083445651dc68deed25c22",
44
44
  "3.2.4" => "c72b3c5c30482dca18b0f868c9075f3f47d8168eaf626d4e682ce5b59c858692",
45
+ "3.2.5" => "ef0610b498f60fb5cfd77b51adb3c10f4ca8ed9a17cb87c61e5bea314ac34a16",
45
46
  "3.3.3" => "83c05b2177ee9c335b631b29b8c077b4770166d02fa527f3a9f6a40d13f3cce2",
46
47
  "3.3.4" => "fe6a30f97d54e029768f2ddf4923699c416cdbc3a6e96db3e2d5716c7db96a34"
47
48
  }.freeze
48
49
 
49
- DEFAULT_RUBY_VERSION = "3.1.6"
50
+ MIN_RUBY_VERSION_WINDOWS = "3.1.6"
51
+ DEFAULT_RUBY_VERSION = "3.2.5"
50
52
 
51
53
  def version_check(version)
52
54
  return if RUBY_VERSIONS.key?(version)
53
55
 
54
56
  raise Tebako::Error.new(
55
- "Ruby version #{version} is not supported yet, exiting",
57
+ "Ruby version #{version} is not supported, exiting",
56
58
  253
57
59
  )
58
60
  end
59
61
 
60
62
  def version_check_msys(version)
61
- if Gem::Version.new(version) < Gem::Version.new(DEFAULT_RUBY_VERSION) && RUBY_PLATFORM =~ /msys|mingw|cygwin/
63
+ if Gem::Version.new(version) < Gem::Version.new(MIN_RUBY_VERSION_WINDOWS) && RUBY_PLATFORM =~ /msys|mingw|cygwin/
62
64
  raise Tebako::Error.new(
63
- "Windows packaging works for Ruby #{DEFAULT_RUBY_VERSION} or above, version #{version} is not supported",
65
+ "Windows packaging works for Ruby #{MIN_RUBY_VERSION_WINDOWS} or above, version #{version} is not supported",
64
66
  252
65
67
  )
66
68
  end
@@ -29,6 +29,7 @@ require "fileutils"
29
29
  require "find"
30
30
 
31
31
  require_relative "error"
32
+ require_relative "build_helpers"
32
33
  require_relative "packager/patch_helpers"
33
34
 
34
35
  # Tebako - an executable packager
@@ -48,16 +49,18 @@ module Tebako
48
49
  @target_dir = target_dir
49
50
  @pre_dir = pre_dir
50
51
  @verbose = ENV["VERBOSE"] == "yes" || ENV["VERBOSE"] == "true"
52
+ @ncores = BuildHelpers.ncores
51
53
  end
52
54
 
53
55
  attr_reader :bundler_command, :gem_command, :gem_home
54
56
 
55
- def config(os_type, ruby_ver)
57
+ def config(os_type, ruby_ver, cwd)
56
58
  @ruby_ver = ruby_ver
57
59
  @os_type = os_type
60
+ @cwd = cwd
58
61
 
59
62
  @tbd = File.join(@target_dir, "bin")
60
- @tgd = @gem_home = File.join(@target_dir, "lib", "ruby", "gems", ruby_api_version)
63
+ @tgd = @gem_home = File.join(@target_dir, "lib", "ruby", "gems", @ruby_ver.api_version)
61
64
  @tld = File.join(@target_dir, "local")
62
65
 
63
66
  lookup_files
@@ -66,15 +69,13 @@ module Tebako
66
69
  end
67
70
 
68
71
  def deploy
69
- Packager::PatchHelpers.with_env(deploy_env) do
70
- unless Packager::PatchHelpers.ruby31?(@ruby_ver)
71
- update_rubygems
72
- patch_after_rubygems_update(@target_dir, @ruby_api_version)
73
- end
72
+ BuildHelpers.with_env(deploy_env) do
73
+ update_rubygems
74
74
  system("#{gem_command} env")
75
75
  install_gem("tebako-runtime")
76
76
  install_gem("bundler", BUNDLER_VERSION) if needs_bundler?
77
77
  deploy_solution
78
+ check_cwd
78
79
  end
79
80
  end
80
81
 
@@ -95,11 +96,7 @@ module Tebako
95
96
  ["--no-document", "--install-dir", @tgd].each do |param|
96
97
  params.push(param)
97
98
  end
98
- run_with_capture_v(params)
99
- end
100
-
101
- def ruby_api_version
102
- @ruby_api_version ||= "#{@ruby_ver.split(".")[0..1].join(".")}.0"
99
+ BuildHelpers.run_with_capture_v(params)
103
100
  end
104
101
 
105
102
  def needs_bundler?
@@ -107,16 +104,23 @@ module Tebako
107
104
  end
108
105
 
109
106
  def update_rubygems
107
+ return if @ruby_ver.ruby31?
108
+
110
109
  puts " ... updating rubygems to #{Tebako::RUBYGEMS_VERSION}"
111
- run_with_capture_v([@gem_command, "update", "--no-doc", "--system", Tebako::RUBYGEMS_VERSION])
110
+ BuildHelpers.run_with_capture_v([@gem_command, "update", "--no-doc", "--system",
111
+ Tebako::RUBYGEMS_VERSION])
112
+ patch_after_rubygems_update(@target_dir, @ruby_ver.api_version)
112
113
  end
113
114
 
114
115
  private
115
116
 
116
117
  def bundle_config
117
- run_with_capture_v([@bundler_command, "config", "set", "--local", "build.ffi", "--disable-system-libffi"])
118
- run_with_capture_v([@bundler_command, "config", "set", "--local", "build.nokogiri", @nokogiri_option])
119
- run_with_capture_v([@bundler_command, "config", "set", "--local", "force_ruby_platform", @force_ruby_platform])
118
+ BuildHelpers.run_with_capture_v([@bundler_command, "config", "set", "--local", "build.ffi",
119
+ "--disable-system-libffi"])
120
+ BuildHelpers.run_with_capture_v([@bundler_command, "config", "set", "--local", "build.nokogiri",
121
+ @nokogiri_option])
122
+ BuildHelpers.run_with_capture_v([@bundler_command, "config", "set", "--local", "force_ruby_platform",
123
+ @force_ruby_platform])
120
124
  end
121
125
 
122
126
  def check_entry_point(entry_point_root)
@@ -128,13 +132,22 @@ module Tebako
128
132
  raise Tebako::Error.new("Entry point #{fs_entry_point} does not exist or is not accessible", 106)
129
133
  end
130
134
 
135
+ def check_cwd
136
+ return if @cwd.nil?
137
+
138
+ cwd_full = File.join(@target_dir, @cwd)
139
+ return if File.directory?(cwd_full)
140
+
141
+ raise Tebako::Error.new("Package working directory #{@cwd} does not exist", 108)
142
+ end
143
+
131
144
  def collect_and_deploy_gem(gemspec)
132
145
  puts " ... Collecting gem from gemspec #{gemspec}"
133
146
 
134
147
  copy_files(@pre_dir)
135
148
 
136
149
  Dir.chdir(@pre_dir) do
137
- run_with_capture_v([@gem_command, "build", gemspec])
150
+ BuildHelpers.run_with_capture_v([@gem_command, "build", gemspec])
138
151
  install_all_gems_or_fail
139
152
  end
140
153
 
@@ -149,8 +162,8 @@ module Tebako
149
162
  Dir.chdir(@pre_dir) do
150
163
  bundle_config
151
164
  puts " *** It may take a long time for a big project. It takes REALLY long time on Windows ***"
152
- run_with_capture_v([@bundler_command, "install", "--jobs=#{ncores}"])
153
- run_with_capture_v([@bundler_command, "exec", @gem_command, "build", gemspec])
165
+ BuildHelpers.run_with_capture_v([@bundler_command, "install", "--jobs=#{@ncores}"])
166
+ BuildHelpers.run_with_capture_v([@bundler_command, "exec", @gem_command, "build", gemspec])
154
167
  install_all_gems_or_fail
155
168
  end
156
169
 
@@ -216,7 +229,7 @@ module Tebako
216
229
  Dir.chdir(@tld) do
217
230
  bundle_config
218
231
  puts " *** It may take a long time for a big project. It takes REALLY long time on Windows ***"
219
- run_with_capture_v([@bundler_command, "install", "--jobs=#{ncores}"])
232
+ BuildHelpers.run_with_capture_v([@bundler_command, "install", "--jobs=#{@ncores}"])
220
233
  end
221
234
 
222
235
  check_entry_point("local")
@@ -256,43 +269,11 @@ module Tebako
256
269
  @g_length = Dir.glob(File.join(@fs_root, "*.gem")).length
257
270
  end
258
271
 
259
- def ncores
260
- if RUBY_PLATFORM.include?("darwin")
261
- out, st = Open3.capture2e("sysctl", "-n", "hw.ncpu")
262
- else
263
- out, st = Open3.capture2e("nproc", "--all")
264
- end
265
-
266
- @ncores ||= if st.exitstatus.zero?
267
- out.strip.to_i
268
- else
269
- 4
270
- end
271
- end
272
-
273
272
  def patch_after_rubygems_update(target_dir, ruby_api_ver)
274
273
  # Autoload cannot handle statically linked openssl extension
275
274
  # Changing it to require seems to be the simplest solution
276
275
  Packager::PatchHelpers.patch_file("#{target_dir}/lib/ruby/site_ruby/#{ruby_api_ver}/rubygems/openssl.rb",
277
276
  { "autoload :OpenSSL, \"openssl\"" => "require \"openssl\"" })
278
277
  end
279
-
280
- def run_with_capture(args)
281
- puts " ... @ #{args.join(" ")}"
282
- out, st = Open3.capture2e(*args)
283
- raise Tebako::Error, "Failed to run #{args.join(" ")} (#{st}):\n #{out}" unless st.exitstatus.zero?
284
-
285
- out
286
- end
287
-
288
- def run_with_capture_v(args)
289
- if @verbose
290
- args_v = args.dup
291
- args_v.push("--verbose")
292
- puts run_with_capture(args_v)
293
- else
294
- run_with_capture(args)
295
- end
296
- end
297
278
  end
298
279
  end
data/lib/tebako/error.rb CHANGED
@@ -34,7 +34,8 @@ module Tebako
34
34
  104 => "'tebako press' build step failed",
35
35
  105 => "Failed to map MSys path to Windows",
36
36
  106 => "Entry point does not exist or is not accessible",
37
- 107 => "Project root does not exist or is not accessible"
37
+ 107 => "Project root does not exist or is not accessible",
38
+ 108 => "Package working directory does not exist"
38
39
  }.freeze
39
40
 
40
41
  class << self
@@ -156,7 +156,7 @@ module Tebako
156
156
  # ....................................................
157
157
  # autoload :OpenSSL, "openssl"
158
158
  # fails to deal with a default gem from statically linked extension
159
- patch_map.store("lib/rubygems/openssl.rb", RUBYGEM_OPENSSL_RB_PATCH) if PatchHelpers.ruby3x?(ruby_ver)
159
+ patch_map.store("lib/rubygems/openssl.rb", RUBYGEM_OPENSSL_RB_PATCH) if ruby_ver.ruby3x?
160
160
 
161
161
  if ostype =~ /msys/
162
162
  # ....................................................
@@ -176,7 +176,7 @@ module Tebako
176
176
  include Tebako::Packager::PatchBuildsystem
177
177
 
178
178
  def get_gnumakefile_in_patch_p1(ruby_ver) # rubocop:disable Metrics/MethodLength
179
- objext = PatchHelpers.ruby32?(ruby_ver) ? "$(OBJEXT)" : "@OBJEXT@"
179
+ objext = ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
180
180
  {
181
181
  " DLLWRAP += -mno-cygwin" =>
182
182
  "# tebako patched DLLWRAP += -mno-cygwin",
@@ -26,6 +26,7 @@
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
28
  require_relative "patch_literals"
29
+ require_relative "patch_main"
29
30
  require_relative "patch_libraries"
30
31
  require_relative "patch_helpers"
31
32
  require_relative "patch_buildsystem"
@@ -41,7 +42,7 @@ module Tebako
41
42
  patch_map.store("thread_pthread.c", LINUX_MUSL_THREAD_PTHREAD_PATCH) if ostype =~ /linux-musl/
42
43
  if PatchHelpers.msys?(ostype)
43
44
  patch_map.merge!(get_msys_patches(ruby_ver))
44
- elsif PatchHelpers.ruby3x?(ruby_ver)
45
+ elsif ruby_ver.ruby3x?
45
46
  patch_map.store("common.mk", COMMON_MK_PATCH)
46
47
  end
47
48
  extend_patch_map_r33(patch_map, ostype, deps_lib_dir, ruby_ver)
@@ -52,7 +53,7 @@ module Tebako
52
53
  include Tebako::Packager::PatchBuildsystem
53
54
  include Tebako::Packager::PatchLiterals
54
55
  def extend_patch_map_r33(patch_map, ostype, deps_lib_dir, ruby_ver)
55
- if PatchHelpers.ruby33?(ruby_ver) || PatchHelpers.msys?(ostype)
56
+ if ruby_ver.ruby33? || PatchHelpers.msys?(ostype)
56
57
  patch_map.store("config.status",
57
58
  get_config_status_patch(ostype, deps_lib_dir, ruby_ver))
58
59
  end
@@ -75,7 +76,7 @@ module Tebako
75
76
  }
76
77
 
77
78
  if PatchHelpers.msys?(ostype)
78
- patch = PatchHelpers.ruby32?(ruby_ver) ? DLN_C_MSYS_PATCH : DLN_C_MSYS_PATCH_PRE32
79
+ patch = ruby_ver.ruby32? ? DLN_C_MSYS_PATCH : DLN_C_MSYS_PATCH_PRE32
79
80
  dln_c_patch.merge!(patch)
80
81
  end
81
82
 
@@ -83,7 +84,7 @@ module Tebako
83
84
  end
84
85
 
85
86
  def get_io_c_msys_patch(ruby_ver)
86
- io_c_msys_patch = PatchHelpers.ruby32?(ruby_ver) ? IO_C_MSYS_PATCH : IO_C_MSYS_PATCH_PRE_32
87
+ io_c_msys_patch = ruby_ver.ruby32? ? IO_C_MSYS_PATCH : IO_C_MSYS_PATCH_PRE_32
87
88
  io_c_msys_patch.merge(IO_C_MSYS_BASE_PATCH)
88
89
  end
89
90
 
@@ -94,7 +95,7 @@ module Tebako
94
95
  end
95
96
 
96
97
  def get_util_c_patch(ruby_ver)
97
- if PatchHelpers.ruby31?(ruby_ver)
98
+ if ruby_ver.ruby31?
98
99
  PatchHelpers.patch_c_file_post("#endif /* !HAVE_GNU_QSORT_R */")
99
100
  else
100
101
  PatchHelpers.patch_c_file_pre("#ifndef S_ISDIR")
@@ -122,14 +123,14 @@ module Tebako
122
123
  "template/Makefile.in" => template_makefile_in_patch(ostype, deps_lib_dir, ruby_ver),
123
124
  "tool/mkconfig.rb" => get_tool_mkconfig_rb_patch(ostype),
124
125
  "dir.c" => get_dir_c_patch(ostype), "dln.c" => get_dln_c_patch(ostype, ruby_ver),
125
- "io.c" => get_io_c_patch(ostype, ruby_ver), "main.c" => MAIN_C_PATCH,
126
+ "io.c" => get_io_c_patch(ostype, ruby_ver), "main.c" => PatchMain.get_main_c_patch(ruby_ver),
126
127
  "file.c" => PatchHelpers.patch_c_file_pre("/* define system APIs */"),
127
128
  "util.c" => get_util_c_patch(ruby_ver)
128
129
  }
129
130
  end
130
131
 
131
132
  def mlibs_subst(ostype, deps_lib_dir, ruby_ver)
132
- yjit_libs = PatchHelpers.ruby32only?(ruby_ver) ? "$(YJIT_LIBS) " : ""
133
+ yjit_libs = ruby_ver.ruby32only? ? "$(YJIT_LIBS) " : ""
133
134
  {
134
135
  "MAINLIBS = #{yjit_libs}@MAINLIBS@" =>
135
136
  "# -- Start of tebako patch -- \n" \
@@ -80,7 +80,7 @@ module Tebako
80
80
  def template_makefile_in_subst(ostype, ruby_ver)
81
81
  if PatchHelpers.msys?(ostype)
82
82
  TEMPLATE_MAKEFILE_IN_BASE_PATCH_MSYS
83
- elsif !PatchHelpers.ruby31?(ruby_ver)
83
+ elsif !ruby_ver.ruby31?
84
84
  TEMPLATE_MAKEFILE_IN_BASE_PATCH_PRE_3_1
85
85
  else
86
86
  TEMPLATE_MAKEFILE_IN_BASE_PATCH
@@ -88,9 +88,9 @@ module Tebako
88
88
  end
89
89
 
90
90
  def template_makefile_in_patch_two(ostype, ruby_ver)
91
- if !PatchHelpers.ruby31?(ruby_ver)
91
+ if !ruby_ver.ruby31?
92
92
  { TEMPLATE_MAKEFILE_IN_BASE_PATTERN_PRE_3_1 => template_makefile_in_subst(ostype, ruby_ver) }
93
- elsif !PatchHelpers.ruby33?(ruby_ver)
93
+ elsif !ruby_ver.ruby33?
94
94
  { TEMPLATE_MAKEFILE_IN_BASE_PATTERN_PRE_3_3 => template_makefile_in_subst(ostype, ruby_ver) }
95
95
  else
96
96
  { TEMPLATE_MAKEFILE_IN_BASE_PATTERN => template_makefile_in_subst(ostype, ruby_ver) }
@@ -136,7 +136,7 @@ module Tebako
136
136
  # - Introduce LIBRUBY dependency on static extensions
137
137
  # This is an addition to COMMON_MK_PATCH specified above
138
138
  def get_gnumakefile_in_patch_p2(ruby_ver) # rubocop:disable Metrics/MethodLength
139
- objext = PatchHelpers.ruby32?(ruby_ver) ? "$(OBJEXT)" : "@OBJEXT@"
139
+ objext = ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
140
140
 
141
141
  {
142
142
  "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
@@ -108,44 +108,8 @@ module Tebako
108
108
  end
109
109
  end
110
110
 
111
- def ruby3x?(ruby_ver)
112
- ruby_ver[0] == "3"
113
- end
114
-
115
- def ruby31?(ruby_ver)
116
- ruby3x?(ruby_ver) && ruby_ver[2].to_i >= 1
117
- end
118
-
119
- def ruby32?(ruby_ver)
120
- ruby3x?(ruby_ver) && ruby_ver[2].to_i >= 2
121
- end
122
-
123
- def ruby32only?(ruby_ver)
124
- ruby3x?(ruby_ver) && ruby_ver[2] == "2"
125
- end
126
-
127
- def ruby33?(ruby_ver)
128
- ruby3x?(ruby_ver) && ruby_ver[2].to_i >= 3
129
- end
130
-
131
- # Sets up temporary environment variables and yields to the
132
- # block. When the block exits, the environment variables are set
133
- # back to their original values.
134
- def with_env(hash)
135
- old = {}
136
- hash.each do |k, v|
137
- old[k] = ENV.fetch(k, nil)
138
- ENV[k] = v
139
- end
140
- begin
141
- yield
142
- ensure
143
- hash.each_key { |k| ENV[k] = old[k] }
144
- end
145
- end
146
-
147
111
  def yaml_reference(ruby_ver)
148
- ruby32?(ruby_ver) ? "-l:libyaml.a" : ""
112
+ ruby_ver.ruby32? ? "-l:libyaml.a" : ""
149
113
  end
150
114
  end
151
115
  end
@@ -125,7 +125,7 @@ module Tebako
125
125
  libs = String.new
126
126
 
127
127
  DARWIN_DEP_LIBS_1.each { |lib| libs << "#{deps_lib_dir}/lib#{lib}.a " }
128
- process_brew_libs!(libs, PatchHelpers.ruby31?(ruby_ver) ? DARWIN_BREW_LIBS_31 : DARWIN_BREW_LIBS_PRE_31)
128
+ process_brew_libs!(libs, ruby_ver.ruby31? ? DARWIN_BREW_LIBS_31 : DARWIN_BREW_LIBS_PRE_31)
129
129
  process_brew_libs!(libs, DARWIN_BREW_LIBS)
130
130
 
131
131
  DARWIN_DEP_LIBS_2.each { |lib| libs << "#{deps_lib_dir}/lib#{lib}.a " }
@@ -125,21 +125,6 @@ module Tebako
125
125
  SUBST
126
126
  }.freeze
127
127
 
128
- MAIN_C_PATCH = {
129
- "int\nmain(int argc, char **argv)" =>
130
- "#include <tebako/tebako-main.h>\n\nint\nmain(int argc, char **argv)",
131
-
132
- " ruby_sysinit(&argc, &argv);" => <<~SUBST
133
- ruby_sysinit(&argc, &argv);
134
- /* -- Start of tebako patch -- */
135
- if (tebako_main(&argc, &argv) != 0) {
136
- printf("Tebako intialization failed.");
137
- return -1;
138
- }
139
- /* -- End of tebako patch -- */
140
- SUBST
141
- }.freeze
142
-
143
128
  # Compensate ruby incorrect processing of (f)getattrlist returning ENOTSUP
144
129
  # Note. We are not patching need_normalization function
145
130
  # In this function (f)getattrlist failure with ENOTSUP is processed correctly
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
4
+ # All rights reserved.
5
+ # This file is a part of tebako
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
20
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ # POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ # Tebako - an executable packager
29
+ module Tebako
30
+ module Packager
31
+ # Ruby patching literals (main.c)
32
+ module PatchMain
33
+ MAIN_C_SUBST_RB_MAIN = <<~SUBST
34
+ /* -- Start of tebako patch -- */
35
+ #include <tebako/tebako-main.h>
36
+ /* -- End of tebako patch -- */
37
+
38
+ static int
39
+ rb_main(int argc, char **argv)
40
+ SUBST
41
+
42
+ MAIN_C_SUBST_MAIN = <<~SUBST
43
+ /* -- Start of tebako patch -- */
44
+ #include <tebako/tebako-main.h>
45
+ /* -- End of tebako patch -- */
46
+
47
+ int
48
+ main(int argc, char **argv)
49
+ SUBST
50
+
51
+ MAIN_C_SUBST_RB_MAIN_INNER = <<~SUBST
52
+ ruby_init();
53
+ /* -- Start of tebako patch -- */
54
+ if (!tebako_is_running_miniruby())
55
+ {
56
+ VALUE cwd = rb_str_new_cstr(tebako_original_pwd());
57
+ rb_gv_set("$tebako_original_pwd", cwd);
58
+ }
59
+ /* -- End of tebako patch -- */
60
+ SUBST
61
+
62
+ MAIN_C_SUBST_MAIN_INNER = <<~SUBST
63
+ ruby_sysinit(&argc, &argv);
64
+ /* -- Start of tebako patch -- */
65
+ if (tebako_main(&argc, &argv) != 0) {
66
+ printf("Tebako intialization failed.");
67
+ return -1;
68
+ }
69
+ /* -- End of tebako patch -- */
70
+ SUBST
71
+
72
+ class << self
73
+ def get_main_c_patch(ruby_ver)
74
+ puts get_main_c_main_pattern(ruby_ver)
75
+ {
76
+ get_main_c_main_pattern(ruby_ver) => get_main_c_main_subst(ruby_ver),
77
+ "ruby_init();" => MAIN_C_SUBST_RB_MAIN_INNER,
78
+ " ruby_sysinit(&argc, &argv);" => MAIN_C_SUBST_MAIN_INNER
79
+ }
80
+ end
81
+
82
+ private
83
+
84
+ def get_main_c_main_pattern(ruby_ver)
85
+ ruby_ver.ruby32? ? "static int\nrb_main(int argc, char **argv)" : "int\nmain(int argc, char **argv)"
86
+ end
87
+
88
+ def get_main_c_main_subst(ruby_ver)
89
+ ruby_ver.ruby32? ? MAIN_C_SUBST_RB_MAIN : MAIN_C_SUBST_MAIN
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -31,6 +31,7 @@ require "pathname"
31
31
 
32
32
  require_relative "error"
33
33
  require_relative "deploy_helper"
34
+ require_relative "ruby_builder"
34
35
  require_relative "stripper"
35
36
  require_relative "packager/pass1"
36
37
  require_relative "packager/pass1a"
@@ -75,16 +76,17 @@ module Tebako
75
76
  end
76
77
 
77
78
  # Deploy
78
- def deploy(os_type, target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, fs_mount_point) # rubocop:disable Metrics/ParameterLists
79
+ def deploy(os_type, target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, fs_mount_point, cwd) # rubocop:disable Metrics/ParameterLists
79
80
  puts "-- Running deploy script"
80
81
 
81
82
  deploy_helper = Tebako::DeployHelper.new(fs_root, fs_entrance, fs_mount_point, target_dir, pre_dir)
82
- deploy_helper.config(os_type, ruby_ver)
83
+ deploy_helper.config(os_type, ruby_ver, cwd)
83
84
  deploy_helper.deploy
84
85
  Tebako::Stripper.strip(os_type, target_dir)
85
86
  end
86
87
 
87
- def finalize(os_type, src_dir, app_name)
88
+ def finalize(os_type, src_dir, app_name, ruby_ver)
89
+ RubyBuilder.new(ruby_ver, src_dir).final_build
88
90
  exe_suffix = Packager::PatchHelpers.exe_suffix(os_type)
89
91
  src_name = File.join(src_dir, "ruby#{exe_suffix}")
90
92
  package_name = "#{app_name}#{exe_suffix}"
@@ -177,7 +179,7 @@ module Tebako
177
179
  end
178
180
 
179
181
  def lib_fname(src_dir, ruby_ver)
180
- File.join(src_dir, "lib", "libx64-ucrt-ruby#{ruby_ver[0]}#{ruby_ver[2]}0.a")
182
+ File.join(src_dir, "lib", "libx64-ucrt-ruby#{ruby_ver.lib_version}.a")
181
183
  end
182
184
 
183
185
  def do_patch(patch_map, root)