tebako 0.14.0 → 0.15.0
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 +4 -4
- data/Brewfile +0 -5
- data/CMakeLists.txt +94 -46
- data/cmake/tebako-libtfs.cmake +456 -0
- data/common.env +1 -1
- data/include/tebako/tpkg.h +575 -0
- data/lib/tebako/cli.rb +91 -0
- data/lib/tebako/cli_helpers.rb +24 -0
- data/lib/tebako/error.rb +10 -0
- data/lib/tebako/launcher_abi.rb +99 -0
- data/lib/tebako/options_manager.rb +71 -0
- data/lib/tebako/packager/patch_libraries.rb +47 -27
- data/lib/tebako/packager.rb +40 -1
- data/lib/tebako/runtime_manager.rb +347 -0
- data/lib/tebako/stitcher.rb +255 -0
- data/lib/tebako/version.rb +1 -1
- data/src/tebako-main.cpp +577 -9
- data/tools/.github/workflows/test.yml +6 -6
- data/tools/cmake-scripts/macos-environment.cmake +11 -2
- metadata +7 -4
- data/tools/ci-scripts/patch-fbthrift.sh +0 -94
- data/tools/ci-scripts/patch-folly.sh +0 -551
data/lib/tebako/cli_helpers.rb
CHANGED
|
@@ -33,7 +33,9 @@ require "rbconfig"
|
|
|
33
33
|
require_relative "codegen"
|
|
34
34
|
require_relative "error"
|
|
35
35
|
require_relative "options_manager"
|
|
36
|
+
require_relative "runtime_manager"
|
|
36
37
|
require_relative "scenario_manager"
|
|
38
|
+
require_relative "stitcher"
|
|
37
39
|
require_relative "packager_lite"
|
|
38
40
|
|
|
39
41
|
# Tebako - an executable packager
|
|
@@ -85,10 +87,32 @@ module Tebako
|
|
|
85
87
|
check_warnings(options_manager)
|
|
86
88
|
puts options_manager.press_announce(scenario_manager.msys?)
|
|
87
89
|
|
|
90
|
+
if options_manager.prebuilt_runtime?
|
|
91
|
+
do_press_prebuilt(options_manager, scenario_manager)
|
|
92
|
+
else
|
|
93
|
+
do_press_source(options_manager, scenario_manager)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def do_press_source(options_manager, scenario_manager)
|
|
88
98
|
do_press_runtime(options_manager, scenario_manager)
|
|
89
99
|
do_press_application(options_manager, scenario_manager)
|
|
90
100
|
end
|
|
91
101
|
|
|
102
|
+
# Press onto a prebuilt runtime package: resolve (download/verify/cache)
|
|
103
|
+
# the runtime, deploy the application image, stitch, re-sign on macOS.
|
|
104
|
+
def do_press_prebuilt(options_manager, scenario_manager)
|
|
105
|
+
Tebako::Packager.check_prebuilt_env!(options_manager.stash_dir, options_manager.deps_bin_dir)
|
|
106
|
+
runtime_path = Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
107
|
+
app_image = Tebako::Packager.build_app_image(options_manager, scenario_manager)
|
|
108
|
+
|
|
109
|
+
images = [{ path: app_image, mount_point: scenario_manager.fs_mount_point,
|
|
110
|
+
format_id: Tebako::Stitcher::FORMAT_DWARFS }] + options_manager.images
|
|
111
|
+
package = "#{options_manager.package}#{scenario_manager.exe_suffix}"
|
|
112
|
+
Tebako::Stitcher.stitch(runtime_path, images: images, output: package)
|
|
113
|
+
puts "Created tebako #{options_manager.output_type_first} at \"#{package}\""
|
|
114
|
+
end
|
|
115
|
+
|
|
92
116
|
def do_press_application(options_manager, scenario_manager)
|
|
93
117
|
return unless %w[both application].include?(options_manager.mode)
|
|
94
118
|
|
data/lib/tebako/error.rb
CHANGED
|
@@ -47,6 +47,16 @@ module Tebako
|
|
|
47
47
|
117 => "Failed to load Gemfile.lock",
|
|
48
48
|
118 => "Bundler version in Gemfile.lock does satisfy minimal Tebako version requirememnts",
|
|
49
49
|
119 => "Failed to find compatible bundler version",
|
|
50
|
+
120 => "No prebuilt tebako runtime package for the requested Ruby/platform combination",
|
|
51
|
+
121 => "SHA256 checksum mismatch for downloaded tebako runtime package",
|
|
52
|
+
122 => "Failed to download tebako runtime package",
|
|
53
|
+
123 => "TEBAKO_OFFLINE is set and the requested tebako runtime package is not cached",
|
|
54
|
+
124 => "Runtime package release carries no usable package index",
|
|
55
|
+
125 => "Timed out waiting for the runtime package cache lock",
|
|
56
|
+
126 => "Invalid stitch specification",
|
|
57
|
+
127 => "Stitch input file is not accessible",
|
|
58
|
+
128 => "Prebuilt runtime press requires the packaging environment (run 'tebako setup' first)",
|
|
59
|
+
130 => "Option combination is not supported",
|
|
50
60
|
201 => "Warning. Could not create cache version file"
|
|
51
61
|
}.freeze
|
|
52
62
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2026 [Ribose Inc](https://www.ribose.com).
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
# This file is a part of the Tebako project.
|
|
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
|
+
module Tebako
|
|
29
|
+
# Launcher ABI v1 — the bootstrap → runtime handoff contract of the
|
|
30
|
+
# three-part package model (spec §4.4).
|
|
31
|
+
#
|
|
32
|
+
# A lean package is [tebako-bootstrap][.tfs image slots][tpkg trailer].
|
|
33
|
+
# The bootstrap (tamatebako/tebako-bootstrap) parses the trailer of its own
|
|
34
|
+
# executable, resolves the language runtime into the shared cache, and
|
|
35
|
+
# execs it as:
|
|
36
|
+
#
|
|
37
|
+
# <runtime> --tebako-image <file>:<slot>:<mount-point> ...
|
|
38
|
+
# --tebako-entry <argv0> <user args...>
|
|
39
|
+
#
|
|
40
|
+
# The runtime (a tebako-packaged interpreter built from this repo) consumes
|
|
41
|
+
# that handoff in src/tebako-main.cpp:
|
|
42
|
+
#
|
|
43
|
+
# --tebako-image <file>:<slot>:<mount-point>
|
|
44
|
+
# Repeatable, one per image slot, in slot order. <file> is a package
|
|
45
|
+
# file carrying a tpkg manifest trailer (spec §4.3); <slot> is the
|
|
46
|
+
# 0-based index into that file's slot table; <mount-point> is the
|
|
47
|
+
# memfs path the image is mounted at. The runtime reads the trailer
|
|
48
|
+
# of <file>, takes the slot's recorded offset/size, and mounts the
|
|
49
|
+
# image directly out of <file> — no extraction, no temp copies.
|
|
50
|
+
# The image whose mount point equals the runtime's compiled-in
|
|
51
|
+
# fs_mount_point becomes the root filesystem (fallback: the first
|
|
52
|
+
# image given); the remaining images are mounted as extra slots.
|
|
53
|
+
#
|
|
54
|
+
# --tebako-entry <argv0>
|
|
55
|
+
# Not repeatable. <argv0> is the lean package's original argv[0] (a
|
|
56
|
+
# host path as invoked by the user — not a path inside the memfs);
|
|
57
|
+
# the runtime presents it as the application program name. Every
|
|
58
|
+
# argument after <argv0> is application argv and is passed through
|
|
59
|
+
# to the interpreter untouched; tebako option scanning stops here.
|
|
60
|
+
# The runtime then runs its compiled-in entry point (for prebuilt
|
|
61
|
+
# runtimes, the /local/stub.rb dispatcher inside the root image).
|
|
62
|
+
#
|
|
63
|
+
# --tebako-launcher-abi <n>
|
|
64
|
+
# Not repeatable, optional. States the launcher ABI version the
|
|
65
|
+
# bootstrap speaks; the runtime refuses the handoff when <n> exceeds
|
|
66
|
+
# the ABI it supports, naming both versions. tebako-bootstrap v1 does
|
|
67
|
+
# not emit this option — it validates the trailer's launcher_abi
|
|
68
|
+
# field itself and encodes the ABI in the runtime name it resolves
|
|
69
|
+
# (runtime_ref "...;tebako=<abi>") — but the runtime accepts the
|
|
70
|
+
# option so the check exists on both sides of the handoff.
|
|
71
|
+
#
|
|
72
|
+
# The three option spellings above are exactly what tebako-bootstrap
|
|
73
|
+
# v1 emits (space-separated values, images before --tebako-entry); the
|
|
74
|
+
# runtime additionally accepts the --opt=value form of each.
|
|
75
|
+
#
|
|
76
|
+
# Versioning: VERSION is bumped whenever the handoff changes incompatibly.
|
|
77
|
+
# This file is the Ruby-side constant set; src/tebako-main.cpp carries the
|
|
78
|
+
# matching C++ constants — keep the two in sync.
|
|
79
|
+
module LauncherAbi
|
|
80
|
+
# Launcher ABI version implemented by this gem and by tebako-main.cpp
|
|
81
|
+
VERSION = 1
|
|
82
|
+
|
|
83
|
+
# Repeatable: hand one image slot of a package file to the runtime
|
|
84
|
+
IMAGE_ARG = "--tebako-image"
|
|
85
|
+
|
|
86
|
+
# Separator: value is the package argv[0]; the rest is application argv
|
|
87
|
+
ENTRY_ARG = "--tebako-entry"
|
|
88
|
+
|
|
89
|
+
# Optional: launcher ABI version the bootstrap speaks
|
|
90
|
+
VERSION_ARG = "--tebako-launcher-abi"
|
|
91
|
+
|
|
92
|
+
# Format one --tebako-image value per the ABI: "<file>:<slot>:<mount-point>".
|
|
93
|
+
# (The parser splits on the last two colons, so <file> may itself contain
|
|
94
|
+
# colons — e.g. Windows drive prefixes.)
|
|
95
|
+
def self.image_spec(file, slot, mount_point)
|
|
96
|
+
"#{file}:#{slot}:#{mount_point}"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -33,6 +33,7 @@ require "rbconfig"
|
|
|
33
33
|
require_relative "codegen"
|
|
34
34
|
require_relative "error"
|
|
35
35
|
require_relative "ruby_version"
|
|
36
|
+
require_relative "stitcher"
|
|
36
37
|
require_relative "version"
|
|
37
38
|
|
|
38
39
|
# Tebako - an executable packager
|
|
@@ -159,6 +160,39 @@ module Tebako
|
|
|
159
160
|
@mode ||= @options["mode"].nil? ? "bundle" : @options["mode"]
|
|
160
161
|
end
|
|
161
162
|
|
|
163
|
+
# Runtime provenance: "prebuilt" (resolve/download a prebuilt runtime
|
|
164
|
+
# package and stitch the application image onto it) or "source" (the
|
|
165
|
+
# Stage-2 source build). Default is "prebuilt" for the bundle mode;
|
|
166
|
+
# other modes always build from source, and --build-runtime forces the
|
|
167
|
+
# source path everywhere (back-compat alias for '--runtime source').
|
|
168
|
+
def runtime_source
|
|
169
|
+
@runtime_source ||= checked_runtime_source(requested_runtime_source)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def prebuilt_runtime?
|
|
173
|
+
runtime_source == "prebuilt"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Additional images for the stitched package, from repeatable
|
|
177
|
+
# '--image <path>:<mount-point>' (split on the last colon so Windows
|
|
178
|
+
# drive-letter paths survive)
|
|
179
|
+
def images
|
|
180
|
+
@images ||= Array(@options["image"]).map do |spec|
|
|
181
|
+
path, _sep, mount = spec.to_s.rpartition(":")
|
|
182
|
+
if path.empty? || mount.empty?
|
|
183
|
+
Tebako.packaging_error(130, "invalid --image specification '#{spec}' ('<path>:<mount-point>' expected)")
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
{ path: path, mount_point: mount, format_id: Tebako::Stitcher::FORMAT_DWARFS }
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Platform id of the host, as used by tebako-runtime-ruby package names
|
|
191
|
+
# (e.g. "macos-arm64", "linux-gnu-x86_64")
|
|
192
|
+
def host_platform(ostype = RUBY_PLATFORM, arch = RbConfig::CONFIG["host_cpu"])
|
|
193
|
+
@host_platform ||= "#{host_os_id(ostype)}-#{host_arch_id(arch)}"
|
|
194
|
+
end
|
|
195
|
+
|
|
162
196
|
def output_folder
|
|
163
197
|
@output_folder ||= File.join(prefix, "o")
|
|
164
198
|
end
|
|
@@ -334,5 +368,42 @@ module Tebako
|
|
|
334
368
|
def stash_dir_all
|
|
335
369
|
@stash_dir_all ||= File.join(deps, "stash")
|
|
336
370
|
end
|
|
371
|
+
|
|
372
|
+
private
|
|
373
|
+
|
|
374
|
+
def requested_runtime_source
|
|
375
|
+
explicit = @options["runtime"]
|
|
376
|
+
return "source" if @options["build-runtime"]
|
|
377
|
+
return mode == "bundle" ? "prebuilt" : "source" if explicit.nil?
|
|
378
|
+
|
|
379
|
+
explicit
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def checked_runtime_source(source)
|
|
383
|
+
if source == "prebuilt" && mode != "bundle"
|
|
384
|
+
Tebako.packaging_error(130, "--runtime prebuilt is supported in bundle mode only (mode: '#{mode}')")
|
|
385
|
+
end
|
|
386
|
+
source
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def host_os_id(ostype)
|
|
390
|
+
case ostype
|
|
391
|
+
when /msys|mingw|cygwin/ then "windows"
|
|
392
|
+
when /darwin/ then "macos"
|
|
393
|
+
when /linux-musl/ then "linux-musl"
|
|
394
|
+
when /linux/ then "linux-gnu"
|
|
395
|
+
else
|
|
396
|
+
Tebako.packaging_error(112, ostype)
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def host_arch_id(arch)
|
|
401
|
+
case arch
|
|
402
|
+
when /^(x86_64|amd64)$/ then "x86_64"
|
|
403
|
+
when /^(aarch64|arm64)$/ then "arm64"
|
|
404
|
+
else
|
|
405
|
+
Tebako.packaging_error(112, arch)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
337
408
|
end
|
|
338
409
|
end
|
|
@@ -36,37 +36,52 @@ module Tebako
|
|
|
36
36
|
# rubocop:disable Style/WordArray
|
|
37
37
|
DARWIN_BREW_LIBS = [
|
|
38
38
|
["zlib", "z"], ["gdbm", "gdbm"], ["readline", "readline"], ["libffi", "ffi"],
|
|
39
|
-
["ncurses", "ncurses"], ["lz4", "lz4"], ["xz", "lzma"], ["libyaml", "yaml"]
|
|
40
|
-
["boost", "boost_chrono"], ["double-conversion", "double-conversion"]
|
|
39
|
+
["ncurses", "ncurses"], ["lz4", "lz4"], ["xz", "lzma"], ["libyaml", "yaml"]
|
|
41
40
|
].freeze
|
|
42
41
|
|
|
43
42
|
DARWIN_BREW_LIBS_PRE_31 = [["openssl@1.1", "ssl"], ["openssl@1.1", "crypto"]].freeze
|
|
44
43
|
|
|
45
44
|
DARWIN_BREW_LIBS_31 = [["openssl@3", "ssl"], ["openssl@3", "crypto"]].freeze
|
|
46
45
|
|
|
47
|
-
DARWIN_DEP_LIBS_1 = ["
|
|
48
|
-
|
|
46
|
+
DARWIN_DEP_LIBS_1 = ["tfs", "tebako_dirent_helper_c"].freeze
|
|
47
|
+
# Referenced by full path from the vcpkg triplet lib dir (see
|
|
48
|
+
# darwin_libraries): Apple ld does not implement the GNU-style
|
|
49
|
+
# -l:<filename> library search, so -l:libX.a refs do not resolve.
|
|
50
|
+
DARWIN_DEP_LIBS_2 = ["dwarfs_reader", "dwarfs_common", "dwarfs_metadata_legacy",
|
|
51
|
+
"dwarfs_decompressor", "flatbuffers", "zip",
|
|
52
|
+
"fmt", "xxhash", "zstd",
|
|
53
|
+
"brotlidec", "brotlienc", "brotlicommon",
|
|
54
|
+
"bz2", "boost_filesystem", "boost_chrono"].freeze
|
|
49
55
|
# rubocop:enable Style/WordArray
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
# --start-group/--end-group around the libtfs + transitive static archives:
|
|
58
|
+
# the dwarfs reader set has circular member-level references that trip GNU
|
|
59
|
+
# ld's single-pass scanning when built with clang (compression registrar).
|
|
60
|
+
# libtfs (libtfs.a + its pure-C dirent helper) and the transitive static
|
|
61
|
+
# set resolved by vcpkg into deps/vcpkg_installed/<triplet>/lib: the
|
|
62
|
+
# dwarfs reader side, flatbuffers, zip and the C++ support libs.
|
|
63
|
+
# Compression codecs register explicitly (compression_registry ctor),
|
|
64
|
+
# so no --whole-archive compression lib is needed anymore.
|
|
53
65
|
COMMON_LINUX_LIBRARIES = [
|
|
54
|
-
|
|
55
|
-
"-l:
|
|
56
|
-
"-l:
|
|
57
|
-
"-l:
|
|
66
|
+
"-Wl,--push-state,--whole-archive -l:libtebako-fs.a -Wl,--pop-state",
|
|
67
|
+
"-l:libtfs.a", "-l:libtebako_dirent_helper_c.a",
|
|
68
|
+
"-l:libdwarfs_reader.a", "-l:libdwarfs_common.a", "-l:libdwarfs_metadata_legacy.a",
|
|
69
|
+
"-l:libdwarfs_decompressor.a", "-l:libflatbuffers.a", "-l:libzip.a",
|
|
70
|
+
"-l:libfmt.a", "-l:libxxhash.a", "-l:libboost_filesystem.a",
|
|
71
|
+
"-l:libboost_chrono.a"
|
|
58
72
|
].freeze
|
|
59
73
|
|
|
60
74
|
COMMON_ARCHIEVE_LIBRARIES = [
|
|
61
|
-
"-l:
|
|
62
|
-
"-l:libbrotlienc.a",
|
|
75
|
+
"-l:liblz4.a", "-l:libz.a", "-l:libzstd.a",
|
|
76
|
+
"-l:libbrotlienc.a", "-l:libbrotlidec.a", "-l:libbrotlicommon.a",
|
|
77
|
+
"-l:liblzma.a", "-l:libbz2.a"
|
|
63
78
|
].freeze
|
|
64
79
|
|
|
65
80
|
LINUX_GNU_LIBRARIES = [
|
|
66
81
|
"-l:libiberty.a", "-l:libacl.a", "-l:libssl.a", "-l:libcrypto.a",
|
|
67
82
|
"-l:libgdbm.a", "-l:libreadline.a", "-l:libtinfo.a", "-l:libffi.a",
|
|
68
83
|
"-l:libncurses.a", "-l:libjemalloc.a", "-l:libcrypt.a", "-l:libanl.a",
|
|
69
|
-
"LIBYAML", "-l:
|
|
84
|
+
"LIBYAML", "-l:libutil.a",
|
|
70
85
|
"-l:libstdc++.a", "-lgcc_eh", "-l:libunwind.a", "-l:liblzma.a",
|
|
71
86
|
"-l:librt.a", "-ldl", "-lpthread", "-lm"
|
|
72
87
|
].freeze
|
|
@@ -74,15 +89,15 @@ module Tebako
|
|
|
74
89
|
LINUX_MUSL_LIBRARIES = [
|
|
75
90
|
"-l:libiberty.a", "-l:libacl.a", "-l:libssl.a", "-l:libcrypto.a",
|
|
76
91
|
"-l:libreadline.a", "-l:libgdbm.a", "-l:libffi.a", "-l:libncurses.a",
|
|
77
|
-
"-l:libjemalloc.a", "-l:libcrypt.a", "LIBYAML",
|
|
78
|
-
"-l:
|
|
79
|
-
" -l:libunwind.a", "-l:liblzma.a", "-ldl",
|
|
92
|
+
"-l:libjemalloc.a", "-l:libcrypt.a", "LIBYAML",
|
|
93
|
+
"-l:librt.a", "-l:libstdc++.a", "-lgcc_eh",
|
|
94
|
+
" -l:libunwind.a", "-l:liblzma.a", "-ldl", "-lpthread"
|
|
80
95
|
].freeze
|
|
81
96
|
|
|
82
97
|
MSYS_LIBRARIES = [
|
|
83
98
|
"-l:liblz4.a", "-l:libz.a", "-l:libzstd.a", "-l:liblzma.a",
|
|
84
99
|
"-l:libncurses.a", "-l:liblzma.a", "-l:libiberty.a", "LIBYAML",
|
|
85
|
-
"-l:libffi.a", "-l:
|
|
100
|
+
"-l:libffi.a", "-l:libstdc++.a", "-l:libdl.a",
|
|
86
101
|
"-static-libgcc", "-static-libstdc++", "-l:libssl.a", "-l:libcrypto.a",
|
|
87
102
|
"-l:libz.a", "-l:libwinpthread.a", "-lcrypt32", "-lshlwapi",
|
|
88
103
|
"-lwsock32", "-liphlpapi", "-limagehlp", "-lbcrypt",
|
|
@@ -90,21 +105,21 @@ module Tebako
|
|
|
90
105
|
].freeze
|
|
91
106
|
|
|
92
107
|
def linux_gnu_libraries(ruby_ver, with_compression)
|
|
93
|
-
libraries = COMMON_LINUX_LIBRARIES + COMMON_ARCHIEVE_LIBRARIES +
|
|
108
|
+
libraries = ["-Wl,--start-group"] + COMMON_LINUX_LIBRARIES + COMMON_ARCHIEVE_LIBRARIES +
|
|
109
|
+
["-Wl,--end-group"] + LINUX_GNU_LIBRARIES
|
|
94
110
|
linux_libraries(libraries, ruby_ver, with_compression)
|
|
95
111
|
end
|
|
96
112
|
|
|
97
113
|
def linux_musl_libraries(ruby_ver, with_compression)
|
|
98
|
-
libraries = COMMON_LINUX_LIBRARIES + COMMON_ARCHIEVE_LIBRARIES +
|
|
114
|
+
libraries = ["-Wl,--start-group"] + COMMON_LINUX_LIBRARIES + COMMON_ARCHIEVE_LIBRARIES +
|
|
115
|
+
["-Wl,--end-group"] + LINUX_MUSL_LIBRARIES
|
|
99
116
|
linux_libraries(libraries, ruby_ver, with_compression)
|
|
100
117
|
end
|
|
101
118
|
|
|
102
|
-
def linux_libraries(libraries, ruby_ver,
|
|
119
|
+
def linux_libraries(libraries, ruby_ver, _with_compression)
|
|
103
120
|
libraries.map! do |lib|
|
|
104
121
|
if lib == "LIBYAML"
|
|
105
122
|
PatchHelpers.yaml_reference(ruby_ver)
|
|
106
|
-
elsif lib == "LIBCOMPRESSION"
|
|
107
|
-
with_compression ? "-Wl,--push-state,--whole-archive -l:libdwarfs_compression.a -Wl,--pop-state" : ""
|
|
108
123
|
else
|
|
109
124
|
lib
|
|
110
125
|
end
|
|
@@ -122,17 +137,22 @@ module Tebako
|
|
|
122
137
|
brew_libs.each { |lib| libs << "#{PatchHelpers.get_prefix_macos(lib[0]).chop}/lib/lib#{lib[1]}.a " }
|
|
123
138
|
end
|
|
124
139
|
|
|
125
|
-
def darwin_libraries(deps_lib_dir, ruby_ver,
|
|
140
|
+
def darwin_libraries(deps_lib_dir, ruby_ver, _with_compression)
|
|
126
141
|
libs = String.new
|
|
127
142
|
|
|
128
143
|
DARWIN_DEP_LIBS_1.each { |lib| libs << "#{deps_lib_dir}/lib#{lib}.a " }
|
|
129
144
|
process_brew_libs!(libs, ruby_ver.ruby31? ? DARWIN_BREW_LIBS_31 : DARWIN_BREW_LIBS_PRE_31)
|
|
130
145
|
process_brew_libs!(libs, DARWIN_BREW_LIBS)
|
|
131
146
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
# The vcpkg set by full path: Apple ld does not implement -l:<filename>
|
|
148
|
+
vcpkg_lib_dir = Dir.glob(File.join(deps_lib_dir, "..", "vcpkg_installed", "*", "lib")).min
|
|
149
|
+
DARWIN_DEP_LIBS_2.each { |lib| libs << "#{vcpkg_lib_dir}/lib#{lib}.a " }
|
|
150
|
+
# No allocator link: brew's static libjemalloc.a crashes tebako
|
|
151
|
+
# binaries at startup on the XCode 15.4 runners (je_arena_ralloc
|
|
152
|
+
# SEGV at builtin init), and the dylib fails the test_101
|
|
153
|
+
# no-shared-libs assertion. System malloc until a properly built
|
|
154
|
+
# static jemalloc ships with libtfs-deps.
|
|
155
|
+
"-ltebako-fs #{libs}-lc++ -lc++abi"
|
|
136
156
|
end
|
|
137
157
|
|
|
138
158
|
# .....................................................
|
data/lib/tebako/packager.rb
CHANGED
|
@@ -68,7 +68,7 @@ module Tebako
|
|
|
68
68
|
win32/file.c
|
|
69
69
|
].freeze
|
|
70
70
|
|
|
71
|
-
class << self
|
|
71
|
+
class << self # rubocop:disable Metrics/ClassLength
|
|
72
72
|
# Create implib
|
|
73
73
|
def create_implib(src_dir, package_src_dir, app_name, ruby_ver)
|
|
74
74
|
a_name = File.basename(app_name, ".*")
|
|
@@ -115,6 +115,45 @@ module Tebako
|
|
|
115
115
|
FileUtils.cp_r "#{stash_dir}/.", src_dir
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
+
# Check that the packaging environment the prebuilt-runtime press
|
|
119
|
+
# needs (pristine Ruby stash + mkdwarfs) is in place
|
|
120
|
+
def check_prebuilt_env!(stash_dir, deps_bin_dir)
|
|
121
|
+
missing = []
|
|
122
|
+
missing << "Ruby environment stash (#{stash_dir})" unless Dir.exist?(stash_dir)
|
|
123
|
+
missing << "mkdwarfs (#{deps_bin_dir})" if Dir.glob(File.join(deps_bin_dir, "mkdwarfs*")).empty?
|
|
124
|
+
return if missing.empty?
|
|
125
|
+
|
|
126
|
+
Tebako.packaging_error(128, missing.join(", "))
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Deploy the application and build its DwarFS image for stitching onto
|
|
130
|
+
# a prebuilt runtime. Same layout as the bundle-mode image, plus an
|
|
131
|
+
# entry dispatcher at /local/stub.rb (the runtime's compiled-in entry).
|
|
132
|
+
def build_app_image(options_manager, scenario_manager) # rubocop:disable Metrics/AbcSize
|
|
133
|
+
init(options_manager.stash_dir, options_manager.data_src_dir, options_manager.data_pre_dir,
|
|
134
|
+
options_manager.data_bin_dir)
|
|
135
|
+
deploy(options_manager.data_src_dir, options_manager.data_pre_dir, options_manager.rv,
|
|
136
|
+
options_manager.root, scenario_manager.fs_entrance, options_manager.cwd)
|
|
137
|
+
write_entry_dispatcher(options_manager.data_src_dir, scenario_manager, options_manager.cwd)
|
|
138
|
+
mkdwarfs(options_manager.deps_bin_dir, options_manager.data_bundle_file, options_manager.data_src_dir)
|
|
139
|
+
options_manager.data_bundle_file
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# The prebuilt runtime packages are pressed in 'runtime' mode, so their
|
|
143
|
+
# compiled-in entry point is /local/stub.rb. A stitched package mounts
|
|
144
|
+
# the application image as the root filesystem; the dispatcher written
|
|
145
|
+
# here receives control from the runtime and loads the real entry point
|
|
146
|
+
# (replicating the bundle-mode working directory when --cwd was given).
|
|
147
|
+
def write_entry_dispatcher(data_src_dir, scenario_manager, cwd)
|
|
148
|
+
dispatcher = +""
|
|
149
|
+
dispatcher << "Dir.chdir(\"#{scenario_manager.fs_mount_point}/#{cwd}\")\n" unless cwd.nil?
|
|
150
|
+
dispatcher << "load \"#{scenario_manager.fs_mount_point}#{scenario_manager.fs_entry_point}\"\n"
|
|
151
|
+
|
|
152
|
+
local_dir = File.join(data_src_dir, "local")
|
|
153
|
+
FileUtils.mkdir_p(local_dir)
|
|
154
|
+
File.write(File.join(local_dir, "stub.rb"), dispatcher)
|
|
155
|
+
end
|
|
156
|
+
|
|
118
157
|
def mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil)
|
|
119
158
|
puts "-- Running mkdwarfs script"
|
|
120
159
|
FileUtils.chmod("a+x", Dir.glob(File.join(deps_bin_dir, "mkdwarfs*")))
|