I have modules compiled on their own and then linked in an executible to form a program. I am calling symbols from the cgns library, but some of them throw an undefined reference error, even though the symbol exists in the library.
This code seems to compile fine in older gcc ~4 to 8 versions, but not my current version 13. I am also using the mpif90 compiler from mpich.
So I recreated the problem with a dummy code. Here is my setup with a dummy code that recreates the issue exactly:
- Fedora 39
- GCC 13 via
dnf install gcc gfortran - MPICH 4.1 via
dnf install mpich-devel - CGNS 4.4 via
dnf install cgnslib-mpich-devel - HDF5 1.12.1 via
dnf install hdf5-mpich-devel(not sure if relevant here)
The reference in question is cg_nbases_f, so doing
me@pc:dir$ objdump -T $MPI_LIB/libcgns.so | grep cg_nbases_t
00000000000a44b0 g DF .text 0000000000000055 Base cg_nbases_f
The dummy code consists of two files, a module cgnsreading.f90 and a program cgnsread.f90
cgnsreading.f90:
module cgnsreading
implicit none
private
public talk_to_cgns
contains
subroutine error_check()
print *, 'hi I am the bane of arthropods'
end subroutine error_check
subroutine talk_To_cgns()
character(100) :: errmsg
integer :: i = 1
integer :: nbases = 1
integer :: ierr
call cg_get_error_f(errmsg)
print *, errmsg ! Should print that there is no error
call error_check() ! Should print its guts
call cg_nbases_f(i,nbases,ierr) ! Throws undefined reference error
end subroutine talk_To_cgns
end module cgnsreading
cgnsread.f90:
program cgnsread
use cgnsreading
implicit none
call talk_to_cgns()
end program cgnsread
Compiling it and linking in the following way produces the error:
me@pc:dir$ mpif90 cgnsreading.f90 -c
me@pc:dir$ mpif90 cgnsread.f90 -c
me@pc:dir$ mpif90 cgnsreading.o cgnsread.o -lcgns -o cgnsread
/usr/bin/ld: cgnsreading.o: in function `__cgnsreading_MOD_talk_to_cgns':
cgnsreading.f90:(.text+0x95): undefined reference to `cg_nbases_f_'
collect2: error: ld returned 1 exit status
My thought was that there were either some issues related to the module having private subroutines, but that is ruled out because the error occures by calling the public subroutine.
I was also suspecting that it's due to the compiler ignoring the linking flag (flags order), but when that happens, cg_get_error_f throws the same error. Hence, why I tested that as well.
I expected that the references would only be available in the devel versions of the cgns library, but that doesn't seem to be the case because I am using the devel version.
There was a suspicion that a different library was installed somewhere else, and indeed there is, but it also contains the missing reference.
I do not know if this is a specific problem to cgns or its installation, but I haven't tested this with something else.
Why would a library provide a symbol but not the other, even though both exist in the same library.
The same error occures on another pc with the same setup as mentioned above. So the problem can be replicated.
Check the symbol names defined in the library:
The symbol that we are looking for is there, but the
mpif90compiler has appended an underscore to the name. In principle this is to prevent clashes between Fortran and C names.Update
cgnsreading.f90and adduse cgns:When you compile that you'll need to specify the include path for
cgns.mod, which should be located at/usr/include/cgns.mod.I don't have a Fedora 39 system but I can replicate with Docker. Follow these steps to get it set up.