Xcode 3.0, Intel Fortran 10.1.007 and FORTRAN common blocks

Xcode 3.0, Intel Fortran 10.1.007 and FORTRAN common blocks

Is anyone else having problems with Fortran COMMON blocks not being 'common' when compiled with Intel Fortran 10.1.007, then linked with mixed C/C++ shared libraries?

Using Xcode 2.4.1 and Intel Fortran 10.1.007, COMMON blocks that are in one dylib get properly referenced from another dylib, i.e. there's only one instance of the COMMON block symbols.

However, using the same compiler/linker flags but switching to Xcode 3.0, my common blocks are no longer common - each dylib that references them get their *own* copies.

I'm not using the Xcode 3.0 IDE, all my building is done from the command line; I am using the gcc linker to link. Since this worked fine with Xcode 2.4.1, my tests point at it being an issue to take up with Apple, but I wanted to see if others have encountered the problem.

For what it's worth, I see the identical problem on PowerPC using the Absoft Pro Fortran 9.2 compiler.

Thanks, Todd.

13 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I believe I am seeing the same problem. I am using XCode 3 under Leopard.

I am loading a dynamic library and calling an entry point from within an executable. The calling program can see the common block (which it defined) but the code inside the dylib cannot see the common block.

Both the executable and the dylib are mixed C and Fortran. Both C and Fortran functions are able to see the common block in the executable, and neither are able to see it in the dylib.

I wish I had more to contribute...

- Mark

Thanks for the feedback. I created a small example with a dylib and a separate executable - each has the same common block definition. When I build using Xcode 3, there are two different instances of the common block - if I set common block values in a function in the dylib, those values are not reflected in the executable.

Compiling the same example using Xcode 2.4.1 will produce expected results. Perhaps there are changes I need to make for Xcode 3, but I'll contact Apple to find out, and file a bug if this is indeed an Xcode 3 bug.

-Todd

Please reporthere what you learn from Apple.

Thanks.

Sure thing. My sources at Apple say they are aware of the problem and it will be fixed in an upcoming Xcode 3 release. They did not mention any timeframe.

Hope this helps.

FWIW I'm having the same problem in 10.1.008.

Any word on this bug? I have not renewed my Intel FORTRAN subscription because of this bug. Is the FORTRAN still being supported by Intel? Did anyone file a bug report on Apple's website? XCode 3.0 and 3.1 have not fixed this problem...

If tpeterson@spss.com is still reading, if you filed a bug willyou please post your Radar#?

Yes, Intel still supports our Fortran compiler, however, we do not have control over the OS vendors tools. In this case, the root-cause lies with the GNU linker (ld) provided w/Xcode. I will check on the status from Apple and post again if there is any news.

I am unable to show success with Xcode 2.4.1 with the example below (sans the DLLEXPORT/DLLIMPORT), so I do not know how it differs from codes reported earlier that work with Xcode 2.4.1 but fail with the newer Xcode 3.x. It would be interesting to see a sample that works with Xcode 2.4.1 if anyone has one.

As a work-around one could consider using DLLIMPORT/DLLEXPORT directives with the Intel Fortran compiler as shown in the example below. Support for these directives was added in an earlier 9.1 update. This works with Xcode 3.0 and our latest 10.1.015 update.

main.f90:

PROGRAM CTEST

!DEC$ ATTRIBUTES C, ALIAS:'_TESTSUB3' :: TESTSUB3

CALL TESTSUB1

CALL TESTSUB2

CALL TESTSUB3

CALL TESTSUB2

STOP

END

sub1.f90:

SUBROUTINE TESTSUB1

!dec$ attributes dllexport :: CMBLK1

COMMON/CMBLK1/A,B

INTEGER A,B

DATA A,B/0,20/

END

sub2.f90:

SUBROUTINE TESTSUB2

!dec$ attributes dllimport :: CMBLK1

COMMON/CMBLK1/A,B

INTEGER A,B

IF (A==0) PRINT *,'Fortran TESTSUB2, B = ',B, 'should be 20 '

IF (A==1) PRINT *,'Back to Fortran TESTSUB2, B = ',B, 'should be 21 '

RETURN

END

sub3.c:

#include

struct comstruct{

int A;

int B;

};

extern struct comstruct cmblk1_;

void TESTSUB3(void)

{

cmblk1_.A = 1;

cmblk1_.B = cmblk1_.B + 1;

printf(" C TESTSUB3, A is: %d
",cmblk1_.A);

printf(" C TESTSUB3, B is: %d
",cmblk1_.B);

}

Compile/link using the Intel 64 compiler and gcc as follows:

ifort -dynamiclib -o sub1.dylib sub1.f90 -Wl,-single_module -Wl,-undefined dynamic_lookup

ifort -dynamiclib -o sub2.dylib sub2.f90 -Wl,-single_module -Wl,-undefined dynamic_lookup

gcc -m64 -dynamiclib -o sub3.dylib sub3.c -Wl,-flat_namespace,-single_module,-U,_cmblk1_

ifort -o main main.f90 sub1.dylib sub2.dylib sub3.dylib -Wl,-bind_at_load

The correct results will be:

Fortran TESTSUB2, B = 20 should be 20

C TESTSUB3, A is: 1

C TESTSUB3, B is: 21

Back to Fortran TESTSUB2, B = 21 should be 21

Hi,

This common block issue has been fixed in XCode 3.1. Look at the man page for ld(1) and search for the -commons switch and its treatment options: ignore_dylibs, use_dylibs, and error.

Hope this helps, Todd

To expound a little more on my previous reply, in order for Fortran common blocks to be common across libraries, use

-commons use_dylibs

if you'd like to send this through to the linker from gcc, just use :

-Wl,-commons,use_dylibs

This has worked for me in my small sample program I submitted to Apple to show the problem.

The Radar bug I filed was #5697630; it got closed as a duplicate of #5132652.

Best regards,

Todd

I decided to try this again, and it still appears to not work. I've distilled it down quite a bit, it's just a shell script.#!/bin/shrm -f sub.f90 main.f90 *.o static dylibcat >sub.f90 < SUBROUTINE TESTSUB !dec$ attributes dllimport :: CMBLK1 COMMON/CMBLK1/A,B INTEGER A,B PRINT *,'TESTSUB: location of A is ',%loc(A) PRINT *,'TESTSUB: A = ',A RETURN ENDEOTcat >main.f90 < PROGRAM FTEST !dec$ attributes dllexport :: CMBLK1 COMMON/CMBLK1/A,B INTEGER A,B DATA A,B/555,20/ PRINT *,'-----------' PRINT *,'MAIN: location of A is ',%loc(A) PRINT *,'MAIN: A = ',A CALL TESTSUB PRINT *,'-----------' STOP ENDEOTifort -dynamiclib -o sub.dylib sub.f90 -Wl,-single_module -Wl,-undefined,dynamic_lookup -dyncom="CMBLKL1"ifort -c -o main.o main.f90 -Wl,-undefined,dynamic_lookup -dyncom="CMBLKL1"ifort -o static main.f90 sub.f90 -Wl,-undefined,dynamic_lookup -dyncom="CMBLKL1"ifort -o dylib main.o sub.dylib -Wl,-undefined,dynamic_lookup -dyncom="CMBLKL1"./static./dylibThe output of the two programs should be the same, or at least the values of A should match. Currently the output is:-----------MAIN: location of A is 4295546224MAIN: A = 555TESTSUB: location of A is 4295546224TESTSUB: A = 555----------------------MAIN: location of A is 4294983984MAIN: A = 555TESTSUB: location of A is 4295624224TESTSUB: A = 0-----------Is there an option I'm missing? I thought this was fixed.

Oh, and BTW I downloaded the latest ifort last night.

BTW I downloaded the latest ifort last night.The -dyncom options do nothing because I spelled the common block name wrong. If I spell it right, I get errors, so disregard them.

Leave a Comment

Please sign in to add a comment. Not a member? Join today