diff options
Diffstat (limited to 'meta/classes/package_rpm.bbclass')
-rw-r--r-- | meta/classes/package_rpm.bbclass | 1201 |
1 files changed, 1201 insertions, 0 deletions
diff --git a/meta/classes/package_rpm.bbclass b/meta/classes/package_rpm.bbclass new file mode 100644 index 0000000000..36bad09ea1 --- /dev/null +++ b/meta/classes/package_rpm.bbclass | |||
@@ -0,0 +1,1201 @@ | |||
1 | inherit package | ||
2 | |||
3 | IMAGE_PKGTYPE ?= "rpm" | ||
4 | |||
5 | RPM="rpm" | ||
6 | RPMBUILD="rpmbuild" | ||
7 | |||
8 | PKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms" | ||
9 | PKGWRITEDIRSRPM = "${DEPLOY_DIR}/sources/deploy-srpm" | ||
10 | |||
11 | # Maintaining the perfile dependencies has singificant overhead when writing the | ||
12 | # packages. When set, this value merges them for efficiency. | ||
13 | MERGEPERFILEDEPS = "1" | ||
14 | |||
15 | # | ||
16 | # Update the packages indexes ${DEPLOY_DIR_RPM} | ||
17 | # | ||
18 | package_update_index_rpm () { | ||
19 | if [ ! -z "${DEPLOY_KEEP_PACKAGES}" ]; then | ||
20 | return | ||
21 | fi | ||
22 | |||
23 | sdk_archs=`echo "${SDK_PACKAGE_ARCHS}" | tr - _` | ||
24 | |||
25 | target_archs="" | ||
26 | for i in ${MULTILIB_PREFIX_LIST} ; do | ||
27 | old_IFS="$IFS" | ||
28 | IFS=":" | ||
29 | set $i | ||
30 | IFS="$old_IFS" | ||
31 | shift # remove mlib | ||
32 | while [ -n "$1" ]; do | ||
33 | target_archs="$target_archs $1" | ||
34 | shift | ||
35 | done | ||
36 | done | ||
37 | |||
38 | # FIXME stopgap for broken "bitbake package-index" since MULTILIB_PREFIX_LIST isn't set for that | ||
39 | if [ "$target_archs" = "" ] ; then | ||
40 | target_archs="${ALL_MULTILIB_PACKAGE_ARCHS}" | ||
41 | fi | ||
42 | |||
43 | target_archs=`echo "$target_archs" | tr - _` | ||
44 | |||
45 | archs=`for arch in $target_archs $sdk_archs ; do | ||
46 | echo $arch | ||
47 | done | sort | uniq` | ||
48 | |||
49 | found=0 | ||
50 | for arch in $archs; do | ||
51 | if [ -d ${DEPLOY_DIR_RPM}/$arch ] ; then | ||
52 | createrepo --update -q ${DEPLOY_DIR_RPM}/$arch | ||
53 | found=1 | ||
54 | fi | ||
55 | done | ||
56 | if [ "$found" != "1" ]; then | ||
57 | bbfatal "There are no packages in ${DEPLOY_DIR_RPM}!" | ||
58 | fi | ||
59 | } | ||
60 | |||
61 | rpm_log_check() { | ||
62 | target="$1" | ||
63 | lf_path="$2" | ||
64 | |||
65 | lf_txt="`cat $lf_path`" | ||
66 | for keyword_die in "unpacking of archive failed" "Cannot find package" "exit 1" ERR Fail | ||
67 | do | ||
68 | if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1 | ||
69 | then | ||
70 | echo "log_check: There were error messages in the logfile" | ||
71 | printf "log_check: Matched keyword: [$keyword_die]\n\n" | ||
72 | echo "$lf_txt" | grep -v log_check | grep -C 5 -i "$keyword_die" | ||
73 | echo "" | ||
74 | do_exit=1 | ||
75 | fi | ||
76 | done | ||
77 | test "$do_exit" = 1 && exit 1 | ||
78 | true | ||
79 | } | ||
80 | |||
81 | # Translate the RPM/Smart format names to the OE multilib format names | ||
82 | # Input via stdin (only the first item per line is converted!) | ||
83 | # Output via stdout | ||
84 | translate_smart_to_oe() { | ||
85 | arg1="$1" | ||
86 | |||
87 | # Dump installed packages | ||
88 | while read pkg arch other ; do | ||
89 | found=0 | ||
90 | if [ -z "$pkg" ]; then | ||
91 | continue | ||
92 | fi | ||
93 | new_pkg=$pkg | ||
94 | fixed_arch=`echo "$arch" | tr _ -` | ||
95 | for i in ${MULTILIB_PREFIX_LIST} ; do | ||
96 | old_IFS="$IFS" | ||
97 | IFS=":" | ||
98 | set $i | ||
99 | IFS="$old_IFS" | ||
100 | mlib="$1" | ||
101 | shift | ||
102 | while [ -n "$1" ]; do | ||
103 | cmp_arch=$1 | ||
104 | shift | ||
105 | fixed_cmp_arch=`echo "$cmp_arch" | tr _ -` | ||
106 | if [ "$fixed_arch" = "$fixed_cmp_arch" ]; then | ||
107 | if [ "$mlib" = "default" ]; then | ||
108 | new_pkg="$pkg" | ||
109 | new_arch=$cmp_arch | ||
110 | else | ||
111 | new_pkg="$mlib-$pkg" | ||
112 | # We need to strip off the ${mlib}_ prefix on the arch | ||
113 | new_arch=${cmp_arch#${mlib}_} | ||
114 | fi | ||
115 | # Workaround for bug 3565 | ||
116 | # Simply look to see if we know of a package with that name, if not try again! | ||
117 | filename=`ls ${PKGDATA_DIR}/runtime-reverse/$new_pkg 2>/dev/null | head -n 1` | ||
118 | if [ -n "$filename" ] ; then | ||
119 | found=1 | ||
120 | break | ||
121 | fi | ||
122 | # 'real' code | ||
123 | # found=1 | ||
124 | # break | ||
125 | fi | ||
126 | done | ||
127 | if [ "$found" = "1" ] && [ "$fixed_arch" = "$fixed_cmp_arch" ]; then | ||
128 | break | ||
129 | fi | ||
130 | done | ||
131 | |||
132 | #echo "$pkg -> $new_pkg" >&2 | ||
133 | if [ "$arg1" = "arch" ]; then | ||
134 | echo $new_pkg $new_arch $other | ||
135 | elif [ "$arg1" = "file" ]; then | ||
136 | echo $new_pkg $other $new_arch | ||
137 | else | ||
138 | echo $new_pkg $other | ||
139 | fi | ||
140 | done | ||
141 | } | ||
142 | |||
143 | # Translate the OE multilib format names to the RPM/Smart format names | ||
144 | # Input via arguments | ||
145 | # Ouput via pkgs_to_install | ||
146 | translate_oe_to_smart() { | ||
147 | default_archs="" | ||
148 | sdk_mode="" | ||
149 | if [ "$1" = "--sdk" ]; then | ||
150 | shift | ||
151 | sdk_mode="true" | ||
152 | # Need to reverse the order of the SDK_ARCHS highest -> lowest priority | ||
153 | archs=`echo "${SDK_PACKAGE_ARCHS}" | tr - _` | ||
154 | for arch in $archs ; do | ||
155 | default_archs="$arch $default_archs" | ||
156 | done | ||
157 | fi | ||
158 | |||
159 | attemptonly="Error" | ||
160 | if [ "$1" = "--attemptonly" ]; then | ||
161 | attemptonly="Warning" | ||
162 | shift | ||
163 | fi | ||
164 | |||
165 | # Dump a list of all available packages | ||
166 | [ ! -e ${target_rootfs}/install/tmp/fullpkglist.query ] && smart --data-dir=${target_rootfs}/var/lib/smart query --output ${target_rootfs}/install/tmp/fullpkglist.query | ||
167 | |||
168 | pkgs_to_install="" | ||
169 | for pkg in "$@" ; do | ||
170 | new_pkg="$pkg" | ||
171 | if [ -z "$sdk_mode" ]; then | ||
172 | for i in ${MULTILIB_PREFIX_LIST} ; do | ||
173 | old_IFS="$IFS" | ||
174 | IFS=":" | ||
175 | set $i | ||
176 | IFS="$old_IFS" | ||
177 | mlib="$1" | ||
178 | shift | ||
179 | if [ "$mlib" = "default" ]; then | ||
180 | if [ -z "$default_archs" ]; then | ||
181 | default_archs=$@ | ||
182 | fi | ||
183 | continue | ||
184 | fi | ||
185 | subst=${pkg#${mlib}-} | ||
186 | if [ "$subst" != "$pkg" ]; then | ||
187 | feeds=$@ | ||
188 | while [ -n "$1" ]; do | ||
189 | arch="$1" | ||
190 | arch=`echo "$arch" | tr - _` | ||
191 | shift | ||
192 | if grep -q '^'$subst'-[^-]*-[^-]*@'$arch'$' ${target_rootfs}/install/tmp/fullpkglist.query ; then | ||
193 | new_pkg="$subst@$arch" | ||
194 | # First found is best match | ||
195 | break | ||
196 | fi | ||
197 | done | ||
198 | if [ "$pkg" = "$new_pkg" ]; then | ||
199 | # Failed to translate, package not found! | ||
200 | echo "$attemptonly: $pkg not found in the $mlib feeds ($feeds)." >&2 | ||
201 | if [ "$attemptonly" = "Error" ]; then | ||
202 | exit 1 | ||
203 | fi | ||
204 | continue | ||
205 | fi | ||
206 | fi | ||
207 | done | ||
208 | fi | ||
209 | # Apparently not a multilib package... | ||
210 | if [ "$pkg" = "$new_pkg" ]; then | ||
211 | default_archs_fixed=`echo "$default_archs" | tr - _` | ||
212 | for arch in $default_archs_fixed ; do | ||
213 | if grep -q '^'$pkg'-[^-]*-[^-]*@'$arch'$' ${target_rootfs}/install/tmp/fullpkglist.query ; then | ||
214 | new_pkg="$pkg@$arch" | ||
215 | # First found is best match | ||
216 | break | ||
217 | fi | ||
218 | done | ||
219 | if [ "$pkg" = "$new_pkg" ]; then | ||
220 | # Failed to translate, package not found! | ||
221 | echo "$attemptonly: $pkg not found in the base feeds ($default_archs)." >&2 | ||
222 | if [ "$attemptonly" = "Error" ]; then | ||
223 | exit 1 | ||
224 | fi | ||
225 | continue | ||
226 | fi | ||
227 | fi | ||
228 | #echo "$pkg -> $new_pkg" >&2 | ||
229 | pkgs_to_install="${pkgs_to_install} ${new_pkg}" | ||
230 | done | ||
231 | export pkgs_to_install | ||
232 | } | ||
233 | |||
234 | package_write_smart_config() { | ||
235 | # Write common configuration for host and target usage | ||
236 | smart --data-dir=$1/var/lib/smart config --set rpm-nolinktos=1 | ||
237 | smart --data-dir=$1/var/lib/smart config --set rpm-noparentdirs=1 | ||
238 | for i in ${BAD_RECOMMENDATIONS}; do | ||
239 | smart --data-dir=$1/var/lib/smart flag --set ignore-recommends $i | ||
240 | done | ||
241 | } | ||
242 | |||
243 | # | ||
244 | # Install a bunch of packages using rpm. | ||
245 | # There are two solutions in an image's FRESH generation: | ||
246 | # 1) main package solution | ||
247 | # 2) complementary solution | ||
248 | # | ||
249 | # It is different when incremental image generation is enabled: | ||
250 | # 1) The incremental image generation takes action during the main package | ||
251 | # installation, the previous installed complementary packages would | ||
252 | # usually be removed here, and the new complementary ones would be | ||
253 | # installed in the next step. | ||
254 | # 2) The complementary would always be installed since it is | ||
255 | # generated based on the first step's image. | ||
256 | # | ||
257 | # the following shell variables needs to be set before calling this func: | ||
258 | # INSTALL_ROOTFS_RPM - install root dir | ||
259 | # INSTALL_PLATFORM_RPM - main platform | ||
260 | # INSTALL_PLATFORM_EXTRA_RPM - extra platform | ||
261 | # INSTALL_PACKAGES_RPM - packages to be installed | ||
262 | # INSTALL_PACKAGES_ATTEMPTONLY_RPM - packages attemped to be installed only | ||
263 | # INSTALL_PACKAGES_LINGUAS_RPM - additional packages for uclibc | ||
264 | # INSTALL_PROVIDENAME_RPM - content for provide name | ||
265 | # INSTALL_TASK_RPM - task name | ||
266 | # INSTALL_COMPLEMENTARY_RPM - 1 to enable complementary package install mode | ||
267 | |||
268 | package_install_internal_rpm () { | ||
269 | |||
270 | local target_rootfs="$INSTALL_ROOTFS_RPM" | ||
271 | local package_to_install="$INSTALL_PACKAGES_RPM" | ||
272 | local package_attemptonly="$INSTALL_PACKAGES_ATTEMPTONLY_RPM" | ||
273 | local package_linguas="$INSTALL_PACKAGES_LINGUAS_RPM" | ||
274 | local providename="$INSTALL_PROVIDENAME_RPM" | ||
275 | local task="$INSTALL_TASK_RPM" | ||
276 | |||
277 | local sdk_mode="" | ||
278 | if [ "$1" = "--sdk" ]; then | ||
279 | sdk_mode="--sdk" | ||
280 | fi | ||
281 | |||
282 | # Configure internal RPM environment when using Smart | ||
283 | export RPM_ETCRPM=${target_rootfs}/etc/rpm | ||
284 | |||
285 | # Setup temporary directory -- install... | ||
286 | rm -rf ${target_rootfs}/install | ||
287 | mkdir -p ${target_rootfs}/install/tmp | ||
288 | |||
289 | channel_priority=5 | ||
290 | if [ "${INSTALL_COMPLEMENTARY_RPM}" != "1" ] ; then | ||
291 | # Setup base system configuration | ||
292 | echo "Note: configuring RPM platform settings" | ||
293 | mkdir -p ${target_rootfs}/etc/rpm/ | ||
294 | echo "$INSTALL_PLATFORM_RPM" > ${target_rootfs}/etc/rpm/platform | ||
295 | |||
296 | if [ ! -z "$INSTALL_PLATFORM_EXTRA_RPM" ]; then | ||
297 | for pt in $INSTALL_PLATFORM_EXTRA_RPM ; do | ||
298 | channel_priority=$(expr $channel_priority + 5) | ||
299 | case $pt in | ||
300 | noarch-* | any-* | all-*) | ||
301 | pt=$(echo $pt | sed "s,-linux.*$,-linux\.*,") | ||
302 | ;; | ||
303 | esac | ||
304 | echo "$pt" >> ${target_rootfs}/etc/rpm/platform | ||
305 | done | ||
306 | fi | ||
307 | |||
308 | # Tell RPM that the "/" directory exist and is available | ||
309 | echo "Note: configuring RPM system provides" | ||
310 | mkdir -p ${target_rootfs}/etc/rpm/sysinfo | ||
311 | echo "/" >${target_rootfs}/etc/rpm/sysinfo/Dirnames | ||
312 | |||
313 | if [ ! -z "$providename" ]; then | ||
314 | cat /dev/null > ${target_rootfs}/etc/rpm/sysinfo/Providename | ||
315 | for provide in $providename ; do | ||
316 | echo $provide >> ${target_rootfs}/etc/rpm/sysinfo/Providename | ||
317 | done | ||
318 | fi | ||
319 | |||
320 | # Configure RPM... we enforce these settings! | ||
321 | echo "Note: configuring RPM DB settings" | ||
322 | mkdir -p ${target_rootfs}${rpmlibdir} | ||
323 | mkdir -p ${target_rootfs}${rpmlibdir}/log | ||
324 | # After change the __db.* cache size, log file will not be generated automatically, | ||
325 | # that will raise some warnings, so touch a bare log for rpm write into it. | ||
326 | touch ${target_rootfs}${rpmlibdir}/log/log.0000000001 | ||
327 | if [ ! -e ${target_rootfs}${rpmlibdir}/DB_CONFIG ]; then | ||
328 | cat > ${target_rootfs}${rpmlibdir}/DB_CONFIG << EOF | ||
329 | # ================ Environment | ||
330 | set_data_dir . | ||
331 | set_create_dir . | ||
332 | set_lg_dir ./log | ||
333 | set_tmp_dir ./tmp | ||
334 | set_flags db_log_autoremove on | ||
335 | |||
336 | # -- thread_count must be >= 8 | ||
337 | set_thread_count 64 | ||
338 | |||
339 | # ================ Logging | ||
340 | |||
341 | # ================ Memory Pool | ||
342 | set_cachesize 0 1048576 0 | ||
343 | set_mp_mmapsize 268435456 | ||
344 | |||
345 | # ================ Locking | ||
346 | set_lk_max_locks 16384 | ||
347 | set_lk_max_lockers 16384 | ||
348 | set_lk_max_objects 16384 | ||
349 | mutex_set_max 163840 | ||
350 | |||
351 | # ================ Replication | ||
352 | EOF | ||
353 | fi | ||
354 | |||
355 | # Create database so that smart doesn't complain (lazy init) | ||
356 | rpm --root $target_rootfs --dbpath /var/lib/rpm -qa > /dev/null | ||
357 | |||
358 | # Configure smart | ||
359 | echo "Note: configuring Smart settings" | ||
360 | rm -rf ${target_rootfs}/var/lib/smart | ||
361 | smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-root=${target_rootfs} | ||
362 | smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-dbpath=${rpmlibdir} | ||
363 | smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._var=${localstatedir} | ||
364 | smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._tmppath=/install/tmp | ||
365 | package_write_smart_config ${target_rootfs} | ||
366 | # Do the following configurations here, to avoid them being saved for field upgrade | ||
367 | if [ "x${NO_RECOMMENDATIONS}" = "x1" ]; then | ||
368 | smart --data-dir=${target_rootfs}/var/lib/smart config --set ignore-all-recommends=1 | ||
369 | fi | ||
370 | for i in ${PACKAGE_EXCLUDE}; do | ||
371 | smart --data-dir=${target_rootfs}/var/lib/smart flag --set exclude-packages $i | ||
372 | done | ||
373 | |||
374 | # Optional debugging | ||
375 | #smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-log-level=debug | ||
376 | #smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-log-file=/tmp/smart-debug-logfile | ||
377 | |||
378 | # Delay this until later... | ||
379 | #smart --data-dir=${target_rootfs}/var/lib/smart channel --add rpmsys type=rpm-sys -y | ||
380 | |||
381 | for canonical_arch in $INSTALL_PLATFORM_EXTRA_RPM; do | ||
382 | arch=$(echo $canonical_arch | sed "s,\([^-]*\)-.*,\1,") | ||
383 | if [ -d ${DEPLOY_DIR_RPM}/$arch -a ! -e ${target_rootfs}/install/channel.$arch.stamp ] ; then | ||
384 | echo "Note: adding Smart channel $arch ($channel_priority)" | ||
385 | smart --data-dir=${target_rootfs}/var/lib/smart channel --add $arch type=rpm-md type=rpm-md baseurl=${DEPLOY_DIR_RPM}/$arch -y | ||
386 | smart --data-dir=${target_rootfs}/var/lib/smart channel --set $arch priority=$channel_priority | ||
387 | touch ${target_rootfs}/install/channel.$arch.stamp | ||
388 | fi | ||
389 | channel_priority=$(expr $channel_priority - 5) | ||
390 | done | ||
391 | fi | ||
392 | |||
393 | # Construct install scriptlet wrapper | ||
394 | # Scripts need to be ordered when executed, this ensures numeric order | ||
395 | # If we ever run into needing more the 899 scripts, we'll have to | ||
396 | # change num to start with 1000. | ||
397 | # | ||
398 | cat << EOF > ${WORKDIR}/scriptlet_wrapper | ||
399 | #!/bin/bash | ||
400 | |||
401 | export PATH="${PATH}" | ||
402 | export D="${target_rootfs}" | ||
403 | export OFFLINE_ROOT="\$D" | ||
404 | export IPKG_OFFLINE_ROOT="\$D" | ||
405 | export OPKG_OFFLINE_ROOT="\$D" | ||
406 | export INTERCEPT_DIR="${WORKDIR}/intercept_scripts" | ||
407 | export NATIVE_ROOT=${STAGING_DIR_NATIVE} | ||
408 | |||
409 | \$2 \$1/\$3 \$4 | ||
410 | if [ \$? -ne 0 ]; then | ||
411 | if [ \$4 -eq 1 ]; then | ||
412 | mkdir -p \$1/etc/rpm-postinsts | ||
413 | num=100 | ||
414 | while [ -e \$1/etc/rpm-postinsts/\${num}-* ]; do num=\$((num + 1)); done | ||
415 | name=\`head -1 \$1/\$3 | cut -d' ' -f 2\` | ||
416 | echo "#!\$2" > \$1/etc/rpm-postinsts/\${num}-\${name} | ||
417 | echo "# Arg: \$4" >> \$1/etc/rpm-postinsts/\${num}-\${name} | ||
418 | cat \$1/\$3 >> \$1/etc/rpm-postinsts/\${num}-\${name} | ||
419 | chmod +x \$1/etc/rpm-postinsts/\${num}-\${name} | ||
420 | else | ||
421 | echo "Error: pre/post remove scriptlet failed" | ||
422 | fi | ||
423 | fi | ||
424 | EOF | ||
425 | |||
426 | echo "Note: configuring RPM cross-install scriptlet_wrapper" | ||
427 | chmod 0755 ${WORKDIR}/scriptlet_wrapper | ||
428 | smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._cross_scriptlet_wrapper=${WORKDIR}/scriptlet_wrapper | ||
429 | |||
430 | # Determine what to install | ||
431 | translate_oe_to_smart ${sdk_mode} ${package_to_install} ${package_linguas} | ||
432 | |||
433 | # If incremental install, we need to determine what we've got, | ||
434 | # what we need to add, and what to remove... | ||
435 | if [ "${INC_RPM_IMAGE_GEN}" = "1" -a "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then | ||
436 | # Dump the new solution | ||
437 | echo "Note: creating install solution for incremental install" | ||
438 | smart --data-dir=${target_rootfs}/var/lib/smart install -y --dump ${pkgs_to_install} 2> ${target_rootfs}/../solution.manifest | ||
439 | fi | ||
440 | |||
441 | if [ "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then | ||
442 | echo "Note: adding Smart RPM DB channel" | ||
443 | smart --data-dir=${target_rootfs}/var/lib/smart channel --add rpmsys type=rpm-sys -y | ||
444 | fi | ||
445 | |||
446 | # If incremental install, we need to determine what we've got, | ||
447 | # what we need to add, and what to remove... | ||
448 | if [ "${INC_RPM_IMAGE_GEN}" = "1" -a "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then | ||
449 | # First upgrade everything that was previously installed to the latest version | ||
450 | echo "Note: incremental update -- upgrade packages in place" | ||
451 | smart --data-dir=${target_rootfs}/var/lib/smart upgrade | ||
452 | |||
453 | # Dump what is already installed | ||
454 | echo "Note: dump installed packages for incremental update" | ||
455 | smart --data-dir=${target_rootfs}/var/lib/smart query --installed --output ${target_rootfs}/../installed.manifest | ||
456 | |||
457 | sort ${target_rootfs}/../installed.manifest > ${target_rootfs}/../installed.manifest.sorted | ||
458 | sort ${target_rootfs}/../solution.manifest > ${target_rootfs}/../solution.manifest.sorted | ||
459 | |||
460 | comm -1 -3 ${target_rootfs}/../solution.manifest.sorted ${target_rootfs}/../installed.manifest.sorted \ | ||
461 | > ${target_rootfs}/../remove.list | ||
462 | comm -2 -3 ${target_rootfs}/../solution.manifest.sorted ${target_rootfs}/../installed.manifest.sorted \ | ||
463 | > ${target_rootfs}/../install.list | ||
464 | |||
465 | pkgs_to_remove=`cat ${target_rootfs}/../remove.list | xargs echo` | ||
466 | pkgs_to_install=`cat ${target_rootfs}/../install.list | xargs echo` | ||
467 | |||
468 | echo "Note: to be removed: ${pkgs_to_remove}" | ||
469 | |||
470 | for pkg in ${pkgs_to_remove}; do | ||
471 | echo "Debug: What required: $pkg" | ||
472 | smart --data-dir=${target_rootfs}/var/lib/smart query $pkg --show-requiredby | ||
473 | done | ||
474 | |||
475 | [ -n "$pkgs_to_remove" ] && smart --data-dir=${target_rootfs}/var/lib/smart remove -y ${pkgs_to_remove} | ||
476 | fi | ||
477 | |||
478 | echo "Note: to be installed: ${pkgs_to_install}" | ||
479 | [ -n "$pkgs_to_install" ] && smart --data-dir=${target_rootfs}/var/lib/smart install -y ${pkgs_to_install} | ||
480 | |||
481 | if [ -n "${package_attemptonly}" ]; then | ||
482 | echo "Note: installing attempt only packages..." | ||
483 | echo "Attempting $pkgs_to_install" | ||
484 | echo "Note: see `dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" | ||
485 | translate_oe_to_smart ${sdk_mode} --attemptonly $package_attemptonly | ||
486 | echo "Attempting $pkgs_to_install" >> "`dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" | ||
487 | smart --data-dir=${target_rootfs}/var/lib/smart install --attempt -y ${pkgs_to_install} >> "`dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" 2>&1 || : | ||
488 | fi | ||
489 | } | ||
490 | |||
491 | # Construct per file dependencies file | ||
492 | def write_rpm_perfiledata(srcname, d): | ||
493 | workdir = d.getVar('WORKDIR', True) | ||
494 | packages = d.getVar('PACKAGES', True) | ||
495 | pkgd = d.getVar('PKGD', True) | ||
496 | |||
497 | def dump_filerdeps(varname, outfile, d): | ||
498 | outfile.write("#!/usr/bin/env python\n\n") | ||
499 | outfile.write("# Dependency table\n") | ||
500 | outfile.write('deps = {\n') | ||
501 | for pkg in packages.split(): | ||
502 | dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg | ||
503 | dependsflist = (d.getVar(dependsflist_key, True) or "") | ||
504 | for dfile in dependsflist.split(): | ||
505 | key = "FILE" + varname + "_" + dfile + "_" + pkg | ||
506 | depends_dict = bb.utils.explode_dep_versions(d.getVar(key, True) or "") | ||
507 | file = dfile.replace("@underscore@", "_") | ||
508 | file = file.replace("@closebrace@", "]") | ||
509 | file = file.replace("@openbrace@", "[") | ||
510 | file = file.replace("@tab@", "\t") | ||
511 | file = file.replace("@space@", " ") | ||
512 | file = file.replace("@at@", "@") | ||
513 | outfile.write('"' + pkgd + file + '" : "') | ||
514 | for dep in depends_dict: | ||
515 | ver = depends_dict[dep] | ||
516 | if dep and ver: | ||
517 | ver = ver.replace("(","") | ||
518 | ver = ver.replace(")","") | ||
519 | outfile.write(dep + " " + ver + " ") | ||
520 | else: | ||
521 | outfile.write(dep + " ") | ||
522 | outfile.write('",\n') | ||
523 | outfile.write('}\n\n') | ||
524 | outfile.write("import sys\n") | ||
525 | outfile.write("while 1:\n") | ||
526 | outfile.write("\tline = sys.stdin.readline().strip()\n") | ||
527 | outfile.write("\tif not line:\n") | ||
528 | outfile.write("\t\tsys.exit(0)\n") | ||
529 | outfile.write("\tif line in deps:\n") | ||
530 | outfile.write("\t\tprint(deps[line] + '\\n')\n") | ||
531 | |||
532 | # OE-core dependencies a.k.a. RPM requires | ||
533 | outdepends = workdir + "/" + srcname + ".requires" | ||
534 | |||
535 | try: | ||
536 | dependsfile = open(outdepends, 'w') | ||
537 | except OSError: | ||
538 | raise bb.build.FuncFailed("unable to open spec file for writing.") | ||
539 | |||
540 | dump_filerdeps('RDEPENDS', dependsfile, d) | ||
541 | |||
542 | dependsfile.close() | ||
543 | os.chmod(outdepends, 0755) | ||
544 | |||
545 | # OE-core / RPM Provides | ||
546 | outprovides = workdir + "/" + srcname + ".provides" | ||
547 | |||
548 | try: | ||
549 | providesfile = open(outprovides, 'w') | ||
550 | except OSError: | ||
551 | raise bb.build.FuncFailed("unable to open spec file for writing.") | ||
552 | |||
553 | dump_filerdeps('RPROVIDES', providesfile, d) | ||
554 | |||
555 | providesfile.close() | ||
556 | os.chmod(outprovides, 0755) | ||
557 | |||
558 | return (outdepends, outprovides) | ||
559 | |||
560 | |||
561 | python write_specfile () { | ||
562 | import oe.packagedata | ||
563 | |||
564 | # append information for logs and patches to %prep | ||
565 | def add_prep(d,spec_files_bottom): | ||
566 | if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': | ||
567 | spec_files_bottom.append('%%prep -n %s' % d.getVar('PN', True) ) | ||
568 | spec_files_bottom.append('%s' % "echo \"include logs and patches, Please check them in SOURCES\"") | ||
569 | spec_files_bottom.append('') | ||
570 | |||
571 | # append the name of tarball to key word 'SOURCE' in xxx.spec. | ||
572 | def tail_source(d): | ||
573 | if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': | ||
574 | source_list = get_package(d) | ||
575 | source_number = 0 | ||
576 | workdir = d.getVar('WORKDIR', True) | ||
577 | for source in source_list: | ||
578 | # The rpmbuild doesn't need the root permission, but it needs | ||
579 | # to know the file's user and group name, the only user and | ||
580 | # group in fakeroot is "root" when working in fakeroot. | ||
581 | os.chown("%s/%s" % (workdir, source), 0, 0) | ||
582 | spec_preamble_top.append('Source' + str(source_number) + ': %s' % source) | ||
583 | source_number += 1 | ||
584 | # We need a simple way to remove the MLPREFIX from the package name, | ||
585 | # and dependency information... | ||
586 | def strip_multilib(name, d): | ||
587 | multilibs = d.getVar('MULTILIBS', True) or "" | ||
588 | for ext in multilibs.split(): | ||
589 | eext = ext.split(':') | ||
590 | if len(eext) > 1 and eext[0] == 'multilib' and name and name.find(eext[1] + '-') >= 0: | ||
591 | name = "".join(name.split(eext[1] + '-')) | ||
592 | return name | ||
593 | |||
594 | def strip_multilib_deps(deps, d): | ||
595 | depends = bb.utils.explode_dep_versions2(deps or "") | ||
596 | newdeps = {} | ||
597 | for dep in depends: | ||
598 | newdeps[strip_multilib(dep, d)] = depends[dep] | ||
599 | return bb.utils.join_deps(newdeps) | ||
600 | |||
601 | # ml = d.getVar("MLPREFIX", True) | ||
602 | # if ml and name and len(ml) != 0 and name.find(ml) == 0: | ||
603 | # return ml.join(name.split(ml, 1)[1:]) | ||
604 | # return name | ||
605 | |||
606 | # In RPM, dependencies are of the format: pkg <>= Epoch:Version-Release | ||
607 | # This format is similar to OE, however there are restrictions on the | ||
608 | # characters that can be in a field. In the Version field, "-" | ||
609 | # characters are not allowed. "-" is allowed in the Release field. | ||
610 | # | ||
611 | # We translate the "-" in the version to a "+", by loading the PKGV | ||
612 | # from the dependent recipe, replacing the - with a +, and then using | ||
613 | # that value to do a replace inside of this recipe's dependencies. | ||
614 | # This preserves the "-" separator between the version and release, as | ||
615 | # well as any "-" characters inside of the release field. | ||
616 | # | ||
617 | # All of this has to happen BEFORE the mapping_rename_hook as | ||
618 | # after renaming we cannot look up the dependencies in the packagedata | ||
619 | # store. | ||
620 | def translate_vers(varname, d): | ||
621 | depends = d.getVar(varname, True) | ||
622 | if depends: | ||
623 | depends_dict = bb.utils.explode_dep_versions2(depends) | ||
624 | newdeps_dict = {} | ||
625 | for dep in depends_dict: | ||
626 | verlist = [] | ||
627 | for ver in depends_dict[dep]: | ||
628 | if '-' in ver: | ||
629 | subd = oe.packagedata.read_subpkgdata_dict(dep, d) | ||
630 | if 'PKGV' in subd: | ||
631 | pv = subd['PV'] | ||
632 | pkgv = subd['PKGV'] | ||
633 | reppv = pkgv.replace('-', '+') | ||
634 | ver = ver.replace(pv, reppv).replace(pkgv, reppv) | ||
635 | if 'PKGR' in subd: | ||
636 | # Make sure PKGR rather than PR in ver | ||
637 | pr = '-' + subd['PR'] | ||
638 | pkgr = '-' + subd['PKGR'] | ||
639 | if pkgr not in ver: | ||
640 | ver = ver.replace(pr, pkgr) | ||
641 | verlist.append(ver) | ||
642 | else: | ||
643 | verlist.append(ver) | ||
644 | newdeps_dict[dep] = verlist | ||
645 | depends = bb.utils.join_deps(newdeps_dict) | ||
646 | d.setVar(varname, depends.strip()) | ||
647 | |||
648 | # We need to change the style the dependency from BB to RPM | ||
649 | # This needs to happen AFTER the mapping_rename_hook | ||
650 | def print_deps(variable, tag, array, d): | ||
651 | depends = variable | ||
652 | if depends: | ||
653 | depends_dict = bb.utils.explode_dep_versions2(depends) | ||
654 | for dep in depends_dict: | ||
655 | for ver in depends_dict[dep]: | ||
656 | ver = ver.replace('(', '') | ||
657 | ver = ver.replace(')', '') | ||
658 | array.append("%s: %s %s" % (tag, dep, ver)) | ||
659 | if not len(depends_dict[dep]): | ||
660 | array.append("%s: %s" % (tag, dep)) | ||
661 | |||
662 | def walk_files(walkpath, target, conffiles): | ||
663 | for rootpath, dirs, files in os.walk(walkpath): | ||
664 | path = rootpath.replace(walkpath, "") | ||
665 | for dir in dirs: | ||
666 | # All packages own the directories their files are in... | ||
667 | target.append('%dir "' + path + '/' + dir + '"') | ||
668 | for file in files: | ||
669 | if conffiles.count(path + '/' + file): | ||
670 | target.append('%config "' + path + '/' + file + '"') | ||
671 | else: | ||
672 | target.append('"' + path + '/' + file + '"') | ||
673 | |||
674 | # Prevent the prerm/postrm scripts from being run during an upgrade | ||
675 | def wrap_uninstall(scriptvar): | ||
676 | scr = scriptvar.strip() | ||
677 | if scr.startswith("#!"): | ||
678 | pos = scr.find("\n") + 1 | ||
679 | else: | ||
680 | pos = 0 | ||
681 | scr = scr[:pos] + 'if [ "$1" = "0" ] ; then\n' + scr[pos:] + '\nfi' | ||
682 | return scr | ||
683 | |||
684 | def get_perfile(varname, pkg, d): | ||
685 | deps = [] | ||
686 | dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg | ||
687 | dependsflist = (d.getVar(dependsflist_key, True) or "") | ||
688 | for dfile in dependsflist.split(): | ||
689 | key = "FILE" + varname + "_" + dfile + "_" + pkg | ||
690 | depends = d.getVar(key, True) | ||
691 | if depends: | ||
692 | deps.append(depends) | ||
693 | return " ".join(deps) | ||
694 | |||
695 | def append_description(spec_preamble, text): | ||
696 | """ | ||
697 | Add the description to the spec file. | ||
698 | """ | ||
699 | import textwrap | ||
700 | dedent_text = textwrap.dedent(text).strip() | ||
701 | # Bitbake saves "\n" as "\\n" | ||
702 | if '\\n' in dedent_text: | ||
703 | for t in dedent_text.split('\\n'): | ||
704 | spec_preamble.append(t.strip()) | ||
705 | else: | ||
706 | spec_preamble.append('%s' % textwrap.fill(dedent_text, width=75)) | ||
707 | |||
708 | packages = d.getVar('PACKAGES', True) | ||
709 | if not packages or packages == '': | ||
710 | bb.debug(1, "No packages; nothing to do") | ||
711 | return | ||
712 | |||
713 | pkgdest = d.getVar('PKGDEST', True) | ||
714 | if not pkgdest: | ||
715 | bb.fatal("No PKGDEST") | ||
716 | |||
717 | outspecfile = d.getVar('OUTSPECFILE', True) | ||
718 | if not outspecfile: | ||
719 | bb.fatal("No OUTSPECFILE") | ||
720 | |||
721 | # Construct the SPEC file... | ||
722 | srcname = strip_multilib(d.getVar('PN', True), d) | ||
723 | srcsummary = (d.getVar('SUMMARY', True) or d.getVar('DESCRIPTION', True) or ".") | ||
724 | srcversion = d.getVar('PKGV', True).replace('-', '+') | ||
725 | srcrelease = d.getVar('PKGR', True) | ||
726 | srcepoch = (d.getVar('PKGE', True) or "") | ||
727 | srclicense = d.getVar('LICENSE', True) | ||
728 | srcsection = d.getVar('SECTION', True) | ||
729 | srcmaintainer = d.getVar('MAINTAINER', True) | ||
730 | srchomepage = d.getVar('HOMEPAGE', True) | ||
731 | srcdescription = d.getVar('DESCRIPTION', True) or "." | ||
732 | |||
733 | srcdepends = strip_multilib_deps(d.getVar('DEPENDS', True), d) | ||
734 | srcrdepends = [] | ||
735 | srcrrecommends = [] | ||
736 | srcrsuggests = [] | ||
737 | srcrprovides = [] | ||
738 | srcrreplaces = [] | ||
739 | srcrconflicts = [] | ||
740 | srcrobsoletes = [] | ||
741 | |||
742 | srcrpreinst = [] | ||
743 | srcrpostinst = [] | ||
744 | srcrprerm = [] | ||
745 | srcrpostrm = [] | ||
746 | |||
747 | spec_preamble_top = [] | ||
748 | spec_preamble_bottom = [] | ||
749 | |||
750 | spec_scriptlets_top = [] | ||
751 | spec_scriptlets_bottom = [] | ||
752 | |||
753 | spec_files_top = [] | ||
754 | spec_files_bottom = [] | ||
755 | |||
756 | perfiledeps = (d.getVar("MERGEPERFILEDEPS", True) or "0") == "0" | ||
757 | |||
758 | for pkg in packages.split(): | ||
759 | localdata = bb.data.createCopy(d) | ||
760 | |||
761 | root = "%s/%s" % (pkgdest, pkg) | ||
762 | |||
763 | lf = bb.utils.lockfile(root + ".lock") | ||
764 | |||
765 | localdata.setVar('ROOT', '') | ||
766 | localdata.setVar('ROOT_%s' % pkg, root) | ||
767 | pkgname = localdata.getVar('PKG_%s' % pkg, True) | ||
768 | if not pkgname: | ||
769 | pkgname = pkg | ||
770 | localdata.setVar('PKG', pkgname) | ||
771 | |||
772 | localdata.setVar('OVERRIDES', pkg) | ||
773 | |||
774 | bb.data.update_data(localdata) | ||
775 | |||
776 | conffiles = (localdata.getVar('CONFFILES', True) or "").split() | ||
777 | |||
778 | splitname = strip_multilib(pkgname, d) | ||
779 | |||
780 | splitsummary = (localdata.getVar('SUMMARY', True) or localdata.getVar('DESCRIPTION', True) or ".") | ||
781 | splitversion = (localdata.getVar('PKGV', True) or "").replace('-', '+') | ||
782 | splitrelease = (localdata.getVar('PKGR', True) or "") | ||
783 | splitepoch = (localdata.getVar('PKGE', True) or "") | ||
784 | splitlicense = (localdata.getVar('LICENSE', True) or "") | ||
785 | splitsection = (localdata.getVar('SECTION', True) or "") | ||
786 | splitdescription = (localdata.getVar('DESCRIPTION', True) or ".") | ||
787 | |||
788 | translate_vers('RDEPENDS', localdata) | ||
789 | translate_vers('RRECOMMENDS', localdata) | ||
790 | translate_vers('RSUGGESTS', localdata) | ||
791 | translate_vers('RPROVIDES', localdata) | ||
792 | translate_vers('RREPLACES', localdata) | ||
793 | translate_vers('RCONFLICTS', localdata) | ||
794 | |||
795 | # Map the dependencies into their final form | ||
796 | mapping_rename_hook(localdata) | ||
797 | |||
798 | splitrdepends = strip_multilib_deps(localdata.getVar('RDEPENDS', True), d) | ||
799 | splitrrecommends = strip_multilib_deps(localdata.getVar('RRECOMMENDS', True), d) | ||
800 | splitrsuggests = strip_multilib_deps(localdata.getVar('RSUGGESTS', True), d) | ||
801 | splitrprovides = strip_multilib_deps(localdata.getVar('RPROVIDES', True), d) | ||
802 | splitrreplaces = strip_multilib_deps(localdata.getVar('RREPLACES', True), d) | ||
803 | splitrconflicts = strip_multilib_deps(localdata.getVar('RCONFLICTS', True), d) | ||
804 | splitrobsoletes = [] | ||
805 | |||
806 | splitrpreinst = localdata.getVar('pkg_preinst', True) | ||
807 | splitrpostinst = localdata.getVar('pkg_postinst', True) | ||
808 | splitrprerm = localdata.getVar('pkg_prerm', True) | ||
809 | splitrpostrm = localdata.getVar('pkg_postrm', True) | ||
810 | |||
811 | |||
812 | if not perfiledeps: | ||
813 | # Add in summary of per file dependencies | ||
814 | splitrdepends = splitrdepends + " " + get_perfile('RDEPENDS', pkg, d) | ||
815 | splitrprovides = splitrprovides + " " + get_perfile('RPROVIDES', pkg, d) | ||
816 | |||
817 | # Gather special src/first package data | ||
818 | if srcname == splitname: | ||
819 | srcrdepends = splitrdepends | ||
820 | srcrrecommends = splitrrecommends | ||
821 | srcrsuggests = splitrsuggests | ||
822 | srcrprovides = splitrprovides | ||
823 | srcrreplaces = splitrreplaces | ||
824 | srcrconflicts = splitrconflicts | ||
825 | |||
826 | srcrpreinst = splitrpreinst | ||
827 | srcrpostinst = splitrpostinst | ||
828 | srcrprerm = splitrprerm | ||
829 | srcrpostrm = splitrpostrm | ||
830 | |||
831 | file_list = [] | ||
832 | walk_files(root, file_list, conffiles) | ||
833 | if not file_list and localdata.getVar('ALLOW_EMPTY') != "1": | ||
834 | bb.note("Not creating empty RPM package for %s" % splitname) | ||
835 | else: | ||
836 | bb.note("Creating RPM package for %s" % splitname) | ||
837 | spec_files_top.append('%files') | ||
838 | spec_files_top.append('%defattr(-,-,-,-)') | ||
839 | if file_list: | ||
840 | bb.note("Creating RPM package for %s" % splitname) | ||
841 | spec_files_top.extend(file_list) | ||
842 | else: | ||
843 | bb.note("Creating EMPTY RPM Package for %s" % splitname) | ||
844 | spec_files_top.append('') | ||
845 | |||
846 | bb.utils.unlockfile(lf) | ||
847 | continue | ||
848 | |||
849 | # Process subpackage data | ||
850 | spec_preamble_bottom.append('%%package -n %s' % splitname) | ||
851 | spec_preamble_bottom.append('Summary: %s' % splitsummary) | ||
852 | if srcversion != splitversion: | ||
853 | spec_preamble_bottom.append('Version: %s' % splitversion) | ||
854 | if srcrelease != splitrelease: | ||
855 | spec_preamble_bottom.append('Release: %s' % splitrelease) | ||
856 | if srcepoch != splitepoch: | ||
857 | spec_preamble_bottom.append('Epoch: %s' % splitepoch) | ||
858 | if srclicense != splitlicense: | ||
859 | spec_preamble_bottom.append('License: %s' % splitlicense) | ||
860 | spec_preamble_bottom.append('Group: %s' % splitsection) | ||
861 | |||
862 | # Replaces == Obsoletes && Provides | ||
863 | robsoletes = bb.utils.explode_dep_versions2(splitrobsoletes or "") | ||
864 | rprovides = bb.utils.explode_dep_versions2(splitrprovides or "") | ||
865 | rreplaces = bb.utils.explode_dep_versions2(splitrreplaces or "") | ||
866 | for dep in rreplaces: | ||
867 | if not dep in robsoletes: | ||
868 | robsoletes[dep] = rreplaces[dep] | ||
869 | if not dep in rprovides: | ||
870 | rprovides[dep] = rreplaces[dep] | ||
871 | splitrobsoletes = bb.utils.join_deps(robsoletes, commasep=False) | ||
872 | splitrprovides = bb.utils.join_deps(rprovides, commasep=False) | ||
873 | |||
874 | print_deps(splitrdepends, "Requires", spec_preamble_bottom, d) | ||
875 | if splitrpreinst: | ||
876 | print_deps(splitrdepends, "Requires(pre)", spec_preamble_bottom, d) | ||
877 | if splitrpostinst: | ||
878 | print_deps(splitrdepends, "Requires(post)", spec_preamble_bottom, d) | ||
879 | if splitrprerm: | ||
880 | print_deps(splitrdepends, "Requires(preun)", spec_preamble_bottom, d) | ||
881 | if splitrpostrm: | ||
882 | print_deps(splitrdepends, "Requires(postun)", spec_preamble_bottom, d) | ||
883 | |||
884 | # Suggests in RPM are like recommends in OE-core! | ||
885 | print_deps(splitrrecommends, "Suggests", spec_preamble_bottom, d) | ||
886 | # While there is no analog for suggests... (So call them recommends for now) | ||
887 | print_deps(splitrsuggests, "Recommends", spec_preamble_bottom, d) | ||
888 | print_deps(splitrprovides, "Provides", spec_preamble_bottom, d) | ||
889 | print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d) | ||
890 | |||
891 | # conflicts can not be in a provide! We will need to filter it. | ||
892 | if splitrconflicts: | ||
893 | depends_dict = bb.utils.explode_dep_versions2(splitrconflicts) | ||
894 | newdeps_dict = {} | ||
895 | for dep in depends_dict: | ||
896 | if dep not in splitrprovides: | ||
897 | newdeps_dict[dep] = depends_dict[dep] | ||
898 | if newdeps_dict: | ||
899 | splitrconflicts = bb.utils.join_deps(newdeps_dict) | ||
900 | else: | ||
901 | splitrconflicts = "" | ||
902 | |||
903 | print_deps(splitrconflicts, "Conflicts", spec_preamble_bottom, d) | ||
904 | |||
905 | spec_preamble_bottom.append('') | ||
906 | |||
907 | spec_preamble_bottom.append('%%description -n %s' % splitname) | ||
908 | append_description(spec_preamble_bottom, splitdescription) | ||
909 | |||
910 | spec_preamble_bottom.append('') | ||
911 | |||
912 | # Now process scriptlets | ||
913 | if splitrpreinst: | ||
914 | spec_scriptlets_bottom.append('%%pre -n %s' % splitname) | ||
915 | spec_scriptlets_bottom.append('# %s - preinst' % splitname) | ||
916 | spec_scriptlets_bottom.append(splitrpreinst) | ||
917 | spec_scriptlets_bottom.append('') | ||
918 | if splitrpostinst: | ||
919 | spec_scriptlets_bottom.append('%%post -n %s' % splitname) | ||
920 | spec_scriptlets_bottom.append('# %s - postinst' % splitname) | ||
921 | spec_scriptlets_bottom.append(splitrpostinst) | ||
922 | spec_scriptlets_bottom.append('') | ||
923 | if splitrprerm: | ||
924 | spec_scriptlets_bottom.append('%%preun -n %s' % splitname) | ||
925 | spec_scriptlets_bottom.append('# %s - prerm' % splitname) | ||
926 | scriptvar = wrap_uninstall(splitrprerm) | ||
927 | spec_scriptlets_bottom.append(scriptvar) | ||
928 | spec_scriptlets_bottom.append('') | ||
929 | if splitrpostrm: | ||
930 | spec_scriptlets_bottom.append('%%postun -n %s' % splitname) | ||
931 | spec_scriptlets_bottom.append('# %s - postrm' % splitname) | ||
932 | scriptvar = wrap_uninstall(splitrpostrm) | ||
933 | spec_scriptlets_bottom.append(scriptvar) | ||
934 | spec_scriptlets_bottom.append('') | ||
935 | |||
936 | # Now process files | ||
937 | file_list = [] | ||
938 | walk_files(root, file_list, conffiles) | ||
939 | if not file_list and localdata.getVar('ALLOW_EMPTY') != "1": | ||
940 | bb.note("Not creating empty RPM package for %s" % splitname) | ||
941 | else: | ||
942 | spec_files_bottom.append('%%files -n %s' % splitname) | ||
943 | spec_files_bottom.append('%defattr(-,-,-,-)') | ||
944 | if file_list: | ||
945 | bb.note("Creating RPM package for %s" % splitname) | ||
946 | spec_files_bottom.extend(file_list) | ||
947 | else: | ||
948 | bb.note("Creating EMPTY RPM Package for %s" % splitname) | ||
949 | spec_files_bottom.append('') | ||
950 | |||
951 | del localdata | ||
952 | bb.utils.unlockfile(lf) | ||
953 | |||
954 | add_prep(d,spec_files_bottom) | ||
955 | spec_preamble_top.append('Summary: %s' % srcsummary) | ||
956 | spec_preamble_top.append('Name: %s' % srcname) | ||
957 | spec_preamble_top.append('Version: %s' % srcversion) | ||
958 | spec_preamble_top.append('Release: %s' % srcrelease) | ||
959 | if srcepoch and srcepoch.strip() != "": | ||
960 | spec_preamble_top.append('Epoch: %s' % srcepoch) | ||
961 | spec_preamble_top.append('License: %s' % srclicense) | ||
962 | spec_preamble_top.append('Group: %s' % srcsection) | ||
963 | spec_preamble_top.append('Packager: %s' % srcmaintainer) | ||
964 | spec_preamble_top.append('URL: %s' % srchomepage) | ||
965 | tail_source(d) | ||
966 | |||
967 | # Replaces == Obsoletes && Provides | ||
968 | robsoletes = bb.utils.explode_dep_versions2(srcrobsoletes or "") | ||
969 | rprovides = bb.utils.explode_dep_versions2(srcrprovides or "") | ||
970 | rreplaces = bb.utils.explode_dep_versions2(srcrreplaces or "") | ||
971 | for dep in rreplaces: | ||
972 | if not dep in robsoletes: | ||
973 | robsoletes[dep] = rreplaces[dep] | ||
974 | if not dep in rprovides: | ||
975 | rprovides[dep] = rreplaces[dep] | ||
976 | srcrobsoletes = bb.utils.join_deps(robsoletes, commasep=False) | ||
977 | srcrprovides = bb.utils.join_deps(rprovides, commasep=False) | ||
978 | |||
979 | print_deps(srcdepends, "BuildRequires", spec_preamble_top, d) | ||
980 | print_deps(srcrdepends, "Requires", spec_preamble_top, d) | ||
981 | if srcrpreinst: | ||
982 | print_deps(srcrdepends, "Requires(pre)", spec_preamble_top, d) | ||
983 | if srcrpostinst: | ||
984 | print_deps(srcrdepends, "Requires(post)", spec_preamble_top, d) | ||
985 | if srcrprerm: | ||
986 | print_deps(srcrdepends, "Requires(preun)", spec_preamble_top, d) | ||
987 | if srcrpostrm: | ||
988 | print_deps(srcrdepends, "Requires(postun)", spec_preamble_top, d) | ||
989 | |||
990 | # Suggests in RPM are like recommends in OE-core! | ||
991 | print_deps(srcrrecommends, "Suggests", spec_preamble_top, d) | ||
992 | # While there is no analog for suggests... (So call them recommends for now) | ||
993 | print_deps(srcrsuggests, "Recommends", spec_preamble_top, d) | ||
994 | print_deps(srcrprovides, "Provides", spec_preamble_top, d) | ||
995 | print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d) | ||
996 | |||
997 | # conflicts can not be in a provide! We will need to filter it. | ||
998 | if srcrconflicts: | ||
999 | depends_dict = bb.utils.explode_dep_versions2(srcrconflicts) | ||
1000 | newdeps_dict = {} | ||
1001 | for dep in depends_dict: | ||
1002 | if dep not in srcrprovides: | ||
1003 | newdeps_dict[dep] = depends_dict[dep] | ||
1004 | if newdeps_dict: | ||
1005 | srcrconflicts = bb.utils.join_deps(newdeps_dict) | ||
1006 | else: | ||
1007 | srcrconflicts = "" | ||
1008 | |||
1009 | print_deps(srcrconflicts, "Conflicts", spec_preamble_top, d) | ||
1010 | |||
1011 | spec_preamble_top.append('') | ||
1012 | |||
1013 | spec_preamble_top.append('%description') | ||
1014 | append_description(spec_preamble_top, srcdescription) | ||
1015 | |||
1016 | spec_preamble_top.append('') | ||
1017 | |||
1018 | if srcrpreinst: | ||
1019 | spec_scriptlets_top.append('%pre') | ||
1020 | spec_scriptlets_top.append('# %s - preinst' % srcname) | ||
1021 | spec_scriptlets_top.append(srcrpreinst) | ||
1022 | spec_scriptlets_top.append('') | ||
1023 | if srcrpostinst: | ||
1024 | spec_scriptlets_top.append('%post') | ||
1025 | spec_scriptlets_top.append('# %s - postinst' % srcname) | ||
1026 | spec_scriptlets_top.append(srcrpostinst) | ||
1027 | spec_scriptlets_top.append('') | ||
1028 | if srcrprerm: | ||
1029 | spec_scriptlets_top.append('%preun') | ||
1030 | spec_scriptlets_top.append('# %s - prerm' % srcname) | ||
1031 | scriptvar = wrap_uninstall(srcrprerm) | ||
1032 | spec_scriptlets_top.append(scriptvar) | ||
1033 | spec_scriptlets_top.append('') | ||
1034 | if srcrpostrm: | ||
1035 | spec_scriptlets_top.append('%postun') | ||
1036 | spec_scriptlets_top.append('# %s - postrm' % srcname) | ||
1037 | scriptvar = wrap_uninstall(srcrpostrm) | ||
1038 | spec_scriptlets_top.append(scriptvar) | ||
1039 | spec_scriptlets_top.append('') | ||
1040 | |||
1041 | # Write the SPEC file | ||
1042 | try: | ||
1043 | specfile = open(outspecfile, 'w') | ||
1044 | except OSError: | ||
1045 | raise bb.build.FuncFailed("unable to open spec file for writing.") | ||
1046 | |||
1047 | # RPMSPEC_PREAMBLE is a way to add arbitrary text to the top | ||
1048 | # of the generated spec file | ||
1049 | external_preamble = d.getVar("RPMSPEC_PREAMBLE", True) | ||
1050 | if external_preamble: | ||
1051 | specfile.write(external_preamble + "\n") | ||
1052 | |||
1053 | for line in spec_preamble_top: | ||
1054 | specfile.write(line + "\n") | ||
1055 | |||
1056 | for line in spec_preamble_bottom: | ||
1057 | specfile.write(line + "\n") | ||
1058 | |||
1059 | for line in spec_scriptlets_top: | ||
1060 | specfile.write(line + "\n") | ||
1061 | |||
1062 | for line in spec_scriptlets_bottom: | ||
1063 | specfile.write(line + "\n") | ||
1064 | |||
1065 | for line in spec_files_top: | ||
1066 | specfile.write(line + "\n") | ||
1067 | |||
1068 | for line in spec_files_bottom: | ||
1069 | specfile.write(line + "\n") | ||
1070 | |||
1071 | specfile.close() | ||
1072 | } | ||
1073 | |||
1074 | python do_package_rpm () { | ||
1075 | def creat_srpm_dir(d): | ||
1076 | if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': | ||
1077 | clean_licenses = get_licenses(d) | ||
1078 | pkgwritesrpmdir = bb.data.expand('${PKGWRITEDIRSRPM}/${PACKAGE_ARCH_EXTEND}', d) | ||
1079 | pkgwritesrpmdir = pkgwritesrpmdir + '/' + clean_licenses | ||
1080 | bb.utils.mkdirhier(pkgwritesrpmdir) | ||
1081 | os.chmod(pkgwritesrpmdir, 0755) | ||
1082 | return pkgwritesrpmdir | ||
1083 | |||
1084 | # We need a simple way to remove the MLPREFIX from the package name, | ||
1085 | # and dependency information... | ||
1086 | def strip_multilib(name, d): | ||
1087 | ml = d.getVar("MLPREFIX", True) | ||
1088 | if ml and name and len(ml) != 0 and name.find(ml) >= 0: | ||
1089 | return "".join(name.split(ml)) | ||
1090 | return name | ||
1091 | |||
1092 | workdir = d.getVar('WORKDIR', True) | ||
1093 | tmpdir = d.getVar('TMPDIR', True) | ||
1094 | pkgd = d.getVar('PKGD', True) | ||
1095 | pkgdest = d.getVar('PKGDEST', True) | ||
1096 | if not workdir or not pkgd or not tmpdir: | ||
1097 | bb.error("Variables incorrectly set, unable to package") | ||
1098 | return | ||
1099 | |||
1100 | packages = d.getVar('PACKAGES', True) | ||
1101 | if not packages or packages == '': | ||
1102 | bb.debug(1, "No packages; nothing to do") | ||
1103 | return | ||
1104 | |||
1105 | # Construct the spec file... | ||
1106 | # If the spec file already exist, and has not been stored into | ||
1107 | # pseudo's files.db, it maybe cause rpmbuild src.rpm fail, | ||
1108 | # so remove it before doing rpmbuild src.rpm. | ||
1109 | srcname = strip_multilib(d.getVar('PN', True), d) | ||
1110 | outspecfile = workdir + "/" + srcname + ".spec" | ||
1111 | if os.path.isfile(outspecfile): | ||
1112 | os.remove(outspecfile) | ||
1113 | d.setVar('OUTSPECFILE', outspecfile) | ||
1114 | bb.build.exec_func('write_specfile', d) | ||
1115 | |||
1116 | perfiledeps = (d.getVar("MERGEPERFILEDEPS", True) or "0") == "0" | ||
1117 | if perfiledeps: | ||
1118 | outdepends, outprovides = write_rpm_perfiledata(srcname, d) | ||
1119 | |||
1120 | # Setup the rpmbuild arguments... | ||
1121 | rpmbuild = d.getVar('RPMBUILD', True) | ||
1122 | targetsys = d.getVar('TARGET_SYS', True) | ||
1123 | targetvendor = d.getVar('TARGET_VENDOR', True) | ||
1124 | package_arch = (d.getVar('PACKAGE_ARCH', True) or "").replace("-", "_") | ||
1125 | if package_arch not in "all any noarch".split() and not package_arch.endswith("_nativesdk"): | ||
1126 | ml_prefix = (d.getVar('MLPREFIX', True) or "").replace("-", "_") | ||
1127 | d.setVar('PACKAGE_ARCH_EXTEND', ml_prefix + package_arch) | ||
1128 | else: | ||
1129 | d.setVar('PACKAGE_ARCH_EXTEND', package_arch) | ||
1130 | pkgwritedir = d.expand('${PKGWRITEDIRRPM}/${PACKAGE_ARCH_EXTEND}') | ||
1131 | pkgarch = d.expand('${PACKAGE_ARCH_EXTEND}${TARGET_VENDOR}-${TARGET_OS}') | ||
1132 | magicfile = d.expand('${STAGING_DIR_NATIVE}${datadir_native}/misc/magic.mgc') | ||
1133 | bb.utils.mkdirhier(pkgwritedir) | ||
1134 | os.chmod(pkgwritedir, 0755) | ||
1135 | |||
1136 | cmd = rpmbuild | ||
1137 | cmd = cmd + " --nodeps --short-circuit --target " + pkgarch + " --buildroot " + pkgd | ||
1138 | cmd = cmd + " --define '_topdir " + workdir + "' --define '_rpmdir " + pkgwritedir + "'" | ||
1139 | cmd = cmd + " --define '_build_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm'" | ||
1140 | cmd = cmd + " --define '_use_internal_dependency_generator 0'" | ||
1141 | if perfiledeps: | ||
1142 | cmd = cmd + " --define '__find_requires " + outdepends + "'" | ||
1143 | cmd = cmd + " --define '__find_provides " + outprovides + "'" | ||
1144 | else: | ||
1145 | cmd = cmd + " --define '__find_requires %{nil}'" | ||
1146 | cmd = cmd + " --define '__find_provides %{nil}'" | ||
1147 | cmd = cmd + " --define '_unpackaged_files_terminate_build 0'" | ||
1148 | cmd = cmd + " --define 'debug_package %{nil}'" | ||
1149 | cmd = cmd + " --define '_rpmfc_magic_path " + magicfile + "'" | ||
1150 | cmd = cmd + " --define '_tmppath " + workdir + "'" | ||
1151 | if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': | ||
1152 | cmd = cmd + " --define '_sourcedir " + workdir + "'" | ||
1153 | cmdsrpm = cmd + " --define '_srcrpmdir " + creat_srpm_dir(d) + "'" | ||
1154 | cmdsrpm = cmdsrpm + " -bs " + outspecfile | ||
1155 | # Build the .src.rpm | ||
1156 | d.setVar('SBUILDSPEC', cmdsrpm + "\n") | ||
1157 | d.setVarFlag('SBUILDSPEC', 'func', '1') | ||
1158 | bb.build.exec_func('SBUILDSPEC', d) | ||
1159 | # Remove the source (SOURCE0, SOURCE1 ...) | ||
1160 | cmd = cmd + " --rmsource " | ||
1161 | cmd = cmd + " -bb " + outspecfile | ||
1162 | |||
1163 | # Build the rpm package! | ||
1164 | d.setVar('BUILDSPEC', cmd + "\n") | ||
1165 | d.setVarFlag('BUILDSPEC', 'func', '1') | ||
1166 | bb.build.exec_func('BUILDSPEC', d) | ||
1167 | } | ||
1168 | |||
1169 | python () { | ||
1170 | if d.getVar('PACKAGES', True) != '': | ||
1171 | deps = ' rpm-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot' | ||
1172 | d.appendVarFlag('do_package_write_rpm', 'depends', deps) | ||
1173 | d.setVarFlag('do_package_write_rpm', 'fakeroot', 1) | ||
1174 | } | ||
1175 | |||
1176 | SSTATETASKS += "do_package_write_rpm" | ||
1177 | do_package_write_rpm[sstate-name] = "deploy-rpm" | ||
1178 | do_package_write_rpm[sstate-inputdirs] = "${PKGWRITEDIRRPM}" | ||
1179 | do_package_write_rpm[sstate-outputdirs] = "${DEPLOY_DIR_RPM}" | ||
1180 | # Take a shared lock, we can write multiple packages at the same time... | ||
1181 | # but we need to stop the rootfs/solver from running while we do... | ||
1182 | do_package_write_rpm[sstate-lockfile-shared] += "${DEPLOY_DIR_RPM}/rpm.lock" | ||
1183 | |||
1184 | python do_package_write_rpm_setscene () { | ||
1185 | sstate_setscene(d) | ||
1186 | } | ||
1187 | addtask do_package_write_rpm_setscene | ||
1188 | |||
1189 | python do_package_write_rpm () { | ||
1190 | bb.build.exec_func("read_subpackage_metadata", d) | ||
1191 | bb.build.exec_func("do_package_rpm", d) | ||
1192 | } | ||
1193 | |||
1194 | do_package_write_rpm[dirs] = "${PKGWRITEDIRRPM}" | ||
1195 | do_package_write_rpm[cleandirs] = "${PKGWRITEDIRRPM}" | ||
1196 | do_package_write_rpm[umask] = "022" | ||
1197 | addtask package_write_rpm before do_package_write after do_packagedata do_package | ||
1198 | |||
1199 | PACKAGEINDEXES += "[ ! -e ${DEPLOY_DIR_RPM} ] || package_update_index_rpm;" | ||
1200 | PACKAGEINDEXDEPS += "rpm-native:do_populate_sysroot" | ||
1201 | PACKAGEINDEXDEPS += "createrepo-native:do_populate_sysroot" | ||