- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, all
I am new to mac os and ifort. Here i have a basic question: how to link the g++ compiled .o files with ifort compiled .o files?
Below is my very simple example:
an aver.cpp file:
------------------------------------------------------------------
#include
#include
#include
#include
double myaver(double x, double y, double z){
double aver;
aver=(x+y+z)/3;
return aver;
}
--------------------------------------------------------------------
a fortran main.F90 file using myaver function:
-------------------------------------------------------------------
PROGRAM MAIN
REAL x, y,z, average
x=100
y=200
z=300
PRINT *, 'three numbers: ', x, y, z
average = myaver(x,y,z)
PRINT *, 'Average of the three numbers is: ', average
END PROGRAM MAIN
---------------------------------------------------------------------------
now i compile each of them without link (make sure they are 32 bit):
---------------------------------------------------------------------
g++ -c aver.cpp
ifort -m32 -c main.f90
-------------------------------------------------------------------------
then link them
-----------------------------------------------------------------------
ifort -m32 -fPIC -o mytest main.o aver.o
------------------------------------------------------------------------
but i got error :
------------------------------------------------------------------------
Undefined symbols:
"_myaver_", referenced from:
_MAIN__ in main.o
ld: symbol(s) not found
-------------------------------------------------------------------------
how do I resolve this error? I guess I have fundamental misunderstanding here. Hope experts could help me.
many thanks
I am new to mac os and ifort. Here i have a basic question: how to link the g++ compiled .o files with ifort compiled .o files?
Below is my very simple example:
an aver.cpp file:
------------------------------------------------------------------
#include
#include
#include
#include
double myaver(double x, double y, double z){
double aver;
aver=(x+y+z)/3;
return aver;
}
--------------------------------------------------------------------
a fortran main.F90 file using myaver function:
-------------------------------------------------------------------
PROGRAM MAIN
REAL x, y,z, average
x=100
y=200
z=300
PRINT *, 'three numbers: ', x, y, z
average = myaver(x,y,z)
PRINT *, 'Average of the three numbers is: ', average
END PROGRAM MAIN
---------------------------------------------------------------------------
now i compile each of them without link (make sure they are 32 bit):
---------------------------------------------------------------------
g++ -c aver.cpp
ifort -m32 -c main.f90
-------------------------------------------------------------------------
then link them
-----------------------------------------------------------------------
ifort -m32 -fPIC -o mytest main.o aver.o
------------------------------------------------------------------------
but i got error :
------------------------------------------------------------------------
Undefined symbols:
"_myaver_", referenced from:
_MAIN__ in main.o
ld: symbol(s) not found
-------------------------------------------------------------------------
how do I resolve this error? I guess I have fundamental misunderstanding here. Hope experts could help me.
many thanks
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As you see, the default Fortran name mangling appends an underscore to the function name, while C++ mangling is entirely different. Perhaps not so obvious, the Fortran arguments pass by reference. Consider using the iso_c_interop on the Fortran side, with extern "C" definition on the C++ side.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
As you see, the default Fortran name mangling appends an underscore to the function name, while C++ mangling is entirely different. Perhaps not so obvious, the Fortran arguments pass by reference. Consider using the iso_c_interop on the Fortran side, with extern "C" definition on the C++ side.
many thanks, tim18, now i get everything works. But I have some further questions:
the way I did is : the aver.cpp
--------------------------------------------------------------------------------
#include
#include
#include
#include
extern "C" {
void myaver_(float *x, float *y, float *z, float *aver);}
void myaver_(float *x, float *y, float *z,float *aver){
*aver=(*x+*y+*z)/3;
}
------------------------------------------------------------------------------------
and the main.f90 file is
PROGRAM MAIN
REAL x, y,z, average
x=100
y=200
z=300
PRINT *, 'three numbers: ', x, y, z
call myaver(x,y,z, average)
PRINT *, 'Average of the five numbers is: ', average
END PROGRAM MAIN
-------------------------------------------------------------------------------------
then i compile on the MAC OS :
g++ -c aver.cpp
ifort -m32 -c main.f90
ifort -m32 -o mytest aver.o main.o
then i get the correct answer. while I also did the same thing on my RHEL5.3
g++ -c aver.cpp
ifort -c main.f90
ifort -o mytest aver.o main.o -lstdc++
then it works. But a further exploration confused me:
-------------------------------------------------------------------------------------------------
on the RHEL 5.3 | on the MAC OS
nm aver.o | nm aver.o
U __gxx_personality_v0 | 00000000 T _myaver_
0000000000000000 T myaver_ | 00000000 A _myaver_.eh
--------------------------------------------------------------------------------------------------
the __gxx_personality_v0 is the reason to add libstdc++.
I use the same compiler and no other flags. The only difference is RHEL is 64 bit but Mac is 32 bit. Why are the names on the mac os all added "_" in the front? How do I modified the compiler option to make the mac os have the same function names as the RHEL 5.3 ? what is .eh? and how does the RHEL5.3 add __gxx_personality_v0 automatically when compiling?
Hope I am clear. Many thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe you're correct about different ABI conventions chosen for 32- and 64-bit. Mac g++ includes some differences specified by Apple, while linux g++ is under the control of an FSF steering committee. Any .o file made by linux g++ includes the __gxx_personality reference. If you had used any C++ syntax, you would need -lstdc++ on both linux and Mac, I suppose.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
I believe you're correct about different ABI conventions chosen for 32- and 64-bit. Mac g++ includes some differences specified by Apple, while linux g++ is under the control of an FSF steering committee. Any .o file made by linux g++ includes the __gxx_personality reference. If you had used any C++ syntax, you would need -lstdc++ on both linux and Mac, I suppose.
OK, I see.
Is there any options or flags of "ifort" such that no undercores are added on the function names? I check online and find the gfortran has a flag "fno-underscoring", which could let me add no underscore to the functions in my .cpp file but link successfully.
thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - pilot117
OK, I see.
Is there any options or flags of "ifort" such that no undercores are added on the function names? I check online and find the gfortran has a flag "fno-underscoring", which could let me add no underscore to the functions in my .cpp file but link successfully.
thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
There's no flag to modify leading underscores. You're stuck with using the convention of your OS. You could look up the flags for trailing underscores in ifort documentation, recognizing that changes from default are at your own risk and not an adequate substitute for USE iso_c_interop.
Oh, thanks for pointing out that! I believe you are absolutely right.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have tried something else using the "decorate". But there is something wrong which i can not figure out:
the main.f90 is written as this:
---------------------------------------------------------------------------------------------------
! File: main.f90
! This program calculates the average of three numbers
PROGRAM MAIN
implicit none
interface
subroutine fc_myaver(A,B,C,aver)
!DEC$ ATTRIBUTES C, DECORATE, ALIAS:'cf_myaver'::fc_myaver
real A, B, C, aver
end subroutine
end interface
REAL x, y,z, average
x=100
y=200
z=300
PRINT *, 'three numbers: ', x, y, z
call fc_myaver(x,y,z, average)
PRINT *, 'Average of the five numbers is: ', average
END PROGRAM MAIN
----------------------------------------------------------------------------------------
the aver.cpp is the same as the above. I can compile successfully by
ifort -m32 -c main.f90
g++ -c aver.cpp
ifort -m32 -o mytest aver.o main.o
but when i run ./test, it gave these wrong information:
----------------------------------------------------------------------------------------------
three numbers: 100.0000 200.0000 300.0000
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
mytest 00001E1F Unknown Unknown Unknown
mytest 00001FA2 Unknown Unknown Unknown
mytest 00001DFD Unknown Unknown Unknown
mytest 00001D86 Unknown Unknown Unknown
Unknown 00000001 Unknown Unknown Unknown
------------------------------------------------------------------------------------------------
can anyone figure out what is wrong here? many thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Remove the C in the ATTRIBUTES directive - that changes everything to pass-by-value.
Let me suggest that you do it this way instead:
Let me suggest that you do it this way instead:
subroutine fc_myaver(A,B,C,aver) BIND(C,NAME='cf_myaver')
and remove the !DEC$ ATTRIBUTES line. If this doesn't work, please show the current source for the C routine.
and remove the !DEC$ ATTRIBUTES line. If this doesn't work, please show the current source for the C routine.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page