123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583 |
- #!/bin/bash
- ############################################################################
- #
- # MODULE: dep_tree2sql.sh
- # AUTHOR(S): Glynn Clements
- # PURPOSE: run "nm" on every object file, library and executable to
- # find dependencies, stored in PostgreSQL database
- # COPYRIGHT: (C) 2006 by the GRASS Development Team
- #
- # This program is free software under the GNU General Public
- # License (>=v2). Read the file COPYING that comes with GRASS
- # for details.
- #
- #############################################################################
- #
- # From: Glynn Clements <glynn at gclements.plus.com>
- # Date: Mon, 12 Jun 2006 13:00:25 +0100
- #
- # Usage: after having compiled GRASS, run "tools/dep_tree2sql.sh `pwd`" from the
- # top of the GRASS source tree.
- #
- # Essentially, the script runs "nm" on every object file, library and
- # executable it finds (and "ldd" on all of the executables), processes
- # the output with egrep/sed/awk, then imports the results into a
- # PostgreSQL database.
- #
- # "nm" lists the symbol table of an object file, library, or executable,
- # indicating whether each symbol is imported into, defined in and/or
- # exported from the file.
- #
- # Most of the database tables record which symbols are imported into or
- # exported from which object files, libraries or executables. E.g. the
- # "obj_imp" table lists which symbols are imported into which object
- # files.
- #
- # You can then use simple queries such as:
- #
- # grass=> SELECT object FROM obj_imp WHERE symbol = 'I_get_target' ;
- # object
- # --------------------------------------------------------------------
- # imagery/i.ortho.photo/photo.2image/OBJ.i686-pc-linux-gnu/target.o
- # imagery/i.ortho.photo/photo.2target/OBJ.i686-pc-linux-gnu/target.o
- # imagery/i.ortho.photo/photo.elev/OBJ.i686-pc-linux-gnu/main.o
- # imagery/i.ortho.photo/photo.rectify/OBJ.i686-pc-linux-gnu/target.o
- # imagery/i.ortho.photo/photo.target/OBJ.i686-pc-linux-gnu/main.o
- # imagery/i.rectify/OBJ.i686-pc-linux-gnu/target.o
- #
- # to discover which files import a given symbol, or more complex queries
- # such as:
- #
- # grass=> SELECT DISTINCT b.object FROM lib_exp a, obj_imp b
- # grass-> WHERE a.library = 'libgrass_form.6.1.cvs.so' AND a.symbol = b.symbol ;
- # object
- # -----------------------------------------------------------
- # vector/v.digit/OBJ.i686-pc-linux-gnu/attr.o
- # vector/v.digit/OBJ.i686-pc-linux-gnu/line.o
- # vector/v.what/OBJ.i686-pc-linux-gnu/what.o
- # visualization/nviz/src/OBJ.i686-pc-linux-gnu/query_vect.o
- # (5 rows)
- #
- # to discover which files import any symbol defined in a specific
- # library. And so on.
- #
- # For simple "which files use this function" queries, a database lookup
- # is quicker and more reliable than grep-ing the source tree.
- #
- # Assuming that the dep_tree2sql.sh script runs successfully (some of it is
- # Linux-specific, other bits are PostgreSQL-specific, but the changes
- # required for a different OS or RDBMS should be quite minor), the
- # easiest way to figure out what is in a given table (apart from looking
- # at the name) is to just sample it, e.g.:
- #
- # grass=> SELECT * FROM stlib_exp LIMIT 5 ;
- # library | object | symbol
- # -------------------+------------+---------------
- # libgrass_manage.a | add_elem.o | add_element
- # libgrass_manage.a | ask.o | ask_in_mapset
- # libgrass_manage.a | ask.o | ask_new
- # libgrass_manage.a | ask.o | ask_old
- # libgrass_manage.a | copyfile.o | copyfile
- # (5 rows)
- #
- tmpdir=/tmp/sql-grass
- dbname=grass
- if [ -n "$1" ] ; then
- builddir="$1"
- else
- echo "Usage: del_tree2sql.sh <source directory>" >&2
- exit 1
- fi
- rm -rf "$tmpdir"
- mkdir -m 711 "$tmpdir" || exit 1
- cd $builddir
- ( cd dist.*
- #LD_LIBRARY_PATH=`pwd`/lib
- #export LD_LIBRARY_PATH
- find . -type f -perm +111 \! -name '*.so.*' \
- | while read file ; do ldd $file | sed 's!^!'$file'!' ; done 2>/dev/null \
- | sed -e 's/^\.\///' -e 's/ (0x.*)$//' -e 's/ => \(.*\)$/ \1/' -e 's/ => .*$//' \
- | fgrep -v 'not a dynamic executable' \
- | awk -vOFS='\t' '{print $1,$2,$3 ? $3 : $2}' \
- > "$tmpdir/ldd.lst"
- find . -type f -perm +111 \! -name '*.so' \
- | xargs nm -AD 2>/dev/null \
- | egrep ': {8}{1,2} U ' \
- | sed -e 's/:/ /g' -e 's/\.\///' \
- | awk -vOFS='\t' '{print $1,$3}' \
- > "$tmpdir/prog_imp.lst"
- find . -type f -perm +111 \! -name '*.so' \
- | xargs nm -AD 2>/dev/null \
- | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
- | sed -e 's/:/ /g' -e 's/\.\///' \
- | awk -vOFS='\t' '{print $1,$4}' \
- > "$tmpdir/prog_exp.lst"
- )
- find * -type f -name 'lib?*.a' \
- | xargs nm -A \
- | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$2,$5}' \
- > "$tmpdir/stlib_exp.lst"
- find * -type f -name 'lib?*.so' \
- | xargs nm -AD \
- | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$4}' \
- > "$tmpdir/shlib_exp.lst"
- find * -type f -name '*.o' \
- | xargs nm -A \
- | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print $1,$4}' \
- > "$tmpdir/obj_exp.lst"
- find * -type f -name 'lib?*.a' \
- | xargs nm -A \
- | egrep ': {8}{1,2} U ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$2,$4}' \
- > "$tmpdir/stlib_imp.lst"
- find * -type f -name 'lib?*.so' \
- | xargs nm -AD \
- | egrep ': {8}{1,2} U ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$3}' \
- > "$tmpdir/shlib_imp.lst"
- find * -type f -name '*.o' \
- | xargs nm -A \
- | egrep ': {8}{1,2} U ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print $1,$3}' \
- > "$tmpdir/obj_imp.lst"
- libs=`awk '{print $3}' "$tmpdir/ldd.lst" | uniq | sort | uniq`
- nm -AD $libs \
- | egrep ':[0-9a-f]{8}{1,2} [TWDRC] ' \
- | sed 's/:/ /g' \
- | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$4}' \
- > "$tmpdir/libs.lst"
- cat > "$tmpdir/ansi.lst" <<EOF
- abort
- asctime
- atexit
- atof
- atoi
- atol
- bsearch
- calloc
- clearerr
- ctime
- exit
- fclose
- feof
- ferror
- fflush
- fgetc
- fgetpos
- fgets
- fopen
- fprintf
- fputc
- fputs
- fread
- free
- freopen
- fscanf
- fseek
- fsetpos
- ftell
- fwrite
- getc
- getchar
- getenv
- gets
- isalnum
- isalpha
- isdigit
- islower
- isspace
- ldiv
- localtime
- longjmp
- malloc
- memcmp
- memcpy
- memmove
- memset
- perror
- printf
- putc
- putchar
- puts
- qsort
- rand
- realloc
- remove
- rename
- rewind
- scanf
- setbuf
- setjmp
- setvbuf
- signal
- sprintf
- srand
- sscanf
- stderr
- stdin
- stdout
- strcat
- strchr
- strcmp
- strcpy
- strcspn
- strerror
- strftime
- strlen
- strncat
- strncmp
- strncpy
- strpbrk
- strrchr
- strspn
- strstr
- strtod
- strtok
- strtol
- time
- tmpfile
- tmpnam
- tolower
- toupper
- ungetc
- vfprintf
- vsprintf
- fgetpos64
- fopen64
- freopen64
- fsetpos64
- tmpfile64
- EOF
- dropdb "$dbname"
- createdb "$dbname"
- psql -n -q -d "$dbname" << EOF
- -- ----------------------------------------------------------------------
- CREATE TABLE stlib_exp (
- library VARCHAR(80) NOT NULL,
- object VARCHAR(40) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy stlib_exp FROM '$tmpdir/stlib_exp.lst'
- CREATE TABLE shlib_exp (
- library VARCHAR(80) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy shlib_exp FROM '$tmpdir/shlib_exp.lst'
- CREATE TABLE obj_exp (
- object VARCHAR(100) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy obj_exp FROM '$tmpdir/obj_exp.lst'
- CREATE TABLE stlib_imp (
- library VARCHAR(80) NOT NULL,
- object VARCHAR(40) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy stlib_imp FROM '$tmpdir/stlib_imp.lst'
- CREATE TABLE shlib_imp (
- library VARCHAR(80) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy shlib_imp FROM '$tmpdir/shlib_imp.lst'
- CREATE TABLE obj_imp (
- object VARCHAR(100) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy obj_imp FROM '$tmpdir/obj_imp.lst'
- CREATE TABLE prog_imp (
- program VARCHAR(80) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy prog_imp FROM '$tmpdir/prog_imp.lst'
- CREATE TABLE prog_exp (
- program VARCHAR(80) NOT NULL,
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy prog_exp FROM '$tmpdir/prog_exp.lst'
- CREATE TABLE libs (
- library VARCHAR(80) NOT NULL,
- symbol VARCHAR(1000) NOT NULL
- ) ;
- \copy libs FROM '$tmpdir/libs.lst'
- CREATE TABLE ldd (
- program VARCHAR(80) NOT NULL,
- library VARCHAR(256) NOT NULL,
- path VARCHAR(256)
- ) ;
- \copy ldd FROM '$tmpdir/ldd.lst'
- CREATE TABLE ansi (
- symbol VARCHAR(256) NOT NULL
- ) ;
- \copy ansi FROM '$tmpdir/ansi.lst'
- -- ----------------------------------------------------------------------
- SELECT DISTINCT library, symbol
- INTO TABLE lib_exp
- FROM stlib_exp
- UNION
- SELECT DISTINCT library, symbol
- FROM shlib_exp ;
- CREATE TABLE duplicates AS
- SELECT DISTINCT symbol
- FROM lib_exp
- GROUP BY symbol
- HAVING COUNT(*) > 1 ;
- CREATE TABLE duplicates2 AS
- SELECT *
- FROM lib_exp
- WHERE symbol IN (
- SELECT symbol
- FROM duplicates
- ) ;
- SELECT DISTINCT library, symbol
- INTO TABLE lib_imp
- FROM stlib_imp
- UNION
- SELECT DISTINCT library, symbol
- FROM shlib_imp ;
- CREATE TABLE imports AS
- SELECT a.library, a.symbol
- FROM lib_imp a
- WHERE NOT EXISTS (
- SELECT b.library, b.symbol
- FROM lib_exp b
- WHERE b.symbol = a.symbol
- AND b.library = a.library
- ) ;
- CREATE TABLE defined AS
- SELECT DISTINCT symbol
- FROM lib_exp ;
- CREATE TABLE used AS
- SELECT DISTINCT symbol
- FROM imports ;
- CREATE TABLE undefined AS
- SELECT symbol
- FROM used u
- WHERE NOT EXISTS (
- SELECT *
- FROM defined d
- WHERE d.symbol = u.symbol
- ) ;
- SELECT symbol
- INTO TABLE undefined_1
- FROM undefined
- EXCEPT
- SELECT b.symbol
- FROM undefined a, libs b
- WHERE a.symbol = b.symbol ;
- CREATE TABLE undefined_2 AS
- SELECT i.symbol, i.object, i.library
- FROM stlib_imp i, undefined_1 u
- WHERE i.symbol = u.symbol ;
- CREATE TABLE depends AS
- SELECT i.library AS im_lib,
- i.symbol AS symbol,
- e.library AS ex_lib
- FROM imports i, lib_exp e
- WHERE i.symbol = e.symbol ;
- CREATE TABLE lib_deps AS
- SELECT DISTINCT im_lib, ex_lib
- FROM depends
- WHERE im_lib <> ex_lib ;
- CREATE TABLE lib_deps_1 AS
- SELECT a.im_lib,
- a.ex_lib AS in_lib,
- b.ex_lib
- FROM lib_deps a, lib_deps b
- WHERE a.ex_lib = b.im_lib ;
- CREATE TABLE lib_deps_2 AS
- SELECT a.im_lib,
- a.in_lib AS in1_lib,
- a.ex_lib AS in2_lib,
- b.ex_lib
- FROM lib_deps_1 a, lib_deps b
- WHERE a.ex_lib = b.im_lib
- AND a.im_lib <> a.ex_lib ;
- SELECT im_lib, ex_lib
- INTO TABLE lib_deps_trans
- FROM lib_deps
- UNION
- SELECT im_lib, ex_lib
- FROM lib_deps_1
- UNION
- SELECT im_lib, ex_lib
- FROM lib_deps_2 ;
- CREATE TABLE prog_libs AS
- SELECT DISTINCT a.program, b.library
- FROM prog_imp a, lib_exp b
- WHERE a.symbol = b.symbol ;
- SELECT DISTINCT a.symbol
- INTO TABLE libc
- FROM prog_imp a, libs b
- WHERE a.symbol = b.symbol
- AND b.library = 'libc.so.6'
- UNION
- SELECT DISTINCT a.symbol
- FROM imports a, libs b
- WHERE a.symbol = b.symbol
- AND b.library = 'libc.so.6' ;
- SELECT symbol
- INTO nonansi
- FROM libc
- WHERE symbol !~ '_.*'
- EXCEPT
- SELECT symbol
- FROM ansi ;
- CREATE TABLE nonansi_progs AS
- SELECT a.program, a.symbol
- FROM prog_imp a, nonansi b
- WHERE a.symbol = b.symbol ;
- CREATE TABLE nonansi_libs AS
- SELECT a.library, a.symbol
- FROM imports a, nonansi b
- WHERE a.symbol = b.symbol ;
- CREATE TABLE nonansi_prog_counts AS
- SELECT symbol, COUNT(*)
- FROM nonansi_progs
- GROUP BY symbol ;
- CREATE TABLE nonansi_lib_counts AS
- SELECT symbol, COUNT(*)
- FROM nonansi_libs
- GROUP BY symbol ;
- SELECT symbol
- INTO TABLE nonansi_counts
- FROM nonansi_prog_counts
- UNION
- SELECT symbol
- FROM nonansi_lib_counts ;
- ALTER TABLE nonansi_counts
- ADD COLUMN progs INTEGER ;
- ALTER TABLE nonansi_counts
- ADD COLUMN libs INTEGER ;
- UPDATE nonansi_counts
- SET progs = 0, libs = 0 ;
- UPDATE nonansi_counts
- SET progs = b.count
- FROM nonansi_prog_counts b
- WHERE nonansi_counts.symbol = b.symbol ;
- UPDATE nonansi_counts
- SET libs = c.count
- FROM nonansi_lib_counts c
- WHERE nonansi_counts.symbol = c.symbol;
- -- SELECT a.symbol, a.program
- -- FROM prog_imp a, nonansi_prog_counts b
- -- WHERE a.symbol = b.symbol
- -- AND a.program NOT LIKE 'bin/%'
- -- ORDER BY b.count DESC, b.symbol ;
- -- SELECT symbol, library
- -- FROM duplicates2
- -- ORDER BY symbol ;
- -- SELECT a.im_lib, a.ex_lib
- -- FROM lib_deps a, lib_deps b
- -- WHERE a.ex_lib = b.im_lib
- -- AND b.ex_lib = a.im_lib ;
- -- SELECT * FROM lib_deps_2
- -- WHERE im_lib = ex_lib ;
- -- SELECT * FROM lib_deps_1
- -- WHERE im_lib = ex_lib ;
- -- SELECT im_lib FROM lib_deps_trans
- -- WHERE im_lib = ex_lib ;
- -- SELECT a.program, a.library
- -- FROM ldd a
- -- WHERE a.library LIKE 'libgrass_%.so'
- -- AND a.library NOT IN (
- -- SELECT b.library
- -- FROM prog_libs b
- -- WHERE b.program = a.program
- -- ) ;
- -- ----------------------------------------------------------------------
- EOF
|