Skip to content

Commit

Permalink
tests: refactor packager tests pass1/pass1a
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Jan 3, 2025
1 parent 12f019f commit 007d54c
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 126 deletions.
5 changes: 3 additions & 2 deletions lib/tebako/packager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
require_relative "deploy_helper"
require_relative "ruby_builder"
require_relative "stripper"
require_relative "packager/pass1"
require_relative "packager/pass1_patch"
require_relative "packager/pass1a_patch"
require_relative "packager/pass2"
require_relative "packager/patch_helpers"
Expand Down Expand Up @@ -119,7 +119,8 @@ def pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver)
puts "-- Running pass1 script"

PatchHelpers.recreate(src_dir)
do_patch(Pass1.get_patch_map(ostype, mount_point, ruby_ver), ruby_source_dir)
patch = crt_pass1_patch(ostype, mount_point, ruby_ver)
do_patch(patch.patch_map, ruby_source_dir)

# Roll back pass1a, pass2 patches
# Just in case we are recovering after some error
Expand Down
272 changes: 155 additions & 117 deletions lib/tebako/packager/pass1.rb → lib/tebako/packager/pass1_patch.rb
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) 2021-2024 [Ribose Inc](https://www.ribose.com).
# Copyright (c) 2021-2025 [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
Expand All @@ -25,15 +25,28 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

require_relative "patch_literals"
require_relative "patch_helpers"
require_relative "patch_buildsystem"

require_relative "patch"
# Tebako - an executable packager
module Tebako
# Packager module
module Packager
# Ruby patching definitions (pass1)
module Pass1
class << self
def crt_pass1_patch(os_type, mount_point, ruby_ver)
case os_type
when /darwin/
Pass1DarwinPatch.new(mount_point, ruby_ver)
when /msys/
Pass1MSysPatch.new(mount_point, ruby_ver)
else
Pass1Patch.new(mount_point, ruby_ver)
end
end
end
# Ruby patching definitions (pass1 - common)
class Pass1Patch < Patch
# [TODO] looks like it does not exist in 3.1.4
# May be obsolete
TOOL_RBINSTALL_RB_PATCH = {
Expand Down Expand Up @@ -106,10 +119,6 @@ module Pass1
# # program to bind symbols from the ruby executable
# EXTDLDFLAGS="-bundle_loader '\$(BUILTRUBY)'"

DARWIN_CONFIGURE_PATCH = {
"elif test \"x$EXTSTATIC\" = x" => "elif true"
}.freeze

OPENSSL_EXTCONF_RB_SUBST = <<~SUBST
# Start of tebako patch
$defs.push("-DRUBY_EXPORT=1")
Expand All @@ -122,141 +131,170 @@ module Pass1
"Logging::message \"=== Checking done. ===\\n\"" => OPENSSL_EXTCONF_RB_SUBST
}.freeze

INCLUDE_RUBY_ONIGMO_H_PATCH = {
"# define ONIG_EXTERN RUBY_EXTERN" => "# define ONIG_EXTERN extern"
}.freeze

WIN32_WINMAIN_C_PATCH = {
"WinMain(HINSTANCE current, HINSTANCE prev, LPSTR cmdline, int showcmd)" =>
"wWinMain(HINSTANCE current, HINSTANCE prev, LPWSTR cmdline, int showcmd)"
}.freeze

class << self
def get_base_patch_map(mount_point)
{
# ....................................................
# It won't install gems with no files defined in spec
# However if
# -- we are installing a default gem from extension
# -- extension is build statically
# there may be no files install in addition to spec
# Example: io/wait extension (and others)
# [TODO] Check if it is still required
# No match and patching on Ruby 3.1.4 but works wo issues
"tool/rbinstall.rb" => TOOL_RBINSTALL_RB_PATCH,

# ....................................................
# Allow only packaged gems (from within memfs)
"lib/rubygems/path_support.rb" => rubygems_path_support_patch(mount_point),

# ....................................................
# Disable dynamic extensions
"ext/Setup" => EXT_SETUP_PATCH
}
end

def get_patch_map(ostype, mount_point, ruby_ver)
patch_map = get_base_patch_map(mount_point)
def initialize(mountpoint, ruby_ver)
super()
@mountpoint = mountpoint
@ruby_ver = ruby_ver
end

def base_patch_map
{
# ....................................................
patch_map.store("ext/bigdecimal/bigdecimal.h", EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH) unless ruby_ver.ruby34?
# It won't install gems with no files defined in spec
# However if
# -- we are installing a default gem from extension
# -- extension is build statically
# there may be no files install in addition to spec
# Example: io/wait extension (and others)
# [TODO] Check if it is still required
# No match and patching on Ruby 3.1.4 but works wo issues
"tool/rbinstall.rb" => TOOL_RBINSTALL_RB_PATCH,

Check warning on line 151 in lib/tebako/packager/pass1_patch.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/packager/pass1_patch.rb#L151

Added line #L151 was not covered by tests

# ....................................................
patch_map.store("configure", DARWIN_CONFIGURE_PATCH) if ostype =~ /darwin/
# Allow only packaged gems (from within memfs)
"lib/rubygems/path_support.rb" => rubygems_path_support_patch,

# ....................................................
# autoload :OpenSSL, "openssl"
# fails to deal with a default gem from statically linked extension
patch_map.store("lib/rubygems/openssl.rb", RUBYGEM_OPENSSL_RB_PATCH) if ruby_ver.ruby3x?
# Disable dynamic extensions
"ext/Setup" => EXT_SETUP_PATCH
}
end

patch_map.merge!(get_msys_patches(ruby_ver)) if ostype =~ /msys/
def patch_map
pm = base_patch_map
pm.merge!(super)

patch_map
end
# ....................................................
pm.store("ext/bigdecimal/bigdecimal.h", EXT_BIGDECIMAL_BIGDECIMAL_H_PATCH) unless @ruby_ver.ruby34?

private
# ....................................................
# autoload :OpenSSL, "openssl"
# fails to deal with a default gem from statically linked extension
pm.store("lib/rubygems/openssl.rb", RUBYGEM_OPENSSL_RB_PATCH) if @ruby_ver.ruby3x?

# include Tebako::Packager::PatchLiterals
include Tebako::Packager::PatchBuildsystem
pm.freeze
end

def get_gnumakefile_in_patch_p1(ruby_ver) # rubocop:disable Metrics/MethodLength
objext = ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
{
" DLLWRAP += -mno-cygwin" =>
"# tebako patched DLLWRAP += -mno-cygwin",
private

"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",
def rubygems_path_support_patch_one
<<~SUBST

Check warning on line 181 in lib/tebako/packager/pass1_patch.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/packager/pass1_patch.rb#L181

Added line #L181 was not covered by tests
@home = env["GEM_HOME"] || Gem.default_dir
# -- Start of tebako patch --
unless env["TEBAKO_PASS_THROUGH"]
@home = Gem.default_dir unless @home.index("#{@mount_point}") == 0
end
# -- End of tebako patch --
"$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>
"$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ # tebako patched",
SUBST
end

"--output-exp=$(RUBY_EXP) \\" =>
"--output-exp=$(RUBY_EXP) --output-lib=$(LIBRUBY) --output-def=tebako.def \\",
def rubygems_path_support_patch_two
<<~SUBST

Check warning on line 193 in lib/tebako/packager/pass1_patch.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/packager/pass1_patch.rb#L193

Added line #L193 was not covered by tests
"--export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)" =>
"--export-all $(LIBRUBY_A) $(LIBS) -o program-stub.exe # tebako patched",
@path = split_gem_path env["GEM_PATH"], @home
# -- Start of tebako patch --
unless env["TEBAKO_PASS_THROUGH"]
@path.keep_if do |xpath|
xpath.index("#{@mount_point}") == 0
end
end
# -- End of tebako patch --
"@rm -f $(PROGRAM)" =>
"@rm -f program-stub.exe # tebako patched",
SUBST
end

" $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)" =>
"# tebako patched $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)",
def rubygems_path_support_patch
{
' @home = env["GEM_HOME"] || Gem.default_dir' => rubygems_path_support_patch_one,

Check warning on line 209 in lib/tebako/packager/pass1_patch.rb

View check run for this annotation

Codecov / codecov/patch

lib/tebako/packager/pass1_patch.rb#L209

Added line #L209 was not covered by tests
' @path = split_gem_path env["GEM_PATH"], @home' => rubygems_path_support_patch_two
}
end
end

"RUBYDEF = $(DLL_BASE_NAME).def" => GNUMAKEFILE_IN_WINMAIN_SUBST
}
end
# Ruby patching definitions (pass1 - darwin)
class Pass1DarwinPatch < Pass1Patch
DARWIN_CONFIGURE_PATCH = {
"elif test \"x$EXTSTATIC\" = x" => "elif true"
}.freeze

def get_msys_patches(ruby_ver)
patch_map = {
# ....................................................
# Generate export definitions; use WinMain to build rubyw.exe
"cygwin/GNUmakefile.in" => get_gnumakefile_in_patch_p1(ruby_ver),
# ....................................................
# RUBY_EXPORT=1 (shall be set for static builds but is missing in openssl extension)
"ext/openssl/extconf.rb" => OPENSSL_EXTCONF_RB_PATCH
}
# ....................................................
# RUBY_EXTERN shall be extern for static build but is set to __declspec(dllimport) for encodin libarary
patch_map.store("include/ruby/onigmo.h", INCLUDE_RUBY_ONIGMO_H_PATCH) if ruby_ver.ruby34?
# ....................................................
patch_map.store("win32/winmain.c", WIN32_WINMAIN_C_PATCH) if ruby_ver.ruby34?
patch_map
end
def patch_map
pm = { "configure" => DARWIN_CONFIGURE_PATCH }
pm.merge!(super)
pm.freeze
end
end

def rubygems_path_support_patch_one(mount_point)
<<~SUBST
@home = env["GEM_HOME"] || Gem.default_dir
# -- Start of tebako patch --
unless env["TEBAKO_PASS_THROUGH"]
@home = Gem.default_dir unless @home.index("#{mount_point}") == 0
end
# -- End of tebako patch --
# Ruby patching definitions (pass1 - Windows)
class Pass1MSysPatch < Pass1Patch
INCLUDE_RUBY_ONIGMO_H_PATCH = {
"# define ONIG_EXTERN RUBY_EXTERN" => "# define ONIG_EXTERN extern"
}.freeze

SUBST
end
WIN32_WINMAIN_C_PATCH = {
"WinMain(HINSTANCE current, HINSTANCE prev, LPSTR cmdline, int showcmd)" =>
"wWinMain(HINSTANCE current, HINSTANCE prev, LPWSTR cmdline, int showcmd)"
}.freeze

def rubygems_path_support_patch_two(mount_point)
<<~SUBST
def patch_map
pm = msys_patches
pm.merge!(super)
pm.freeze
end

@path = split_gem_path env["GEM_PATH"], @home
# -- Start of tebako patch --
unless env["TEBAKO_PASS_THROUGH"]
@path.keep_if do |xpath|
xpath.index("#{mount_point}") == 0
end
end
# -- End of tebako patch --
private

SUBST
end
include Tebako::Packager::PatchBuildsystem

def rubygems_path_support_patch(mount_point)
{
' @home = env["GEM_HOME"] || Gem.default_dir' => rubygems_path_support_patch_one(mount_point),
' @path = split_gem_path env["GEM_PATH"], @home' => rubygems_path_support_patch_two(mount_point)
}
def gnumakefile_in_patch_p1 # rubocop:disable Metrics/MethodLength
objext = @ruby_ver.ruby32? ? "$(OBJEXT)" : "@OBJEXT@"
{
" DLLWRAP += -mno-cygwin" =>
"# tebako patched DLLWRAP += -mno-cygwin",

"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
"$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",

"$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>
"$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ # tebako patched",

"--output-exp=$(RUBY_EXP) \\" =>
"--output-exp=$(RUBY_EXP) --output-lib=$(LIBRUBY) --output-def=tebako.def \\",

"--export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)" =>
"--export-all $(LIBRUBY_A) $(LIBS) -o program-stub.exe # tebako patched",

"@rm -f $(PROGRAM)" =>
"@rm -f program-stub.exe # tebako patched",

" $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)" =>
"# tebako patched $(Q) $(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)",

"RUBYDEF = $(DLL_BASE_NAME).def" => GNUMAKEFILE_IN_WINMAIN_SUBST
}
end

def msys_base_patches
{
# ....................................................
# Generate export definitions; use WinMain to build rubyw.exe
"cygwin/GNUmakefile.in" => gnumakefile_in_patch_p1,
# ....................................................
# RUBY_EXPORT=1 (shall be set for static builds but is missing in openssl extension)
"ext/openssl/extconf.rb" => OPENSSL_EXTCONF_RB_PATCH
}
end

def msys_patches
pm = msys_base_patches

if @ruby_ver.ruby34?
# ....................................................
# RUBY_EXTERN shall be extern for static build but is set to __declspec(dllimport) for encodin libarary
pm.store("include/ruby/onigmo.h", INCLUDE_RUBY_ONIGMO_H_PATCH)
pm.store("win32/winmain.c", WIN32_WINMAIN_C_PATCH)
end
pm
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/tebako/packager/pass1a_patch.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
# Copyright (c) 2024-2025 [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
Expand Down
2 changes: 1 addition & 1 deletion lib/tebako/packager/patch.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
# Copyright (c) 2025 [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
Expand Down
2 changes: 1 addition & 1 deletion lib/tebako/packager/patch_literals.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
# Copyright (c) 2023-2025 [Ribose Inc](https://www.ribose.com).
# All rights reserved.
# This file is a part of tebako
#
Expand Down
Loading

0 comments on commit 007d54c

Please sign in to comment.