summaryrefslogtreecommitdiffstats
path: root/meta/classes/package_ipk.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/package_ipk.bbclass')
-rw-r--r--meta/classes/package_ipk.bbclass443
1 files changed, 443 insertions, 0 deletions
diff --git a/meta/classes/package_ipk.bbclass b/meta/classes/package_ipk.bbclass
new file mode 100644
index 0000000000..a633cfcc76
--- /dev/null
+++ b/meta/classes/package_ipk.bbclass
@@ -0,0 +1,443 @@
1inherit package
2
3IMAGE_PKGTYPE ?= "ipk"
4
5IPKGCONF_TARGET = "${WORKDIR}/opkg.conf"
6IPKGCONF_SDK = "${WORKDIR}/opkg-sdk.conf"
7
8PKGWRITEDIRIPK = "${WORKDIR}/deploy-ipks"
9
10# Program to be used to build opkg packages
11OPKGBUILDCMD ??= "opkg-build"
12
13OPKG_ARGS = "-f $INSTALL_CONF_IPK -o $INSTALL_ROOTFS_IPK --force_postinstall --prefer-arch-to-version"
14OPKG_ARGS += "${@['', '--no-install-recommends'][d.getVar("NO_RECOMMENDATIONS", True) == "1"]}"
15OPKG_ARGS += "${@['', '--add-exclude ' + ' --add-exclude '.join((d.getVar('PACKAGE_EXCLUDE', True) or "").split())][(d.getVar("PACKAGE_EXCLUDE", True) or "") != ""]}"
16
17OPKGLIBDIR = "${localstatedir}/lib"
18
19package_tryout_install_multilib_ipk() {
20 #try install multilib
21 multilib_tryout_dirs=""
22 for item in ${MULTILIB_VARIANTS}; do
23 local target_rootfs="${MULTILIB_TEMP_ROOTFS}/${item}"
24 local ipkg_args="${OPKG_ARGS}"
25 local selected_pkg=""
26 local pkgname_prefix="${item}-"
27 local pkgname_len=${#pkgname_prefix}
28 for pkg in ${INSTALL_PACKAGES_MULTILIB_IPK}; do
29 local pkgname=$(echo $pkg | awk -v var=$pkgname_len '{ pkgname=substr($1, 1, var); print pkgname; }' )
30 if [ ${pkgname} = ${pkgname_prefix} ]; then
31 selected_pkg="${selected_pkg} ${pkg}"
32 fi
33 done
34 if [ ! -z "${selected_pkg}" ]; then
35 rm -f ${target_rootfs}
36 mkdir -p ${target_rootfs}/${opkglibdir}
37 opkg-cl ${ipkg_args} update
38 opkg-cl ${ipkg_args} install ${selected_pkg}
39 multilib_tryout_dirs="${multilib_tryout_dirs} ${target_rootfs}"
40 fi
41 done
42}
43
44split_multilib_packages() {
45 INSTALL_PACKAGES_NORMAL_IPK=""
46 INSTALL_PACKAGES_MULTILIB_IPK=""
47 for pkg in ${INSTALL_PACKAGES_IPK}; do
48 is_multilib=0
49 for item in ${MULTILIB_VARIANTS}; do
50 local pkgname_prefix="${item}-"
51 local pkgname_len=${#pkgname_prefix}
52 local pkgname=$(echo $pkg | awk -v var=$pkgname_len '{ pkgname=substr($1, 1, var); print pkgname; }' )
53 if [ ${pkgname} = ${pkgname_prefix} ]; then
54 is_multilib=1
55 break
56 fi
57 done
58
59 if [ ${is_multilib} = 0 ]; then
60 INSTALL_PACKAGES_NORMAL_IPK="${INSTALL_PACKAGES_NORMAL_IPK} ${pkg}"
61 else
62 INSTALL_PACKAGES_MULTILIB_IPK="${INSTALL_PACKAGES_MULTILIB_IPK} ${pkg}"
63 fi
64 done
65}
66
67#
68# install a bunch of packages using opkg
69# the following shell variables needs to be set before calling this func:
70# INSTALL_ROOTFS_IPK - install root dir
71# INSTALL_CONF_IPK - configuration file
72# INSTALL_PACKAGES_IPK - packages to be installed
73# INSTALL_PACKAGES_ATTEMPTONLY_IPK - packages attemped to be installed only
74# INSTALL_PACKAGES_LINGUAS_IPK - additional packages for uclibc
75# INSTALL_TASK_IPK - task name
76
77package_install_internal_ipk() {
78
79 local target_rootfs="${INSTALL_ROOTFS_IPK}"
80 local package_attemptonly="${INSTALL_PACKAGES_ATTEMPTONLY_IPK}"
81 local package_linguas="${INSTALL_PACKAGES_LINGUAS_IPK}"
82 local task="${INSTALL_TASK_IPK}"
83
84 split_multilib_packages
85
86 local package_to_install="${INSTALL_PACKAGES_NORMAL_IPK}"
87 local package_multilib="${INSTALL_PACKAGES_MULTILIB_IPK}"
88
89 mkdir -p ${target_rootfs}${OPKGLIBDIR}/opkg
90 touch ${target_rootfs}${OPKGLIBDIR}/opkg/status
91
92 local ipkg_args="${OPKG_ARGS}"
93
94 opkg-cl ${ipkg_args} update
95
96 for i in ${package_linguas}; do
97 opkg-cl ${ipkg_args} install $i
98 done
99
100 if [ ! -z "${package_to_install}" ]; then
101 opkg-cl ${ipkg_args} install ${package_to_install}
102 fi
103
104 if [ ! -z "${package_attemptonly}" ]; then
105 opkg-cl ${ipkg_args} install ${package_attemptonly} > "`dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" || true
106 fi
107
108 package_tryout_install_multilib_ipk
109 if [ ! -z "${MULTILIB_CHECK_FILE}" ]; then
110 #sanity check
111 multilib_sanity_check ${target_rootfs} ${multilib_tryout_dirs} || exit 1
112 fi
113
114 if [ ! -z "${package_multilib}" ]; then
115 opkg-cl ${ipkg_args} install ${package_multilib}
116 fi
117}
118
119ipk_log_check() {
120 target="$1"
121 lf_path="$2"
122
123 lf_txt="`cat $lf_path`"
124 for keyword_die in "exit 1" "Collected errors" ERR Fail
125 do
126 if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1
127 then
128 echo "log_check: There were error messages in the logfile"
129 printf "log_check: Matched keyword: [$keyword_die]\n\n"
130 echo "$lf_txt" | grep -v log_check | grep -C 5 "$keyword_die"
131 echo ""
132 do_exit=1
133 fi
134 done
135 test "$do_exit" = 1 && exit 1
136 true
137}
138
139#
140# Update the Packages index files in ${DEPLOY_DIR_IPK}
141#
142package_update_index_ipk () {
143 #set -x
144
145 ipkgarchs="${ALL_MULTILIB_PACKAGE_ARCHS} ${SDK_PACKAGE_ARCHS}"
146
147 if [ ! -z "${DEPLOY_KEEP_PACKAGES}" ]; then
148 return
149 fi
150
151 packagedirs="${DEPLOY_DIR_IPK}"
152 for arch in $ipkgarchs; do
153 packagedirs="$packagedirs ${DEPLOY_DIR_IPK}/$arch"
154 done
155
156 multilib_archs="${MULTILIB_ARCHS}"
157 for arch in $multilib_archs; do
158 packagedirs="$packagedirs ${DEPLOY_DIR_IPK}/$arch"
159 done
160
161 found=0
162 for pkgdir in $packagedirs; do
163 if [ -e $pkgdir/ ]; then
164 found=1
165 touch $pkgdir/Packages
166 flock $pkgdir/Packages.flock -c "opkg-make-index -r $pkgdir/Packages -p $pkgdir/Packages -m $pkgdir/"
167 fi
168 done
169 if [ "$found" != "1" ]; then
170 bbfatal "There are no packages in ${DEPLOY_DIR_IPK}!"
171 fi
172}
173
174#
175# Generate an ipkg conf file ${IPKGCONF_TARGET} suitable for use against
176# the target system and an ipkg conf file ${IPKGCONF_SDK} suitable for
177# use against the host system in sdk builds
178#
179package_generate_ipkg_conf () {
180 package_generate_archlist
181 echo "src oe file:${DEPLOY_DIR_IPK}" >> ${IPKGCONF_SDK}
182 ipkgarchs="${SDK_PACKAGE_ARCHS}"
183 for arch in $ipkgarchs; do
184 if [ -e ${DEPLOY_DIR_IPK}/$arch/Packages ] ; then
185 echo "src oe-$arch file:${DEPLOY_DIR_IPK}/$arch" >> ${IPKGCONF_SDK}
186 fi
187 done
188
189 echo "src oe file:${DEPLOY_DIR_IPK}" >> ${IPKGCONF_TARGET}
190 ipkgarchs="${ALL_MULTILIB_PACKAGE_ARCHS}"
191 for arch in $ipkgarchs; do
192 if [ -e ${DEPLOY_DIR_IPK}/$arch/Packages ] ; then
193 echo "src oe-$arch file:${DEPLOY_DIR_IPK}/$arch" >> ${IPKGCONF_TARGET}
194 fi
195 done
196}
197
198package_generate_archlist () {
199 ipkgarchs="${SDK_PACKAGE_ARCHS}"
200 priority=1
201 for arch in $ipkgarchs; do
202 echo "arch $arch $priority" >> ${IPKGCONF_SDK}
203 priority=$(expr $priority + 5)
204 done
205
206 ipkgarchs="${ALL_MULTILIB_PACKAGE_ARCHS}"
207 priority=1
208 for arch in $ipkgarchs; do
209 echo "arch $arch $priority" >> ${IPKGCONF_TARGET}
210 priority=$(expr $priority + 5)
211 done
212}
213
214python do_package_ipk () {
215 import re, copy
216 import textwrap
217 import subprocess
218
219 workdir = d.getVar('WORKDIR', True)
220 outdir = d.getVar('PKGWRITEDIRIPK', True)
221 tmpdir = d.getVar('TMPDIR', True)
222 pkgdest = d.getVar('PKGDEST', True)
223 if not workdir or not outdir or not tmpdir:
224 bb.error("Variables incorrectly set, unable to package")
225 return
226
227 packages = d.getVar('PACKAGES', True)
228 if not packages or packages == '':
229 bb.debug(1, "No packages; nothing to do")
230 return
231
232 # We're about to add new packages so the index needs to be checked
233 # so remove the appropriate stamp file.
234 if os.access(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN"), os.R_OK):
235 os.unlink(os.path.join(tmpdir, "stamps", "IPK_PACKAGE_INDEX_CLEAN"))
236
237 for pkg in packages.split():
238 localdata = bb.data.createCopy(d)
239 root = "%s/%s" % (pkgdest, pkg)
240
241 lf = bb.utils.lockfile(root + ".lock")
242
243 localdata.setVar('ROOT', '')
244 localdata.setVar('ROOT_%s' % pkg, root)
245 pkgname = localdata.getVar('PKG_%s' % pkg, True)
246 if not pkgname:
247 pkgname = pkg
248 localdata.setVar('PKG', pkgname)
249
250 localdata.setVar('OVERRIDES', pkg)
251
252 bb.data.update_data(localdata)
253 basedir = os.path.join(os.path.dirname(root))
254 arch = localdata.getVar('PACKAGE_ARCH', True)
255 pkgoutdir = "%s/%s" % (outdir, arch)
256 bb.utils.mkdirhier(pkgoutdir)
257 os.chdir(root)
258 from glob import glob
259 g = glob('*')
260 try:
261 del g[g.index('CONTROL')]
262 del g[g.index('./CONTROL')]
263 except ValueError:
264 pass
265 if not g and localdata.getVar('ALLOW_EMPTY') != "1":
266 bb.note("Not creating empty archive for %s-%s-%s" % (pkg, localdata.getVar('PKGV', True), localdata.getVar('PKGR', True)))
267 bb.utils.unlockfile(lf)
268 continue
269
270 controldir = os.path.join(root, 'CONTROL')
271 bb.utils.mkdirhier(controldir)
272 try:
273 ctrlfile = open(os.path.join(controldir, 'control'), 'w')
274 except OSError:
275 bb.utils.unlockfile(lf)
276 raise bb.build.FuncFailed("unable to open control file for writing.")
277
278 fields = []
279 pe = d.getVar('PKGE', True)
280 if pe and int(pe) > 0:
281 fields.append(["Version: %s:%s-%s\n", ['PKGE', 'PKGV', 'PKGR']])
282 else:
283 fields.append(["Version: %s-%s\n", ['PKGV', 'PKGR']])
284 fields.append(["Description: %s\n", ['DESCRIPTION']])
285 fields.append(["Section: %s\n", ['SECTION']])
286 fields.append(["Priority: %s\n", ['PRIORITY']])
287 fields.append(["Maintainer: %s\n", ['MAINTAINER']])
288 fields.append(["License: %s\n", ['LICENSE']])
289 fields.append(["Architecture: %s\n", ['PACKAGE_ARCH']])
290 fields.append(["OE: %s\n", ['PN']])
291 fields.append(["Homepage: %s\n", ['HOMEPAGE']])
292
293 def pullData(l, d):
294 l2 = []
295 for i in l:
296 l2.append(d.getVar(i, True))
297 return l2
298
299 ctrlfile.write("Package: %s\n" % pkgname)
300 # check for required fields
301 try:
302 for (c, fs) in fields:
303 for f in fs:
304 if localdata.getVar(f) is None:
305 raise KeyError(f)
306 # Special behavior for description...
307 if 'DESCRIPTION' in fs:
308 summary = localdata.getVar('SUMMARY', True) or localdata.getVar('DESCRIPTION', True) or "."
309 ctrlfile.write('Description: %s\n' % summary)
310 description = localdata.getVar('DESCRIPTION', True) or "."
311 description = textwrap.dedent(description).strip()
312 if '\\n' in description:
313 # Manually indent
314 for t in description.split('\\n'):
315 # We don't limit the width when manually indent, but we do
316 # need the textwrap.fill() to set the initial_indent and
317 # subsequent_indent, so set a large width
318 ctrlfile.write('%s\n' % textwrap.fill(t.strip(), width=100000, initial_indent=' ', subsequent_indent=' '))
319 else:
320 # Auto indent
321 ctrlfile.write('%s\n' % textwrap.fill(description, width=74, initial_indent=' ', subsequent_indent=' '))
322 else:
323 ctrlfile.write(c % tuple(pullData(fs, localdata)))
324 except KeyError:
325 import sys
326 (type, value, traceback) = sys.exc_info()
327 ctrlfile.close()
328 bb.utils.unlockfile(lf)
329 raise bb.build.FuncFailed("Missing field for ipk generation: %s" % value)
330 # more fields
331
332 mapping_rename_hook(localdata)
333
334 def debian_cmp_remap(var):
335 # In debian '>' and '<' do not mean what it appears they mean
336 # '<' = less or equal
337 # '>' = greater or equal
338 # adjust these to the '<<' and '>>' equivalents
339 #
340 for dep in var:
341 for i, v in enumerate(var[dep]):
342 if (v or "").startswith("< "):
343 var[dep][i] = var[dep][i].replace("< ", "<< ")
344 elif (v or "").startswith("> "):
345 var[dep][i] = var[dep][i].replace("> ", ">> ")
346
347 rdepends = bb.utils.explode_dep_versions2(localdata.getVar("RDEPENDS", True) or "")
348 debian_cmp_remap(rdepends)
349 rrecommends = bb.utils.explode_dep_versions2(localdata.getVar("RRECOMMENDS", True) or "")
350 debian_cmp_remap(rrecommends)
351 rsuggests = bb.utils.explode_dep_versions2(localdata.getVar("RSUGGESTS", True) or "")
352 debian_cmp_remap(rsuggests)
353 rprovides = bb.utils.explode_dep_versions2(localdata.getVar("RPROVIDES", True) or "")
354 debian_cmp_remap(rprovides)
355 rreplaces = bb.utils.explode_dep_versions2(localdata.getVar("RREPLACES", True) or "")
356 debian_cmp_remap(rreplaces)
357 rconflicts = bb.utils.explode_dep_versions2(localdata.getVar("RCONFLICTS", True) or "")
358 debian_cmp_remap(rconflicts)
359
360 if rdepends:
361 ctrlfile.write("Depends: %s\n" % bb.utils.join_deps(rdepends))
362 if rsuggests:
363 ctrlfile.write("Suggests: %s\n" % bb.utils.join_deps(rsuggests))
364 if rrecommends:
365 ctrlfile.write("Recommends: %s\n" % bb.utils.join_deps(rrecommends))
366 if rprovides:
367 ctrlfile.write("Provides: %s\n" % bb.utils.join_deps(rprovides))
368 if rreplaces:
369 ctrlfile.write("Replaces: %s\n" % bb.utils.join_deps(rreplaces))
370 if rconflicts:
371 ctrlfile.write("Conflicts: %s\n" % bb.utils.join_deps(rconflicts))
372 src_uri = localdata.getVar("SRC_URI", True) or "None"
373 if src_uri:
374 src_uri = re.sub("\s+", " ", src_uri)
375 ctrlfile.write("Source: %s\n" % " ".join(src_uri.split()))
376 ctrlfile.close()
377
378 for script in ["preinst", "postinst", "prerm", "postrm"]:
379 scriptvar = localdata.getVar('pkg_%s' % script, True)
380 if not scriptvar:
381 continue
382 try:
383 scriptfile = open(os.path.join(controldir, script), 'w')
384 except OSError:
385 bb.utils.unlockfile(lf)
386 raise bb.build.FuncFailed("unable to open %s script file for writing." % script)
387 scriptfile.write(scriptvar)
388 scriptfile.close()
389 os.chmod(os.path.join(controldir, script), 0755)
390
391 conffiles_str = localdata.getVar("CONFFILES", True)
392 if conffiles_str:
393 try:
394 conffiles = open(os.path.join(controldir, 'conffiles'), 'w')
395 except OSError:
396 bb.utils.unlockfile(lf)
397 raise bb.build.FuncFailed("unable to open conffiles for writing.")
398 for f in conffiles_str.split():
399 if os.path.exists(oe.path.join(root, f)):
400 conffiles.write('%s\n' % f)
401 conffiles.close()
402
403 os.chdir(basedir)
404 ret = subprocess.call("PATH=\"%s\" %s %s %s" % (localdata.getVar("PATH", True),
405 d.getVar("OPKGBUILDCMD",1), pkg, pkgoutdir), shell=True)
406 if ret != 0:
407 bb.utils.unlockfile(lf)
408 raise bb.build.FuncFailed("opkg-build execution failed")
409
410 bb.utils.prunedir(controldir)
411 bb.utils.unlockfile(lf)
412
413}
414
415SSTATETASKS += "do_package_write_ipk"
416do_package_write_ipk[sstate-name] = "deploy-ipk"
417do_package_write_ipk[sstate-inputdirs] = "${PKGWRITEDIRIPK}"
418do_package_write_ipk[sstate-outputdirs] = "${DEPLOY_DIR_IPK}"
419
420python do_package_write_ipk_setscene () {
421 sstate_setscene(d)
422}
423addtask do_package_write_ipk_setscene
424
425python () {
426 if d.getVar('PACKAGES', True) != '':
427 deps = ' opkg-utils-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot'
428 d.appendVarFlag('do_package_write_ipk', 'depends', deps)
429 d.setVarFlag('do_package_write_ipk', 'fakeroot', "1")
430}
431
432python do_package_write_ipk () {
433 bb.build.exec_func("read_subpackage_metadata", d)
434 bb.build.exec_func("do_package_ipk", d)
435}
436do_package_write_ipk[dirs] = "${PKGWRITEDIRIPK}"
437do_package_write_ipk[cleandirs] = "${PKGWRITEDIRIPK}"
438do_package_write_ipk[umask] = "022"
439addtask package_write_ipk before do_package_write after do_packagedata do_package
440
441PACKAGEINDEXES += "[ ! -e ${DEPLOY_DIR_IPK} ] || package_update_index_ipk;"
442PACKAGEINDEXDEPS += "opkg-utils-native:do_populate_sysroot"
443PACKAGEINDEXDEPS += "opkg-native:do_populate_sysroot"