tebako 0.5.12 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2021-2023 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2021-2024 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -26,7 +26,9 @@
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
28
  require_relative "patch_literals"
29
+ require_relative "patch_libraries"
29
30
  require_relative "patch_helpers"
31
+ require_relative "patch_buildsystem"
30
32
 
31
33
  # Tebako - an executable packager
32
34
  module Tebako
@@ -37,134 +39,102 @@ module Tebako
37
39
  def get_patch_map(ostype, deps_lib_dir, ruby_ver)
38
40
  patch_map = get_patch_map_base(ostype, deps_lib_dir, ruby_ver)
39
41
 
40
- C_FILES_TO_PATCH.each { |patch| patch_map.store(patch[0], patch_c_file(patch[1])) }
41
42
  patch_map.store("thread_pthread.c", LINUX_MUSL_THREAD_PTHREAD_PATCH) if ostype =~ /linux-musl/
42
- patch_map.store("common.mk", COMMON_MK_PATCH) if PatchHelpers.ruby3x?(ruby_ver)
43
43
 
44
- ostype =~ /msys/ ? patch_map.merge!(MSYS_PATCHES) : patch_map
45
- # patch_map.merge!(LINUX_PATCHES)
44
+ if PatchHelpers.msys?(ostype)
45
+ patch_map.merge!(get_msys_patches(ruby_ver))
46
+ elsif PatchHelpers.ruby3x?(ruby_ver)
47
+ # [TODO] Do we really need it for platforms other then Windows ??
48
+ patch_map.store("common.mk", COMMON_MK_PATCH)
49
+ end
50
+
51
+ patch_map
46
52
  end
47
53
 
48
54
  private
49
55
 
56
+ include Tebako::Packager::PatchBuildsystem
50
57
  include Tebako::Packager::PatchLiterals
51
58
 
52
59
  def get_dir_c_patch(ostype)
53
- dir_c_patch = patch_c_file(ostype =~ /msys/ ? "/* define system APIs */" : "#ifdef HAVE_GETATTRLIST")
60
+ pattern = PatchHelpers.msys?(ostype) ? "/* define system APIs */" : "#ifdef HAVE_GETATTRLIST"
61
+ dir_c_patch = PatchHelpers.patch_c_file(pattern)
54
62
  dir_c_patch.merge!(DIR_C_BASE_PATCH)
63
+ dir_c_patch
55
64
  end
56
65
 
57
- def get_patch_map_base(ostype, deps_lib_dir, ruby_ver)
58
- {
59
- "template/Makefile.in" => template_makefile_in_patch(ostype, deps_lib_dir, ruby_ver),
60
- "main.c" => MAIN_C_PATCH,
61
- "tool/mkconfig.rb" => TOOL_MKCONFIG_RB_PATCH,
62
- "gem_prelude.rb" => GEM_PRELUDE_RB_PATCH,
63
- "dir.c" => get_dir_c_patch(ostype)
66
+ def get_dln_c_patch(ostype, ruby_ver)
67
+ # Not using substitutions of dlxxx functions on Windows
68
+ dln_c_patch = {
69
+ "static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;" =>
70
+ "#{PatchHelpers.msys?(ostype) ? C_FILE_SUBST_LESS : C_FILE_SUBST}\n" \
71
+ "static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;\n"
64
72
  }
65
- end
66
73
 
67
- def process_brew_libs!(libs, brew_libs)
68
- brew_libs.each { |lib| libs << "#{PatchHelpers.get_prefix_macos(lib[0]).chop}/lib/lib#{lib[1]}.a " }
69
- end
70
-
71
- def darwin_libs(deps_lib_dir, ruby_ver)
72
- libs = String.new
74
+ if PatchHelpers.msys?(ostype)
75
+ patch = PatchHelpers.ruby32?(ruby_ver) ? DLN_C_MSYS_PATCH : DLN_C_MSYS_PATCH_PRE32
76
+ dln_c_patch.merge!(patch)
77
+ end
73
78
 
74
- process_brew_libs!(libs, PatchHelpers.ruby31?(ruby_ver) ? DARWIN_BREW_LIBS_31 : DARWIN_BREW_LIBS_PRE_31)
75
- process_brew_libs!(libs, DARWIN_BREW_LIBS)
79
+ dln_c_patch
80
+ end
76
81
 
77
- DARWIN_DEP_LIBS.each { |lib| libs << "#{deps_lib_dir}/lib#{lib}.a " }
78
- <<~SUBST
79
- -ltebako-fs -ldwarfs-wr -ldwarfs -force_load #{deps_lib_dir}/libdwarfs_compression.a -lfolly -lfsst -lmetadata_thrift -lthrift_light -lxxhash \
80
- -lzstd #{libs} -ljemalloc -lc++ -lc++abi
81
- SUBST
82
+ def get_io_c_msys_patch(ruby_ver)
83
+ io_c_msys_patch = PatchHelpers.ruby32?(ruby_ver) ? IO_C_MSYS_PATCH : IO_C_MSYS_PATCH_PRE_32
84
+ io_c_msys_patch.merge(IO_C_MSYS_BASE_PATCH)
82
85
  end
83
86
 
84
- # .....................................................
85
- # Notes re linux libraries
86
- # 1) This order is important: -lgcc_eh -l:libunwind.a -l:liblzma.a lzma is used to process debug sections.
87
- # gcc_eh shall be linked before unwind to avoid duplicate symbols.
88
- # 2) -lgcc_eh assumes -static-libgcc (applied in CMakeLists.ext, RUBY_C_FLAGS)
89
- # 3) -static-libstdc++ did not work, not sure why [TODO ?]
90
- # 4) When clang is used linker links libraries specified in exensions in such way that they are linked shared
91
- # (libz, libffi, libreadline, libncurses, libtinfo, ... )
92
- # Using stuff like -l:libz.a does not help; there is a reference to libz.so anyway.
93
- # This is fixed by ext/extmk.rb patch [TODO ?]
94
- # .....................................................
95
-
96
- def linux_gnu_libs(ruby_ver)
97
- <<~SUBST
98
- -l:libtebako-fs.a -l:libdwarfs-wr.a -l:libdwarfs.a -Wl,--push-state,--whole-archive -l:libdwarfs_compression.a -Wl,--pop-state -l:libfolly.a -l:libfsst.a \
99
- -l:libmetadata_thrift.a -l:libthrift_light.a -l:libxxhash.a -l:libarchive.a -l:libfmt.a -l:libdouble-conversion.a -l:libglog.a -l:libgflags.a -l:libevent.a \
100
- -l:libiberty.a -l:libacl.a -l:libssl.a -l:libcrypto.a -l:liblz4.a -l:libz.a -l:libzstd.a -l:libbrotlienc.a -l:libbrotlidec.a -l:libbrotlicommon.a -l:libgdbm.a \
101
- -l:libreadline.a -l:libtinfo.a -l:libffi.a -l:libncurses.a -l:libjemalloc.a -l:libcrypt.a -l:libanl.a #{PatchHelpers.yaml_reference(ruby_ver)} \
102
- -l:libboost_system.a -l:libboost_chrono.a -l:libutil.a -l:libstdc++.a -lgcc_eh -l:libunwind.a -l:liblzma.a -l:librt.a -ldl -lpthread -lm
103
- SUBST
87
+ def get_io_c_patch(ostype, ruby_ver)
88
+ io_c_patch = PatchHelpers.patch_c_file("/* define system APIs */")
89
+ io_c_patch.merge!(get_io_c_msys_patch(ruby_ver)) if PatchHelpers.msys?(ostype)
90
+ io_c_patch
104
91
  end
105
92
 
106
- def linux_musl_libs(ruby_ver)
107
- <<~SUBST
108
- -l:libtebako-fs.a -l:libdwarfs-wr.a -l:libdwarfs.a -Wl,--push-state,--whole-archive -l:libdwarfs_compression.a -Wl,--pop-state -l:libfolly.a -l:libfsst.a \
109
- -l:libmetadata_thrift.a -l:libthrift_light.a -l:libxxhash.a -l:libfmt.a -l:libdouble-conversion.a -l:libglog.a -l:libgflags.a -l:libevent.a -l:libiberty.a \
110
- -l:libacl.a -l:libssl.a -l:libcrypto.a -l:liblz4.a -l:libz.a -l:libzstd.a -l:libbrotlienc.a -l:libbrotlidec.a -l:libbrotlicommon.a -l:libgdbm.a -l:libreadline.a \
111
- -l:libffi.a -l:libncurses.a -l:libjemalloc.a -l:libcrypt.a #{PatchHelpers.yaml_reference(ruby_ver)} -l:libboost_system.a -l:libboost_chrono.a -l:librt.a \
112
- -l:libstdc++.a -lgcc_eh -l:libunwind.a -l:liblzma.a -ldl -lpthread
113
- SUBST
93
+ def get_msys_mkconfig_rb_patches(ruby_ver)
94
+ {
95
+ " if fast[name]" => TOOLS_MKCONFIG_RB_SUBST,
96
+ "when /RUBYGEMS/; next" =>
97
+ "when /RUBYGEMS/; next\n\n" \
98
+ "# Start of tebako patch\n" \
99
+ "when /MAINLIBS/; val = #{PatchLibraries.msys_base_libs(ruby_ver)}\n" \
100
+ "# End of tebako patch"
101
+ }
114
102
  end
115
103
 
116
- def msys_libs(ruby_ver)
117
- <<~SUBST
118
- -l:libtebako-fs.a -l:libdwarfs-wr.a -l:libdwarfs.a -l:libfolly.a -l:libfsst.a -l:libmetadata_thrift.a -l:libthrift_light.a -l:libxxhash.a \
119
- -l:libfmt.a -l:libdouble-conversion.a -l:libglog.a -l:libgflags.a -l:libevent.a -l:libssl.a -l:libcrypto.a -l:liblz4.a -l:libz.a \
120
- -l:libzstd.a -l:libffi.a -l:libgdbm.a -l:libncurses.a -l:libjemalloc.a -l:libunwind.a -l:liblzma.a -l:libiberty.a \
121
- #{PatchHelpers.yaml_reference(ruby_ver)} -l:libstdc++.a -l:libdl.a -lole32 -loleaut32 -luuid
122
- SUBST
104
+ def get_msys_patches(ruby_ver)
105
+ {
106
+ "cygwin/GNUmakefile.in" => get_gnumakefile_in_patch_p2(ruby_ver),
107
+ "ruby.c" => RUBY_C_MSYS_PATCHES,
108
+ "win32/file.c" => WIN32_FILE_C_MSYS_PATCHES,
109
+ "win32/win32.c" => WIN32_WIN32_C_MSYS_PATCHES
110
+ }
123
111
  end
124
112
 
125
- # rubocop:disable Metrics/MethodLength
126
- def mlibs(ostype, deps_lib_dir, ruby_ver)
127
- case ostype
128
- when /linux-gnu/
129
- linux_gnu_libs(ruby_ver)
130
- when /linux-musl/
131
- linux_musl_libs(ruby_ver)
132
- when /darwin/
133
- darwin_libs(deps_lib_dir, ruby_ver)
134
- when /msys/
135
- msys_libs(ruby_ver)
136
- else
137
- raise Tebako::Error, "Unknown ostype #{ostype}"
138
- end
113
+ def get_patch_map_base(ostype, deps_lib_dir, ruby_ver)
114
+ mcrb_subst = PatchHelpers.msys?(ostype) ? get_msys_mkconfig_rb_patches(ruby_ver) : TOOL_MKCONFIG_RB_PATCH
115
+ {
116
+ "template/Makefile.in" => template_makefile_in_patch(ostype, deps_lib_dir, ruby_ver),
117
+ "tool/mkconfig.rb" => mcrb_subst,
118
+ "gem_prelude.rb" => GEM_PRELUDE_RB_PATCH,
119
+ "dir.c" => get_dir_c_patch(ostype), "dln.c" => get_dln_c_patch(ostype, ruby_ver),
120
+ "io.c" => get_io_c_patch(ostype, ruby_ver), "main.c" => MAIN_C_PATCH,
121
+ "file.c" => PatchHelpers.patch_c_file("/* define system APIs */"),
122
+ "util.c" => PatchHelpers.patch_c_file("#ifndef S_ISDIR")
123
+ }
139
124
  end
140
- # rubocop:enable Metrics/MethodLength
141
125
 
142
126
  def mlibs_subst(ostype, deps_lib_dir, ruby_ver)
143
127
  yjit_libs = PatchHelpers.ruby32only?(ruby_ver) ? "$(YJIT_LIBS) " : ""
144
128
  {
145
129
  "MAINLIBS = #{yjit_libs}@MAINLIBS@" =>
146
130
  "# -- Start of tebako patch -- \n" \
147
- "MAINLIBS = #{yjit_libs}#{mlibs(ostype, deps_lib_dir, ruby_ver)}" \
131
+ "MAINLIBS = #{yjit_libs}#{PatchLibraries.mlibs(ostype, deps_lib_dir, ruby_ver)}" \
148
132
  "# -- End of tebako patch -- \n"
149
133
  }
150
134
  end
151
135
 
152
- def patch_c_file(pattern)
153
- {
154
- pattern => "#{C_FILE_SUBST}\n#{pattern}"
155
- }
156
- end
157
-
158
136
  def template_makefile_in_patch(ostype, deps_lib_dir, ruby_ver)
159
- template_makefile_in_patch_two(ruby_ver).merge(mlibs_subst(ostype, deps_lib_dir, ruby_ver))
160
- end
161
-
162
- def template_makefile_in_patch_two(ruby_ver)
163
- if PatchHelpers.ruby31?(ruby_ver)
164
- { TEMPLATE_MAKEFILE_IN_BASE_PATTERN => TEMPLATE_MAKEFILE_IN_BASE_PATCH }
165
- else
166
- { TEMPLATE_MAKEFILE_IN_BASE_PATTERN_PRE_3_1 => TEMPLATE_MAKEFILE_IN_BASE_PATCH_PRE_3_1 }
167
- end
137
+ template_makefile_in_patch_two(ostype, ruby_ver).merge(mlibs_subst(ostype, deps_lib_dir, ruby_ver))
168
138
  end
169
139
  end
170
140
  end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
4
+ # All rights reserved.
5
+ # This file is a part of tebako
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
20
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ # POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ require_relative "patch_helpers"
29
+
30
+ # Tebako - an executable packager
31
+ module Tebako
32
+ module Packager
33
+ # Ruby buildsystem patches (pass2)
34
+ module PatchBuildsystem
35
+ # This patch forces rebuild of extinit.c when exts.mk changes
36
+ # exts.mk changes when we rebuild extensions to make them statically linked
37
+ # [TODO] it is possible that we can build extensions statically on pass1 and it will
38
+ # eliminate the need for this patch
39
+ COMMON_MK_PATCH = {
40
+ "ext/extinit.c: $(srcdir)/template/extinit.c.tmpl $(PREP)" =>
41
+ "ext/extinit.c: $(srcdir)/template/extinit.c.tmpl $(PREP) $(EXTS_MK)"
42
+ }.freeze
43
+
44
+ # This patch changes libraries that are used for Ruby linking
45
+ # MAINLIBS is patched elsewhere (not with literal but dynamically)
46
+ # to haold the list of sattic libraries and related options
47
+ # Also we have to put LIBRUBYARG_STATIC instead of LIBRUBYARG to link with static libruby,
48
+ # configure's --disable-shared option does not do it
49
+ # Several variants depending on os and version
50
+ TEMPLATE_MAKEFILE_IN_BASE_PATTERN_PRE_3_1 =
51
+ "\t\t$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) " \
52
+ "$(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@"
53
+
54
+ TEMPLATE_MAKEFILE_IN_BASE_PATCH_PRE_3_1 =
55
+ "# -- Start of tebako patch --\n" \
56
+ "\t\t$(Q) $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) " \
57
+ "$(EXTOBJS) $(LIBRUBYARG_STATIC) $(OUTFLAG)$@\n" \
58
+ "# -- End of tebako patch --"
59
+
60
+ TEMPLATE_MAKEFILE_IN_BASE_PATTERN =
61
+ "\t\t$(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(EXTOBJS) " \
62
+ "$(LIBRUBYARG) $(MAINLIBS) $(LIBS) $(EXTLIBS) $(OUTFLAG)$@"
63
+
64
+ TEMPLATE_MAKEFILE_IN_BASE_PATCH =
65
+ "# -- Start of tebako patch --\n" \
66
+ "\t\t$(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(MAINOBJ) " \
67
+ "$(EXTOBJS) $(LIBRUBYARG_STATIC) $(OUTFLAG)$@\n" \
68
+ "# -- End of tebako patch --"
69
+
70
+ TEMPLATE_MAKEFILE_IN_BASE_PATCH_MSYS =
71
+ "# -- Start of tebako patch --\n" \
72
+ "\t\t$(Q) $(PURIFY) $(CC) $(EXE_LDFLAGS) $(XLDFLAGS) $(RUBY_EXP) $(MAINOBJ) " \
73
+ "$(EXTOBJS) $(LIBRUBYARG_STATIC) $(OUTFLAG)$@\n" \
74
+ "# -- End of tebako patch --"
75
+
76
+ def template_makefile_in_patch_two(ostype, ruby_ver)
77
+ if PatchHelpers.msys?(ostype)
78
+ { TEMPLATE_MAKEFILE_IN_BASE_PATTERN => TEMPLATE_MAKEFILE_IN_BASE_PATCH_MSYS }
79
+ elsif PatchHelpers.ruby31?(ruby_ver)
80
+ { TEMPLATE_MAKEFILE_IN_BASE_PATTERN => TEMPLATE_MAKEFILE_IN_BASE_PATCH }
81
+ else
82
+ { TEMPLATE_MAKEFILE_IN_BASE_PATTERN_PRE_3_1 => TEMPLATE_MAKEFILE_IN_BASE_PATCH_PRE_3_1 }
83
+ end
84
+ end
85
+
86
+ # This MSYS specific thing ensure compilation of winmain.c
87
+ # Did try to understand why it did not work out of the box
88
+ GNUMAKEFILE_IN_WINMAIN_SUBST = <<~SUBST
89
+ RUBYDEF = $(DLL_BASE_NAME).def
90
+
91
+ # Start of tebako patch
92
+ WINMAINOBJ = win32/winmain.$(OBJEXT)
93
+ $(WINMAINOBJ): win32/winmain.c
94
+ # End of tebako patch
95
+ SUBST
96
+
97
+ # Other MSYS (GNUMakefile) specific patches
98
+ # - The same issue with libraries as for Makefile above
99
+ # - 'Kill' ruby.exp regeneration on pass2
100
+ # since we want to use outpu from pass1 for implib generation
101
+ # [VERY UGLY HACK]
102
+ # - Introduce LIBRUBY dependency on static extensions
103
+ # This is an addition to COMMON_MK_PATCH specified above
104
+ def get_gnumakefile_in_patch_p2(ruby_ver) # rubocop:disable Metrics/MethodLength
105
+ objext = PatchHelpers.ruby32?(ruby_ver) ? "$(OBJEXT)" : "@OBJEXT@"
106
+
107
+ {
108
+ "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext}" =>
109
+ "$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.#{objext} $(WINMAINOBJ) # tebako patched",
110
+
111
+ "RUBYDEF = $(DLL_BASE_NAME).def" => GNUMAKEFILE_IN_WINMAIN_SUBST,
112
+
113
+ "$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@" =>
114
+ "$(WINMAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(MAINLIBS) -o $@ # tebako patched",
115
+
116
+ "$(RUBY_EXP): $(LIBRUBY_A)" => "dummy.exp: $(LIBRUBY_A) # tebako patched",
117
+
118
+ "$(PROGRAM): $(RUBY_INSTALL_NAME).res.#{objext}" =>
119
+ "$(PROGRAM): $(RUBY_INSTALL_NAME).res.#{objext} $(LIBRUBY_A) # tebako patched\n" \
120
+ "$(LIBRUBY_A): $(LIBRUBY_A_OBJS) $(INITOBJS) # tebako patched\n"
121
+ }
122
+ end
123
+ end
124
+ end
125
+ end
@@ -61,6 +61,16 @@ module Tebako
61
61
  out
62
62
  end
63
63
 
64
+ def msys?(ostype)
65
+ ostype =~ /msys|cygwin|mingw/
66
+ end
67
+
68
+ def patch_c_file(pattern)
69
+ {
70
+ pattern => "#{PatchLiterals::C_FILE_SUBST}\n#{pattern}"
71
+ }
72
+ end
73
+
64
74
  def recreate(dirname)
65
75
  FileUtils.rm_rf(dirname, noop: nil, verbose: nil, secure: true)
66
76
  FileUtils.mkdir(dirname)
@@ -0,0 +1,150 @@
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_helpers"
29
+
30
+ # Tebako - an executable packager
31
+ module Tebako
32
+ module Packager
33
+ # Ruby patching definitions (pass2)
34
+ module PatchLibraries
35
+ class << self
36
+ # rubocop:disable Style/WordArray
37
+
38
+ # NOTE: folly provides build-in implementation of jemalloc
39
+
40
+ DARWIN_BREW_LIBS = [
41
+ ["zlib", "z"], ["gdbm", "gdbm"], ["readline", "readline"], ["libffi", "ffi"],
42
+ ["ncurses", "ncurses"], ["fmt", "fmt"], ["lz4", "lz4"], ["xz", "lzma"],
43
+ ["libyaml", "yaml"], ["boost", "boost_chrono"],
44
+ ["double-conversion", "double-conversion"]
45
+ ].freeze
46
+
47
+ DARWIN_BREW_LIBS_PRE_31 = [["openssl@1.1", "ssl"], ["openssl@1.1", "crypto"]].freeze
48
+
49
+ DARWIN_BREW_LIBS_31 = [["libyaml", "yaml"], ["openssl@3", "ssl"], ["openssl@3", "crypto"]].freeze
50
+
51
+ DARWIN_DEP_LIBS = ["glog", "gflags", "brotlienc", "brotlidec", "brotlicommon"].freeze
52
+ # rubocop:enable Style/WordArray
53
+
54
+ def process_brew_libs!(libs, brew_libs)
55
+ brew_libs.each { |lib| libs << "#{PatchHelpers.get_prefix_macos(lib[0]).chop}/lib/lib#{lib[1]}.a " }
56
+ end
57
+
58
+ def darwin_libs(deps_lib_dir, ruby_ver)
59
+ libs = String.new
60
+
61
+ process_brew_libs!(libs, PatchHelpers.ruby31?(ruby_ver) ? DARWIN_BREW_LIBS_31 : DARWIN_BREW_LIBS_PRE_31)
62
+ process_brew_libs!(libs, DARWIN_BREW_LIBS)
63
+
64
+ DARWIN_DEP_LIBS.each { |lib| libs << "#{deps_lib_dir}/lib#{lib}.a " }
65
+ <<~SUBST
66
+ -ltebako-fs -ldwarfs-wr -ldwarfs -force_load #{deps_lib_dir}/libdwarfs_compression.a -lfolly -lfsst -lmetadata_thrift -lthrift_light -lxxhash \
67
+ -lzstd #{libs} -ljemalloc -lc++ -lc++abi
68
+ SUBST
69
+ end
70
+
71
+ # .....................................................
72
+ # Notes re linux libraries
73
+ # 1) This order is important: -lgcc_eh -l:libunwind.a -l:liblzma.a lzma is used to process debug sections.
74
+ # gcc_eh shall be linked before unwind to avoid duplicate symbols.
75
+ # 2) -lgcc_eh assumes -static-libgcc (applied in CMakeLists.ext, RUBY_C_FLAGS)
76
+ # 3) -static-libstdc++ did not work, not sure why [TODO ?]
77
+ # 4) When clang is used linker links libraries specified in exensions in such way that they are linked shared
78
+ # (libz, libffi, libreadline, libncurses, libtinfo, ... )
79
+ # Using stuff like -l:libz.a does not help; there is a reference to libz.so anyway.
80
+ # This is fixed by ext/extmk.rb patch [TODO ?]
81
+ # .....................................................
82
+
83
+ def linux_common_libs
84
+ <<~SUBST
85
+ -l:libtebako-fs.a -l:libdwarfs-wr.a -l:libdwarfs.a -Wl,--push-state,--whole-archive -l:libdwarfs_compression.a -Wl,--pop-state -l:libfolly.a -l:libfsst.a \\
86
+ -l:libmetadata_thrift.a -l:libthrift_light.a -l:libxxhash.a -l:libfmt.a -l:libdouble-conversion.a -l:libglog.a -l:libgflags.a -l:libevent.a \\
87
+ SUBST
88
+ end
89
+
90
+ def common_enc_libs
91
+ "-l:liblz4.a -l:libz.a -l:libzstd.a -l:libbrotlienc.a -l:libbrotlidec.a -l:libbrotlicommon.a -l:liblzma.a"
92
+ end
93
+
94
+ def linux_gnu_libs(ruby_ver)
95
+ <<~SUBST
96
+ #{linux_common_libs} \
97
+ -l:libarchive.a -l:libiberty.a -l:libacl.a -l:libssl.a -l:libcrypto.a #{common_enc_libs} \\
98
+ -l:libgdbm.a -l:libreadline.a -l:libtinfo.a -l:libffi.a -l:libncurses.a -l:libjemalloc.a -l:libcrypt.a -l:libanl.a #{PatchHelpers.yaml_reference(ruby_ver)} \\
99
+ -l:libboost_system.a -l:libboost_chrono.a -l:libutil.a -l:libstdc++.a -lgcc_eh -l:libunwind.a -l:liblzma.a -l:librt.a -ldl -lpthread -lm
100
+ SUBST
101
+ end
102
+
103
+ def linux_musl_libs(ruby_ver)
104
+ <<~SUBST
105
+ #{linux_common_libs} \
106
+ -l:libiberty.a -l:libacl.a -l:libssl.a -l:libcrypto.a #{common_enc_libs} -l:libreadline.a \\
107
+ -l:libgdbm.a -l:libffi.a -l:libncurses.a -l:libjemalloc.a -l:libcrypt.a #{PatchHelpers.yaml_reference(ruby_ver)} -l:libboost_system.a -l:libboost_chrono.a \\
108
+ -l:librt.a -l:libstdc++.a -lgcc_eh -l:libunwind.a -l:liblzma.a -ldl -lpthread
109
+ SUBST
110
+ end
111
+
112
+ # Used for mkconfig.rb
113
+ def msys_base_libs(ruby_ver)
114
+ <<~SUBST
115
+ "-l:libtebako-fs.a -l:libdwarfs-wr.a -l:libdwarfs.a -l:libdwarfs_compression.a -l:libfolly.a -l:libfsst.a " \\
116
+ "-l:libmetadata_thrift.a -l:libthrift_light.a -l:libxxhash.a -l:libfmt.a -l:libdouble-conversion.a -l:libglog.a -l:libgflags.a -l:libevent.a " \\
117
+ "-l:liblz4.a -l:libz.a -l:libzstd.a -l:liblzma.a -l:libncurses.a -l:libunwind.a -l:liblzma.a -l:libiberty.a #{PatchHelpers.yaml_reference(ruby_ver)} " \\
118
+ "-l:libffi.a -l:libboost_system-mt.a -l:libboost_chrono-mt.a -l:libstdc++.a -l:libdl.a -static-libgcc -static-libstdc++ -l:libssl.a -l:libcrypto.a " \\
119
+ "-l:libz.a -l:libwinpthread.a -lcrypt32 -lshlwapi -lwsock32 -liphlpapi -limagehlp -lbcrypt -lole32 -loleaut32 -luuid"
120
+ SUBST
121
+ end
122
+
123
+ # Used in Makefile
124
+ def msys_libs(ruby_ver)
125
+ <<~SUBST
126
+ -Wl,-Bstatic #{linux_common_libs} \
127
+ -l:liblz4.a -l:libz.a -l:libzstd.a -l:liblzma.a -l:libncurses.a -l:libunwind.a -l:liblzma.a -l:libiberty.a #{PatchHelpers.yaml_reference(ruby_ver)} \\
128
+ -l:libffi.a -l:libboost_system-mt.a -l:libboost_chrono-mt.a -l:libstdc++.a -l:libdl.a -static-libgcc -static-libstdc++ -l:libssl.a -l:libcrypto.a -l:libz.a \\
129
+ -l:libwinpthread.a -lcrypt32 -lshlwapi -lwsock32 -liphlpapi -limagehlp -lshlwapi -lbcrypt -lws2_32 -lole32 -loleaut32 -luuid
130
+ SUBST
131
+ end
132
+
133
+ def mlibs(ostype, deps_lib_dir, ruby_ver) # rubocop:disable Metrics/MethodLength
134
+ case ostype
135
+ when /linux-gnu/
136
+ linux_gnu_libs(ruby_ver)
137
+ when /linux-musl/
138
+ linux_musl_libs(ruby_ver)
139
+ when /darwin/
140
+ darwin_libs(deps_lib_dir, ruby_ver)
141
+ when /msys/
142
+ msys_libs(ruby_ver)
143
+ else
144
+ raise Tebako::Error, "Unknown ostype #{ostype}"
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end