Hello,
while testing the new functionality of slink64 concerning static libraries I ran into a problem when making use of a subroutine defined in a library which calls a subroutine defined in the same library. The scenario consists of three fortran files, main.for, MYSUB_1.for and MYSUB_2.for and a batch file create_main.bat which creates object files, libraries and executables in diffent ways depending on the command line parameters.
Main.for:
character*256 MYFILE,MYTEXT
integer*2 I1,I2,NUM
#if 1
write(*,*) 'main: MYSUB_1 started'
CALL MYSUB_1('abcdefgh',8_2,I1,MYFILE,I2)
write(*,*) 'main: MYSUB_1 finished'
#else
write(*,*) 'main: MYSUB_2 started'
call MYSUB_2(MYTEXT,NUM)
write(*,*) 'main: MYSUB_2 finished'
#endif
stop
end
MYSUB_1.for:
SUBROUTINE MYSUB_1 (MYFILE,i1,i2,MYPATH,i3)
INTEGER*2 i1,i2,i3
CHARACTER MYFILE*(*),MYPATH*(*),MYTEXT*(2048)
write(*,*) 'MYSUB_1 started'
CALL MYSUB_2(MYTEXT,i1)
write(*,*) 'MYSUB_1 finished'
RETURN
END
MYSUB_2.for:
SUBROUTINE MYSUB_2(MYTEXT,NUM)
CHARACTER MYTEXT*(*)
INTEGER*2 NUM
write(*,*) 'MYSUB_2 started'
NUM=32
MYTEXT='xxxx'
write(*,*) 'MYSUB_2 finished'
END
The code is created by means of batch file create_main.bat:
@echo off
setlocal
if '%1' == '' (
echo Usage: create_main [64 or 32] [/objs]
echo Params: 64 - 64 bit build
echo 32 - 32 bit build
echo /objs - link against objects as opposed to library
exit /B 1
)
set DO_LINK_FROM_OBJECTS=0
set CCOPTS=/debug /Cfpp
if '%1' == '64' (
set CCOPTS=%CCOPTS% /64
set MYTARGET=_64
set MYSLINK=slink64
) else (
if '%1' == '32' (
set MYTARGET=_32
set MYSLINK=slink
) else (
echo Error: one of 32 or 64 needs to be specified
exit /B 2
)
)
if '%2' == '/objs' set DO_LINK_FROM_OBJECTS=1
set MYFILES=MYSUB_1,MYSUB_2
for %%f in (%MYFILES%) do (
echo ftn95 %%f.for /FIxed_format %CCOPTS% /Binary %%f%MYTARGET%.obj
ftn95 %%f.for /FIxed_format %CCOPTS% /Binary %%f%MYTARGET%.obj
)
echo ; > mylib%MYTARGET%.lnk
if '%1' == '64' (
for %%f in (%MYFILES%) do (
echo lo %%f%MYTARGET% >> mylib%MYTARGET%.lnk
)
) else (
echo ; > mylib%MYTARGET%.lnk
echo archive >> mylib%MYTARGET%.lib >> mylib%MYTARGET%.lnk
for %%f in (%MYFILES%) do (
echo addobj %%f%MYTARGET% >> mylib%MYTARGET%.lnk
)
)
echo file mylib%MYTARGET%.lib >> mylib%MYTARGET%.lnk
echo %MYSLINK% mylib%MYTARGET%.lnk
%MYSLINK% mylib%MYTARGET%.lnk
echo ftn95 main.for /FIxed_format %CCOPTS% /Binary main%MYTARGET%.obj
ftn95 main.for /FIxed_format %CCOPTS% /Binary main%MYTARGET%.obj
echo lo main%MYTARGET% > main%MYTARGET%.lnk
if '%DO_LINK_FROM_OBJECTS%' == '1' (
echo lo MYSUB_1%MYTARGET%.obj >> main%MYTARGET%.lnk
echo lo MYSUB_2%MYTARGET%.obj >> main%MYTARGET%.lnk
) else (
echo lo mylib%MYTARGET%.lib >> main%MYTARGET%.lnk
)
echo map main%MYTARGET%.map >> main%MYTARGET%.lnk
echo file >> main%MYTARGET%.lnk
echo %MYSLINK% main%MYTARGET%.lnk
%MYSLINK% main%MYTARGET%.lnk
endlocal
Now executing
create_main.bat 64
results in creating executable main_64.exe, however, symbol MYSUB_2 is marked as undefined and executing main_64.exe results in exception
Silverfrost 64-bit exception report on c:\ds\samples\salford_8.30\test_link\gplini\sample_2salford\main_64.EXE Fri Apr 20 14:32:04 2018
Call to missing routine - MYSUB_2 at address 1c0086c0
Within file main_64.EXE
in MYSUB_1 in line 6, at address 8b
in MAIN@ in line 6, at address ac
RAX = 000000000000001d RBX = 000000000240fda0 RCX = 00000000004019a3 RDX = 00000000004050c8
RBP = 000000001c000000 RSI = 00000000004051ef RDI = 00000000004014f0 RSP = 000000000240f490
R8 = 00000000004019a3 R9 = 000000000240d940 R10 = 0000000000000000 R11 = 0000000000000246
R12 = 0000000000000000 R13 = 0000000000000000 R14 = 0000000000000008 R15 = 0000000000000100
1c0086c0) int 9
This seems strange to me for I think the symbol **has **been defined in library mylib_64.lib which executable main_64.exe is linked against.
Please find more information in the continuation of this post.