I need to run an old program found here: http://netlib.sandia.gov/conformal/ under the title "kirch1" in the list. I have absolutely no experience running fortran code, but I would like to do so from my Mac OS X 10.10 command line.
I know I have the 'gfortan' compiler installed on my system, but I'm not sure if this doesn't like this older code. When I run gfortran KIRCH1.f (this file is the one above) I get the following error:
KIRCH1.f:266.8:
x(2) = -1. + dx
1
Warning: Array reference at (1) is out of bounds (2 > 1) in dimension 1
KIRCH1.f:200.21:
common /param1/ nq2,c2,x2(20),z2(20),qwork2(460),betam2(20)
1
Warning: Padding of 4 bytes required before 'c2' in COMMON 'param1' at (1); reorder elements or use -fno-align-commons
KIRCH1.f:285.21:
common /param1/ nq,c,x(20),z(20),qwork(460),betam(20)
1
Warning: Padding of 4 bytes required before 'c' in COMMON 'param1' at (1); reorder elements or use -fno-align-commons
Undefined symbols for architecture x86_64:
"_gaussj_", referenced from:
_qinitx_ in ccoKtvwZ.o
"_ns01a_", referenced from:
_ksolv_ in ccoKtvwZ.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
This error seems to be do to the syntax in the code? I doubt there is anything wrong with the code itself, so I'm thinking its something to do with my systems interpretation of the code (for lack of a better way of phrasing this)
I have no fortran programming experience, I should mention. What am I doing wrong?
EDIT
As suggested by Ed Smith
I run gfortran sclibdbl.f KIRCH1.f but I still get the following warnings:
KIRCH1.f:266.8:
x(2) = -1. + dx
1
Warning: Array reference at (1) is out of bounds (2 > 1) in dimension 1
KIRCH1.f:200.21:
common /param1/ nq2,c2,x2(20),z2(20),qwork2(460),betam2(20)
1
Warning: Padding of 4 bytes required before 'c2' in COMMON 'param1' at (1); reorder elements or use -fno-align-commons
KIRCH1.f:285.21:
common /param1/ nq,c,x(20),z(20),qwork(460),betam(20)
1
Warning: Padding of 4 bytes required before 'c' in COMMON 'param1' at (1); reorder elements or use -fno-align-commons
The following compiled for me:
gfortran sclibdbl.f KIRCH1.f
where KIRCH1.f is the code from http://netlib.sandia.gov/conformal/kirch1 and sclibdb1.f is the code from http://netlib.org/conformal/sclibdbl.
You were just missing the required subroutines gaussj and ns01a which are referenced in the KIRCH1 source code but included in sclibdbl. The code from netlib.org/conformal/sclibdbl includes both the gaussj and ns01a subroutine (note the underscore is added to routine names by default in gfortran).
As #francescalus noted, it's modern fortran compiler and old school FORTRAN code. The warning is because modern fortran is far more explicit about array extents. In this code, x is passed with size 1 to yxtran() which is okay as passing is a reference to the start of array. When element 2 is accessed the modern fortran compiler gets worried. You can remove the two common block errors by adding the -fno-align-commons flag to the compiler. The x(1) error could be removed by replacing x(1) on line 258 with x(n-1). Personally, I wouldn't worry unless you notice problems/unexpected behavior when you run the code (especially as it's from netlib).
Related
I'm trying to compile legacy Fortran code with fort77. The command:
fort77 -c leg_code.f leg_code.o
fails with:
Error on line XXX: syntax error
Line XXX reads:
CHARACTER(LEN=10) TREE(2,MAXF)
where MAXF is defined some lines above with:
INTEGER MAXF, MAXC
PARAMETER (MAXF=400, MAXC=20)
If I remove (LEN=10), the code compiles with no issues.
Anyone know the reason for this error?
As noted in the comments, the declaration statement
CHARACTER(LEN=10) TREE(2,MAXF)
is not valid in Fortran 77. This form, declaring a rank-2 array of character of length 10, was introduced to standard Fortran in the Fortran 90 revision.
To declare such a variable in Fortran 77 the alternative form
CHARACTER*10 TREE(2,MAXF)
or
CHARACTER TREE(2,MAXF)*10
would be required. Simply removing the (len=10), as in
CHARACTER TREE(2,MAXF)
declares the variable to be an array of character of length 1, but this is valid in Fortran 77.
I'm using gfortran [GNU Fortran (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)] on a Fedora 20 x86_64 to compile a bunch of Fortran 77 code which refers to 'iargc' function in the following manner:
bin2D2nc.f:31: integer iargc,strlen1
bin2D2nc.f:32: external iargc,strlen1
bin2D2nc.f:44: i=iargc()
When the make script reaches the compilation comand bellow,
gfortran -O3 -ffixed-line-length-132 -fall-intrinsics -I/home/santiago/Install/netcdf_sam/include -o bin2D2nc -I./SRC ./SRC/bin2D2nc.f ./SRC/hbuf_lib.f ./SRC/cape.f ./SRC/cin.f -L/home/santiago/Install/netcdf_sam/lib -lnetcdf -L/usr/lib64 -lpthread
I receive these messages:
bin2D2nc.f:(.text+0x14): undefined reference to `iargc_'
collect2: error: ld returned 1 exit status
make: ** [bin2D2nc] Erro 1
I'm not the author of this code. As far as I know, I set up correctly the library paths in the makefile.
I have found that 'iargc' is a routine for backward compability with GNU Fotran 77, but I don't understand it deeply.
Could someone give some advise to surpass this problem?
The problem is very similar to Fixing FORTRAN IV warning: "The number of arguments is incompatible with intrinsinc procedure, assume 'external' " but the difference is that in the other question there was an external function present and the similarity with an intrinsic was inadvertent, but you are calling the intrinsic on purpose.
The statement
EXTERNAL IARGC
meant that IARGC is an external or an intrinsic function in FORTRAN 66, but in "modern Fortran" 77 and later it means that it is an external function only.
But you need to call the intrinsic function https://gcc.gnu.org/onlinedocs/gfortran/IARGC.html .
You should use
INTRINSIC IARGC
or even just delete IARGC from the EXTERNAL statement without adding anything else. The compiler will then stop searching for a non-existent external function and will use the intrinsic.
A final note, IARGC itself is not standard Fortran, ut it shouldn't matter here.
I try the following makefile:
MAKEFLAGS += s
MAKEFLAGS += r
configure:
Then, when I run make, I get the following errors, as if it wants to compile 'configure', per some default implicit-rule:
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 11
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 13
If I run:
make -r
I do not get the above errors, Instead, I get:
make: Nothing to be done for 'configure'.
I got the idea to define MAKEFLAGS from here:
The 'MAKEFLAGS' variable can also be useful if you want to have
certain options, such as '-k' (*note Summary of Options: Options
Summary.), set each time you run 'make'. You simply put a value for
'MAKEFLAGS' in your environment. You can also set 'MAKEFLAGS' in a
makefile, to specify additional flags that should also be in effect for
that makefile. (Note that you cannot use 'MFLAGS' this way. That
variable is set only for compatibility; 'make' does not interpret a
value you set for it in any way.)
When 'make' interprets the value of 'MAKEFLAGS' (either from the
environment or from a makefile), it first prepends a hyphen if the value
does not already begin with one. Then it chops the value into words
separated by blanks, and parses these words as if they were options
given on the command line (except that '-C', '-f', '-h', '-o', '-W', and
their long-named versions are ignored; and there is no error for an
invalid option).
You don't say, but probably you're using a too-old version of GNU make. The ability to remove built-in rules by adding -r to MAKEFLAGS inside a makefile was added in GNU make 4.0, released in early October 2013.
It's important to remember that when you look at the manual on the GNU website you're looking at the documentation for the latest version of GNU make. It's better to read the documentation which comes with your distribution, as that will be the correct version of the manual associated with the version of GNU make that you're using.
ETA:
You have to use real flags in MAKEFLAGS. You can't just use the single letter versions. The only time single-letter options are allowed is in the first word of the variable value (I would have removed that too if it weren't required by the standard). You've written:
MAKEFLAGS += s
MAKEFLAGS += r
which gives a value for MAKEFLAGS (if you run make with no other options) of s r. Make will add a dash to the first word, but not any other words, so this is interpreted as -s r and the r is not the -r option. Also, if you happened to run make with an option, say make -k then MAKEFLAGS would be k s r and make would interpret that as -k s r, and then the -s flag would not be set either.
In short, just prepend your options with dashes always when you want to modify MAKEFLAGS:
MAKEFLAGS += -s
MAKEFLAGS += -r
I am trying to link a few static libraries to create the final executable for iOS using a build script. My problem is that ldalways exits with code 136. My question is: how can I find out what code 136 means? man ld does not mention any return codes at all. I found two lists of system error codes but none for ld:
System error codes from 0 to -261, System error codes from 1 to 32767
Alternatively, how can I get ld to tell me the problem. I have tried all the options for logging but none of them get it to print anything.
Typically, exit codes greater than 127 mean that a signal terminated your program. The signal number is the exit code - 128. In your case,the signal with the number 8 is SIGFPE. Seems like a floating point exception was the cause of the abort.
I've been tasked with maintaing some legacy fortran code, and I'm having trouble getting it to compile with gfortran. I've written a fair amount of Fortran 95, but this is my first experience with Fortran 77. This snippet of code is the problematic one:
CHARACTER*22 IFILE, OFILE
IFILE='TEST.IN'
OFILE='TEST.OUT'
OPEN(5,FILE=IFILE,STATUS='NEW')
OPEN(6,FILE=OFILE,STATUS='NEW')
common/pabcde/nfghi
When I compile with gfortran file.FOR, all lines starting with the common statement are errors (e.g. Error: Unexpected COMMON statement at (1) for each following line until it hits the 25 error limit). I compiled with -Wall -pedantic, but fixing the warnings did not fix this problem.
The crazy thing is that if I comment out all 4 lines starting with IF='TEST.IN', the program compiles and works as expected, but I must comment out all of them. Leaving any of them uncommented gives me the same errors starting with the common statement. If I comment out the common statement, I get the same errors, just starting on the following line.
I am on OS X Leopard (not Snow Leopard) using gfortran. I've used this very system with gfortran extensively to write Fortran 95 programs, so in theory the compiler itself is sane. What the hell is going on with this code?
Edit: Compiling with g77 gives:
test.FOR: In program `MAIN__':
test.FOR:154:
IFILE='TEST.IN'
1
test.FOR:158: (continued):
common/pabcde/nfghi
2
Statement at (2) invalid in context established by statement at (1)
Er, what context is established at (1)?
I don't think you can put COMMON statements below the executable statements in FORTRAN 77, see the specification, Sec. 3.5.
Just move the COMMON statement close to the beginning of the procedure, before any executable statement.