diff options
Diffstat (limited to 'meta/classes/package_rpm.bbclass')
| -rw-r--r-- | meta/classes/package_rpm.bbclass | 867 |
1 files changed, 208 insertions, 659 deletions
diff --git a/meta/classes/package_rpm.bbclass b/meta/classes/package_rpm.bbclass index 3ac379d19a..084546f733 100644 --- a/meta/classes/package_rpm.bbclass +++ b/meta/classes/package_rpm.bbclass @@ -6,469 +6,16 @@ RPM="rpm" RPMBUILD="rpmbuild" PKGWRITEDIRRPM = "${WORKDIR}/deploy-rpms" -PKGWRITEDIRSRPM = "${DEPLOY_DIR}/sources/deploy-srpm" # Maintaining the perfile dependencies has singificant overhead when writing the # packages. When set, this value merges them for efficiency. MERGEPERFILEDEPS = "1" -# -# Update the packages indexes ${DEPLOY_DIR_RPM} -# -package_update_index_rpm () { - if [ ! -z "${DEPLOY_KEEP_PACKAGES}" ]; then - return - fi - - sdk_archs=`echo "${SDK_PACKAGE_ARCHS}" | tr - _` - - target_archs="" - for i in ${MULTILIB_PREFIX_LIST} ; do - old_IFS="$IFS" - IFS=":" - set $i - IFS="$old_IFS" - shift # remove mlib - while [ -n "$1" ]; do - target_archs="$target_archs $1" - shift - done - done - - target_archs=`echo "$target_archs" | tr - _` - - archs=`for arch in $target_archs $sdk_archs ; do - echo $arch - done | sort | uniq` - - found=0 - for arch in $archs; do - if [ -d ${DEPLOY_DIR_RPM}/$arch ] ; then - createrepo --update -q ${DEPLOY_DIR_RPM}/$arch - found=1 - fi - done - if [ "$found" != "1" ]; then - bbfatal "There are no packages in ${DEPLOY_DIR_RPM}!" - fi -} - -rpm_log_check() { - target="$1" - lf_path="$2" - - lf_txt="`cat $lf_path`" - for keyword_die in "unpacking of archive failed" "Cannot find package" "exit 1" ERR Fail - do - if (echo "$lf_txt" | grep -v log_check | grep "$keyword_die") >/dev/null 2>&1 - then - echo "log_check: There were error messages in the logfile" - printf "log_check: Matched keyword: [$keyword_die]\n\n" - echo "$lf_txt" | grep -v log_check | grep -C 5 -i "$keyword_die" - echo "" - do_exit=1 - fi - done - test "$do_exit" = 1 && exit 1 - true -} - -# Translate the RPM/Smart format names to the OE multilib format names -# Input via stdin (only the first item per line is converted!) -# Output via stdout -translate_smart_to_oe() { - arg1="$1" - - # Dump installed packages - while read pkg arch other ; do - found=0 - if [ -z "$pkg" ]; then - continue - fi - new_pkg=$pkg - fixed_arch=`echo "$arch" | tr _ -` - for i in ${MULTILIB_PREFIX_LIST} ; do - old_IFS="$IFS" - IFS=":" - set $i - IFS="$old_IFS" - mlib="$1" - shift - while [ -n "$1" ]; do - cmp_arch=$1 - shift - fixed_cmp_arch=`echo "$cmp_arch" | tr _ -` - if [ "$fixed_arch" = "$fixed_cmp_arch" ]; then - if [ "$mlib" = "default" ]; then - new_pkg="$pkg" - new_arch=$cmp_arch - else - new_pkg="$mlib-$pkg" - # We need to strip off the ${mlib}_ prefix on the arch - new_arch=${cmp_arch#${mlib}_} - fi - # Workaround for bug 3565 - # Simply look to see if we know of a package with that name, if not try again! - filename=`ls ${TMPDIR}/pkgdata/*/runtime-reverse/$new_pkg 2>/dev/null | head -n 1` - if [ -n "$filename" ] ; then - found=1 - break - fi - # 'real' code - # found=1 - # break - fi - done - if [ "$found" = "1" ] && [ "$fixed_arch" = "$fixed_cmp_arch" ]; then - break - fi - done - - #echo "$pkg -> $new_pkg" >&2 - if [ "$arg1" = "arch" ]; then - echo $new_pkg $new_arch $other - else - echo $new_pkg $other - fi - done -} - -# Translate the OE multilib format names to the RPM/Smart format names -# Input via arguments -# Ouput via pkgs_to_install -translate_oe_to_smart() { - default_archs="" - sdk_mode="" - if [ "$1" = "--sdk" ]; then - shift - sdk_mode="true" - # Need to reverse the order of the SDK_ARCHS highest -> lowest priority - archs=`echo "${SDK_PACKAGE_ARCHS}" | tr - _` - for arch in $archs ; do - default_archs="$arch $default_archs" - done - fi - - attemptonly="Error" - if [ "$1" = "--attemptonly" ]; then - attemptonly="Warning" - shift - fi - - # Dump a list of all available packages - [ ! -e ${target_rootfs}/install/tmp/fullpkglist.query ] && smart --data-dir=${target_rootfs}/var/lib/smart query --output ${target_rootfs}/install/tmp/fullpkglist.query - - pkgs_to_install="" - for pkg in "$@" ; do - new_pkg="$pkg" - if [ -z "$sdk_mode" ]; then - for i in ${MULTILIB_PREFIX_LIST} ; do - old_IFS="$IFS" - IFS=":" - set $i - IFS="$old_IFS" - mlib="$1" - shift - if [ "$mlib" = "default" ]; then - if [ -z "$default_archs" ]; then - default_archs=$@ - fi - continue - fi - subst=${pkg#${mlib}-} - if [ "$subst" != "$pkg" ]; then - feeds=$@ - while [ -n "$1" ]; do - arch="$1" - arch=`echo "$arch" | tr - _` - shift - if grep -q '^'$subst'-[^-]*-[^-]*@'$arch'$' ${target_rootfs}/install/tmp/fullpkglist.query ; then - new_pkg="$subst@$arch" - # First found is best match - break - fi - done - if [ "$pkg" = "$new_pkg" ]; then - # Failed to translate, package not found! - echo "$attemptonly: $pkg not found in the $mlib feeds ($feeds)." >&2 - if [ "$attemptonly" = "Error" ]; then - exit 1 - fi - continue - fi - fi - done - fi - # Apparently not a multilib package... - if [ "$pkg" = "$new_pkg" ]; then - default_archs_fixed=`echo "$default_archs" | tr - _` - for arch in $default_archs_fixed ; do - if grep -q '^'$pkg'-[^-]*-[^-]*@'$arch'$' ${target_rootfs}/install/tmp/fullpkglist.query ; then - new_pkg="$pkg@$arch" - # First found is best match - break - fi - done - if [ "$pkg" = "$new_pkg" ]; then - # Failed to translate, package not found! - echo "$attemptonly: $pkg not found in the base feeds ($default_archs)." >&2 - if [ "$attemptonly" = "Error" ]; then - exit 1 - fi - continue - fi - fi - #echo "$pkg -> $new_pkg" >&2 - pkgs_to_install="${pkgs_to_install} ${new_pkg}" - done - export pkgs_to_install -} - - -# -# Install a bunch of packages using rpm. -# There are two solutions in an image's FRESH generation: -# 1) main package solution -# 2) complementary solution -# -# It is different when incremental image generation is enabled: -# 1) The incremental image generation takes action during the main package -# installation, the previous installed complementary packages would -# usually be removed here, and the new complementary ones would be -# installed in the next step. -# 2) The complementary would always be installed since it is -# generated based on the first step's image. -# -# the following shell variables needs to be set before calling this func: -# INSTALL_ROOTFS_RPM - install root dir -# INSTALL_PLATFORM_RPM - main platform -# INSTALL_PLATFORM_EXTRA_RPM - extra platform -# INSTALL_PACKAGES_RPM - packages to be installed -# INSTALL_PACKAGES_ATTEMPTONLY_RPM - packages attemped to be installed only -# INSTALL_PACKAGES_LINGUAS_RPM - additional packages for uclibc -# INSTALL_PROVIDENAME_RPM - content for provide name -# INSTALL_TASK_RPM - task name -# INSTALL_COMPLEMENTARY_RPM - 1 to enable complementary package install mode - -package_install_internal_rpm () { - - local target_rootfs="$INSTALL_ROOTFS_RPM" - local package_to_install="$INSTALL_PACKAGES_RPM" - local package_attemptonly="$INSTALL_PACKAGES_ATTEMPTONLY_RPM" - local package_linguas="$INSTALL_PACKAGES_LINGUAS_RPM" - local providename="$INSTALL_PROVIDENAME_RPM" - local task="$INSTALL_TASK_RPM" - - local sdk_mode="" - if [ "$1" = "--sdk" ]; then - sdk_mode="--sdk" - fi - - # Configure internal RPM environment when using Smart - export RPM_ETCRPM=${target_rootfs}/etc/rpm - - # Setup temporary directory -- install... - rm -rf ${target_rootfs}/install - mkdir -p ${target_rootfs}/install/tmp - - channel_priority=5 - if [ "${INSTALL_COMPLEMENTARY_RPM}" != "1" ] ; then - # Setup base system configuration - echo "Note: configuring RPM platform settings" - mkdir -p ${target_rootfs}/etc/rpm/ - echo "$INSTALL_PLATFORM_RPM" > ${target_rootfs}/etc/rpm/platform - - if [ ! -z "$INSTALL_PLATFORM_EXTRA_RPM" ]; then - for pt in $INSTALL_PLATFORM_EXTRA_RPM ; do - channel_priority=$(expr $channel_priority + 5) - case $pt in - noarch-* | any-* | all-*) - pt=$(echo $pt | sed "s,-linux.*$,-linux\.*,") - ;; - esac - echo "$pt" >> ${target_rootfs}/etc/rpm/platform - done - fi - - # Tell RPM that the "/" directory exist and is available - echo "Note: configuring RPM system provides" - mkdir -p ${target_rootfs}/etc/rpm/sysinfo - echo "/" >${target_rootfs}/etc/rpm/sysinfo/Dirnames - - if [ ! -z "$providename" ]; then - cat /dev/null > ${target_rootfs}/etc/rpm/sysinfo/Providename - for provide in $providename ; do - echo $provide >> ${target_rootfs}/etc/rpm/sysinfo/Providename - done - fi - - # Configure RPM... we enforce these settings! - echo "Note: configuring RPM DB settings" - mkdir -p ${target_rootfs}${rpmlibdir} - mkdir -p ${target_rootfs}${rpmlibdir}/log - # After change the __db.* cache size, log file will not be generated automatically, - # that will raise some warnings, so touch a bare log for rpm write into it. - touch ${target_rootfs}${rpmlibdir}/log/log.0000000001 - if [ ! -e ${target_rootfs}${rpmlibdir}/DB_CONFIG ]; then - cat > ${target_rootfs}${rpmlibdir}/DB_CONFIG << EOF -# ================ Environment -set_data_dir . -set_create_dir . -set_lg_dir ./log -set_tmp_dir ./tmp -set_flags db_log_autoremove on - -# -- thread_count must be >= 8 -set_thread_count 64 - -# ================ Logging - -# ================ Memory Pool -set_cachesize 0 1048576 0 -set_mp_mmapsize 268435456 - -# ================ Locking -set_lk_max_locks 16384 -set_lk_max_lockers 16384 -set_lk_max_objects 16384 - mutex_set_max 163840 - -# ================ Replication -EOF - fi - - # Create database so that smart doesn't complain (lazy init) - rpm --root $target_rootfs --dbpath /var/lib/rpm -qa > /dev/null - - # Configure smart - echo "Note: configuring Smart settings" - rm -rf ${target_rootfs}/var/lib/smart - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-root=${target_rootfs} - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-dbpath=${rpmlibdir} - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-nolinktos=1 - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-noparentdirs=1 - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._var=${localstatedir} - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._tmppath=/install/tmp - # Optional debugging - #smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-log-level=debug - #smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-log-file=/tmp/smart-debug-logfile - - # Delay this until later... - #smart --data-dir=${target_rootfs}/var/lib/smart channel --add rpmsys type=rpm-sys -y - - for canonical_arch in $INSTALL_PLATFORM_EXTRA_RPM; do - arch=$(echo $canonical_arch | sed "s,\([^-]*\)-.*,\1,") - if [ -d ${DEPLOY_DIR_RPM}/$arch -a ! -e ${target_rootfs}/install/channel.$arch.stamp ] ; then - echo "Note: adding Smart channel $arch ($channel_priority)" - smart --data-dir=${target_rootfs}/var/lib/smart channel --add $arch type=rpm-md type=rpm-md baseurl=${DEPLOY_DIR_RPM}/$arch -y - smart --data-dir=${target_rootfs}/var/lib/smart channel --set $arch priority=$channel_priority - touch ${target_rootfs}/install/channel.$arch.stamp - fi - channel_priority=$(expr $channel_priority - 5) - done - fi - - # Uclibc builds don't provide this stuff... - if [ x${TARGET_OS} != "xlinux" ] && [ x${TARGET_OS} != "xlinux-gnueabi" ] ; then - package_linguas="" - fi - - # Construct install scriptlet wrapper - cat << EOF > ${WORKDIR}/scriptlet_wrapper -#!/bin/bash - -export PATH="${PATH}" -export D="${target_rootfs}" -export OFFLINE_ROOT="\$D" -export IPKG_OFFLINE_ROOT="\$D" -export OPKG_OFFLINE_ROOT="\$D" -export INTERCEPT_DIR="${WORKDIR}/intercept_scripts" -export NATIVE_ROOT=${STAGING_DIR_NATIVE} - -\$2 \$1/\$3 \$4 -if [ \$? -ne 0 ]; then - mkdir -p \$1/etc/rpm-postinsts - name=\`head -1 \$1/\$3 | cut -d' ' -f 2\` - echo "#!\$2" > \$1/etc/rpm-postinsts/\${name} - echo "# Arg: \$4" >> \$1/etc/rpm-postinsts/\${name} - cat \$1/\$3 >> \$1/etc/rpm-postinsts/\${name} - chmod +x \$1/etc/rpm-postinsts/\${name} -fi -EOF - - echo "Note: configuring RPM cross-install scriptlet_wrapper" - chmod 0755 ${WORKDIR}/scriptlet_wrapper - smart --data-dir=${target_rootfs}/var/lib/smart config --set rpm-extra-macros._cross_scriptlet_wrapper=${WORKDIR}/scriptlet_wrapper - - # Determine what to install - translate_oe_to_smart ${sdk_mode} ${package_to_install} ${package_linguas} - - # If incremental install, we need to determine what we've got, - # what we need to add, and what to remove... - if [ "${INC_RPM_IMAGE_GEN}" = "1" -a "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then - # Dump the new solution - echo "Note: creating install solution for incremental install" - smart --data-dir=${target_rootfs}/var/lib/smart install -y --dump ${pkgs_to_install} 2> ${target_rootfs}/../solution.manifest - fi - - if [ "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then - echo "Note: adding Smart RPM DB channel" - smart --data-dir=${target_rootfs}/var/lib/smart channel --add rpmsys type=rpm-sys -y - fi - - # If incremental install, we need to determine what we've got, - # what we need to add, and what to remove... - if [ "${INC_RPM_IMAGE_GEN}" = "1" -a "${INSTALL_COMPLEMENTARY_RPM}" != "1" ]; then - # First upgrade everything that was previously installed to the latest version - echo "Note: incremental update -- upgrade packages in place" - smart --data-dir=${target_rootfs}/var/lib/smart upgrade - - # Dump what is already installed - echo "Note: dump installed packages for incremental update" - smart --data-dir=${target_rootfs}/var/lib/smart query --installed --output ${target_rootfs}/../installed.manifest - - sort ${target_rootfs}/../installed.manifest > ${target_rootfs}/../installed.manifest.sorted - sort ${target_rootfs}/../solution.manifest > ${target_rootfs}/../solution.manifest.sorted - - comm -1 -3 ${target_rootfs}/../solution.manifest.sorted ${target_rootfs}/../installed.manifest.sorted \ - > ${target_rootfs}/../remove.list - comm -2 -3 ${target_rootfs}/../solution.manifest.sorted ${target_rootfs}/../installed.manifest.sorted \ - > ${target_rootfs}/../install.list - - pkgs_to_remove=`cat ${target_rootfs}/../remove.list | xargs echo` - pkgs_to_install=`cat ${target_rootfs}/../install.list | xargs echo` - - echo "Note: to be removed: ${pkgs_to_remove}" - - for pkg in ${pkgs_to_remove}; do - echo "Debug: What required: $pkg" - smart --data-dir=${target_rootfs}/var/lib/smart query $pkg --show-requiredby - done - - [ -n "$pkgs_to_remove" ] && smart --data-dir=${target_rootfs}/var/lib/smart remove -y ${pkgs_to_remove} - fi - - echo "Note: to be installed: ${pkgs_to_install}" - [ -n "$pkgs_to_install" ] && smart --data-dir=${target_rootfs}/var/lib/smart install -y ${pkgs_to_install} - - if [ -n "${package_attemptonly}" ]; then - echo "Note: installing attempt only packages..." - echo "Attempting $pkgs_to_install" - echo "Note: see `dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" - translate_oe_to_smart ${sdk_mode} --attemptonly $package_attemptonly - for each_pkg in $pkgs_to_install ; do - # We need to try each package individually as a single dependency failure - # will break the whole set otherwise. - smart --data-dir=${target_rootfs}/var/lib/smart install -y $each_pkg >> "`dirname ${BB_LOGFILE}`/log.do_${task}_attemptonly.${PID}" 2>&1 || true - done - fi -} - # Construct per file dependencies file def write_rpm_perfiledata(srcname, d): - workdir = d.getVar('WORKDIR', True) - packages = d.getVar('PACKAGES', True) - pkgd = d.getVar('PKGD', True) + workdir = d.getVar('WORKDIR') + packages = d.getVar('PACKAGES') + pkgd = d.getVar('PKGD') def dump_filerdeps(varname, outfile, d): outfile.write("#!/usr/bin/env python\n\n") @@ -476,10 +23,10 @@ def write_rpm_perfiledata(srcname, d): outfile.write('deps = {\n') for pkg in packages.split(): dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg - dependsflist = (d.getVar(dependsflist_key, True) or "") + dependsflist = (d.getVar(dependsflist_key) or "") for dfile in dependsflist.split(): key = "FILE" + varname + "_" + dfile + "_" + pkg - depends_dict = bb.utils.explode_dep_versions(d.getVar(key, True) or "") + depends_dict = bb.utils.explode_dep_versions(d.getVar(key) or "") file = dfile.replace("@underscore@", "_") file = file.replace("@closebrace@", "]") file = file.replace("@openbrace@", "[") @@ -508,79 +55,52 @@ def write_rpm_perfiledata(srcname, d): # OE-core dependencies a.k.a. RPM requires outdepends = workdir + "/" + srcname + ".requires" - try: - from __builtin__ import file - dependsfile = file(outdepends, 'w') - except OSError: - raise bb.build.FuncFailed("unable to open spec file for writing.") + dependsfile = open(outdepends, 'w') dump_filerdeps('RDEPENDS', dependsfile, d) dependsfile.close() - os.chmod(outdepends, 0755) + os.chmod(outdepends, 0o755) # OE-core / RPM Provides outprovides = workdir + "/" + srcname + ".provides" - try: - from __builtin__ import file - providesfile = file(outprovides, 'w') - except OSError: - raise bb.build.FuncFailed("unable to open spec file for writing.") + providesfile = open(outprovides, 'w') dump_filerdeps('RPROVIDES', providesfile, d) providesfile.close() - os.chmod(outprovides, 0755) + os.chmod(outprovides, 0o755) return (outdepends, outprovides) python write_specfile () { - import textwrap import oe.packagedata # append information for logs and patches to %prep def add_prep(d,spec_files_bottom): - if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': - spec_files_bottom.append('%%prep -n %s' % d.getVar('PN', True) ) + if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d): + spec_files_bottom.append('%%prep -n %s' % d.getVar('PN') ) spec_files_bottom.append('%s' % "echo \"include logs and patches, Please check them in SOURCES\"") spec_files_bottom.append('') # append the name of tarball to key word 'SOURCE' in xxx.spec. def tail_source(d): - if d.getVar('SOURCE_ARCHIVE_PACKAGE_TYPE', True) == 'srpm': - source_list = get_package(d) + if d.getVarFlag('ARCHIVER_MODE', 'srpm') == '1' and bb.data.inherits_class('archiver', d): + ar_outdir = d.getVar('ARCHIVER_OUTDIR') + if not os.path.exists(ar_outdir): + return + source_list = os.listdir(ar_outdir) source_number = 0 - workdir = d.getVar('WORKDIR', True) for source in source_list: # The rpmbuild doesn't need the root permission, but it needs # to know the file's user and group name, the only user and # group in fakeroot is "root" when working in fakeroot. - os.chown("%s/%s" % (workdir, source), 0, 0) - spec_preamble_top.append('Source' + str(source_number) + ': %s' % source) + f = os.path.join(ar_outdir, source) + os.chown(f, 0, 0) + spec_preamble_top.append('Source%s: %s' % (source_number, source)) source_number += 1 - # We need a simple way to remove the MLPREFIX from the package name, - # and dependency information... - def strip_multilib(name, d): - multilibs = d.getVar('MULTILIBS', True) or "" - for ext in multilibs.split(): - eext = ext.split(':') - if len(eext) > 1 and eext[0] == 'multilib' and name and name.find(eext[1] + '-') >= 0: - name = "".join(name.split(eext[1] + '-')) - return name - - def strip_multilib_deps(deps, d): - depends = bb.utils.explode_dep_versions2(deps or "") - newdeps = {} - for dep in depends: - newdeps[strip_multilib(dep, d)] = depends[dep] - return bb.utils.join_deps(newdeps) - -# ml = d.getVar("MLPREFIX", True) -# if ml and name and len(ml) != 0 and name.find(ml) == 0: -# return ml.join(name.split(ml, 1)[1:]) -# return name # In RPM, dependencies are of the format: pkg <>= Epoch:Version-Release # This format is similar to OE, however there are restrictions on the @@ -597,7 +117,7 @@ python write_specfile () { # after renaming we cannot look up the dependencies in the packagedata # store. def translate_vers(varname, d): - depends = d.getVar(varname, True) + depends = d.getVar(varname) if depends: depends_dict = bb.utils.explode_dep_versions2(depends) newdeps_dict = {} @@ -607,9 +127,17 @@ python write_specfile () { if '-' in ver: subd = oe.packagedata.read_subpkgdata_dict(dep, d) if 'PKGV' in subd: - pv = subd['PKGV'] - reppv = pv.replace('-', '+') - verlist.append(ver.replace(pv, reppv)) + pv = subd['PV'] + pkgv = subd['PKGV'] + reppv = pkgv.replace('-', '+') + ver = ver.replace(pv, reppv).replace(pkgv, reppv) + if 'PKGR' in subd: + # Make sure PKGR rather than PR in ver + pr = '-' + subd['PR'] + pkgr = '-' + subd['PKGR'] + if pkgr not in ver: + ver = ver.replace(pr, pkgr) + verlist.append(ver) else: verlist.append(ver) newdeps_dict[dep] = verlist @@ -630,13 +158,57 @@ python write_specfile () { if not len(depends_dict[dep]): array.append("%s: %s" % (tag, dep)) - def walk_files(walkpath, target, conffiles): + def walk_files(walkpath, target, conffiles, dirfiles): + # We can race against the ipk/deb backends which create CONTROL or DEBIAN directories + # when packaging. We just ignore these files which are created in + # packages-split/ and not package/ + # We have the odd situation where the CONTROL/DEBIAN directory can be removed in the middle of + # of the walk, the isdir() test would then fail and the walk code would assume its a file + # hence we check for the names in files too. for rootpath, dirs, files in os.walk(walkpath): path = rootpath.replace(walkpath, "") - for dir in dirs: - # All packages own the directories their files are in... - target.append('%dir "' + path + '/' + dir + '"') + if path.endswith("DEBIAN") or path.endswith("CONTROL"): + continue + path = path.replace("%", "%%%%%%%%") + path = path.replace("[", "?") + path = path.replace("]", "?") + + # Treat all symlinks to directories as normal files. + # os.walk() lists them as directories. + def move_to_files(dir): + if os.path.islink(os.path.join(rootpath, dir)): + files.append(dir) + return True + else: + return False + dirs[:] = [dir for dir in dirs if not move_to_files(dir)] + + # Directory handling can happen in two ways, either DIRFILES is not set at all + # in which case we fall back to the older behaviour of packages owning all their + # directories + if dirfiles is None: + for dir in dirs: + if dir == "CONTROL" or dir == "DEBIAN": + continue + dir = dir.replace("%", "%%%%%%%%") + dir = dir.replace("[", "?") + dir = dir.replace("]", "?") + # All packages own the directories their files are in... + target.append('%dir "' + path + '/' + dir + '"') + else: + # packages own only empty directories or explict directory. + # This will prevent the overlapping of security permission. + if path and not files and not dirs: + target.append('%dir "' + path + '"') + elif path and path in dirfiles: + target.append('%dir "' + path + '"') + for file in files: + if file == "CONTROL" or file == "DEBIAN": + continue + file = file.replace("%", "%%%%%%%%") + file = file.replace("[", "?") + file = file.replace("]", "?") if conffiles.count(path + '/' + file): target.append('%config "' + path + '/' + file + '"') else: @@ -655,42 +227,54 @@ python write_specfile () { def get_perfile(varname, pkg, d): deps = [] dependsflist_key = 'FILE' + varname + 'FLIST' + "_" + pkg - dependsflist = (d.getVar(dependsflist_key, True) or "") + dependsflist = (d.getVar(dependsflist_key) or "") for dfile in dependsflist.split(): key = "FILE" + varname + "_" + dfile + "_" + pkg - depends = d.getVar(key, True) + depends = d.getVar(key) if depends: deps.append(depends) return " ".join(deps) - packages = d.getVar('PACKAGES', True) + def append_description(spec_preamble, text): + """ + Add the description to the spec file. + """ + import textwrap + dedent_text = textwrap.dedent(text).strip() + # Bitbake saves "\n" as "\\n" + if '\\n' in dedent_text: + for t in dedent_text.split('\\n'): + spec_preamble.append(t.strip()) + else: + spec_preamble.append('%s' % textwrap.fill(dedent_text, width=75)) + + packages = d.getVar('PACKAGES') if not packages or packages == '': bb.debug(1, "No packages; nothing to do") return - pkgdest = d.getVar('PKGDEST', True) + pkgdest = d.getVar('PKGDEST') if not pkgdest: bb.fatal("No PKGDEST") - return - outspecfile = d.getVar('OUTSPECFILE', True) + outspecfile = d.getVar('OUTSPECFILE') if not outspecfile: bb.fatal("No OUTSPECFILE") - return # Construct the SPEC file... - srcname = strip_multilib(d.getVar('PN', True), d) - srcsummary = (d.getVar('SUMMARY', True) or d.getVar('DESCRIPTION', True) or ".") - srcversion = d.getVar('PKGV', True).replace('-', '+') - srcrelease = d.getVar('PKGR', True) - srcepoch = (d.getVar('PKGE', True) or "") - srclicense = d.getVar('LICENSE', True) - srcsection = d.getVar('SECTION', True) - srcmaintainer = d.getVar('MAINTAINER', True) - srchomepage = d.getVar('HOMEPAGE', True) - srcdescription = d.getVar('DESCRIPTION', True) or "." - - srcdepends = strip_multilib_deps(d.getVar('DEPENDS', True), d) + srcname = d.getVar('PN') + srcsummary = (d.getVar('SUMMARY') or d.getVar('DESCRIPTION') or ".") + srcversion = d.getVar('PKGV').replace('-', '+') + srcrelease = d.getVar('PKGR') + srcepoch = (d.getVar('PKGE') or "") + srclicense = d.getVar('LICENSE') + srcsection = d.getVar('SECTION') + srcmaintainer = d.getVar('MAINTAINER') + srchomepage = d.getVar('HOMEPAGE') + srcdescription = d.getVar('DESCRIPTION') or "." + srccustomtagschunk = get_package_additional_metadata("rpm", d) + + srcdepends = d.getVar('DEPENDS') srcrdepends = [] srcrrecommends = [] srcrsuggests = [] @@ -713,37 +297,38 @@ python write_specfile () { spec_files_top = [] spec_files_bottom = [] - perfiledeps = (d.getVar("MERGEPERFILEDEPS", True) or "0") == "0" + perfiledeps = (d.getVar("MERGEPERFILEDEPS") or "0") == "0" + extra_pkgdata = (d.getVar("RPM_EXTRA_PKGDATA") or "0") == "1" for pkg in packages.split(): localdata = bb.data.createCopy(d) root = "%s/%s" % (pkgdest, pkg) - lf = bb.utils.lockfile(root + ".lock") - localdata.setVar('ROOT', '') localdata.setVar('ROOT_%s' % pkg, root) - pkgname = localdata.getVar('PKG_%s' % pkg, True) + pkgname = localdata.getVar('PKG_%s' % pkg) if not pkgname: pkgname = pkg localdata.setVar('PKG', pkgname) - localdata.setVar('OVERRIDES', pkg) - - bb.data.update_data(localdata) + localdata.setVar('OVERRIDES', d.getVar("OVERRIDES", False) + ":" + pkg) - conffiles = (localdata.getVar('CONFFILES', True) or "").split() + conffiles = get_conffiles(pkg, d) + dirfiles = localdata.getVar('DIRFILES') + if dirfiles is not None: + dirfiles = dirfiles.split() - splitname = strip_multilib(pkgname, d) + splitname = pkgname - splitsummary = (localdata.getVar('SUMMARY', True) or localdata.getVar('DESCRIPTION', True) or ".") - splitversion = (localdata.getVar('PKGV', True) or "").replace('-', '+') - splitrelease = (localdata.getVar('PKGR', True) or "") - splitepoch = (localdata.getVar('PKGE', True) or "") - splitlicense = (localdata.getVar('LICENSE', True) or "") - splitsection = (localdata.getVar('SECTION', True) or "") - splitdescription = (localdata.getVar('DESCRIPTION', True) or ".") + splitsummary = (localdata.getVar('SUMMARY') or localdata.getVar('DESCRIPTION') or ".") + splitversion = (localdata.getVar('PKGV') or "").replace('-', '+') + splitrelease = (localdata.getVar('PKGR') or "") + splitepoch = (localdata.getVar('PKGE') or "") + splitlicense = (localdata.getVar('LICENSE') or "") + splitsection = (localdata.getVar('SECTION') or "") + splitdescription = (localdata.getVar('DESCRIPTION') or ".") + splitcustomtagschunk = get_package_additional_metadata("rpm", localdata) translate_vers('RDEPENDS', localdata) translate_vers('RRECOMMENDS', localdata) @@ -755,18 +340,18 @@ python write_specfile () { # Map the dependencies into their final form mapping_rename_hook(localdata) - splitrdepends = strip_multilib_deps(localdata.getVar('RDEPENDS', True), d) - splitrrecommends = strip_multilib_deps(localdata.getVar('RRECOMMENDS', True), d) - splitrsuggests = strip_multilib_deps(localdata.getVar('RSUGGESTS', True), d) - splitrprovides = strip_multilib_deps(localdata.getVar('RPROVIDES', True), d) - splitrreplaces = strip_multilib_deps(localdata.getVar('RREPLACES', True), d) - splitrconflicts = strip_multilib_deps(localdata.getVar('RCONFLICTS', True), d) + splitrdepends = localdata.getVar('RDEPENDS') + splitrrecommends = localdata.getVar('RRECOMMENDS') + splitrsuggests = localdata.getVar('RSUGGESTS') + splitrprovides = localdata.getVar('RPROVIDES') + splitrreplaces = localdata.getVar('RREPLACES') + splitrconflicts = localdata.getVar('RCONFLICTS') splitrobsoletes = [] - splitrpreinst = localdata.getVar('pkg_preinst', True) - splitrpostinst = localdata.getVar('pkg_postinst', True) - splitrprerm = localdata.getVar('pkg_prerm', True) - splitrpostrm = localdata.getVar('pkg_postrm', True) + splitrpreinst = localdata.getVar('pkg_preinst') + splitrpostinst = localdata.getVar('pkg_postinst') + splitrprerm = localdata.getVar('pkg_prerm') + splitrpostrm = localdata.getVar('pkg_postrm') if not perfiledeps: @@ -789,12 +374,14 @@ python write_specfile () { srcrpostrm = splitrpostrm file_list = [] - walk_files(root, file_list, conffiles) - if not file_list and localdata.getVar('ALLOW_EMPTY') != "1": + walk_files(root, file_list, conffiles, dirfiles) + if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1": bb.note("Not creating empty RPM package for %s" % splitname) else: bb.note("Creating RPM package for %s" % splitname) spec_files_top.append('%files') + if extra_pkgdata: + package_rpm_extra_pkgdata(splitname, spec_files_top, localdata) spec_files_top.append('%defattr(-,-,-,-)') if file_list: bb.note("Creating RPM package for %s" % splitname) @@ -802,8 +389,6 @@ python write_specfile () { else: bb.note("Creating EMPTY RPM Package for %s" % splitname) spec_files_top.append('') - - bb.utils.unlockfile(lf) continue # Process subpackage data @@ -819,6 +404,9 @@ python write_specfile () { spec_preamble_bottom.append('License: %s' % splitlicense) spec_preamble_bottom.append('Group: %s' % splitsection) + if srccustomtagschunk != splitcustomtagschunk: + spec_preamble_bottom.append(splitcustomtagschunk) + # Replaces == Obsoletes && Provides robsoletes = bb.utils.explode_dep_versions2(splitrobsoletes or "") rprovides = bb.utils.explode_dep_versions2(splitrprovides or "") @@ -841,32 +429,16 @@ python write_specfile () { if splitrpostrm: print_deps(splitrdepends, "Requires(postun)", spec_preamble_bottom, d) - # Suggests in RPM are like recommends in OE-core! - print_deps(splitrrecommends, "Suggests", spec_preamble_bottom, d) - # While there is no analog for suggests... (So call them recommends for now) - print_deps(splitrsuggests, "Recommends", spec_preamble_bottom, d) + print_deps(splitrrecommends, "Recommends", spec_preamble_bottom, d) + print_deps(splitrsuggests, "Suggests", spec_preamble_bottom, d) print_deps(splitrprovides, "Provides", spec_preamble_bottom, d) print_deps(splitrobsoletes, "Obsoletes", spec_preamble_bottom, d) - - # conflicts can not be in a provide! We will need to filter it. - if splitrconflicts: - depends_dict = bb.utils.explode_dep_versions2(splitrconflicts) - newdeps_dict = {} - for dep in depends_dict: - if dep not in splitrprovides: - newdeps_dict[dep] = depends_dict[dep] - if newdeps_dict: - splitrconflicts = bb.utils.join_deps(newdeps_dict) - else: - splitrconflicts = "" - print_deps(splitrconflicts, "Conflicts", spec_preamble_bottom, d) spec_preamble_bottom.append('') spec_preamble_bottom.append('%%description -n %s' % splitname) - dedent_text = textwrap.dedent(splitdescription).strip() - spec_preamble_bottom.append('%s' % textwrap.fill(dedent_text, width=75)) + append_description(spec_preamble_bottom, splitdescription) spec_preamble_bottom.append('') @@ -896,11 +468,13 @@ python write_specfile () { # Now process files file_list = [] - walk_files(root, file_list, conffiles) - if not file_list and localdata.getVar('ALLOW_EMPTY') != "1": + walk_files(root, file_list, conffiles, dirfiles) + if not file_list and localdata.getVar('ALLOW_EMPTY', False) != "1": bb.note("Not creating empty RPM package for %s" % splitname) else: spec_files_bottom.append('%%files -n %s' % splitname) + if extra_pkgdata: + package_rpm_extra_pkgdata(splitname, spec_files_bottom, localdata) spec_files_bottom.append('%defattr(-,-,-,-)') if file_list: bb.note("Creating RPM package for %s" % splitname) @@ -910,7 +484,6 @@ python write_specfile () { spec_files_bottom.append('') del localdata - bb.utils.unlockfile(lf) add_prep(d,spec_files_bottom) spec_preamble_top.append('Summary: %s' % srcsummary) @@ -922,7 +495,10 @@ python write_specfile () { spec_preamble_top.append('License: %s' % srclicense) spec_preamble_top.append('Group: %s' % srcsection) spec_preamble_top.append('Packager: %s' % srcmaintainer) - spec_preamble_top.append('URL: %s' % srchomepage) + if srchomepage: + spec_preamble_top.append('URL: %s' % srchomepage) + if srccustomtagschunk: + spec_preamble_top.append(srccustomtagschunk) tail_source(d) # Replaces == Obsoletes && Provides @@ -948,32 +524,16 @@ python write_specfile () { if srcrpostrm: print_deps(srcrdepends, "Requires(postun)", spec_preamble_top, d) - # Suggests in RPM are like recommends in OE-core! - print_deps(srcrrecommends, "Suggests", spec_preamble_top, d) - # While there is no analog for suggests... (So call them recommends for now) - print_deps(srcrsuggests, "Recommends", spec_preamble_top, d) - print_deps(srcrprovides, "Provides", spec_preamble_top, d) + print_deps(srcrrecommends, "Recommends", spec_preamble_top, d) + print_deps(srcrsuggests, "Suggests", spec_preamble_top, d) + print_deps(srcrprovides + (" /bin/sh" if srcname.startswith("nativesdk-") else ""), "Provides", spec_preamble_top, d) print_deps(srcrobsoletes, "Obsoletes", spec_preamble_top, d) - - # conflicts can not be in a provide! We will need to filter it. - if srcrconflicts: - depends_dict = bb.utils.explode_ |
