- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I'm trying to link C++ and fortran prorgam together, but I get the following error
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
The main program is fortran, calling a C routine. The linking must be done using C compiler (Because in my work I'm in fact compiling with nvcc (nvidia compiler for cuda) and the linking then can not be done using fortran compiler). I didn't find on the web anything that worked.
Moreover, GNU compiler is working fine (I pasted the test code at the end),
g++ -lstdc++ -g -c add.c g++ -g -o main main.o add.o -lstdc++ -lgfortran
and then,
Hola a+b = 3 6 9 12 15
But compilation with Intel compiler fails,
ifort -cxxlib -lstdc++ -g -c main.f90 icpc -cxxlib -lstdc++ -g -c add.c icpc -g -o main main.o add.o -lstdc++ -lifcore /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start': (.text+0x20): undefined reference to `main' Makefile:12: recipe for target 'main' failed make: *** [main] Error 1
Does someone know what is wrong with my compilation?
Thank you,
Marc Barbry
The C code (add.c),
#include <stdlib.h> #include <stdio.h> #include "add.h" extern "C" void addition_(int *a, int *b, int *c, int *Np) { int N = *Np; int i; for (i=0; i<N; i++) { c = a + b; } }
C header (add.h),
extern "C" void addition_(int *a, int *b, int *c, int *Np);
and Fortran code (main.f90),
program main implicit none integer, allocatable :: a(:), b(:), c(:) integer :: i, N N = 5 print*, 'Hola' allocate(a(N)) allocate(b(N)) allocate(c(N)) c = 0 do i=1, N a(i) = i b(i) = 2*i enddo call addition(a, b, c, N) print*, "a+b = ", c deallocate(a) deallocate(b) deallocate(c) end program
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
use ifort to perform the link of object files where one of which has a Fortran PROGRAM.
Use icpc to link when one of the object files has int main(...
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Jim,
Thank you for your answer, but as I described it in the original message, I MUST link with the C compiler.
This is because in my program, I use CUDA and therefore the nvcc compiler, but the nvcc compiler use as well icpc. Unfortunately, using nvcc, one can not use fortran compiler to link the modules because only nvcc has access to the cuda libraries. Linking this program using GNU C compiler is working very well, there is no way to do it as well with Intel compiler?
Marc Barbry
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Two options:
1) Make a C/C++ main, changing your Fortran .f90 file containing PROGRAM into a SUBROUTINE (then call that from the C/C++ main)
2) Build a Hello World Fortran program and generate a map. Examine that for entrypoint:
Hello World on Windows as Win32
0004:0000142c ___onexitbegin 0040b42c <common> 0004:00001430 ___dyn_tls_init_callback 0040b430 <common> entry point at 0001:00002b40 Static symbols 0000:ffff1000 .debug$S 00400000 MSVCRTD:MSVCR120D.dll Then locate 1:2b40 0001:00002740 __RTC_CheckEsp 00403740 f MSVCRTD:stack.obj 0001:00002860 _NtCurrentTeb 00403860 f i MSVCRTD:crtexe.obj 0001:00002b40 _mainCRTStartup 00403b40 f MSVCRTD:crtexe.obj 0001:00002ca0 ?_RTC_AllocaFailure@@YAXPAXPAU_RTC_ALLOCA_NODE@@H@Z 00403ca0 f MSVCRTD:error.obj 0001:00002e20 ?_RTC_Failure@@YAXPAXH@Z 00403e20 f MSVCRTD:error.obj
On the icpc link line, you can specify the entrypoint as _mainCRTStartup
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The second solution does not seem very portable, no?
Marc Barbry
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The choice of portability (or not) is yours - I am giving you choices.
If you use 1) then (depending on the Fortran code) you may also need to make a one time call at program start to _for_rtl_init_, and at program end _for_rtl_finish_ (if called from C, the "_" may be stripped. Calling those routines may also require libraries from the Fortran collection. The interoperability section of the IVF documentation should discuss this topic.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your help.
I will think what solution is more adapted for our program.
Marc Barbry

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