sql.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. #!/bin/bash
  2. ############################################################################
  3. #
  4. # MODULE: sql.sh
  5. # AUTHOR(S): Glynn Clements
  6. # PURPOSE: run "nm" on every object file, library and executable to
  7. # find dependencies, stored in PostgreSQL database
  8. # COPYRIGHT: (C) 2006 by the GRASS Development Team
  9. #
  10. # This program is free software under the GNU General Public
  11. # License (>=v2). Read the file COPYING that comes with GRASS
  12. # for details.
  13. #
  14. #############################################################################
  15. #
  16. # From: Glynn Clements <glynn at gclements.plus.com>
  17. # Date: Mon, 12 Jun 2006 13:00:25 +0100
  18. #
  19. # Usage: after having compiled GRASS, run "tools/sql.sh `pwd`" from the
  20. # top of the GRASS source tree.
  21. #
  22. # Essentially, the script runs "nm" on every object file, library and
  23. # executable it finds (and "ldd" on all of the executables), processes
  24. # the output with egrep/sed/awk, then imports the results into a
  25. # PostgreSQL database.
  26. #
  27. # "nm" lists the symbol table of an object file, library, or executable,
  28. # indicating whether each symbol is imported into, defined in and/or
  29. # exported from the file.
  30. #
  31. # Most of the database tables record which symbols are imported into or
  32. # exported from which object files, libraries or executables. E.g. the
  33. # "obj_imp" table lists which symbols are imported into which object
  34. # files.
  35. #
  36. # You can then use simple queries such as:
  37. #
  38. # grass=> SELECT object FROM obj_imp WHERE symbol = 'I_get_target' ;
  39. # object
  40. # --------------------------------------------------------------------
  41. # imagery/i.ortho.photo/photo.2image/OBJ.i686-pc-linux-gnu/target.o
  42. # imagery/i.ortho.photo/photo.2target/OBJ.i686-pc-linux-gnu/target.o
  43. # imagery/i.ortho.photo/photo.elev/OBJ.i686-pc-linux-gnu/main.o
  44. # imagery/i.ortho.photo/photo.rectify/OBJ.i686-pc-linux-gnu/target.o
  45. # imagery/i.ortho.photo/photo.target/OBJ.i686-pc-linux-gnu/main.o
  46. # imagery/i.points/OBJ.i686-pc-linux-gnu/target.o
  47. # imagery/i.rectify/OBJ.i686-pc-linux-gnu/target.o
  48. # imagery/i.vpoints/OBJ.i686-pc-linux-gnu/target.o
  49. #
  50. # to discover which files import a given symbol, or more complex queries
  51. # such as:
  52. #
  53. # grass=> SELECT DISTINCT b.object FROM lib_exp a, obj_imp b
  54. # grass-> WHERE a.library = 'libgrass_form.6.1.cvs.so' AND a.symbol = b.symbol ;
  55. # object
  56. # -----------------------------------------------------------
  57. # display/d.what.vect/OBJ.i686-pc-linux-gnu/what.o
  58. # vector/v.digit/OBJ.i686-pc-linux-gnu/attr.o
  59. # vector/v.digit/OBJ.i686-pc-linux-gnu/line.o
  60. # vector/v.what/OBJ.i686-pc-linux-gnu/what.o
  61. # visualization/nviz/src/OBJ.i686-pc-linux-gnu/query_vect.o
  62. # (5 rows)
  63. #
  64. # to discover which files import any symbol defined in a specific
  65. # library. And so on.
  66. #
  67. # For simple "which files use this function" queries, a database lookup
  68. # is quicker and more reliable than grep-ing the source tree.
  69. #
  70. # Assuming that the sql.sh script runs successfully (some of it is
  71. # Linux-specific, other bits are PostgreSQL-specific, but the changes
  72. # required for a different OS or RDBMS should be quite minor), the
  73. # easiest way to figure out what is in a given table (apart from looking
  74. # at the name) is to just sample it, e.g.:
  75. #
  76. # grass=> SELECT * FROM stlib_exp LIMIT 5 ;
  77. # library | object | symbol
  78. # -------------------+------------+---------------
  79. # libgrass_manage.a | add_elem.o | add_element
  80. # libgrass_manage.a | ask.o | ask_in_mapset
  81. # libgrass_manage.a | ask.o | ask_new
  82. # libgrass_manage.a | ask.o | ask_old
  83. # libgrass_manage.a | copyfile.o | copyfile
  84. # (5 rows)
  85. #
  86. tmpdir=/tmp/sql-grass
  87. dbname=grass
  88. if [ -n "$1" ] ; then
  89. builddir="$1"
  90. else
  91. echo "Usage: sql.sh <source directory>" >&2
  92. exit 1
  93. fi
  94. rm -rf "$tmpdir"
  95. mkdir -m 711 "$tmpdir" || exit 1
  96. cd $builddir
  97. ( cd dist.*
  98. #LD_LIBRARY_PATH=`pwd`/lib
  99. #export LD_LIBRARY_PATH
  100. find . -type f -perm +111 \! -name '*.so.*' \
  101. | while read file ; do ldd $file | sed 's!^!'$file'!' ; done 2>/dev/null \
  102. | sed -e 's/^\.\///' -e 's/ (0x.*)$//' -e 's/ => \(.*\)$/ \1/' -e 's/ => .*$//' \
  103. | fgrep -v 'not a dynamic executable' \
  104. | awk -vOFS='\t' '{print $1,$2,$3 ? $3 : $2}' \
  105. > "$tmpdir/ldd.lst"
  106. find . -type f -perm +111 \! -name '*.so' \
  107. | xargs nm -AD 2>/dev/null \
  108. | egrep ': {8}{1,2} U ' \
  109. | sed -e 's/:/ /g' -e 's/\.\///' \
  110. | awk -vOFS='\t' '{print $1,$3}' \
  111. > "$tmpdir/prog_imp.lst"
  112. find . -type f -perm +111 \! -name '*.so' \
  113. | xargs nm -AD 2>/dev/null \
  114. | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
  115. | sed -e 's/:/ /g' -e 's/\.\///' \
  116. | awk -vOFS='\t' '{print $1,$4}' \
  117. > "$tmpdir/prog_exp.lst"
  118. )
  119. find * -type f -name 'lib?*.a' \
  120. | xargs nm -A \
  121. | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
  122. | sed 's/:/ /g' \
  123. | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$2,$5}' \
  124. > "$tmpdir/stlib_exp.lst"
  125. find * -type f -name 'lib?*.so' \
  126. | xargs nm -AD \
  127. | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
  128. | sed 's/:/ /g' \
  129. | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$4}' \
  130. > "$tmpdir/shlib_exp.lst"
  131. find * -type f -name '*.o' \
  132. | xargs nm -A \
  133. | egrep ':[0-9a-f]{8}{1,2} [BCDGRSTW] ' \
  134. | sed 's/:/ /g' \
  135. | awk -vOFS='\t' '{print $1,$4}' \
  136. > "$tmpdir/obj_exp.lst"
  137. find * -type f -name 'lib?*.a' \
  138. | xargs nm -A \
  139. | egrep ': {8}{1,2} U ' \
  140. | sed 's/:/ /g' \
  141. | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$2,$4}' \
  142. > "$tmpdir/stlib_imp.lst"
  143. find * -type f -name 'lib?*.so' \
  144. | xargs nm -AD \
  145. | egrep ': {8}{1,2} U ' \
  146. | sed 's/:/ /g' \
  147. | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$3}' \
  148. > "$tmpdir/shlib_imp.lst"
  149. find * -type f -name '*.o' \
  150. | xargs nm -A \
  151. | egrep ': {8}{1,2} U ' \
  152. | sed 's/:/ /g' \
  153. | awk -vOFS='\t' '{print $1,$3}' \
  154. > "$tmpdir/obj_imp.lst"
  155. libs=`awk '{print $3}' "$tmpdir/ldd.lst" | uniq | sort | uniq`
  156. nm -AD $libs \
  157. | egrep ':[0-9a-f]{8}{1,2} [TWDRC] ' \
  158. | sed 's/:/ /g' \
  159. | awk -vOFS='\t' '{print gensub("^[^ ]*/","",1,$1),$4}' \
  160. > "$tmpdir/libs.lst"
  161. cat > "$tmpdir/ansi.lst" <<EOF
  162. abort
  163. asctime
  164. atexit
  165. atof
  166. atoi
  167. atol
  168. bsearch
  169. calloc
  170. clearerr
  171. ctime
  172. exit
  173. fclose
  174. feof
  175. ferror
  176. fflush
  177. fgetc
  178. fgetpos
  179. fgets
  180. fopen
  181. fprintf
  182. fputc
  183. fputs
  184. fread
  185. free
  186. freopen
  187. fscanf
  188. fseek
  189. fsetpos
  190. ftell
  191. fwrite
  192. getc
  193. getchar
  194. getenv
  195. gets
  196. isalnum
  197. isalpha
  198. isdigit
  199. islower
  200. isspace
  201. ldiv
  202. localtime
  203. longjmp
  204. malloc
  205. memcmp
  206. memcpy
  207. memmove
  208. memset
  209. perror
  210. printf
  211. putc
  212. putchar
  213. puts
  214. qsort
  215. rand
  216. realloc
  217. remove
  218. rename
  219. rewind
  220. scanf
  221. setbuf
  222. setjmp
  223. setvbuf
  224. signal
  225. sprintf
  226. srand
  227. sscanf
  228. stderr
  229. stdin
  230. stdout
  231. strcat
  232. strchr
  233. strcmp
  234. strcpy
  235. strcspn
  236. strerror
  237. strftime
  238. strlen
  239. strncat
  240. strncmp
  241. strncpy
  242. strpbrk
  243. strrchr
  244. strspn
  245. strstr
  246. strtod
  247. strtok
  248. strtol
  249. time
  250. tmpfile
  251. tmpnam
  252. tolower
  253. toupper
  254. ungetc
  255. vfprintf
  256. vsprintf
  257. fgetpos64
  258. fopen64
  259. freopen64
  260. fsetpos64
  261. tmpfile64
  262. EOF
  263. dropdb "$dbname"
  264. createdb "$dbname"
  265. psql -n -q -d "$dbname" << EOF
  266. -- ----------------------------------------------------------------------
  267. CREATE TABLE stlib_exp (
  268. library VARCHAR(80) NOT NULL,
  269. object VARCHAR(40) NOT NULL,
  270. symbol VARCHAR(256) NOT NULL
  271. ) ;
  272. \copy stlib_exp FROM '$tmpdir/stlib_exp.lst'
  273. CREATE TABLE shlib_exp (
  274. library VARCHAR(80) NOT NULL,
  275. symbol VARCHAR(256) NOT NULL
  276. ) ;
  277. \copy shlib_exp FROM '$tmpdir/shlib_exp.lst'
  278. CREATE TABLE obj_exp (
  279. object VARCHAR(100) NOT NULL,
  280. symbol VARCHAR(256) NOT NULL
  281. ) ;
  282. \copy obj_exp FROM '$tmpdir/obj_exp.lst'
  283. CREATE TABLE stlib_imp (
  284. library VARCHAR(80) NOT NULL,
  285. object VARCHAR(40) NOT NULL,
  286. symbol VARCHAR(256) NOT NULL
  287. ) ;
  288. \copy stlib_imp FROM '$tmpdir/stlib_imp.lst'
  289. CREATE TABLE shlib_imp (
  290. library VARCHAR(80) NOT NULL,
  291. symbol VARCHAR(256) NOT NULL
  292. ) ;
  293. \copy shlib_imp FROM '$tmpdir/shlib_imp.lst'
  294. CREATE TABLE obj_imp (
  295. object VARCHAR(100) NOT NULL,
  296. symbol VARCHAR(256) NOT NULL
  297. ) ;
  298. \copy obj_imp FROM '$tmpdir/obj_imp.lst'
  299. CREATE TABLE prog_imp (
  300. program VARCHAR(80) NOT NULL,
  301. symbol VARCHAR(256) NOT NULL
  302. ) ;
  303. \copy prog_imp FROM '$tmpdir/prog_imp.lst'
  304. CREATE TABLE prog_exp (
  305. program VARCHAR(80) NOT NULL,
  306. symbol VARCHAR(256) NOT NULL
  307. ) ;
  308. \copy prog_exp FROM '$tmpdir/prog_exp.lst'
  309. CREATE TABLE libs (
  310. library VARCHAR(80) NOT NULL,
  311. symbol VARCHAR(1000) NOT NULL
  312. ) ;
  313. \copy libs FROM '$tmpdir/libs.lst'
  314. CREATE TABLE ldd (
  315. program VARCHAR(80) NOT NULL,
  316. library VARCHAR(256) NOT NULL,
  317. path VARCHAR(256)
  318. ) ;
  319. \copy ldd FROM '$tmpdir/ldd.lst'
  320. CREATE TABLE ansi (
  321. symbol VARCHAR(256) NOT NULL
  322. ) ;
  323. \copy ansi FROM '$tmpdir/ansi.lst'
  324. -- ----------------------------------------------------------------------
  325. SELECT DISTINCT library, symbol
  326. INTO TABLE lib_exp
  327. FROM stlib_exp
  328. UNION
  329. SELECT DISTINCT library, symbol
  330. FROM shlib_exp ;
  331. CREATE TABLE duplicates AS
  332. SELECT DISTINCT symbol
  333. FROM lib_exp
  334. GROUP BY symbol
  335. HAVING COUNT(*) > 1 ;
  336. CREATE TABLE duplicates2 AS
  337. SELECT *
  338. FROM lib_exp
  339. WHERE symbol IN (
  340. SELECT symbol
  341. FROM duplicates
  342. ) ;
  343. SELECT DISTINCT library, symbol
  344. INTO TABLE lib_imp
  345. FROM stlib_imp
  346. UNION
  347. SELECT DISTINCT library, symbol
  348. FROM shlib_imp ;
  349. CREATE TABLE imports AS
  350. SELECT a.library, a.symbol
  351. FROM lib_imp a
  352. WHERE NOT EXISTS (
  353. SELECT b.library, b.symbol
  354. FROM lib_exp b
  355. WHERE b.symbol = a.symbol
  356. AND b.library = a.library
  357. ) ;
  358. CREATE TABLE defined AS
  359. SELECT DISTINCT symbol
  360. FROM lib_exp ;
  361. CREATE TABLE used AS
  362. SELECT DISTINCT symbol
  363. FROM imports ;
  364. CREATE TABLE undefined AS
  365. SELECT symbol
  366. FROM used u
  367. WHERE NOT EXISTS (
  368. SELECT *
  369. FROM defined d
  370. WHERE d.symbol = u.symbol
  371. ) ;
  372. SELECT symbol
  373. INTO TABLE undefined_1
  374. FROM undefined
  375. EXCEPT
  376. SELECT b.symbol
  377. FROM undefined a, libs b
  378. WHERE a.symbol = b.symbol ;
  379. CREATE TABLE undefined_2 AS
  380. SELECT i.symbol, i.object, i.library
  381. FROM stlib_imp i, undefined_1 u
  382. WHERE i.symbol = u.symbol ;
  383. CREATE TABLE depends AS
  384. SELECT i.library AS im_lib,
  385. i.symbol AS symbol,
  386. e.library AS ex_lib
  387. FROM imports i, lib_exp e
  388. WHERE i.symbol = e.symbol ;
  389. CREATE TABLE lib_deps AS
  390. SELECT DISTINCT im_lib, ex_lib
  391. FROM depends
  392. WHERE im_lib <> ex_lib ;
  393. CREATE TABLE lib_deps_1 AS
  394. SELECT a.im_lib,
  395. a.ex_lib AS in_lib,
  396. b.ex_lib
  397. FROM lib_deps a, lib_deps b
  398. WHERE a.ex_lib = b.im_lib ;
  399. CREATE TABLE lib_deps_2 AS
  400. SELECT a.im_lib,
  401. a.in_lib AS in1_lib,
  402. a.ex_lib AS in2_lib,
  403. b.ex_lib
  404. FROM lib_deps_1 a, lib_deps b
  405. WHERE a.ex_lib = b.im_lib
  406. AND a.im_lib <> a.ex_lib ;
  407. SELECT im_lib, ex_lib
  408. INTO TABLE lib_deps_trans
  409. FROM lib_deps
  410. UNION
  411. SELECT im_lib, ex_lib
  412. FROM lib_deps_1
  413. UNION
  414. SELECT im_lib, ex_lib
  415. FROM lib_deps_2 ;
  416. CREATE TABLE prog_libs AS
  417. SELECT DISTINCT a.program, b.library
  418. FROM prog_imp a, lib_exp b
  419. WHERE a.symbol = b.symbol ;
  420. SELECT DISTINCT a.symbol
  421. INTO TABLE libc
  422. FROM prog_imp a, libs b
  423. WHERE a.symbol = b.symbol
  424. AND b.library = 'libc.so.6'
  425. UNION
  426. SELECT DISTINCT a.symbol
  427. FROM imports a, libs b
  428. WHERE a.symbol = b.symbol
  429. AND b.library = 'libc.so.6' ;
  430. SELECT symbol
  431. INTO nonansi
  432. FROM libc
  433. WHERE symbol !~ '_.*'
  434. EXCEPT
  435. SELECT symbol
  436. FROM ansi ;
  437. CREATE TABLE nonansi_progs AS
  438. SELECT a.program, a.symbol
  439. FROM prog_imp a, nonansi b
  440. WHERE a.symbol = b.symbol ;
  441. CREATE TABLE nonansi_libs AS
  442. SELECT a.library, a.symbol
  443. FROM imports a, nonansi b
  444. WHERE a.symbol = b.symbol ;
  445. CREATE TABLE nonansi_prog_counts AS
  446. SELECT symbol, COUNT(*)
  447. FROM nonansi_progs
  448. GROUP BY symbol ;
  449. CREATE TABLE nonansi_lib_counts AS
  450. SELECT symbol, COUNT(*)
  451. FROM nonansi_libs
  452. GROUP BY symbol ;
  453. SELECT symbol
  454. INTO TABLE nonansi_counts
  455. FROM nonansi_prog_counts
  456. UNION
  457. SELECT symbol
  458. FROM nonansi_lib_counts ;
  459. ALTER TABLE nonansi_counts
  460. ADD COLUMN progs INTEGER ;
  461. ALTER TABLE nonansi_counts
  462. ADD COLUMN libs INTEGER ;
  463. UPDATE nonansi_counts
  464. SET progs = 0, libs = 0 ;
  465. UPDATE nonansi_counts
  466. SET progs = b.count
  467. FROM nonansi_prog_counts b
  468. WHERE nonansi_counts.symbol = b.symbol ;
  469. UPDATE nonansi_counts
  470. SET libs = c.count
  471. FROM nonansi_lib_counts c
  472. WHERE nonansi_counts.symbol = c.symbol;
  473. -- SELECT a.symbol, a.program
  474. -- FROM prog_imp a, nonansi_prog_counts b
  475. -- WHERE a.symbol = b.symbol
  476. -- AND a.program NOT LIKE 'bin/%'
  477. -- ORDER BY b.count DESC, b.symbol ;
  478. -- SELECT symbol, library
  479. -- FROM duplicates2
  480. -- ORDER BY symbol ;
  481. -- SELECT a.im_lib, a.ex_lib
  482. -- FROM lib_deps a, lib_deps b
  483. -- WHERE a.ex_lib = b.im_lib
  484. -- AND b.ex_lib = a.im_lib ;
  485. -- SELECT * FROM lib_deps_2
  486. -- WHERE im_lib = ex_lib ;
  487. -- SELECT * FROM lib_deps_1
  488. -- WHERE im_lib = ex_lib ;
  489. -- SELECT im_lib FROM lib_deps_trans
  490. -- WHERE im_lib = ex_lib ;
  491. -- SELECT a.program, a.library
  492. -- FROM ldd a
  493. -- WHERE a.library LIKE 'libgrass_%.so'
  494. -- AND a.library NOT IN (
  495. -- SELECT b.library
  496. -- FROM prog_libs b
  497. -- WHERE b.program = a.program
  498. -- ) ;
  499. -- ----------------------------------------------------------------------
  500. EOF