summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes/buildhistory.bbclass51
-rw-r--r--meta/classes/rootfs_deb.bbclass28
-rw-r--r--meta/classes/rootfs_ipk.bbclass34
-rw-r--r--meta/classes/rootfs_rpm.bbclass33
-rw-r--r--meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c117
5 files changed, 162 insertions, 101 deletions
diff --git a/meta/classes/buildhistory.bbclass b/meta/classes/buildhistory.bbclass
index f0bf849860..ddb76e8771 100644
--- a/meta/classes/buildhistory.bbclass
+++ b/meta/classes/buildhistory.bbclass
@@ -285,48 +285,43 @@ buildhistory_get_image_installed() {
285 mkdir -p ${BUILDHISTORY_DIR_IMAGE} 285 mkdir -p ${BUILDHISTORY_DIR_IMAGE}
286 286
287 # Get list of installed packages 287 # Get list of installed packages
288 list_installed_packages | sort > ${BUILDHISTORY_DIR_IMAGE}/installed-package-names.txt 288 pkgcache="${BUILDHISTORY_DIR_IMAGE}/installed-packages.tmp"
289 INSTALLED_PKGS=`cat ${BUILDHISTORY_DIR_IMAGE}/installed-package-names.txt` 289 list_installed_packages file | sort > $pkgcache
290
291 cat $pkgcache | awk '{ print $1 }' > ${BUILDHISTORY_DIR_IMAGE}/installed-package-names.txt
292 cat $pkgcache | awk '{ print $2 }' | xargs -n1 basename > ${BUILDHISTORY_DIR_IMAGE}/installed-packages.txt
293
294 # Produce dependency graph
295 # First, filter out characters that cause issues for dot
296 rootfs_list_installed_depends | sed -e 's:-:_:g' -e 's:\.:_:g' -e 's:+::g' > ${BUILDHISTORY_DIR_IMAGE}/depends.tmp
297 # Change delimiter from pipe to -> and set style for recommend lines
298 sed -i -e 's:|: -> :' -e 's:\[REC\]:[style=dotted]:' -e 's:$:;:' ${BUILDHISTORY_DIR_IMAGE}/depends.tmp
299 # Add header, sorted and de-duped contents and footer and then delete the temp file
300 echo -e "digraph depends {\n node [shape=plaintext]" > ${BUILDHISTORY_DIR_IMAGE}/depends.dot
301 cat ${BUILDHISTORY_DIR_IMAGE}/depends.tmp | sort | uniq >> ${BUILDHISTORY_DIR_IMAGE}/depends.dot
302 echo "}" >> ${BUILDHISTORY_DIR_IMAGE}/depends.dot
303 rm ${BUILDHISTORY_DIR_IMAGE}/depends.tmp
290 304
291 # Produce installed package file and size lists and dependency graph 305 # Produce installed package sizes list
292 echo -n > ${BUILDHISTORY_DIR_IMAGE}/installed-packages.txt
293 echo -n > ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp 306 echo -n > ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp
294 echo -e "digraph depends {\n node [shape=plaintext]" > ${BUILDHISTORY_DIR_IMAGE}/depends.dot 307 cat $pkgcache | while read pkg pkgfile
295 for pkg in $INSTALLED_PKGS; do 308 do
296 pkgfile=`get_package_filename $pkg`
297 echo `basename $pkgfile` >> ${BUILDHISTORY_DIR_IMAGE}/installed-packages.txt
298 if [ -f $pkgfile ] ; then 309 if [ -f $pkgfile ] ; then
299 pkgsize=`du -k $pkgfile | head -n1 | awk '{ print $1 }'` 310 pkgsize=`du -k $pkgfile | head -n1 | awk '{ print $1 }'`
300 echo $pkgsize $pkg >> ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp 311 echo $pkgsize $pkg >> ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp
301 fi 312 fi
302 313 done
303 deps=`list_package_depends $pkg`
304 for dep in $deps ; do
305 echo "$pkg OPP $dep;" | sed -e 's:-:_:g' -e 's:\.:_:g' -e 's:+::g' | sed 's:OPP:->:g'
306 done
307
308 recs=`list_package_recommends $pkg`
309 for rec in $recs ; do
310 echo "$pkg OPP $rec [style=dotted];" | sed -e 's:-:_:g' -e 's:\.:_:g' -e 's:+::g' | sed 's:OPP:->:g'
311 done
312 done | sort | uniq >> ${BUILDHISTORY_DIR_IMAGE}/depends.dot
313 echo "}" >> ${BUILDHISTORY_DIR_IMAGE}/depends.dot
314
315 cat ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp | sort -n -r | awk '{print $1 "\tKiB " $2}' > ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.txt 314 cat ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp | sort -n -r | awk '{print $1 "\tKiB " $2}' > ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.txt
316 rm ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp 315 rm ${BUILDHISTORY_DIR_IMAGE}/installed-package-sizes.tmp
317 316
317 # We're now done with the cache, delete it
318 rm $pkgcache
319
318 # Produce some cut-down graphs (for readability) 320 # Produce some cut-down graphs (for readability)
319 grep -v kernel_image ${BUILDHISTORY_DIR_IMAGE}/depends.dot | grep -v kernel_2 | grep -v kernel_3 > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel.dot 321 grep -v kernel_image ${BUILDHISTORY_DIR_IMAGE}/depends.dot | grep -v kernel_2 | grep -v kernel_3 > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel.dot
320 grep -v libc6 ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel.dot | grep -v libgcc > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc.dot 322 grep -v libc6 ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel.dot | grep -v libgcc > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc.dot
321 grep -v update_ ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc.dot > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate.dot 323 grep -v update_ ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc.dot > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate.dot
322 grep -v kernel_module ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate.dot > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate-nomodules.dot 324 grep -v kernel_module ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate.dot > ${BUILDHISTORY_DIR_IMAGE}/depends-nokernel-nolibc-noupdate-nomodules.dot
323
324 # Workaround for broken shell function dependencies
325 if false ; then
326 get_package_filename
327 list_package_depends
328 list_package_recommends
329 fi
330} 325}
331 326
332buildhistory_get_imageinfo() { 327buildhistory_get_imageinfo() {
diff --git a/meta/classes/rootfs_deb.bbclass b/meta/classes/rootfs_deb.bbclass
index a002b1ec02..750a8ca082 100644
--- a/meta/classes/rootfs_deb.bbclass
+++ b/meta/classes/rootfs_deb.bbclass
@@ -96,26 +96,24 @@ list_installed_packages() {
96 if [ "$1" = "arch" ] ; then 96 if [ "$1" = "arch" ] ; then
97 # Here we want the PACKAGE_ARCH not the deb architecture 97 # Here we want the PACKAGE_ARCH not the deb architecture
98 ${DPKG_QUERY_COMMAND} -W -f='${Package} ${PackageArch}\n' 98 ${DPKG_QUERY_COMMAND} -W -f='${Package} ${PackageArch}\n'
99 elif [ "$1" = "file" ] ; then
100 ${DPKG_QUERY_COMMAND} -W -f='${Package} ${Package}_${Version}_${Architecture}.deb\n' | while read pkg pkgfile
101 do
102 fullpath=`find ${DEPLOY_DIR_DEB} -name "$pkgfile" || true`
103 if [ "$fullpath" = "" ] ; then
104 echo "$pkg $pkgfile"
105 else
106 echo "$pkg $fullpath"
107 fi
108 done
99 else 109 else
100 ${DPKG_QUERY_COMMAND} -W -f='${Package}\n' 110 ${DPKG_QUERY_COMMAND} -W -f='${Package}\n'
101 fi 111 fi
102} 112}
103 113
104get_package_filename() { 114rootfs_list_installed_depends() {
105 fullname=`find ${DEPLOY_DIR_DEB} -name "$1_*.deb" || true` 115 # Cheat here a little bit by using the opkg query helper util
106 if [ "$fullname" = "" ] ; then 116 ${DPKG_QUERY_COMMAND} -W -f='Package: ${Package}\nDepends: ${Depends}\nRecommends: ${Recommends}\n\n' | opkg-query-helper.py
107 echo $name
108 else
109 echo $fullname
110 fi
111}
112
113list_package_depends() {
114 ${DPKG_QUERY_COMMAND} -s $1 | grep ^Depends | sed -e 's/^Depends: //' -e 's/,//g' -e 's:([=<>]* [^ )]*)::g'
115}
116
117list_package_recommends() {
118 ${DPKG_QUERY_COMMAND} -s $1 | grep ^Recommends | sed -e 's/^Recommends: //' -e 's/,//g' -e 's:([=<>]* [^ )]*)::g'
119} 117}
120 118
121rootfs_install_packages() { 119rootfs_install_packages() {
diff --git a/meta/classes/rootfs_ipk.bbclass b/meta/classes/rootfs_ipk.bbclass
index 7df97a014b..6cdd8f6062 100644
--- a/meta/classes/rootfs_ipk.bbclass
+++ b/meta/classes/rootfs_ipk.bbclass
@@ -131,33 +131,23 @@ remove_packaging_data_files() {
131list_installed_packages() { 131list_installed_packages() {
132 if [ "$1" = "arch" ] ; then 132 if [ "$1" = "arch" ] ; then
133 opkg-cl ${IPKG_ARGS_POST} status | opkg-query-helper.py -a 133 opkg-cl ${IPKG_ARGS_POST} status | opkg-query-helper.py -a
134 elif [ "$1" = "file" ] ; then
135 opkg-cl ${IPKG_ARGS_POST} status | opkg-query-helper.py -f | while read pkg pkgfile
136 do
137 fullpath=`find ${DEPLOY_DIR_IPK} -name "$pkgfile" || true`
138 if [ "$fullpath" = "" ] ; then
139 echo "$pkg $pkgfile"
140 else
141 echo "$pkg $fullpath"
142 fi
143 done
134 else 144 else
135 opkg-cl ${IPKG_ARGS_POST} list_installed | awk '{ print $1 }' 145 opkg-cl ${IPKG_ARGS_POST} list_installed | awk '{ print $1 }'
136 fi 146 fi
137} 147}
138 148
139get_package_filename() { 149rootfs_list_installed_depends() {
140 set +x 150 opkg-cl ${IPKG_ARGS_POST} status | opkg-query-helper.py
141 info=`opkg-cl ${IPKG_ARGS_POST} info $1 | grep -B 7 -A 7 "^Status.* \(\(installed\)\|\(unpacked\)\)" || true`
142 name=`echo "${info}" | awk '/^Package/ {printf $2"_"}'`
143 name=$name`echo "${info}" | awk -F: '/^Version/ {printf $NF"_"}' | sed 's/^\s*//g'`
144 name=$name`echo "${info}" | awk '/^Archi/ {print $2".ipk"}'`
145 set -x
146
147 fullname=`find ${DEPLOY_DIR_IPK} -name "$name" || true`
148 if [ "$fullname" = "" ] ; then
149 echo $name
150 else
151 echo $fullname
152 fi
153}
154
155list_package_depends() {
156 opkg-cl ${IPKG_ARGS_POST} info $1 | grep ^Depends | sed -e 's/^Depends: //' -e 's/,//g' -e 's:([=<>]* [^ )]*)::g'
157}
158
159list_package_recommends() {
160 opkg-cl ${IPKG_ARGS_POST} info $1 | grep ^Recommends | sed -e 's/^Recommends: //' -e 's/,//g' -e 's:([=<>]* [^ )]*)::g'
161} 151}
162 152
163rootfs_install_packages() { 153rootfs_install_packages() {
diff --git a/meta/classes/rootfs_rpm.bbclass b/meta/classes/rootfs_rpm.bbclass
index 1cc4a84495..c9258dfe39 100644
--- a/meta/classes/rootfs_rpm.bbclass
+++ b/meta/classes/rootfs_rpm.bbclass
@@ -143,40 +143,15 @@ RPM_QUERY_CMD = '${RPM} --root $INSTALL_ROOTFS_RPM -D "_dbpath ${rpmlibdir}" \
143list_installed_packages() { 143list_installed_packages() {
144 if [ "$1" = "arch" ] ; then 144 if [ "$1" = "arch" ] ; then
145 ${RPM_QUERY_CMD} -qa --qf "[%{NAME} %{ARCH}\n]" 145 ${RPM_QUERY_CMD} -qa --qf "[%{NAME} %{ARCH}\n]"
146 elif [ "$1" = "file" ] ; then
147 ${RPM_QUERY_CMD} -qa --qf "[%{NAME} %{PACKAGEORIGIN}\n]"
146 else 148 else
147 ${RPM_QUERY_CMD} -qa --qf "[%{NAME}\n]" 149 ${RPM_QUERY_CMD} -qa --qf "[%{NAME}\n]"
148 fi 150 fi
149} 151}
150 152
151get_package_filename() { 153rootfs_list_installed_depends() {
152 resolve_package_rpm ${RPMCONF_TARGET_BASE}-base_archs.conf $1 154 rpmresolve -d $INSTALL_ROOTFS_RPM/${rpmlibdir}
153}
154
155list_package_depends() {
156 pkglist=`list_installed_packages`
157
158 # REQUIRE* lists "soft" requirements (which we know as recommends and RPM refers to
159 # as "suggests") so filter these out with the help of awk
160 for req in `${RPM_QUERY_CMD} -q --qf "[%{REQUIRENAME} %{REQUIREFLAGS}\n]" $1 | awk '{ if( and($2, 0x80000) == 0) print $1 }'`; do
161 if echo "$req" | grep -q "^rpmlib" ; then continue ; fi
162
163 realpkg=""
164 for dep in $pkglist; do
165 if [ "$dep" = "$req" ] ; then
166 realpkg="1"
167 echo $req
168 break
169 fi
170 done
171
172 if [ "$realdep" = "" ] ; then
173 ${RPM_QUERY_CMD} -q --whatprovides $req --qf "%{NAME}\n"
174 fi
175 done
176}
177
178list_package_recommends() {
179 ${RPM_QUERY_CMD} -q --suggests $1
180} 155}
181 156
182rootfs_install_packages() { 157rootfs_install_packages() {
diff --git a/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c b/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
index 9f6cdf28b8..2d9ed141f4 100644
--- a/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
+++ b/meta/recipes-devtools/rpm/rpmresolve/rpmresolve.c
@@ -204,10 +204,104 @@ int processPackages(rpmts *ts, int tscount, const char *packagelistfn, int ignor
204 return rc; 204 return rc;
205} 205}
206 206
207int lookupProvider(rpmts ts, const char *req, char **provider)
208{
209 int rc = 0;
210 rpmmi provmi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, req, 0);
211 if(provmi) {
212 Header h;
213 if ((h = rpmmiNext(provmi)) != NULL) {
214 HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
215 he->tag = RPMTAG_NAME;
216 rc = (headerGet(h, he, 0) != 1);
217 if(rc==0)
218 *provider = strdup((char *)he->p.ptr);
219 }
220 (void)rpmmiFree(provmi);
221 }
222 else {
223 rc = -1;
224 }
225 return rc;
226}
227
228int printDepList(rpmts *ts, int tscount)
229{
230 int rc = 0;
231
232 if( tscount > 1 )
233 printf(">1 database specified with dependency list, using first only\n");
234
235 /* Get list of names */
236 rpmdb db = rpmtsGetRdb(ts[0]);
237 ARGV_t names = NULL;
238 rc = rpmdbMireApply(db, RPMTAG_NAME,
239 RPMMIRE_STRCMP, NULL, &names);
240 int nnames = argvCount(names);
241
242 /* Get list of NVRAs */
243 ARGV_t keys = NULL;
244 rc = rpmdbMireApply(db, RPMTAG_NVRA,
245 RPMMIRE_STRCMP, NULL, &keys);
246 if (keys) {
247 int i, j;
248 HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
249 int nkeys = argvCount(keys);
250 for(i=0; i<nkeys; i++) {
251 rpmmi mi = rpmtsInitIterator(ts[0], RPMTAG_NVRA, keys[i], 0);
252 Header h;
253 if ((h = rpmmiNext(mi)) != NULL) {
254 /* Get name of package */
255 he->tag = RPMTAG_NAME;
256 rc = (headerGet(h, he, 0) != 1);
257 char *name = strdup((char *)he->p.ptr);
258 /* Get its requires */
259 he->tag = RPMTAG_REQUIRENAME;
260 rc = (headerGet(h, he, 0) != 1);
261 ARGV_t reqs = (ARGV_t)he->p.ptr;
262 /* Get its requireflags */
263 he->tag = RPMTAG_REQUIREFLAGS;
264 rc = (headerGet(h, he, 0) != 1);
265 rpmuint32_t *reqflags = (rpmuint32_t *)he->p.ui32p;
266 for(j=0; j<he->c; j++) {
267 int k;
268 char *prov = NULL;
269 for(k=0; k<nnames; k++) {
270 if(strcmp(names[k], reqs[j]) == 0) {
271 prov = names[k];
272 break;
273 }
274 }
275 if(prov) {
276 if((int)reqflags[j] & 0x80000)
277 printf("%s|%s [REC]\n", name, prov);
278 else
279 printf("%s|%s\n", name, prov);
280 }
281 else {
282 rc = lookupProvider(ts[0], reqs[j], &prov);
283 if(rc==0 && prov) {
284 if((int)reqflags[j] & 0x80000)
285 printf("%s|%s [REC]\n", name, prov);
286 else
287 printf("%s|%s\n", name, prov);
288 free(prov);
289 }
290 }
291 }
292 free(name);
293 }
294 (void)rpmmiFree(mi);
295 }
296 }
297
298 return rc;
299}
300
207void usage() 301void usage()
208{ 302{
209 fprintf(stderr, "OpenEmbedded rpm resolver utility\n"); 303 fprintf(stderr, "OpenEmbedded rpm resolver utility\n");
210 fprintf(stderr, "syntax: rpmresolve [-i] <dblistfile> <packagelistfile>\n"); 304 fprintf(stderr, "syntax: rpmresolve [-i] [-d] <dblistfile> <packagelistfile>\n");
211} 305}
212 306
213int main(int argc, char **argv) 307int main(int argc, char **argv)
@@ -218,13 +312,17 @@ int main(int argc, char **argv)
218 int i; 312 int i;
219 int c; 313 int c;
220 int ignoremissing = 0; 314 int ignoremissing = 0;
315 int deplistmode = 0;
221 316
222 opterr = 0; 317 opterr = 0;
223 while ((c = getopt (argc, argv, "i")) != -1) { 318 while ((c = getopt (argc, argv, "id")) != -1) {
224 switch (c) { 319 switch (c) {
225 case 'i': 320 case 'i':
226 ignoremissing = 1; 321 ignoremissing = 1;
227 break; 322 break;
323 case 'd':
324 deplistmode = 1;
325 break;
228 case '?': 326 case '?':
229 if(isprint(optopt)) 327 if(isprint(optopt))
230 fprintf(stderr, "Unknown option `-%c'.\n", optopt); 328 fprintf(stderr, "Unknown option `-%c'.\n", optopt);
@@ -258,12 +356,17 @@ int main(int argc, char **argv)
258 return 1; 356 return 1;
259 } 357 }
260 358
261 if( argc - optind < 2 ) { 359 if(deplistmode) {
262 fprintf(stderr, "Please specify package list file\n"); 360 rc = printDepList(ts, tscount);
263 return 1; 361 }
362 else {
363 if( argc - optind < 2 ) {
364 fprintf(stderr, "Please specify package list file\n");
365 return 1;
366 }
367 const char *pkglistfn = argv[optind+1];
368 rc = processPackages(ts, tscount, pkglistfn, ignoremissing);
264 } 369 }
265 const char *pkglistfn = argv[optind+1];
266 rc = processPackages(ts, tscount, pkglistfn, ignoremissing);
267 370
268 for(i=0; i<tscount; i++) 371 for(i=0; i<tscount; i++)
269 (void) rpmtsCloseDB(ts[i]); 372 (void) rpmtsCloseDB(ts[i]);