Module: Tebako::Packager
- Defined in:
- lib/tebako/packager.rb,
lib/tebako/packager/patch.rb,
lib/tebako/packager/patch_main.rb,
lib/tebako/packager/pass1_patch.rb,
lib/tebako/packager/pass2_patch.rb,
lib/tebako/packager/pass1a_patch.rb,
lib/tebako/packager/patch_helpers.rb,
lib/tebako/packager/patch_literals.rb,
lib/tebako/packager/rubygems_patch.rb,
lib/tebako/packager/pass2_patch_crt.rb,
lib/tebako/packager/pass2msys_patch.rb,
lib/tebako/packager/patch_libraries.rb,
lib/tebako/packager/patch_buildsystem.rb
Overview
Packager module
Defined Under Namespace
Modules: PatchBuildsystem, PatchHelpers, PatchLibraries, PatchLiterals, PatchMain Classes: Pass1APatch, Pass1DarwinPatch, Pass1MSysPatch, Pass1Patch, Pass2MSysPatch, Pass2NonMSysPatch, Pass2Patch, Patch, RubygemsPatch, RubygemsUpdatePatch
Constant Summary collapse
- FILES_TO_RESTORE =
%w[ common.mk configure config.status dir.c dln.c file.c gem_prelude.rb io.c main.c Makefile ruby.c thread_pthread.c util.c ext/bigdecimal/bigdecimal.h ext/Setup cygwin/GNUmakefile.in include/ruby/onigmo.h lib/rubygems/openssl.rb lib/rubygems/path_support.rb template/Makefile.in tool/mkconfig.rb win32/winmain.c win32/file.c ].freeze
- GNUMAKEFILE_IN_DLLTOOL_SUBST =
Substitutions for cygwin/Gnumakefile.in shared across Pass1 and Pass2
<<~SUBST $(Q) dlltool --output-lib=$(LIBRUBY) --output-def=tebako.def --export-all $(LIBRUBY_A) --output-exp=$(RUBY_EXP) # tebako patched SUBST
- GNUMAKEFILE_IN_WINMAIN_SUBST =
This MSYS specific thing ensure compilation of winmain.c Did try to understand why it did not work out of the box
<<~SUBST RUBYDEF = $(DLL_BASE_NAME).def # Start of tebako patch WINMAINOBJ = win32/winmain.$(OBJEXT) $(WINMAINOBJ): win32/winmain.c # End of tebako patch SUBST
- IO_C_MSYS_BASE_PATCH =
{ "#define open rb_w32_uopen" => "#define open(p, f, m) tebako_open(3, (p), (f), (m))" }.freeze
- IO_C_MSYS_PATCH_PRE_32 =
{ "(rb_w32_io_cancelable_p((fptr)->fd) ? Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil))" => "((is_tebako_file_descriptor((fptr)->fd) || rb_w32_io_cancelable_p((fptr)->fd)) ? \\\n" \ "Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil))" }.freeze
- IO_C_MSYS_PATCH =
{ "(rb_w32_io_cancelable_p((fptr)->fd) ? Qnil : rb_io_wait(fptr->self, " \ "RB_INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT))" => "((is_tebako_file_descriptor((fptr)->fd) || rb_w32_io_cancelable_p((fptr)->fd)) ? \\\n" \ "Qnil : rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT))" }.freeze
- RUBY_C_MSYS_PATH_SUBST =
<<~SUBST /* -- Start of tebako patch -- */ VALUE path = within_tebako_memfs(paths) ? rb_str_new_cstr(paths) : RUBY_RELATIVE(paths, len); /* -- End of tebako patch -- */ SUBST
- RUBY_C_MSYS_PATCHES =
{ "#ifndef MAXPATHLEN" => "#{PatchLiterals::C_FILE_SUBST_LESS}\n#ifndef MAXPATHLEN", "VALUE path = RUBY_RELATIVE(paths, len);" => RUBY_C_MSYS_PATH_SUBST }.freeze
- WIN32_FILE_C_MSYS_SUBST =
<<~SUBST /* -- Start of tebako patch -- */ if (tebako_file_load_ok(path)) return ret; /* -- End of tebako patch -- */ wpath = mbstr_to_wstr(CP_UTF8, path, -1, &len); SUBST
- WIN32_FILE_C_MSYS_PATCHES =
{ "#ifndef INVALID_FILE_ATTRIBUTES" => "#{PatchLiterals::C_FILE_SUBST_LESS}\n#ifndef INVALID_FILE_ATTRIBUTES", "wpath = mbstr_to_wstr(CP_UTF8, path, -1, &len);" => WIN32_FILE_C_MSYS_SUBST }.freeze
- WIN32_WIN32_C_MSYS_SUBST =
<<~SUBST /* -- Start of tebako patch -- */ if (is_tebako_cwd()) { char* tebako_cwd = tebako_getcwd(NULL,0); if (tebako_cwd == NULL) { errno = ENOMEM; return NULL; } len = strlen(tebako_cwd) + 1; if (buffer) { if (size < len) { free(tebako_cwd); errno = ERANGE; return NULL; } } else { buffer = (*alloc)(len, arg); if (!buffer) { free(tebako_cwd); errno = ENOMEM; return NULL; } } translate_char(tebako_cwd, (char)0x5c, '/', CP_UTF8); strcpy(buffer, tebako_cwd); free(tebako_cwd); return buffer; } /* -- End of tebako patch -- */ len = GetCurrentDirectoryW(0, NULL); SUBST
- WIN32_WIN32_C_MSYS_PATCHES =
{ "#if defined _MSC_VER && _MSC_VER <= 1200" => "#{PatchLiterals::C_FILE_SUBST_LESS}\n#if defined _MSC_VER && _MSC_VER <= 1200", "len = GetCurrentDirectoryW(0, NULL);" => WIN32_WIN32_C_MSYS_SUBST, "clock_gettime(clockid_t clock_id, struct timespec *sp)" => "_dummy_clock_gettime(clockid_t clock_id, struct timespec *sp)", "clock_getres(clockid_t clock_id, struct timespec *sp)" => "_dummy_clock_getres(clockid_t clock_id, struct timespec *sp)" }.freeze
Class Method Summary collapse
-
.create_implib(src_dir, package_src_dir, app_name, ruby_ver) ⇒ Object
Create implib.
- .crt_pass1_patch(ostype, mount_point, ruby_ver) ⇒ Object
- .crt_pass2_patch(ostype, deps_lib_dir, ruby_ver) ⇒ Object
-
.deploy(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, cwd, bundle_cache_dir = nil, native_gem_cache_dir = nil, install_runtime: true, tool_bin_dir: nil) ⇒ Object
Deploy.
-
.deploy_runtime(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance) ⇒ Object
rubocop:enable Metrics/ParameterLists.
- .do_patch(patch_map, root) ⇒ Object
- .finalize(src_dir, app_name, ruby_ver, patchelf, output_type) ⇒ Object
-
.init(stash_dir, src_dir, pre_dir, bin_dir, preserve_bin: false) ⇒ Object
Init.
- .init_application(src_dir, pre_dir, bin_dir) ⇒ Object
-
.mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil, compression_level = 5, cache_dir = nil) ⇒ Object
rubocop:disable Metrics/ParameterLists.
-
.pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) ⇒ Object
Pass1 Executed before Ruby build, patching ensures that Ruby itself is linked statically.
-
.pass1a(ruby_source_dir) ⇒ Object
Pass1A Patch gem_prelude.rb.
-
.pass2(ostype, ruby_source_dir, deps_lib_dir, ruby_ver) ⇒ Object
Pass2 Creates packaging environment, patching ensures that tebako package is linked statically.
-
.stash(src_dir, stash_dir, ruby_source_dir, ruby_ver) ⇒ Object
Stash Created and saves pristine Ruby environment that is used to deploy applications for packaging.
Class Method Details
.create_implib(src_dir, package_src_dir, app_name, ruby_ver) ⇒ Object
Create implib
74 75 76 77 78 79 80 81 |
# File 'lib/tebako/packager.rb', line 74 def create_implib(src_dir, package_src_dir, app_name, ruby_ver) a_name = File.basename(app_name, ".*") create_def(src_dir, a_name) puts " ... creating Windows import library" params = ["dlltool", "-d", def_fname(src_dir, a_name), "-D", out_fname(a_name), "--output-lib", lib_fname(package_src_dir, ruby_ver)] BuildHelpers.run_with_capture(params) end |
.crt_pass1_patch(ostype, mount_point, ruby_ver) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/tebako/packager/pass1_patch.rb', line 38 def crt_pass1_patch(ostype, mount_point, ruby_ver) scmb = ScenarioManagerBase.new(ostype) if scmb.macos? Pass1DarwinPatch.new(mount_point, ruby_ver) elsif scmb.msys? Pass1MSysPatch.new(mount_point, ruby_ver) else Pass1Patch.new(mount_point, ruby_ver) end end |
.crt_pass2_patch(ostype, deps_lib_dir, ruby_ver) ⇒ Object
36 37 38 39 40 41 42 43 |
# File 'lib/tebako/packager/pass2_patch_crt.rb', line 36 def crt_pass2_patch(ostype, deps_lib_dir, ruby_ver) scmb = ScenarioManagerBase.new(ostype) if scmb.msys? Pass2MSysPatch.new(ostype, deps_lib_dir, ruby_ver) else Pass2NonMSysPatch.new(ostype, deps_lib_dir, ruby_ver) end end |
.deploy(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, cwd, bundle_cache_dir = nil, native_gem_cache_dir = nil, install_runtime: true, tool_bin_dir: nil) ⇒ Object
Deploy
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/tebako/packager.rb', line 84 def deploy(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, cwd, # rubocop:disable Metrics/ParameterLists bundle_cache_dir = nil, native_gem_cache_dir = nil, install_runtime: true, tool_bin_dir: nil) puts "-- Running deploy script" arguments = [fs_root, fs_entrance, target_dir, pre_dir, bundle_cache_dir, native_gem_cache_dir] deploy_helper = if tool_bin_dir Tebako::DeployHelper.new(*arguments, tool_bin_dir: tool_bin_dir) else Tebako::DeployHelper.new(*arguments) end deploy_helper.configure(ruby_ver, cwd) install_runtime ? deploy_helper.deploy : deploy_helper.deploy(install_runtime: false) Tebako::Stripper.strip(deploy_helper, target_dir) end |
.deploy_runtime(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance) ⇒ Object
rubocop:enable Metrics/ParameterLists
102 103 104 105 106 107 108 |
# File 'lib/tebako/packager.rb', line 102 def deploy_runtime(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance) puts "-- Preparing reusable runtime deployment" deploy_helper = Tebako::DeployHelper.new(fs_root, fs_entrance, target_dir, pre_dir) deploy_helper.configure(ruby_ver, nil) deploy_helper.deploy_runtime Tebako::Stripper.strip(deploy_helper, target_dir) end |
.do_patch(patch_map, root) ⇒ Object
110 111 112 |
# File 'lib/tebako/packager.rb', line 110 def do_patch(patch_map, root) patch_map.each { |fname, mapping| PatchHelpers.patch_file("#{root}/#{fname}", mapping) } end |
.finalize(src_dir, app_name, ruby_ver, patchelf, output_type) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/tebako/packager.rb', line 114 def finalize(src_dir, app_name, ruby_ver, patchelf, output_type) puts "-- Running finalize script" RubyBuilder.new(ruby_ver, src_dir).target_build(output_type) exe_suffix = ScenarioManagerBase.new.exe_suffix src_name = File.join(src_dir, "ruby#{exe_suffix}") patchelf(src_name, patchelf) package_name = "#{app_name}#{exe_suffix}" # strip_or_copy(os_type, src_name, package_name) Tebako::Stripper.strip_file(src_name, package_name) puts "Created tebako #{output_type} at \"#{package_name}\"" end |
.init(stash_dir, src_dir, pre_dir, bin_dir, preserve_bin: false) ⇒ Object
Init
128 129 130 131 132 133 |
# File 'lib/tebako/packager.rb', line 128 def init(stash_dir, src_dir, pre_dir, bin_dir, preserve_bin: false) puts "-- Running init script", " ... creating packaging environment at #{src_dir}" PatchHelpers.recreate([src_dir, pre_dir]) preserve_bin ? FileUtils.mkdir_p(bin_dir) : PatchHelpers.recreate(bin_dir) FileUtils.cp_r "#{stash_dir}/.", src_dir end |
.init_application(src_dir, pre_dir, bin_dir) ⇒ Object
135 136 137 138 139 |
# File 'lib/tebako/packager.rb', line 135 def init_application(src_dir, pre_dir, bin_dir) puts "-- Preparing application-only packaging environment" PatchHelpers.recreate([src_dir, pre_dir]) FileUtils.mkdir_p(bin_dir) end |
.mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil, compression_level = 5, cache_dir = nil) ⇒ Object
rubocop:disable Metrics/ParameterLists
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/tebako/packager.rb', line 141 def mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil, # rubocop:disable Metrics/ParameterLists compression_level = 5, cache_dir = nil) # rubocop:enable Metrics/ParameterLists puts "-- Running mkdwarfs script" mkdwarfs = File.join(deps_bin_dir, "mkdwarfs") FileUtils.chmod("a+x", Dir.glob(File.join(deps_bin_dir, "mkdwarfs*"))) return run_mkdwarfs(mkdwarfs, data_bin_file, data_src_dir, descriptor, compression_level) unless cache_dir cache = Tebako::FilesystemCache.new(cache_dir: cache_dir, mkdwarfs: mkdwarfs, source_dir: data_src_dir, descriptor: descriptor, compression_level: compression_level) cache.fetch(data_bin_file) do run_mkdwarfs(mkdwarfs, data_bin_file, data_src_dir, descriptor, compression_level) end end |
.pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) ⇒ Object
Pass1 Executed before Ruby build, patching ensures that Ruby itself is linked statically
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/tebako/packager.rb', line 157 def pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) puts "-- Running pass1 script" PatchHelpers.recreate(src_dir) # Roll all known patches # Just in case we are recovering after some error PatchHelpers.restore_and_save_files(FILES_TO_RESTORE, ruby_source_dir, strict: false) patch = crt_pass1_patch(ostype, mount_point, ruby_ver) do_patch(patch.patch_map, ruby_source_dir) end |
.pass1a(ruby_source_dir) ⇒ Object
Pass1A Patch gem_prelude.rb
171 172 173 174 175 |
# File 'lib/tebako/packager.rb', line 171 def pass1a(ruby_source_dir) puts "-- Running pass1a script" patch = Pass1APatch.new do_patch(patch.patch_map, ruby_source_dir) end |
.pass2(ostype, ruby_source_dir, deps_lib_dir, ruby_ver) ⇒ Object
Pass2 Creates packaging environment, patching ensures that tebako package is linked statically
179 180 181 182 183 184 |
# File 'lib/tebako/packager.rb', line 179 def pass2(ostype, ruby_source_dir, deps_lib_dir, ruby_ver) puts "-- Running pass2 script" patch = crt_pass2_patch(ostype, deps_lib_dir, ruby_ver) do_patch(patch.patch_map, ruby_source_dir) end |
.stash(src_dir, stash_dir, ruby_source_dir, ruby_ver) ⇒ Object
Stash Created and saves pristine Ruby environment that is used to deploy applications for packaging
188 189 190 191 192 193 194 195 |
# File 'lib/tebako/packager.rb', line 188 def stash(src_dir, stash_dir, ruby_source_dir, ruby_ver) puts "-- Running stash script" RubyBuilder.new(ruby_ver, ruby_source_dir).toolchain_build puts " ... saving pristine Ruby environment to #{stash_dir}" PatchHelpers.recreate(stash_dir) FileUtils.cp_r "#{src_dir}/.", stash_dir end |