tebako 0.11.0 → 0.12.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04ff17b2a527c5b6cf6f1630f097d828a10fa3f0fa32eaa86e3c2a063a579e19
4
- data.tar.gz: 740f889112a57820ce703917e4654403e13dd7960ccab22d02ceb6b9050f51d4
3
+ metadata.gz: 3e602aace5a0b42b9e7599d3bb39c32a2bc6ec01f48ec885d5147c626d79fb3f
4
+ data.tar.gz: 845e5e0a63277d53d64a6ff867d88016f6a002234eb01c0538d97d4ff06ceedf
5
5
  SHA512:
6
- metadata.gz: 4e48b494352c230d533f914ef9553c8a48f8f0de56f291e1738a391d2991469c873be5397ebb58b480f91be0bd2c9510316d4e93922994dd625ffe6045b3f1a8
7
- data.tar.gz: 7c4418d8bba50f67956db52b149001f407d8e1e4f64d44a41bdb63dfdec57d2a9fcebbdf681ed49d97fc3fc841c9515399b67002873aa1821f746e244d8033b0
6
+ metadata.gz: eb6458e260860b68983529d397de867ead824edd5ccd9dc97a37ebd849fec2d8539e25ecfcc7fe1652b9afaef29a1dc189470d0840ec2b986da1a980e9f30f19
7
+ data.tar.gz: b16af1a8fa72fc86e04f64faf7a55be31b325defcbb801ee5bf02ee3551ed6a7bbea1df1920e93d0556963ac17487ed7787551d03d8147e959b9e6bfa00a4e15
data/CMakeLists.txt CHANGED
@@ -91,8 +91,6 @@ set(IS_MSYS OFF)
91
91
  set(IS_DARWIN OFF)
92
92
  set(RB_W32 OFF)
93
93
  set(RUBY_WITHOUT_EXT "dbm,win32,win32ole,-test-/*")
94
- set(RUBY_NAME "ruby")
95
- set(EXE_SUFFIX "")
96
94
  set(DWARFS_PRELOAD OFF)
97
95
  set(WITH_PATCHELF OFF)
98
96
 
@@ -108,7 +106,6 @@ elseif("${OSTYPE_TXT}" MATCHES "^msys*")
108
106
  # set(DWARFS_PRELOAD ON)
109
107
  set(RB_W32 ON)
110
108
  set(RUBY_WITHOUT_EXT "dbm,syslog,pty,gdbm,readline,-test-/*")
111
- set(EXE_SUFFIX ".exe")
112
109
  elseif("${OSTYPE_TXT}" MATCHES "^darwin.*")
113
110
  set(IS_DARWIN ON)
114
111
  if(${RUBY_VER} VERSION_LESS "3.1.0")
@@ -162,7 +159,6 @@ if ("-${RUBY_VER}" STREQUAL "-" OR "-${RUBY_HASH}" STREQUAL "-")
162
159
  message(FATAL_ERROR "Ruby version is not specified")
163
160
  endif()
164
161
 
165
- set(RUBY_NAME ruby)
166
162
  set(RUBY_PRJ _ruby_${RUBY_VER})
167
163
  set(RUBY_SOURCE_DIR ${DEPS}/src/${RUBY_PRJ})
168
164
  set(RUBY_BINARY_DIR ${DEPS}/src/${RUBY_PRJ})
@@ -380,7 +376,6 @@ ExternalProject_Add(${RUBY_PRJ}
380
376
  COMMAND ruby ${EXE}/tebako-packager pass1a ${RUBY_SOURCE_DIR}
381
377
  BUILD_COMMAND make -j${NCORES}
382
378
  INSTALL_COMMAND make install -j${NCORES}
383
- COMMAND ${GNU_BASH} -c "chmod +x ${DEPS_BIN_DIR}/mkdwarfs${EXE_SUFFIX}"
384
379
  COMMAND ${GNU_BASH} -c "ruby ${EXE}/tebako-packager pass2 ${OSTYPE_TXT} ${RUBY_SOURCE_DIR} ${DEPS_LIB_DIR} ${DATA_SRC_DIR} ${RUBY_STASH_DIR} ${RUBY_VER}"
385
380
  )
386
381
 
data/README.adoc CHANGED
@@ -104,8 +104,9 @@ higher.
104
104
  | 2.7.8 | Linux, macOS
105
105
  | 3.0.7 | Linux, macOS
106
106
  | 3.1.6 | Linux, macOS, Windows
107
- | 3.2.{4,5} | Linux, macOS, Windows
108
- | 3.3.{3,4,5} | Linux, macOS, Windows
107
+ | 3.2.{4,5,6} | Linux, macOS, Windows
108
+ | 3.3.{3,4,5,6} | Linux, macOS, Windows
109
+ | 3.4.1 | Linux, macOS, Windows
109
110
 
110
111
  |===
111
112
 
@@ -780,7 +781,7 @@ the Tebako root folder (see details: <<root-folder-selection>>)
780
781
 
781
782
  `Ruby`::
782
783
  this parameter defines Ruby version that will be packaged (optional, defaults to
783
- `3.1.6`)
784
+ `3.2.6`)
784
785
 
785
786
  `project-root`::
786
787
  a folder at the host source file system where project files are located.
@@ -904,7 +905,7 @@ Where:
904
905
 
905
906
  `<tebako-root-folder>`:: the Tebako root folder (see details: <<root-folder-selection>>)
906
907
 
907
- `Ruby`:: parameter defines Ruby version that will be packaged (optional, defaults to `3.1.6`)
908
+ `Ruby`:: parameter defines Ruby version that will be packaged (optional, defaults to `3.2.6`)
908
909
 
909
910
  `tebafile`::
910
911
  the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
@@ -1130,15 +1131,6 @@ Here is a summary of the scenarios:
1130
1131
  | Any
1131
1132
 
1132
1133
 
1133
- | 5
1134
- | Rails project
1135
- | Deploy project to packaged filesystem using `bundle install`
1136
- | `<mount_point>/local/<entry_point base name>`
1137
- | No
1138
- | One
1139
- | Any
1140
-
1141
-
1142
1134
  | Error
1143
1135
  | Error: Two or more `*.gem` files present
1144
1136
  | -
data/common.env CHANGED
@@ -2,4 +2,4 @@ BUILD_TYPE=Release
2
2
  DEPS=deps
3
3
  INCBIN_TAG=348e36b
4
4
  DWARFS_WR_TAG=v0.9.2
5
- RUBY_VER=3.2.5
5
+ RUBY_VER=3.2.6
@@ -0,0 +1,51 @@
1
+ #include <fcntl.h>
2
+
3
+ static pm_string_init_result_t
4
+ tebako_string_file_init(pm_string_t *string, const char *filepath) {
5
+
6
+ // Open the file for reading
7
+ int fd = open(filepath, O_RDONLY);
8
+ if (fd == -1) {
9
+ return PM_STRING_INIT_ERROR_GENERIC;
10
+ }
11
+
12
+ // Stat the file to get the file size
13
+ struct stat sb;
14
+ if (fstat(fd, &sb) == -1) {
15
+ close(fd);
16
+ return PM_STRING_INIT_ERROR_GENERIC;
17
+ }
18
+
19
+ // Ensure it is a file and not a directory
20
+ if (S_ISDIR(sb.st_mode)) {
21
+ close(fd);
22
+ return PM_STRING_INIT_ERROR_DIRECTORY;
23
+ }
24
+
25
+ // Check the size to see if it's empty
26
+ size_t size = (size_t) sb.st_size;
27
+ if (size == 0) {
28
+ close(fd);
29
+ const uint8_t source[] = "";
30
+ *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
31
+ return PM_STRING_INIT_SUCCESS;
32
+ }
33
+
34
+ size_t length = (size_t) size;
35
+ uint8_t *source = xmalloc(length);
36
+ if (source == NULL) {
37
+ close(fd);
38
+ return PM_STRING_INIT_ERROR_GENERIC;
39
+ }
40
+
41
+ long bytes_read = (long) read(fd, source, length);
42
+ close(fd);
43
+
44
+ if (bytes_read == -1) {
45
+ xfree(source);
46
+ return PM_STRING_INIT_ERROR_GENERIC;
47
+ }
48
+
49
+ *string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = length };
50
+ return PM_STRING_INIT_SUCCESS;
51
+ }
data/lib/tebako/cli.rb CHANGED
@@ -53,7 +53,7 @@ module Tebako
53
53
  desc: "tebako configuration file 'tebafile', '$PWD/.tebako.yml' by default"
54
54
  desc "clean", "Clean tebako packaging environment"
55
55
  def clean
56
- (_, cm) = bootstrap
56
+ (_, cm) = bootstrap(clean: true)
57
57
  cm.clean_cache
58
58
  end
59
59
 
@@ -63,7 +63,7 @@ module Tebako
63
63
  desc: "Ruby version to clean, all available versions by default"
64
64
  def clean_ruby
65
65
  puts "Cleaning Ruby sources from tebako packaging environment"
66
- (om,) = bootstrap
66
+ (om,) = bootstrap(clean: true)
67
67
 
68
68
  suffix = options["Ruby"].nil? ? "" : "_#{options["Ruby"]}"
69
69
  nmr = "src/_ruby#{suffix}*"
@@ -84,7 +84,7 @@ module Tebako
84
84
 
85
85
  REF_DESCRIPTION = <<~DESC
86
86
  "Referenced tebako run-time package; 'tebako-runtime' by default".
87
- This option specifies the tebako runtime to be used by the application on Windows and if mode is 'application' only .
87
+ #{" " * 65}# This option specifies the tebako runtime to be used by the application on Windows and if mode is 'application' only .
88
88
  DESC
89
89
 
90
90
  RGP_DESCRIPTION = <<~DESC
@@ -139,11 +139,11 @@ module Tebako
139
139
  end
140
140
 
141
141
  no_commands do
142
- def bootstrap
142
+ def bootstrap(clean: false)
143
143
  options_manager = Tebako::OptionsManager.new(options)
144
144
  cache_manager = Tebako::CacheManager.new(options_manager.deps, options_manager.source,
145
145
  options_manager.output_folder)
146
- cache_manager.version_cache_check unless options[:devmode]
146
+ cache_manager.version_cache_check unless options[:devmode] || clean
147
147
  [options_manager, cache_manager]
148
148
  end
149
149
 
@@ -41,45 +41,52 @@ require_relative "packager_lite"
41
41
  module Tebako
42
42
  # Cli helpers
43
43
  module CliHelpers
44
+ WARN = <<~WARN
45
+
46
+ ******************************************************************************************************************
47
+ * *
48
+ * WARNING: You are packaging in-place, i.e.: tebako package will be placed inside application root. *
49
+ * It is not an error but we do not recommend it because it is a way to keep packaging old versions recrsively. *
50
+ * *
51
+ ******************************************************************************************************************
52
+
53
+ WARN
54
+
44
55
  def do_press(options_manager)
45
56
  scenario_manager = Tebako::ScenarioManager.new(options_manager.root, options_manager.fs_entrance)
46
57
  puts options_manager.press_announce(scenario_manager.msys?)
47
58
 
48
- if options_manager.mode == "both" || options_manager.mode == "runtime" || options_manager.mode == "bundle"
49
- do_press_runtime(options_manager, scenario_manager)
50
- end
51
-
52
- if options_manager.mode == "both" || options_manager.mode == "application"
53
- do_press_application(options_manager, scenario_manager)
59
+ if options_manager.package_within_root?
60
+ puts WARN
61
+ sleep 5
54
62
  end
55
63
 
56
- true
64
+ do_press_runtime(options_manager, scenario_manager)
65
+ do_press_application(options_manager, scenario_manager)
57
66
  end
58
67
 
59
68
  def do_press_application(options_manager, scenario_manager)
69
+ return unless %w[both application].include?(options_manager.mode)
70
+
60
71
  packager = Tebako::PackagerLite.new(options_manager, scenario_manager)
61
72
  packager.create_package
62
73
  end
63
74
 
64
75
  def do_press_runtime(options_manager, scenario_manager)
76
+ return unless %w[both runtime bundle].include?(options_manager.mode)
77
+
65
78
  generate_files(options_manager, scenario_manager)
66
- cfg_cmd = "cmake -DSETUP_MODE:BOOLEAN=OFF #{options_manager.cfg_options} #{options_manager.press_options}"
67
- build_cmd = "cmake --build #{options_manager.output_folder} --target tebako --parallel #{Etc.nprocessors}"
68
79
  merged_env = ENV.to_h.merge(options_manager.b_env)
69
- Tebako.packaging_error(103) unless system(merged_env, cfg_cmd)
70
- Tebako.packaging_error(104) unless system(merged_env, build_cmd)
71
- true
80
+ Tebako.packaging_error(103) unless system(merged_env, press_cfg_cmd(options_manager))
81
+ Tebako.packaging_error(104) unless system(merged_env, press_build_cmd(options_manager))
72
82
  end
73
83
 
74
84
  def do_setup(options_manager)
75
85
  puts "Setting up tebako packaging environment"
76
86
 
77
- cfg_cmd = "cmake -DSETUP_MODE:BOOLEAN=ON #{options_manager.cfg_options}"
78
- build_cmd = "cmake --build \"#{options_manager.output_folder}\" --target setup --parallel #{Etc.nprocessors}"
79
87
  merged_env = ENV.to_h.merge(options_manager.b_env)
80
- Tebako.packaging_error(101) unless system(merged_env, cfg_cmd)
81
- Tebako.packaging_error(102) unless system(merged_env, build_cmd)
82
- true
88
+ Tebako.packaging_error(101) unless system(merged_env, setup_cfg_cmd(options_manager))
89
+ Tebako.packaging_error(102) unless system(merged_env, setup_build_cmd(options_manager))
83
90
  end
84
91
 
85
92
  def generate_files(options_manager, scenario_manager)
@@ -91,7 +98,7 @@ module Tebako
91
98
  Tebako::Codegen.generate_tebako_fs_cpp(options_manager, scenario_manager)
92
99
  Tebako::Codegen.generate_deploy_rb(options_manager, scenario_manager)
93
100
 
94
- return unless options_manager.mode == "both" || options_manager.mode == "runtime"
101
+ return unless %w[both runtime].include?(options_manager.mode)
95
102
 
96
103
  Tebako::Codegen.generate_stub_rb(options_manager)
97
104
  end
@@ -107,5 +114,21 @@ module Tebako
107
114
  puts e.message
108
115
  {}
109
116
  end
117
+
118
+ def press_build_cmd(options_manager)
119
+ "cmake --build #{options_manager.output_folder} --target tebako --parallel #{Etc.nprocessors}"
120
+ end
121
+
122
+ def press_cfg_cmd(options_manager)
123
+ "cmake -DSETUP_MODE:BOOLEAN=OFF #{options_manager.cfg_options} #{options_manager.press_options}"
124
+ end
125
+
126
+ def setup_build_cmd(options_manager)
127
+ "cmake --build \"#{options_manager.output_folder}\" --target setup --parallel #{Etc.nprocessors}"
128
+ end
129
+
130
+ def setup_cfg_cmd(options_manager)
131
+ "cmake -DSETUP_MODE:BOOLEAN=ON #{options_manager.cfg_options}"
132
+ end
110
133
  end
111
134
  end
@@ -62,12 +62,14 @@ module Tebako
62
62
  end
63
63
 
64
64
  def deploy_mk(opt, scm)
65
- case opt.mode
66
- when "bundle"
67
- deploy_mk_bundle(opt, scm)
68
- when /runtime|both/
69
- deploy_mk_stub(opt)
70
- end
65
+ <<~SUBST
66
+ begin
67
+ #{deploy_mk_inner(opt, scm)}
68
+ rescue Tebako::Error => e
69
+ puts "tebako-packager failed: \#{e.message} [\#{e.error_code}]"
70
+ exit(e.error_code)
71
+ end
72
+ SUBST
71
73
  end
72
74
 
73
75
  def deploy_mk_bundle(opt, scm)
@@ -79,6 +81,15 @@ module Tebako
79
81
  SUBST
80
82
  end
81
83
 
84
+ def deploy_mk_inner(opt, scm)
85
+ case opt.mode
86
+ when "bundle"
87
+ deploy_mk_bundle(opt, scm)
88
+ when /runtime|both/
89
+ deploy_mk_stub(opt)
90
+ end
91
+ end
92
+
82
93
  def deploy_mk_stub(opt)
83
94
  <<~SUBST
84
95
  Tebako::Packager.deploy("#{opt.data_src_dir}", "#{opt.data_pre_dir}",
@@ -101,6 +112,7 @@ module Tebako
101
112
 
102
113
  def deploy_rq
103
114
  <<~SUBST
115
+ require "#{File.join(__dir__, "error.rb")}"
104
116
  require "#{File.join(__dir__, "package_descriptor.rb")}"
105
117
  require "#{File.join(__dir__, "packager.rb")}"
106
118
  require "#{File.join(__dir__, "ruby_version.rb")}"
@@ -25,6 +25,7 @@
25
25
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
+ # require "bundler"
28
29
  require "fileutils"
29
30
  require "find"
30
31
 
@@ -49,7 +50,7 @@ module Tebako
49
50
  @fs_entrance = fs_entrance
50
51
  @target_dir = target_dir
51
52
  @pre_dir = pre_dir
52
- @verbose = ENV["VERBOSE"] == "yes" || ENV["VERBOSE"] == "true"
53
+ @verbose = %w[yes true].include?(ENV.fetch("VERBOSE", nil))
53
54
  @ncores = BuildHelpers.ncores
54
55
  end
55
56
 
@@ -92,7 +93,7 @@ module Tebako
92
93
 
93
94
  params = [@gem_command, "install", name.to_s]
94
95
  params.push("-v", ver.to_s) if ver
95
- ["--no-document", "--install-dir", @tgd].each do |param|
96
+ ["--no-document", "--install-dir", @tgd, "--bindir", @tbd].each do |param|
96
97
  params.push(param)
97
98
  end
98
99
  BuildHelpers.run_with_capture_v(params)
@@ -141,11 +142,15 @@ module Tebako
141
142
  end
142
143
 
143
144
  def collect_and_deploy_gem(gemspec)
144
- puts " ... Collecting gem from gemspec #{gemspec}"
145
+ puts " ... collecting gem from gemspec #{gemspec}"
145
146
 
146
147
  copy_files(@pre_dir)
147
148
 
148
149
  Dir.chdir(@pre_dir) do
150
+ # spec = Bundler.load_gemspec(gemspec)
151
+ # puts spec.executables.first unless spec.executables.empty?
152
+ # puts spec.bindir
153
+
149
154
  BuildHelpers.run_with_capture_v([@gem_command, "build", gemspec])
150
155
  install_all_gems_or_fail
151
156
  end
@@ -200,7 +205,7 @@ module Tebako
200
205
  begin
201
206
  FileUtils.cp_r(File.join(@fs_root, "."), dest)
202
207
  rescue StandardError
203
- raise Tebako::Error.new("#{@fs_root} is not accessible or does not exist.", 107)
208
+ raise Tebako::Error.new("#{@fs_root} does not exist or is not accessible.", 107)
204
209
  end
205
210
  return
206
211
  end
@@ -185,6 +185,15 @@ module Tebako
185
185
  end
186
186
  end
187
187
 
188
+ def package_within_root?
189
+ package_path = Pathname.new(package.chomp("/"))
190
+ root_path = Pathname.new(root.chomp("/"))
191
+ package_path.ascend do |path|
192
+ return true if path == root_path
193
+ end
194
+ false
195
+ end
196
+
188
197
  def prefix
189
198
  @prefix ||= if @options["prefix"].nil?
190
199
  handle_nil_prefix
@@ -0,0 +1,301 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2021-2025 [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
+ require_relative "patch_helpers"
29
+ require_relative "patch_buildsystem"
30
+
31
+ require_relative "patch"
32
+ # Tebako - an executable packager
33
+ module Tebako
34
+ # Packager module
35
+ module Packager
36
+ class << self
37
+ def crt_pass1_patch(os_type, mount_point, ruby_ver)
38
+ case os_type
39
+ when /darwin/
40
+ Pass1DarwinPatch.new(mount_point, ruby_ver)
41
+ when /msys/
42
+ Pass1MSysPatch.new(mount_point, ruby_ver)
43
+ else
44
+ Pass1Patch.new(mount_point, ruby_ver)
45
+ end
46
+ end
47
+ end
48
+ # Ruby patching definitions (pass1 - common)
49
+ class Pass1Patch < Patch
50
+ # [TODO] looks like it does not exist in 3.1.4
51
+ # May be obsolete
52
+ TOOL_RBINSTALL_RB_PATCH = {
53
+ " next if files.empty?" => "# tebako patched next if files.empty?"
54
+ }.freeze
55
+
56
+ RUBYGEM_OPENSSL_RB_SUBST = <<~SUBST
57
+ # Start of tebako patch
58
+ require "openssl"
59
+ # End of tebako patch
60
+ autoload :OpenSSL, "openssl"
61
+ SUBST
62
+
63
+ RUBYGEM_OPENSSL_RB_PATCH = {
64
+ 'autoload :OpenSSL, "openssl"' => RUBYGEM_OPENSSL_RB_SUBST
65
+ }.freeze
66
+
67
+ EXT_SETUP_PATCH = {
68
+ "#option nodynamic" => "option nodynamic"
69
+ }.freeze
70
+
71
+ # ....................................................
72
+ # This is something that I cannnot explain
73
+ # (this patch does not seem related to static compilation)
74
+
75
+ EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH = {
76
+ "#include \"ruby/ruby.h\"" => <<~SUBST
77
+ #include "ruby/ruby.h"
78
+
79
+ /* -- Start of tebako patch -- */
80
+ #ifndef HAVE_RB_SYM2STR
81
+ #define HAVE_RB_SYM2STR 1
82
+ #endif
83
+
84
+ #ifndef HAVE_RB_ARRAY_CONST_PTR
85
+ #define HAVE_RB_ARRAY_CONST_PTR 1
86
+ #endif
87
+
88
+ #ifndef HAVE_RB_RATIONAL_NUM
89
+ #define HAVE_RB_RATIONAL_NUM 1
90
+ #endif
91
+
92
+ #ifndef HAVE_RB_RATIONAL_DEN
93
+ #define HAVE_RB_RATIONAL_DEN 1
94
+ #endif
95
+
96
+ #ifndef HAVE_RB_COMPLEX_REAL
97
+ #define HAVE_RB_COMPLEX_REAL
98
+ #endif
99
+
100
+ #ifndef HAVE_RB_COMPLEX_IMAG
101
+ #define HAVE_RB_COMPLEX_IMAG
102
+ #endif
103
+ /* -- End of tebako patch -- */
104
+
105
+ SUBST
106
+ }.freeze
107
+
108
+ # The logic for statically linked extensions is broken entirely in the latest Ruby versions.
109
+ # The code below looks reasonble - we do not set -bundle_loader when building with -with-static-ext option
110
+ # However Gems bundled with Ruby just ignore with-static-ext option and build extensions as shared libraries
111
+ # So the -bundler_loader option is required for them to link.
112
+ # It is strange that it is disabled in any case because this option does not create any issues for static
113
+ # libraries.
114
+ # ---------------------------------------------------
115
+ # elif test "x$EXTSTATIC" = x
116
+ # then :
117
+ #
118
+ # # When building exts as bundles, a mach-o bundle needs to know its loader
119
+ # # program to bind symbols from the ruby executable
120
+ # EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'"
121
+
122
+ OPENSSL_EXTCONF_RB_SUBST = <<~SUBST
123
+ # Start of tebako patch
124
+ $defs.push("-DRUBY_EXPORT=1")
125
+ # End of tebako patch
126
+
127
+ Logging::message "=== Checking done. ===\\n"
128
+ SUBST
129
+
130
+ OPENSSL_EXTCONF_RB_PATCH = {
131
+ "Logging::message \"=== Checking done. ===\\n\"" => OPENSSL_EXTCONF_RB_SUBST
132
+ }.freeze
133
+
134
+ def initialize(mountpoint, ruby_ver)
135
+ super()
136
+ @mountpoint = mountpoint
137
+ @ruby_ver = ruby_ver
138
+ end
139
+
140
+ def base_patch_map
141
+ {
142
+ # ....................................................
143
+ # It won't install gems with no files defined in spec
144
+ # However if
145
+ # -- we are installing a default gem from extension
146
+ # -- extension is build statically
147
+ # there may be no files install in addition to spec
148
+ # Example: io/wait extension (and others)
149
+ # [TODO] Check if it is still required
150
+ # No match and patching on Ruby 3.1.4 but works wo issues
151
+ "tool/rbinstall.rb" => TOOL_RBINSTALL_RB_PATCH,
152
+
153
+ # ....................................................
154
+ # Allow only packaged gems (from within memfs)
155
+ "lib/rubygems/path_support.rb" => rubygems_path_support_patch,
156
+
157
+ # ....................................................
158
+ # Disable dynamic extensions
159
+ "ext/Setup" => EXT_SETUP_PATCH
160
+ }
161
+ end
162
+
163
+ def patch_map
164
+ pm = base_patch_map
165
+ pm.merge!(super)
166
+
167
+ # ....................................................
168
+ pm.store("ext/bigdecimal/bigdecimal.h", EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH) unless @ruby_ver.ruby34?
169
+
170
+ # ....................................................
171
+ # autoload :OpenSSL, "openssl"
172
+ # fails to deal with a default gem from statically linked extension
173
+ pm.store("lib/rubygems/openssl.rb", RUBYGEM_OPENSSL_RB_PATCH) if @ruby_ver.ruby3x?
174
+
175
+ pm.freeze
176
+ end
177
+
178
+ private
179
+
180
+ def rubygems_path_support_patch_one
181
+ <<~SUBST
182
+ @home = env["GEM_HOME"] || Gem.default_dir
183
+ # -- Start of tebako patch --
184
+ unless env["TEBAKO_PASS_THROUGH"]
185
+ @home = Gem.default_dir unless @home.index("#{@mount_point}") == 0
186
+ end
187
+ # -- End of tebako patch --
188
+
189
+ SUBST
190
+ end
191
+
192
+ def rubygems_path_support_patch_two
193
+ <<~SUBST
194
+
195
+ @path = split_gem_path env["GEM_PATH"], @home
196
+ # -- Start of tebako patch --
197
+ unless env["TEBAKO_PASS_THROUGH"]
198
+ @path.keep_if do |xpath|
199
+ xpath.index("#{@mount_point}") == 0
200
+ end
201
+ end
202
+ # -- End of tebako patch --
203
+
204
+ SUBST
205
+ end
206
+
207
+ def rubygems_path_support_patch
208
+ {
209
+ ' @home = env["GEM_HOME"] || Gem.default_dir' => rubygems_path_support_patch_one,
210
+ ' @path = split_gem_path env["GEM_PATH"], @home' => rubygems_path_support_patch_two
211
+ }
212
+ end
213
+ end
214
+
215
+ # Ruby patching definitions (pass1 - darwin)
216
+ class Pass1DarwinPatch < Pass1Patch
217
+ DARWIN_CONFIGURE_PATCH = {
218
+ "elif test \"x$EXTSTATIC\" = x" => "elif true"
219
+ }.freeze
220
+
221
+ def patch_map
222
+ pm = { "configure" => DARWIN_CONFIGURE_PATCH }
223
+ pm.merge!(super)
224
+ pm.freeze
225
+ end
226
+ end
227
+
228
+ # Ruby patching definitions (pass1 - Windows)
229
+ class Pass1MSysPatch < Pass1Patch
230
+ INCLUDE_RUBY_ONIGMO_H_PATCH = {
231
+ "# define ONIG_EXTERN RUBY_EXTERN" => "# define ONIG_EXTERN extern"
232
+ }.freeze
233
+
234
+ WIN32_WINMAIN_C_PATCH = {
235
+ "WinMain(HINSTANCE current, HINSTANCE prev, LPSTR cmdline, int showcmd)" =>
236
+ "wWinMain(HINSTANCE current, HINSTANCE prev, LPWSTR cmdline, int showcmd)"
237
+ }.freeze
238
+
239
+ def patch_map
240
+ pm = msys_patches
241
+ pm.merge!(super)
242
+ pm.freeze
243
+ end
244
+
245
+ private
246
+
247
+ include Tebako::Packager::PatchBuildsystem
248
+
249
+ def gnumakefile_in_patch_p1 # rubocop:disable Metrics/MethodLength
250
+ objext = @ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
251
+ {
252
+ " DLLWRAP += -mno-cygwin" =>
253
+ "# tebako patched DLLWRAP += -mno-cygwin",
254
+
255
+ "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
256
+ "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",
257
+
258
+ "$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>
259
+ "$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ # tebako patched",
260
+
261
+ "--output-exp=$(RUBY_EXP) \\" =>
262
+ "--output-exp=$(RUBY_EXP) --output-lib=$(LIBRUBY) --output-def=tebako.def \\",
263
+
264
+ "--export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)" =>
265
+ "--export-all $(LIBRUBY_A) $(LIBS) -o program-stub.exe # tebako patched",
266
+
267
+ "@rm -f $(PROGRAM)" =>
268
+ "@rm -f program-stub.exe # tebako patched",
269
+
270
+ " $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)" =>
271
+ "# tebako patched $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)",
272
+
273
+ "RUBYDEF = $(DLL_BASE_NAME).def" => GNUMAKEFILE_IN_WINMAIN_SUBST
274
+ }
275
+ end
276
+
277
+ def msys_base_patches
278
+ {
279
+ # ....................................................
280
+ # Generate export definitions; use WinMain to build rubyw.exe
281
+ "cygwin/GNUmakefile.in" => gnumakefile_in_patch_p1,
282
+ # ....................................................
283
+ # RUBY_EXPORT=1 (shall be set for static builds but is missing in openssl extension)
284
+ "ext/openssl/extconf.rb" => OPENSSL_EXTCONF_RB_PATCH
285
+ }
286
+ end
287
+
288
+ def msys_patches
289
+ pm = msys_base_patches
290
+
291
+ if @ruby_ver.ruby34?
292
+ # ....................................................
293
+ # RUBY_EXTERN shall be extern for static build but is set to __declspec(dllimport) for encodin libarary
294
+ pm.store("include/ruby/onigmo.h", INCLUDE_RUBY_ONIGMO_H_PATCH)
295
+ pm.store("win32/winmain.c", WIN32_WINMAIN_C_PATCH)
296
+ end
297
+ pm
298
+ end
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024-2025 [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
+ require_relative "patch"
29
+ # Tebako - an executable packager
30
+ module Tebako
31
+ module Packager
32
+ # Ruby patching definitions (pass1a)
33
+ class Pass1APatch < Patch
34
+ GEM_PRELUDE_RB_PATCH = {
35
+ "if defined?(DidYouMean)" => <<~SUBST
36
+ if defined?(DidYouMean)
37
+
38
+ # -- Start of tebako patch --
39
+ begin
40
+ require 'tebako-runtime'
41
+ rescue LoadError
42
+ warn "'tebako-runtime' was not loaded."
43
+ end
44
+ # -- End of tebako patch --
45
+ SUBST
46
+ }.freeze
47
+
48
+ def patch_map
49
+ {
50
+ "gem_prelude.rb" => GEM_PRELUDE_RB_PATCH
51
+ }.freeze
52
+ end
53
+ end
54
+ end
55
+ end
@@ -46,6 +46,8 @@ module Tebako
46
46
  patch_map.store("common.mk", COMMON_MK_PATCH)
47
47
  end
48
48
  extend_patch_map_r33(patch_map, ostype, deps_lib_dir, ruby_ver)
49
+ patch_map.store("prism_compile.c", PRISM_PATCHES) if ruby_ver.ruby34?
50
+ patch_map
49
51
  end
50
52
 
51
53
  private
@@ -68,11 +70,10 @@ module Tebako
68
70
  end
69
71
 
70
72
  def get_dln_c_patch(ostype, ruby_ver)
73
+ pattern = "#ifndef dln_loaderror"
71
74
  # Not using substitutions of dlxxx functions on Windows
72
75
  dln_c_patch = {
73
- "static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;" =>
74
- "#{PatchHelpers.msys?(ostype) ? C_FILE_SUBST_LESS : C_FILE_SUBST}\n" \
75
- "static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;\n"
76
+ pattern => "#{PatchHelpers.msys?(ostype) ? C_FILE_SUBST_LESS : C_FILE_SUBST}\n#{pattern}\n"
76
77
  }
77
78
 
78
79
  if PatchHelpers.msys?(ostype)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2025 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -25,21 +25,13 @@
25
25
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
- require_relative "patch_literals"
29
-
30
28
  # Tebako - an executable packager
31
29
  module Tebako
32
30
  module Packager
33
- # Ruby patching definitions (pass1a)
34
- module Pass1A
35
- class << self
36
- def get_patch_map # rubocop:disable Naming/AccessorMethodName
37
- {
38
- "gem_prelude.rb" => GEM_PRELUDE_RB_PATCH
39
- }
40
- end
41
-
42
- include Tebako::Packager::PatchLiterals
31
+ # Ruby patching definitions (common base)
32
+ class Patch
33
+ def patch_map
34
+ {}.freeze
43
35
  end
44
36
  end
45
37
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2023-2025 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -150,6 +150,10 @@ module Tebako
150
150
  "else if (e == EIO /* tebako patch */ && !within_tebako_memfs(path)) {"
151
151
  }.freeze
152
152
 
153
+ DLN_C_PRE34_PATCH_PATTERN = "static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;"
154
+
155
+ DLN_C_PATCH_PATTERN = "#define init_funcname(buf, file) build_funcname(FUNCNAME_PREFIX, buf, file)"
156
+
153
157
  DLN_C_MSYS_PATCH_PRE32 = {
154
158
  " winfile = rb_w32_mbstr_to_wstr(CP_UTF8, file, -1, NULL);" => <<~SUBST
155
159
  /* -- Start of tebako patch -- */
@@ -209,20 +213,6 @@ module Tebako
209
213
  /* -- End of tebako patch -- */
210
214
  SUBST
211
215
 
212
- GEM_PRELUDE_RB_PATCH = {
213
- "if defined?(DidYouMean)" => <<~SUBST
214
- if defined?(DidYouMean)
215
-
216
- # -- Start of tebako patch --
217
- begin
218
- require 'tebako-runtime'
219
- rescue LoadError
220
- warn "'tebako-runtime' was not loaded."
221
- end
222
- # -- End of tebako patch --
223
- SUBST
224
- }.freeze
225
-
226
216
  IO_C_SUBST = <<~SUBST
227
217
  /* -- Start of tebako patch -- */
228
218
  if (is_tebako_file_descriptor(fd)) return;
@@ -328,6 +318,40 @@ module Tebako
328
318
  "mf.macro \"EXTLIBS\", $extlibs" => "# mf.macro \"EXTLIBS\", $extlibs tebako patched"
329
319
  }
330
320
  }.freeze
321
+
322
+ PRISM_PATTERN_1 = "pm_string_init_result_t init_result = pm_read_file(&result->input, RSTRING_PTR(filepath));"
323
+
324
+ PRISM_SUBST_1 = <<~SUBST
325
+ /* -- Start of tebako patch -- */
326
+ pm_string_init_result_t init_result;
327
+ if (within_tebako_memfs(RSTRING_PTR(filepath)))
328
+ {
329
+ init_result = tebako_string_file_init(&result->input, RSTRING_PTR(filepath));
330
+ }
331
+ else
332
+ {
333
+ init_result = pm_read_file(&result->input, RSTRING_PTR(filepath));
334
+ }
335
+ /* -- End of tebako patch -- */
336
+ SUBST
337
+
338
+ PRISM_PATTERN_2 = "#include \"prism.h\""
339
+ PRISM_SUBST_2 = <<~SUBST
340
+ #{PRISM_PATTERN_2}
341
+
342
+ /* -- Start of tebako patch -- */
343
+ #include <tebako/tebako-config.h>
344
+ #include <tebako/tebako-defines.h>
345
+ #include <tebako/tebako-io.h>
346
+ #include <tebako/tebako-prism.h>
347
+ /* -- End of tebako patch -- */
348
+
349
+ SUBST
350
+
351
+ PRISM_PATCHES = {
352
+ PRISM_PATTERN_1 => PRISM_SUBST_1,
353
+ PRISM_PATTERN_2 => PRISM_SUBST_2
354
+ }.freeze
331
355
  end
332
356
  end
333
357
  end
@@ -33,8 +33,8 @@ require_relative "error"
33
33
  require_relative "deploy_helper"
34
34
  require_relative "ruby_builder"
35
35
  require_relative "stripper"
36
- require_relative "packager/pass1"
37
- require_relative "packager/pass1a"
36
+ require_relative "packager/pass1_patch"
37
+ require_relative "packager/pass1a_patch"
38
38
  require_relative "packager/pass2"
39
39
  require_relative "packager/patch_helpers"
40
40
 
@@ -108,6 +108,7 @@ module Tebako
108
108
 
109
109
  def mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil)
110
110
  puts "-- Running mkdwarfs script"
111
+ FileUtils.chmod("a+x", Dir.glob(File.join(deps_bin_dir, "mkdwarfs*")))
111
112
  params = [File.join(deps_bin_dir, "mkdwarfs"), "-o", data_bin_file, "-i", data_src_dir, "--no-progress"]
112
113
  params << "--header" << descriptor if descriptor
113
114
  BuildHelpers.run_with_capture_v(params)
@@ -119,7 +120,8 @@ module Tebako
119
120
  puts "-- Running pass1 script"
120
121
 
121
122
  PatchHelpers.recreate(src_dir)
122
- do_patch(Pass1.get_patch_map(ostype, mount_point, ruby_ver), ruby_source_dir)
123
+ patch = crt_pass1_patch(ostype, mount_point, ruby_ver)
124
+ do_patch(patch.patch_map, ruby_source_dir)
123
125
 
124
126
  # Roll back pass1a, pass2 patches
125
127
  # Just in case we are recovering after some error
@@ -132,8 +134,8 @@ module Tebako
132
134
  # Patch gem_prelude.rb
133
135
  def pass1a(ruby_source_dir)
134
136
  puts "-- Running pass1a script"
135
-
136
- do_patch(Pass1A.get_patch_map, ruby_source_dir)
137
+ patch = Pass1APatch.new.patch_map
138
+ do_patch(patch, ruby_source_dir)
137
139
  end
138
140
 
139
141
  # Pass2
@@ -37,15 +37,17 @@ module Tebako
37
37
  "3.1.6" => "0d0dafb859e76763432571a3109d1537d976266be3083445651dc68deed25c22",
38
38
  "3.2.4" => "c72b3c5c30482dca18b0f868c9075f3f47d8168eaf626d4e682ce5b59c858692",
39
39
  "3.2.5" => "ef0610b498f60fb5cfd77b51adb3c10f4ca8ed9a17cb87c61e5bea314ac34a16",
40
+ "3.2.6" => "d9cb65ecdf3f18669639f2638b63379ed6fbb17d93ae4e726d4eb2bf68a48370",
40
41
  "3.3.3" => "83c05b2177ee9c335b631b29b8c077b4770166d02fa527f3a9f6a40d13f3cce2",
41
42
  "3.3.4" => "fe6a30f97d54e029768f2ddf4923699c416cdbc3a6e96db3e2d5716c7db96a34",
42
- "3.3.5" => "3781a3504222c2f26cb4b9eb9c1a12dbf4944d366ce24a9ff8cf99ecbce75196"
43
+ "3.3.5" => "3781a3504222c2f26cb4b9eb9c1a12dbf4944d366ce24a9ff8cf99ecbce75196",
44
+ "3.3.6" => "8dc48fffaf270f86f1019053f28e51e4da4cce32a36760a0603a9aee67d7fd8d",
45
+ "3.4.1" => "3d385e5d22d368b064c817a13ed8e3cc3f71a7705d7ed1bae78013c33aa7c87f"
43
46
  }.freeze
44
47
 
45
48
  MIN_RUBY_VERSION_WINDOWS = "3.1.6"
46
- DEFAULT_RUBY_VERSION = "3.2.5"
49
+ DEFAULT_RUBY_VERSION = "3.2.6"
47
50
 
48
- # rub_ver version = options["Ruby"].nil? ? DEFAULT_RUBY_VERSION : options["Ruby"]
49
51
  def initialize(ruby_version)
50
52
  @ruby_version = ruby_version.nil? ? DEFAULT_RUBY_VERSION : ruby_version
51
53
 
@@ -76,6 +78,10 @@ module Tebako
76
78
  @ruby33 ||= ruby3x? && @ruby_version[2].to_i >= 3
77
79
  end
78
80
 
81
+ def ruby34?
82
+ @ruby34 ||= ruby3x? && @ruby_version[2].to_i >= 4
83
+ end
84
+
79
85
  def api_version
80
86
  @api_version ||= "#{@ruby_version.split(".")[0..1].join(".")}.0"
81
87
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2024-2025 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -36,7 +36,8 @@ module Tebako
36
36
  module Stripper
37
37
  DELETE_EXTENSIONS = %w[o lo obj a la lib].freeze
38
38
  BIN_FILES = %w[
39
- bundle bundler rbs erb gem irb racc racc2y rake rdoc ri y2racc rdbg typeprof
39
+ bundle bundler rbs erb gem irb racc racc2y
40
+ rake rdoc ri y2racc rdbg syntax_suggest typeprof
40
41
  ].freeze
41
42
  CMD_SUFFIX = ".cmd"
42
43
  BAT_SUFFIX = ".bat"
@@ -44,8 +45,6 @@ module Tebako
44
45
  class << self
45
46
  # Strip
46
47
  # Removes build artefacts, strip shared objects
47
- # [TODO] We probably need debug option/flag to say whether we shall delete ruby binaries
48
- # from memfs or not. For debugging purposes it is very handy to have it here
49
48
  def strip(scm, src_dir)
50
49
  puts " ... stripping the output"
51
50
  strip_bs(src_dir)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2023-2025 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -26,5 +26,5 @@
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
28
  module Tebako
29
- VERSION = "0.11.0"
29
+ VERSION = "0.12.1"
30
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tebako
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-25 00:00:00.000000000 Z
11
+ date: 2025-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -162,6 +162,7 @@ files:
162
162
  - exe/tebako-packager
163
163
  - include/tebako/tebako-fs.h
164
164
  - include/tebako/tebako-main.h
165
+ - include/tebako/tebako-prism.h
165
166
  - lib/tebako.rb
166
167
  - lib/tebako/build_helpers.rb
167
168
  - lib/tebako/cache_manager.rb
@@ -173,9 +174,10 @@ files:
173
174
  - lib/tebako/options_manager.rb
174
175
  - lib/tebako/package_descriptor.rb
175
176
  - lib/tebako/packager.rb
176
- - lib/tebako/packager/pass1.rb
177
- - lib/tebako/packager/pass1a.rb
177
+ - lib/tebako/packager/pass1_patch.rb
178
+ - lib/tebako/packager/pass1a_patch.rb
178
179
  - lib/tebako/packager/pass2.rb
180
+ - lib/tebako/packager/patch.rb
179
181
  - lib/tebako/packager/patch_buildsystem.rb
180
182
  - lib/tebako/packager/patch_helpers.rb
181
183
  - lib/tebako/packager/patch_libraries.rb
@@ -1,242 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright (c) 2021-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
- require_relative "patch_literals"
29
- require_relative "patch_helpers"
30
- require_relative "patch_buildsystem"
31
-
32
- # Tebako - an executable packager
33
- module Tebako
34
- module Packager
35
- # Ruby patching definitions (pass1)
36
- module Pass1
37
- # [TODO] looks like it does not exist in 3.1.4
38
- # May be obsolete
39
- TOOL_RBINSTALL_RB_PATCH = {
40
- " next if files.empty?" => "# tebako patched next if files.empty?"
41
- }.freeze
42
-
43
- RUBYGEM_OPENSSL_RB_SUBST = <<~SUBST
44
- # Start of tebako patch
45
- require "openssl"
46
- # End of tebako patch
47
- autoload :OpenSSL, "openssl"
48
- SUBST
49
-
50
- RUBYGEM_OPENSSL_RB_PATCH = {
51
- 'autoload :OpenSSL, "openssl"' => RUBYGEM_OPENSSL_RB_SUBST
52
- }.freeze
53
-
54
- EXT_SETUP_PATCH = {
55
- "#option nodynamic" => "option nodynamic"
56
- }.freeze
57
-
58
- EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH = {
59
- "#include \"ruby/ruby.h\"" => <<~SUBST
60
- #include "ruby/ruby.h"
61
-
62
- /* -- Start of tebako patch -- */
63
- #ifndef HAVE_RB_SYM2STR
64
- #define HAVE_RB_SYM2STR 1
65
- #endif
66
-
67
- #ifndef HAVE_RB_ARRAY_CONST_PTR
68
- #define HAVE_RB_ARRAY_CONST_PTR 1
69
- #endif
70
-
71
- #ifndef HAVE_RB_RATIONAL_NUM
72
- #define HAVE_RB_RATIONAL_NUM 1
73
- #endif
74
-
75
- #ifndef HAVE_RB_RATIONAL_DEN
76
- #define HAVE_RB_RATIONAL_DEN 1
77
- #endif
78
-
79
- #ifndef HAVE_RB_COMPLEX_REAL
80
- #define HAVE_RB_COMPLEX_REAL
81
- #endif
82
-
83
- #ifndef HAVE_RB_COMPLEX_IMAG
84
- #define HAVE_RB_COMPLEX_IMAG
85
- #endif
86
- /* -- End of tebako patch -- */
87
-
88
- SUBST
89
- }.freeze
90
-
91
- # The logic for statically linked extensions is broken entirely in the latest Ruby versions.
92
- # The code below looks reasonble - we do not set -bundle_loader when building with -with-static-ext option
93
- # However Gems bundled with Ruby just ignore with-static-ext option and build extensions as shared libraries
94
- # So the -bundler_loader option is required for them to link.
95
- # It is strange that it is disabled in any case because this option does not create any issues for static
96
- # libraries.
97
- # ---------------------------------------------------
98
- # elif test "x$EXTSTATIC" = x
99
- # then :
100
- #
101
- # # When building exts as bundles, a mach-o bundle needs to know its loader
102
- # # program to bind symbols from the ruby executable
103
- # EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'"
104
-
105
- DARWIN_CONFIGURE_PATCH = {
106
- "elif test \"x$EXTSTATIC\" = x" => "elif true"
107
- }.freeze
108
-
109
- OPENSSL_EXTCONF_RB_SUBST = <<~SUBST
110
- # Start of tebako patch
111
- $defs.push("-DRUBY_EXPORT=1")
112
- # End of tebako patch
113
-
114
- Logging::message "=== Checking done. ===\\n"
115
- SUBST
116
-
117
- OPENSSL_EXTCONF_RB_PATCH = {
118
- "Logging::message \"=== Checking done. ===\\n\"" => OPENSSL_EXTCONF_RB_SUBST
119
- }.freeze
120
-
121
- class << self
122
- def get_base_patch_map(mount_point)
123
- {
124
- # ....................................................
125
- # It won't install gems with no files defined in spec
126
- # However if
127
- # -- we are installing a default gem from extension
128
- # -- extension is build statically
129
- # there may be no files install in addition to spec
130
- # Example: io/wait extension (and others)
131
- # [TODO] Check if it is still required
132
- # No match and patching on Ruby 3.1.4 but works wo issues
133
- "tool/rbinstall.rb" => TOOL_RBINSTALL_RB_PATCH,
134
-
135
- # ....................................................
136
- # This is something that I cannnot explain
137
- # (this patch does not seem related to static compilation)
138
- "ext/bigdecimal/bigdecimal.h" => EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH,
139
-
140
- # ....................................................
141
- # Allow only packaged gems (from within memfs)
142
- "lib/rubygems/path_support.rb" => rubygems_path_support_patch(mount_point),
143
-
144
- # ....................................................
145
- # Disable dynamic extensions
146
- "ext/Setup" => EXT_SETUP_PATCH
147
- }
148
- end
149
-
150
- def get_patch_map(ostype, mount_point, ruby_ver)
151
- patch_map = get_base_patch_map(mount_point)
152
-
153
- # ....................................................
154
- patch_map.store("configure", DARWIN_CONFIGURE_PATCH) if ostype =~ /darwin/
155
-
156
- # ....................................................
157
- # autoload :OpenSSL, "openssl"
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 ruby_ver.ruby3x?
160
-
161
- if ostype =~ /msys/
162
- # ....................................................
163
- # Generate export definitions; use WinMain to build rubyw.exe
164
- patch_map.store("cygwin/GNUmakefile.in", get_gnumakefile_in_patch_p1(ruby_ver))
165
- # ....................................................
166
- # RUBY_EXPORT=1 (shall be set for static builds but is missing in openssl extension)
167
- patch_map.store("ext/openssl/extconf.rb", OPENSSL_EXTCONF_RB_PATCH)
168
- end
169
-
170
- patch_map
171
- end
172
-
173
- private
174
-
175
- include Tebako::Packager::PatchLiterals
176
- include Tebako::Packager::PatchBuildsystem
177
-
178
- def get_gnumakefile_in_patch_p1(ruby_ver) # rubocop:disable Metrics/MethodLength
179
- objext = ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
180
- {
181
- " DLLWRAP += -mno-cygwin" =>
182
- "# tebako patched DLLWRAP += -mno-cygwin",
183
-
184
- "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
185
- "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",
186
-
187
- "$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>
188
- "$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ # tebako patched",
189
-
190
- "--output-exp=$(RUBY_EXP) \\" =>
191
- "--output-exp=$(RUBY_EXP) --output-lib=$(LIBRUBY) --output-def=tebako.def \\",
192
-
193
- "--export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)" =>
194
- "--export-all $(LIBRUBY_A) $(LIBS) -o program-stub.exe # tebako patched",
195
-
196
- "@rm -f $(PROGRAM)" =>
197
- "@rm -f program-stub.exe # tebako patched",
198
-
199
- " $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)" =>
200
- "# tebako patched $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)",
201
-
202
- "RUBYDEF = $(DLL_BASE_NAME).def" => GNUMAKEFILE_IN_WINMAIN_SUBST
203
- }
204
- end
205
-
206
- def rubygems_path_support_patch_one(mount_point)
207
- <<~SUBST
208
- @home = env["GEM_HOME"] || Gem.default_dir
209
- # -- Start of tebako patch --
210
- unless env["TEBAKO_PASS_THROUGH"]
211
- @home = Gem.default_dir unless @home.index("#{mount_point}") == 0
212
- end
213
- # -- End of tebako patch --
214
-
215
- SUBST
216
- end
217
-
218
- def rubygems_path_support_patch_two(mount_point)
219
- <<~SUBST
220
-
221
- @path = split_gem_path env["GEM_PATH"], @home
222
- # -- Start of tebako patch --
223
- unless env["TEBAKO_PASS_THROUGH"]
224
- @path.keep_if do |xpath|
225
- xpath.index("#{mount_point}") == 0
226
- end
227
- end
228
- # -- End of tebako patch --
229
-
230
- SUBST
231
- end
232
-
233
- def rubygems_path_support_patch(mount_point)
234
- {
235
- ' @home = env["GEM_HOME"] || Gem.default_dir' => rubygems_path_support_patch_one(mount_point),
236
- ' @path = split_gem_path env["GEM_PATH"], @home' => rubygems_path_support_patch_two(mount_point)
237
- }
238
- end
239
- end
240
- end
241
- end
242
- end