summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2024-10-11 19:44:36 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2024-10-11 20:14:43 +0000
commitdc37ea052ed74321c5244938f8d702372f663776 (patch)
tree5b561ff383ef5c358a181e99788aef9acd00ef29
parent4f7788bbebe80f1c6b13bd3bc2db875e900bfa29 (diff)
downloadmeta-cloud-services-dc37ea052ed74321c5244938f8d702372f663776.tar.gz
ruby/rubyv2: add new rubyv2 bbclass and support external extconf
When building/installing gems with native components, the target OS and cross compile settings were not correctly being picked up. Enhance the existing bbclass with the ability to copy a extconf.rb from UNPACKDIR, so a recipe can specify fixes in it's own copy of the file. We also bring in a class from meta-rubygems which has more advanced cross compile settings. There are a few minor modifications to this class (copying of extconf.rb) and some spec generation. But it is now available if the basic ruby class cannot compile and install a gem. Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
-rw-r--r--classes/ruby.bbclass27
-rw-r--r--classes/rubyv2.bbclass322
-rw-r--r--recipes-support/puppet/puppet_7.33.0.bb (renamed from recipes-support/puppet/puppet_5.4.0.bb)0
3 files changed, 347 insertions, 2 deletions
diff --git a/classes/ruby.bbclass b/classes/ruby.bbclass
index 384ece9..eb19e37 100644
--- a/classes/ruby.bbclass
+++ b/classes/ruby.bbclass
@@ -1,5 +1,6 @@
1# 1#
2# Copyright (C) 2014 Wind River Systems, Inc. 2# Copyright (C) 2014 Wind River Systems, Inc.
3# Copyright (c) 2024 Bruce Ashfield, Inc.
3# 4#
4DEPENDS += " \ 5DEPENDS += " \
5 ruby-native \ 6 ruby-native \
@@ -24,7 +25,7 @@ def get_rubyversion(p):
24 return found_version 25 return found_version
25 26
26 version = subprocess.Popen([cmd, "--version"], stdout=subprocess.PIPE).communicate()[0] 27 version = subprocess.Popen([cmd, "--version"], stdout=subprocess.PIPE).communicate()[0]
27 28
28 r = re.compile("ruby ([0-9]+\.[0-9]+\.[0-9]+)*") 29 r = re.compile("ruby ([0-9]+\.[0-9]+\.[0-9]+)*")
29 m = r.match(version) 30 m = r.match(version)
30 if m: 31 if m:
@@ -66,7 +67,7 @@ def get_rubygemsversion(p):
66 return found_version 67 return found_version
67 68
68 version = subprocess.Popen([cmd, "env", "gemdir"], stdout=subprocess.PIPE).communicate()[0] 69 version = subprocess.Popen([cmd, "env", "gemdir"], stdout=subprocess.PIPE).communicate()[0]
69 70
70 r = re.compile(".*([0-9]+\.[0-9]+\.[0-9]+)$") 71 r = re.compile(".*([0-9]+\.[0-9]+\.[0-9]+)$")
71 m = r.match(version.decode("utf-8")) 72 m = r.match(version.decode("utf-8"))
72 if m: 73 if m:
@@ -108,6 +109,11 @@ EOF
108} 109}
109 110
110ruby_do_compile() { 111ruby_do_compile() {
112 if [ -f ${UNPACKDIR}/extconf.rb ]; then
113 cp extconf.rb extconf.orig
114 cp ${UNPACKDIR}/extconf.rb extconf.rb
115 fi
116
111 if [ -f extconf.rb -a ! -f extconf.rb.orig ] ; then 117 if [ -f extconf.rb -a ! -f extconf.rb.orig ] ; then
112 grep create_makefile extconf.rb > append2 || (exit 0) 118 grep create_makefile extconf.rb > append2 || (exit 0)
113 ruby_gen_extconf_fix 119 ruby_gen_extconf_fix
@@ -164,3 +170,20 @@ FILES:${PN} += " \
164FILES:${PN}-doc += " \ 170FILES:${PN}-doc += " \
165 ${libdir}/ruby/gems/${RUBY_GEM_VERSION}/doc \ 171 ${libdir}/ruby/gems/${RUBY_GEM_VERSION}/doc \
166 " 172 "
173
174# copied from rubyv2.bbclass
175
176# the ruby dynamic linker just uses plain .so files
177# so we have to supply symlinks as part of the base package
178INSANE_SKIP:${PN} += "dev-so"
179# sadly the shared objects also contain some hard coded
180# host paths, which are not easy to be removed
181INSANE_SKIP:${PN} += "buildpaths"
182# we don't care what is actually needed for the dev-package
183INSANE_SKIP:${PN}-dev += "file-rdeps"
184# same issue for the dev package with buildpaths
185INSANE_SKIP:${PN}-dev += "buildpaths"
186# some of the doc utils contain host specific full paths
187# as they are mostly in binary format we are just going to
188# ignore it here
189INSANE_SKIP:${PN}-doc += "buildpaths"
diff --git a/classes/rubyv2.bbclass b/classes/rubyv2.bbclass
new file mode 100644
index 0000000..3d6654e
--- /dev/null
+++ b/classes/rubyv2.bbclass
@@ -0,0 +1,322 @@
1# copied from: https://layers.openembedded.org/layerindex/branch/master/layer/meta-rubygems/
2#
3# - One local modifcation was made to copy an extconf.rb from UNPACKDIR to the
4# build.
5# - This copy will eventually be deleted, once factoring happens between the
6# two classes.
7
8## SPDX-License-Identifier: MIT, BSD-2-Clause
9## Copyright (c) 2015, Michaƫl Burtin
10## Copyright (c) 2020, Konrad Weihmann
11
12GEMLIB_VERSION = "3.3.0"
13
14GEM_SRC ?= "https://rubygems.org/gems"
15
16# Enforce IPv4 connection - IPv6 seems to be broken
17# nooelint: oelint.vars.specific,oelint.vars.pathhardcode.bindir
18# FETCHCMD_wget ?= "/usr/bin/env wget -t 2 -T 30 --passive-ftp -4"
19
20GEM_NAME ?= ""
21GEM_VERSION ?= "${PV}"
22
23# SRC_URI = "${GEM_SRC}/${GEM_FILENAME}"
24GEMPREFIX = "gem-"
25
26UNPACKDIR ??= "${WORKDIR}/gem-dl"
27
28# S = "${UNPACKDIR}/${GEM_NAME}-${GEM_VERSION}"
29
30GEM_FILENAME = "${GEM_NAME}-${GEM_VERSION}.gem"
31GEM_FILE ?= "${UNPACKDIR}/${GEM_FILENAME}"
32GEM_BUILT_FILE = "${UNPACKDIR}/${GEM_FILENAME}"
33
34GEM_SPEC_FILENAME = "${GEM_FILENAME}spec"
35GEM_SPEC_FILE ?= "${S}/${GEM_SPEC_FILENAME}"
36GEM_SPEC_CACHE ?= "${T}/.gems"
37
38GEM_DIR = "${libdir}/ruby/gems/${GEMLIB_VERSION}"
39RUBY_SITEDIR = "${libdir}/ruby/site_ruby/"
40GEM_HOME = "${D}${GEM_DIR}"
41GEM_PATH:class-target = "${RECIPE_SYSROOT}${GEM_DIR}:${RECIPE_SYSROOT}${GEM_DIR}:${GEM_HOME}"
42GEM_PATH:class-native = "${RECIPE_SYSROOT_NATIVE}${GEM_DIR}:${GEM_HOME}"
43
44# Disable the very strict versioning with ~>
45GEM_DISABLE_STRICT_VER ?= "1"
46
47GEM_INSTALL_FLAGS ?= ""
48
49# Use the following to define extra depend/rdepends
50# which cannot be seen by the package updater
51EXTRA_RDEPENDS ?= ""
52EXTRA_DEPENDS ?= ""
53
54RUBYLIB_EXTRA_PATHS ?= ""
55
56def extra_paths(d):
57 res = (d.getVar('RUBYLIB_EXTRA_PATHS') or '').split(' ')
58 if res:
59 return ':' + ':'.join(res)
60 return ''
61
62RUBYLIB:class-target = "${STAGING_LIBDIR_NATIVE}/ruby/${GEMLIB_VERSION}/${@get_build_platform_folder(d)}${@extra_paths(d)}"
63RUBYPLATFORM ?= "ruby"
64RUBYPLATFORM:class-target ?= "${@get_target_platform_folder(d)}"
65CFLAGS:append = " -DHAVE_GCC_CAS"
66
67def get_gem_name_from_bpn(d):
68 bpn = (d.getVar('BPN', True) or "")
69 gemPrefix = (d.getVar('GEMPREFIX', True) or "")
70 if bpn.startswith(gemPrefix):
71 gemName = bpn[len(gemPrefix):]
72 else:
73 gemName = bpn
74 return gemName
75
76def get_build_platform_folder(d):
77 build_arch = d.getVar("BUILD_ARCH")
78 build_os = d.getVar("BUILD_OS")
79 if build_os.endswith("linux"):
80 build_os = build_os.replace('linux', 'linux-gnu')
81 return build_arch + "-" + build_os
82
83def get_target_platform_folder(d):
84 target_arch = d.getVar("HOST_ARCH")
85 target_os = d.getVar("HOST_OS")
86 if target_os.endswith("linux"):
87 target_os = target_os.replace('linux', 'linux-gnu')
88 return target_arch + "-" + target_os
89
90do_gem_unpack() {
91 return
92
93 export RUBYLIB=${RUBYLIB}
94
95 cd ${UNPACKDIR}
96 # GEM_FILE might not exist if SRC_URI was overloaded
97 [ ! -e ${GEM_FILE} ] && return 0
98
99 gem unpack -V ${GEM_FILE}
100}
101
102DEPENDS:append = " ruby-native ${EXTRA_DEPENDS}"
103DEPENDS:append:class-target = " ruby ruby-native ${EXTRA_DEPENDS}"
104
105python () {
106 d.appendVarFlag('do_gem_unpack', 'depends', ' ruby-native:do_populate_sysroot')
107}
108
109do_gem_unpack[vardepsexclude] += "prefix_native"
110addtask do_gem_unpack after do_unpack before do_patch
111
112python do_unpack:append() {
113 # as the actual unpack happens in do_gem_unpack
114 # we will work around insane-class checks
115 # by just creating the needed directories here
116 os.makedirs(d.expand('${S}'), exist_ok=True)
117 os.makedirs(d.expand('${UNPACKDIR}'), exist_ok=True)
118}
119
120do_generate_spec() {
121 export RUBYLIB=${RUBYLIB}
122 export GEM_SPEC=${GEM_SPEC_CACHE}
123
124 # GEM_FILE might not exist if SRC_URI was overloaded
125 [ ! -e ${GEM_FILE} ] && return 0
126
127 gem spec -V --ruby ${GEM_FILE} > ${GEM_SPEC_FILE}
128
129 # lift the version bindings to be less strict
130 if [ "${GEM_DISABLE_STRICT_VER}" -eq "1" ]; then
131 sed -i 's#=[[:space:]]*[0-9]\+\.[0-9]\+#!=0#g' ${GEM_SPEC_FILE}
132 sed -i 's#~>#>=#g' ${GEM_SPEC_FILE}
133 sed -i 's#<=[[:space:]]*[0-9]\+\.[0-9]\+\.[0-9]\+#!=0#g' ${GEM_SPEC_FILE}
134 sed -i 's#<[[:space:]]*[0-9]\+\.[0-9]\+\.[0-9]\+#!=0#g' ${GEM_SPEC_FILE}
135 sed -i 's#<[[:space:]]*[0-9]\+\.[0-9]\+#!=0#g' ${GEM_SPEC_FILE}
136 sed -i 's#>!=#!=#g' ${GEM_SPEC_FILE}
137 sed -i 's#!!=#!=#g' ${GEM_SPEC_FILE}
138 sed -i 's#<!=0#!=0#g' ${GEM_SPEC_FILE}
139 fi
140}
141
142do_generate_spec[vardepsexclude] += "prefix_native"
143addtask do_generate_spec after do_gem_unpack before do_patch
144
145python do_arch_patch_config() {
146 import re
147 if bb.data.inherits_class('native', d):
148 return
149 target_cpu, target_vendor, target_os = get_target_platform_folder(d).split('-')
150
151 _map = {
152 "AR": d.expand("${AR}"),
153 "arch": d.expand("${RUBYPLATFORM}"),
154 "archincludedir": "$(includedir)",
155 "archlibdir": "$(libdir)",
156 "AS": d.expand("${AS}"),
157 "CC": d.expand("${CC}"),
158 "CFLAGS": d.expand("${CFLAGS}"),
159 "CPP": d.expand("${CPP}"),
160 "CPPFLAGS": d.expand("${CPPFLAGS}"),
161 "cppflags": d.expand("${CPPFLAGS}"),
162 "CROSS_COMPILING": "yes",
163 "CXX": d.expand("${CXX}"),
164 "CXXFLAGS": d.expand("${CFLAGS}"),
165 "DLEXT": d.expand("so.${PV}"),
166 "host_alias": "-".join([target_cpu, target_vendor]),
167 "host_cpu": target_cpu,
168 "host_os": target_os,
169 "host": get_target_platform_folder(d),
170 "includedir": d.expand("${STAGING_INCDIR}"),
171 "LD": d.expand("${LD}"),
172 "LDFLAGS": d.expand("${LDFLAGS}"),
173 "libdir": d.getVar("STAGING_LIBDIR"),
174 "libexecdir": "$(exec_prefix)/libexec",
175 "NM": d.expand("${NM}"),
176 "OBJDUMP": d.expand("${OBJDUMP}"),
177 "RANLIB": d.expand("${RANLIB}"),
178 "SOEXT": d.expand("so.${PV}"),
179 "STRIP": d.expand("${STRIP}"),
180 "target_alias": "-".join([target_cpu, target_vendor]),
181 "target_cpu": target_cpu,
182 "target_os": target_os,
183 "target": get_target_platform_folder(d),
184 "TEST_RUNNABLE": "no",
185 #"DLDFLAGS": d.expand("${LDFLAGS}"),
186 }
187
188 cnt = ""
189 for item in d.expand("${RUBYLIB}").split(':'):
190 item = os.path.join(item, 'rbconfig.rb')
191 if not os.path.isfile(item) or not os.path.exists(item):
192 continue
193 with open(item) as i:
194 cnt = i.read()
195
196 for m in re.finditer(r'^(\s+|\t+)CONFIG\[\"(?P<var>.*)\"\]\s+=\s+\"(?P<value>.*)\"$', cnt, re.MULTILINE):
197 if m.group("var") in _map:
198 _rpl = ' CONFIG["{}"] = "{}"'.format(m.group("var"), _map[m.group("var")])
199 bb.note("Replace {} by {}".format(m.group(0), _rpl))
200 cnt = cnt.replace(m.group(0), _rpl)
201
202 with open(item, "w") as o:
203 o.write(cnt)
204}
205
206do_arch_patch_config[doc] = "patches the correct compiler settings into the cross template"
207addtask do_arch_patch_config after do_generate_spec do_gem_unpack before do_compile
208
209rubyv2_do_compile() {
210 export GEM_PATH=${GEM_PATH}
211 export GEM_HOME=${GEM_HOME}
212 export GEM_SPEC=${GEM_SPEC_CACHE}
213 export RUBYLIB=${RUBYLIB}
214
215 export LANG="en_US.UTF-8"
216 export LANGUAGE="en_US.UTF-8"
217 export LC_ALL="en_US.UTF-8"
218
219 if [ -f ${UNPACKDIR}/extconf.rb ]; then
220 cp extconf.rb extconf.orig
221 cp ${UNPACKDIR}/extconf.rb extconf.rb
222 fi
223
224 # Older versions of gem build don't understand -o flag, so try it once more without
225 # it, if the command is failing
226 gem build -V ${GEM_SPEC_FILE} -o ${GEM_BUILT_FILE} || gem build -V ${GEM_SPEC_FILE}
227
228 # for the install step
229 do_generate_spec
230}
231
232python do_rubyv2_fix_libs() {
233 # as ruby dynloader expects the shared .so files
234 # without extension we will create symlinks to the
235 # properly versioned file
236 for root, dirs, files in os.walk(d.expand("${GEM_HOME}")):
237 for f in files:
238 if f.endswith(d.expand("so.${PV}")):
239 _filename = os.path.basename(f)
240 while "." in _filename:
241 try:
242 os.symlink(os.path.basename(f), os.path.join(root, _filename))
243 except:
244 pass
245 _filename, _ = os.path.splitext(_filename)
246}
247
248RUBY_INSTALL_EXTRA_FLAGS ?= ""
249
250rubyv2_do_install() {
251 export GEM_PATH=${GEM_PATH}
252 export GEM_SPEC=${GEM_SPEC_CACHE}
253 export RUBYLIB=${RUBYLIB}
254
255 gem uninstall ${GEM_NAME} --version ${GEM_VERSION} -x -q -V || true
256
257 gem install --local --bindir ${D}${bindir} ${GEM_BUILT_FILE} --install-dir=${GEM_HOME} -E --backtrace --norc --no-user-install --ignore-dependencies --force --conservative -V ${RUBY_INSTALL_EXTRA_FLAGS} -- ${GEM_INSTALL_FLAGS}
258
259 # remove all object files
260 find ${GEM_HOME} -name "*.o" -type f -exec rm -f {} \;
261}
262
263EXPORT_FUNCTIONS do_compile do_install
264do_install[postfuncs] += "do_rubyv2_fix_libs"
265
266PACKAGES =+ "${PN}-examples ${PN}-tests"
267
268FILES:${PN}-dbg += "\
269 /usr/src/debug/* \
270 ${libdir}/ruby/**/.debug \
271"
272FILES:${PN}-staticdev += "\
273 ${libdir}/ruby/gems/gems/**/.libs/*.a \
274"
275FILES:${PN}-dev += "\
276 ${GEM_DIR}/extensions/*/*/*/gem_make.out \
277 ${GEM_DIR}/extensions/*/*/*/mkmf.log \
278 ${GEM_DIR}/build_info \
279 ${GEM_DIR}/cache \
280 ${GEM_DIR}/gems/*/debian.template \
281 ${GEM_DIR}/gems/*/ext/ \
282 ${GEM_DIR}/gems/*/spec/ \
283 ${GEM_DIR}/gems/*/lib/generators \
284 ${GEM_DIR}/gems/*/patches \
285"
286FILES:${PN}-tests = "\
287 ${GEM_DIR}/gems/*/tests \
288 ${GEM_DIR}/gems/*/test \
289"
290FILES:${PN}-examples = "\
291 ${GEM_DIR}/gems/*/example \
292 ${GEM_DIR}/gems/*/samples \
293"
294FILES:${PN}-doc += "\
295 ${GEM_DIR}/gems/*/doc \
296 ${GEM_DIR}/doc \
297"
298FILES:${PN} += "\
299 ${GEM_DIR}/extensions \
300 ${GEM_DIR}/gems \
301 ${GEM_DIR}/specifications \
302 ${RUBY_SITEDIR} \
303 ${libdir}/ruby/gems/${GEMLIB_VERSION}/plugins \
304"
305
306RDEPENDS:${PN}:append:class-target = " ruby ${EXTRA_RDEPENDS}"
307RDEPENDS:${PN}-tests:append:class-target = " ruby"
308
309# the ruby dynamic linker just uses plain .so files
310# so we have to supply symlinks as part of the base package
311INSANE_SKIP:${PN} += "dev-so"
312# sadly the shared objects also contain some hard coded
313# host paths, which are not easy to be removed
314INSANE_SKIP:${PN} += "buildpaths"
315# we don't care what is actually needed for the dev-package
316INSANE_SKIP:${PN}-dev += "file-rdeps"
317# same issue for the dev package with buildpaths
318INSANE_SKIP:${PN}-dev += "buildpaths"
319# some of the doc utils contain host specific full paths
320# as they are mostly in binary format we are just going to
321# ignore it here
322INSANE_SKIP:${PN}-doc += "buildpaths"
diff --git a/recipes-support/puppet/puppet_5.4.0.bb b/recipes-support/puppet/puppet_7.33.0.bb
index c207e40..c207e40 100644
--- a/recipes-support/puppet/puppet_5.4.0.bb
+++ b/recipes-support/puppet/puppet_7.33.0.bb