Calling a Fortran procedure from C that includes a call to an intrinsic Fortran function [duplicate] - c

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it in Fortran?
(5 answers)
C++/Fortran mixed programming: undefined reference to `_gfortran_reshape_r8'
(3 answers)
Closed 2 days ago.
I'm trying to write a Fortran routine that can be called from a C program. The Fortran code compiles correctly, but when I try to link the C code against the Fortran binary, I get an error saying there's an undefined reference to a Fortran intrinsic routine. Is it possible to write either the Fortran code itself, or its C interface definition, such that a Fortran function that calls a Fortran intrinsic can be called from C? If so, how is this done?
The Fortran code that I want to call from C is in a file called "test.f90":
module test
use, intrinsic :: iso_c_binding, only : c_double
implicit none
contains
function getRand() bind(c)
real(c_double) :: getRand
call random_number(getRand)
end function getRand
end module test
The C code that I want to execute this code is in a file called "main.c":
extern double getrand();
int main(){
double r = 0.0;
r = getrand();
return 0;
}
I tried to build the code with the following commands:
>$ gfortran -c test.f90 (This executed with no error)
Then I ran:
>$ gcc test.o main.c
This command failed with the error message:
/usr/bin/ld: testmodule.o: in function `getrand':
testmodule.f90:(.text+0x15): undefined reference to `_gfortran_random_r8'
collect2: error: ld returned 1 exit status
I'm using gfortran and gcc versions 11.3.0 on Ubuntu 20.04.1, running on Windows WSL version 2. The linker is GNU ld version 2.38.

Related

Riscv32-unknown-elf Linker Error after reading linker script : undefined reference to '_end'

I'm trying to compile and link a custom made c code to risc v project but I'm getting these error in the making:
I'm new to this field so please excuse any mistakes.
/local/home/opt/riscv/lib/gcc/riscv32-unknown-elf/9.2.0/../../../../riscv32-unknown-elf/bin/ld:
/local/home/opt/riscv/lib/gcc/riscv32-unknown-elf/9.2.0/../../../../riscv32-unknown-elf/lib/crt0.o:
in function `_start':
(.text+0x0): undefined reference to `__global_pointer$'
/local/home/s2500108/riscv/lib/gcc/riscv32-unknown-elf/9.2.0/../../../../riscv32-unknown-elf/bin/ld: (.text+0x8): undefined reference to `_edata'
/local/home/s2500108/riscv/lib/gcc/riscv32-unknown-elf/9.2.0/../../../../riscv32-unknown-elf/bin/ld: (.text+0x10): undefined reference to `_end'
collect2: error: ld returned 1 exit status
I also wanted to ask this:
After executing ./configure --prefix=/local/home/s2500108/riscv --with-abi=ilp32 --with-arch=rv32i
+ make
and trying to compile a multiplication instruction in c code examle a=21, b=10; a * b the compiler does not output any error and produces elf files normally. Why is this happening? I want to make sure that no multiplication will take place.

language binding error with Fortran: why won't it link to MPI library?

I'm trying to create language bindings for a message passing interface but the compiler can't recognize my reference to the C functions...
I'm currently using gfortran as my compiler on a linux machine... I know the language bindings work, but whenever I try to link them to the mpi library, I get this error:
/tmp/ccwukrNT.o: In function `MAIN__':
hello_init.f90:(.text+0x17): undefined reference to `mpi_init'
collect2: error: ld returned 1 exit status
the commands to compile I am currently using are:
gfortran -ffree-form foo.f90 ~/dir1/dir2/bar.f90 -o <outfile> -L
/home/.fakeroot/lib -I /home/.fakeroot/include/ -lexampi
(exampi is the standard I am currently working on)
As I said, when I use simple hello_world programs and compile all my files manually, this method works, but it fails when I try and link it to a library. Can anyone help me?
here is my current Fortran binding for MPI_Init:
module mpi_f08
interface MPI_Init
subroutine MPI_Init(ierror) bind(C)
integer, optional, intent(out) :: ierror
end subroutine MPI_Init
end interface MPI_Init
end module mpi_f08
The C function I am using is trivial... it's merely interfacing with PMPI_Init()... In any event, the library linking is the main problem... Yes, I have externalized it from C++.
Here is the simple test program I wrote:
program hello_init
use mpi_f08, only : MPI_Init
implicit none
integer :: ierror
ierror = 0
call MPI_Init(ierror)
stop
end program hello_init
I am not too familiar with Fortran... this was given to me as a side project but it's quickly taking up my whole week simultaneously laughs and cries
Thanks!

Getting undeclared function and undefined symbol errors with rand_r when compiling a multithread C program on Windows

I am creating many threads and each one should output a random number.
I know that srand() with rand is not thread-safe and indeed all the output numbers are the same.
So I tried to use rand_r but I get the following error on my Windows terminal
main.c:47:16: warning: implicit declaration of function 'rand_r'; did you mean 'rand'? [-Wimplicit-function-declaration]
result= ( (rand_r(&seed) % (high+1-low) ) + low);
^~~~~~
rand
main.c: In function 'customerServe':
main.c:333:1: warning: control reaches end of non-void function [-Wreturn-type]
}
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe:
C:\Users\allys\AppData\Local\Temp\ccSslADA.o:main.c:(.text+0xe): undefined
reference to `rand_r'
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe:
C:\Users\allys\AppData\Local\Temp\ccSslADA.o:main.c:(.text+0x41c):
undefined reference to `rand_r'
collect2.exe: error: ld returned 1 exit status
Thank you
I saw from the post tags that you are using the "pthreads" library which stands for POSIX threads. Therefore this project cannot be run on Windows since it does not support the "lpthread" flag on your system.
If you insist on working on a Windows machine, you could use something like this which lets the developer work on an Ubuntu terminal from windows. While having access to an Ubuntu-like system where the lpthreads library is supported, you can move on with your project. Another possible solution could be using docker to compile & run your project on an isolated ubuntu environment but this is kind of an overkill.
Let me know if this helped!
I needed to specify a late enough Posix source to avoid this warning, e.g.:
gcc -Wall -std=c11 -D_POSIX_C_SOURCE=199506L pi.c -o pi -lm -lpthread

Struggling compiling a simple c program (gcc)

I have a very old C program and want to compile to Windows. So I try doing this:
gcc -DNO_GLIBC=1 sakide.c -o sakide.exe
and this returns:
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0xa4): undefined reference to `ekiGetLibVersion'
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0x6b6): undefined reference to `ekiGetLibVersion'
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0x8ff): undefined reference to `ekiEncodeUrl'
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0x954): undefined reference to `ekiDecodeUrl'
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0x993): undefined reference to `ekiDecodeUrl'
\AppData\Local\Temp\ccx7khiy.o:sakide.c:(.text+0xa62): undefined reference to `ekiGetKeyInfo'
collect2.exe: error: ld returned 1 exit status
This ekiGetLibVersion is in a .h file:
INT EKIAPI ekiGetLibVersion(char *outBuffer, LPINT outBufferSize);
and I also have a .dll name of it.
Ive never compiled anything with C though
On windows you cannot link against directly with the .dll, you have to link the import library, name .lib. For more information, refer:
On dynamic linking:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682592(v=vs.85).aspx
On implicit linking:
https://msdn.microsoft.com/en-us/library/d14wsce5.aspx
You are getting linker errors.
You need to link the library (or object file) where those functions are defined.
Undefined reference usually means the compiler has not seen a proper declaration for this variable. Did you include the header file (which defines this variable) in your C program ?
#include "header_file.h"

make error using GNU/GCC quad precision library

When using Cygwin and GCC under Win 7 and the quad precision library:
gcc -c lquad.c
... this runs OK, but
gcc lquad.o
... produces the following error:
/tmp/ccLM2lOn.o:lquad.c:(.text+0xdb3): undefined reference to `sqrtq'
collect2: error: ld returned 1 exit status
I have #include quadmath.h in a C source, and the __float128 type works, but not the functions (e.g. sqrtq above). This header file has all the relevant externs, e.g.:
extern __float128 sqrtq (__float128) __quadmath_throw;
I found a dll cygquadmath-0.dll which definitely has these functions in it. It is in 3 places in the Cygwin installation. Additionally, I copied it to Windows\System, but that did not help.
There is a related question here, but nothing helped me there and it is not exactly the same error: Quadruple Precision in C++ (GCC)
You are looking for a compiler solution when what you need is a linker solution:
Your code is compiling as it should, so no change in the code would solve your problem:
/tmp/ccLM2lOn.o:lquad.c:(.text+0xdb3): undefined reference to `sqrtq'
collect2: error: ld returned 1 exit status
The undefined reference to errors indicate a function needed by your object is in another library.
As suggested by #Marc Glisse, try adding -lquadmath to your linker line.

Resources