kornelix |
10-14-2011 07:19 AM |
I think I likely reinvented the wheel, but I now have a solution.
I wrote a c program that generates the "Depends" text directly.
I put it here in case someone else needs it.
Here is a sample output:
Code:
$: getdeps /usr/bin/mashup
LIBRARY PACKAGE VERSION
libgtk-x11-2.0.so.0 libgtk2.0-0 2.24.6-0ubuntu5
libgdk-x11-2.0.so.0 libgtk2.0-0 2.24.6-0ubuntu5
libgdk_pixbuf-2.0.so.0 libgdk-pixbuf2.0-0 2.24.0-1ubuntu1
libcairo.so.2 libcairo2 1.10.2-6ubuntu3
libpango-1.0.so.0 libpango1.0-0 1.29.3+git20110916-0ubuntu1
libgobject-2.0.so.0 libglib2.0-dev 2.30.0-0ubuntu4
libglib-2.0.so.0 libglib2.0-0 2.30.0-0ubuntu4
libstdc++.so.6 libstdc++6 4.6.1-9ubuntu3
libm.so.6 libc6 2.13-20ubuntu5
libgcc_s.so.1 libgcc1 1:4.6.1-9ubuntu3
libpthread.so.0 libc6 2.13-20ubuntu5
libc.so.6 libc6 2.13-20ubuntu5
PACKAGE VERSION
libgtk2.0-0 2.24.6
libgdk-pixbuf2.0-0 2.24.0
libcairo2 1.10.2
libpango1.0-0 1.29.3+git20110916
libglib2.0-dev 2.30.0
libglib2.0-0 2.30.0
libstdc++6 4.6.1
libc6 2.13
libgcc1 1:4.6.1
Depends: libgtk2.0-0 (>= 2.24.6), libgdk-pixbuf2.0-0 (>= 2.24.0),
libcairo2 (>= 1.10.2), libpango1.0-0 (>= 1.29.3+git20110916),
libglib2.0-dev (>= 2.30.0), libglib2.0-0 (>= 2.30.0),
libstdc++6 (>= 4.6.1), libc6 (>= 2.13), libgcc1 (>= 1:4.6.1),
And here is the source code:
Code:
/**************************************************************************
getdeps.cc v.01
find all package dependencies of a binary executable program
usage: $ getdeps program
STDOUT: "Depends packname1 (>= N.N), packname2 ... "
Copyright 2011 Michael Cornelison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
***************************************************************************/
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int cc, ii, jj, Npkg = 0;
char *program, *pp1, *pp2;
char command[100], buff[200];
char libname[100][100], package[100][100], version[100][100];
FILE *fid;
if (argc < 2) {
printf("usage: $ getdeps program \n");
return 1;
}
program = argv[1];
snprintf(command,100,"readelf -d %s", program); // get linked dynamic libraries
fid = popen(command,"r");
if (! fid) {
printf("getdeps, %s not found \n",program);
return 1;
}
while ((fgets(buff,200,fid))) // process readelf outputs, formatted
{ // ... Shared library: [filename]
pp1 = strstr(buff,"Shared library:");
if (! pp1) continue;
pp1 = strstr(pp1,"[");
if (! pp1) continue;
pp2 = strstr(pp1,"]");
if (! pp2) continue;
cc = pp2 - pp1 - 1;
if (cc > 99) continue;
strncpy(libname[Npkg],pp1+1,cc); // isolate filename
libname[Npkg][cc] = 0;
Npkg++;
if (Npkg > 99) {
printf("over 100 libraries, stop here \n");
break;
}
}
pclose(fid);
for (ii = 0; ii < Npkg; ii++) // find packages containing lib files
{
snprintf(command,100,"dpkg-query -S %s",libname[ii]);
fid = popen(command,"r");
fgets(buff,200,fid);
pclose(fid);
pp1 = strstr(buff,":"); // format is packagename: ...
if (pp1) {
*pp1 = 0;
strncpy(package[ii],buff,100); // isolate packagename
buff[99] = 0;
}
else strcpy(package[ii],"??");
}
for (ii = 0; ii < Npkg; ii++) // get package versions
{
snprintf(command,100,"dpkg-query -W %s",package[ii]);
fid = popen(command,"r");
fgets(buff,200,fid);
pclose(fid);
pp1 = strstr(buff,"\t"); // format is packagename <tab> version
if (pp1) {
strncpy(version[ii],pp1+1,100); // isolate version
version[ii][99] = 0;
cc = strlen(version[ii]);
version[ii][cc-1] = 0; // get rid of trailing \n
}
else strcpy(version[ii],"??");
}
printf("\n %-30s %-30s %-30s \n","LIBRARY","PACKAGE","VERSION"); // print libraries and corresp. packages
for (ii = 0; ii < Npkg; ii++)
printf(" %-30s %-30s %-30s \n",
libname[ii], package[ii], version[ii]);
for (ii = 0; ii < Npkg; ii++) // eliminate duplicates
{
for (jj = ii+1; jj < Npkg; jj++)
{
if (strcmp(package[jj],package[ii]) == 0 &&
strcmp(version[jj],version[ii]) == 0) *package[jj] = 0;
}
}
for (ii = 0; ii < Npkg; ii++) // eliminate distro version appendages
{
pp1 = strrchr(version[ii],'-');
if (pp1) *pp1 = 0;
}
printf("\n\n %-30s %-30s \n","PACKAGE","VERSION"); // print packages and versions
for (ii = 0; ii < Npkg; ii++)
if (*package[ii])
printf(" %-30s %-30s \n",package[ii], version[ii]);
printf("\n\nDepends: "); // print Depends: package (>= version), ...
for (ii = 0; ii < Npkg; ii++)
if (*package[ii])
printf("%s (>= %s), ",package[ii], version[ii]);
printf("\n\n");
return 0;
}
|