Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building an executable shared library with ifort

There are several excellent discussions on SO already covering how to produce an executable shared library on Linux:

  • See https://unix.stackexchange.com/questions/7066
  • and building a .so that is also an executable as examples

In C/C++, this seems relatively straightforward; essentially there are two parts:

  1. Add an .interp section to the ELF (as ld doesn't include one for shared libraries) by including something along these lines in the library source:
    const char interp_section[] __attribute__((section(".interp"))) = "/path/to/dynamic/linker";
  2. Set an appropriate entry point when linking, using -Wl,-e,entry_point

Does anyone know how to achieve this with a library written in Fortran? Specifically, how to add a .interp section to a shared library compiled with ifort?

like image 706
Ingo Avatar asked Aug 25 '21 03:08

Ingo


1 Answers

With help of a C compiler to create an additional object file to be linked to the dynamic library, such a Fortran90 executable and dynamic link library can be created:

/* stub.c: compile e.g. with gcc -c stub.c
const char dl_loader[] __attribute__((section(".interp"))) =
    "/lib64/ld-linux-x86-64.so.2";
    /* adjust string if path or architecture is different */
! testif.f90: compile e.g. with ifort -c -fPIC testif.f90

subroutine execentry
    write(*,*) 'Written from executable.'
    ! without call to exit seems to lead to segmentation fault
    call exit(0)
end subroutine

subroutine libroutine
    write(*,*) 'Written by libroutine.'
end subroutine
! linktest.f90: compile e.g. with ifort -c linktest.f90
! main Fortran program for testing

program linktest

call libroutine

end

For compilation and linking:

gcc -c stub.c
ifort -c -fPIC testif.f90
ifort -c linktest.f90
ifort -shared -o libtestif.so testif.o stub.o -Wl,-e,execentry_
ifort -o linktest linktest.o -L. -ltestif

Executing the dynamic link library directly ./libtestif.so will call execentry, and running the link test program

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./linktest

will call libroutine.

The C code is only needed to create the .interp section. The underscore in the ld flag -Wl,-e,execentry_ is added according to the symbol name mangling for Intel ifort (or GNU gfortran) vs. GNU or Intel C compilers.

like image 137
v-joe Avatar answered Sep 21 '22 13:09

v-joe