Fortran dependency checking


 
Thread Tools Search this Thread
Top Forums Programming Fortran dependency checking
# 1  
Old 08-18-2010
Fortran dependency checking

Hello,

I'm creating an add-on for a large piece of software written in Fortran. In my directory I reference subroutines in other directories, which in turn reference more subroutines.

I'm running into trouble because on occasion the developers of the main software change some sub calls.

e.g.

call this_subroutine (arg1, arg2, arg2)
becomes
call this_subroutine

and the arguments become global variables.

I'm curious if there is a good way of listing all the subroutines which my code DIRECTLY depends on, so I can watch for changes?

thanks
# 2  
Old 08-20-2010
Hi.

You didn't mention which standard your Fortran is written to, so you may need to change some parts of the procedure below.

1) One result of a compile is an object file. You can extract linkage symbols from such files with a utility nm, the most often-occurring are entry points, externals, and common block names.

2) You can use a source scanning utility ftnchek.

3) You can generate a link map with ld (it contains the most information, but ironically has always seemed to be the least useful for me).

Here's a sample of these driven by a demonstration script:
Code:
#!/usr/bin/env bash

# @(#) s1	Demonstrate extraction of external names.

# Uncomment to run script as external user.
# export PATH="/usr/local/bin:/usr/bin:/bin"
# Infrastructure details, environment, commands for forum posts. 
set +o nounset
pe() { for i;do printf "%s" "$i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe ; pe "Environment: LC_ALL = $LC_ALL, LANG = $LANG"
pe "(Versions displayed with local utility \"version\")"
c=$( ps | grep $$ | awk '{print $NF}' )
version >/dev/null 2>&1 && s=$(_eat $0 $1) || s=""
[ "$c" = "$s" ] && p="$s" || p="$c"
version >/dev/null 2>&1 && version "=o" $p specimen gfortran ar nm grep ftnchek ld
set -o nounset

# Sample data files, using head & tail as a last resort.
pe
specimen 7 *.f \
|| { pe "(head/tail)"; head -n 5 data*; pe " ||"; tail -n 5 data*; }

# Remove debris from previous runs.
rm -f *.o a.out *.a

pl " Results of compile, scan for externals::"
gfortran -c *.f

# Build the library.
ar sq libs.a libs.o

# Extract and display the symbols.
pl " Sample of nm output:"
# nm -fbsd main.o subs.o libs.a
# nm -fbsd -u main.o subs.o libs.a	# Unsatisfied only
# nm -fsysv main.o subs.o libs.a
nm -fposix main.o subs.o libs.a |
tee t1 | 
specimen 4

# Massage nm output to obtain entry points, "T", externals, "U".
awk '$2 == "T" { print $1 }' t1 > ent
awk '$2 == "U" { print $1 }' t1 > ext

pl " Non-system externals found:"
grep -v '^_' ext

pl " Unsatisfied externals in this application:"
# Remove matching entry-externals, remove system routines.
grep -v -f ent ext |
grep -v '^_'

pl " Results from ftnchek:"
ftnchek *.f

pl " Create link map from linker (ld):"
gfortran  -Wl,--print-map -Wl,--noinhibit-exec -o a.out main.o subs.o libs.a > map.txt
specimen 3 map.txt

pl " Results of execution:"
gfortran -Wl,--noinhibit-exec -o a.out main.o subs.o libs.a
./a.out

exit 0

producing:
Code:
% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0 
GNU bash 3.2.39
specimen (local) 1.17
gfortran GNU Fortran (Debian 4.3.2-1.1) 4.3.2
GNU ar (GNU Binutils for Debian) 2.18.0.20080103
GNU nm (GNU Binutils for Debian) 2.18.0.20080103
GNU grep 2.5.3
FTNCHEK Version 3.3 November 2004 Patch Level 1
GNU ld (GNU Binutils for Debian) 2.18.0.20080103

Whole: 7:0:7 of 11 lines in file "libs.f"
	subroutine b
	call b1
	return
	end
	subroutine b1
	call b2
	return
	end
	subroutine b2
	return
	end

Whole: 7:0:7 of 13 lines in file "main.f"
	program m
	call a
	call b
	end
	subroutine a
	x = 4.0
	xo = a1(x)
	y = 9.0
	yo = a2(y)
	z = xo + yo
	write(*,*) " z is", z
	return
	end

Whole: 7:0:7 of 12 lines in file "subs.f"
	function a1(x)
	a1 = sqrt(x)
	return
	end
	function a2(y)
	if ( y .lt. 4.0 ) then
	a2 = cubert(y)
	else
	a2 = sqrt(y)
	endif
	return
	end

-----
 Results of compile, scan for externals::
ar: creating libs.a

-----
 Sample of nm output:
Edges: 4:0:4 of 20 lines in file "-"
main.o:
MAIN__ T 0000000000000000 0000000000000029
_gfortran_set_options U         
_gfortran_st_write U         
   ---
libs.a[libs.o]:
b1_ T 0000000000000010 0000000000000010
b2_ T 0000000000000020 0000000000000006
b_ T 0000000000000000 0000000000000010

-----
 Non-system externals found:
a1_
a2_
b_
cubert_

-----
 Unsatisfied externals in this application:
cubert_

-----
 Results from ftnchek:

FTNCHEK Version 3.3 November 2004

File libs.f:
 0 syntax errors detected in file libs.f
File main.f:
 0 syntax errors detected in file main.f
File subs.f:
 0 syntax errors detected in file subs.f
Warning: Subprogram CUBERT never defined
    Invoked in module A2 line 7 file subs.f
    (possibly it is an array which was not declared)

-----
 Create link map from linker (ld):
subs.o: In function `a2_':
subs.f:(.text+0x57): undefined reference to `cubert_'
Edges: 3:0:3 of 487 lines in file "map.txt"
Archive member included because of file (symbol)

libs.a(libs.o)                main.o (b_)
   ---
 *(.note.GNU-stack)
 *(.gnu_debuglink)
OUTPUT(a.out elf64-x86-64)

-----
 Results of execution:
subs.o: In function `a2_':
subs.f:(.text+0x57): undefined reference to `cubert_'
  z is   5.0000000

One advantage to the nm scheme is that it is general, it works with any compiler that produces object files -- c, c++, fortran, etc.

Experimentation and man pages are usually one's best ways to learn.

Good luck ... cheers, drl
This User Gave Thanks to drl For This Post:
# 3  
Old 08-20-2010
wow, thanks for the informative post. I didn't have any idea where to start -- now I know what I'll be working with tomorrow.

Thanks again
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Get the missing dependency from two files

#cat hwlock-full.dep libx11-6 >= 1.4.4 libz1 >= 1.2.7 libtinfo5 >= 5.9 libxcb1 >= 1.8.1 numactl >= 2.0.8+rc4 libpixman-1-0 >= 0.29.2 libxml2 >= 2.7.8 libxext6 >= 1.3.1 libxrender1 >= 0.9.7 libfreetype6 >= 2.4.9 libxcb-render0 >= 1.8.1 libcairo2 >= 1.12.14 libc6 >= 2.15 libxcb-shm0... (7 Replies)
Discussion started by: yanglei_fage
7 Replies

2. Shell Programming and Scripting

Processing Dependency Printing

Gurus, I came across a typical requirement where the input is like- TRANS FIRM DEPT CUST TRANS CUST TRANS DEPT FIRM CUST & the expected Output is- CUST DEPT FIRM TRANS This is basically a dependency list for processing the tables where FIRM is feeding data to TRANS... (3 Replies)
Discussion started by: kapeeljoshi
3 Replies

3. Emergency UNIX and Linux Support

Changing executable dependency

hello, can anyone help in changing the executable dependency on a certain shared library. eg, .. say i am having an executable by name utest. when i run UNIX ldd command on it then it shows the libraries on which it depends as follows: ldd release/utest release/utest needs: ... (4 Replies)
Discussion started by: skyineyes
4 Replies

4. HP-UX

Library dependency coming out of nowhere

I'm building on a HP-UX ia64 system. During building, I'm getting an error ld: Can't find dependent library "libnnz10.so" Nowhere in my makefile do I link with this library. This library is there in the directory /databases/oracle10.2.0_64BIT/lib. I'm having two source files ora8ibulk.cpp... (1 Reply)
Discussion started by: old_as_a_fossil
1 Replies

5. UNIX for Dummies Questions & Answers

make -j dependency

Hi, I had a make file, something like that, all: cd dir1; make cd dir2; make the problem is the makefile under dir2 need some objs from dir1, so I need to set some dependency let dir2 run only after the dir1 run is done. how to set the dependency? Thanks. peter (2 Replies)
Discussion started by: laopi
2 Replies

6. Infrastructure Monitoring

Weird dependency problem!

Hi, I want to install net-snmp-devel package but i have following dependecy problem. It's very odd, i don't get it. One of packages is depended on the other one, the other one is depended on the previous one as well. :S :S Could you help me please? Here are the steps: # ls -l total... (4 Replies)
Discussion started by: oduth
4 Replies

7. Solaris

Dependency problem

Hi all am new to solaris ............ i installed amanda client pkg that time am getting lots of dependency problem.......... is there any Yum server like things in solaris Regards ' prAn (8 Replies)
Discussion started by: pran
8 Replies

8. UNIX for Dummies Questions & Answers

Dependency problems with Fedora7

Hey guys, I installed Fedora7 from DVD yesterday. I have previously worked with RHEL4 and Fedora4(As of RPM based systems). I used to copy all the rpms from the media to a directory. #mkdir /rpms #copy /path_to_rpms_in_media/* /rpms/ My intention for doing this was to get around the... (0 Replies)
Discussion started by: tmm
0 Replies

9. UNIX for Dummies Questions & Answers

process dependency

how to find all the processes associated with a given process in unix,is there any command for this. (3 Replies)
Discussion started by: laddu
3 Replies
Login or Register to Ask a Question