OpenKIM seeks help to address KIM API incompatibility on Apple macOS

30-Apr-2018

Due to a bug in gfortran, it is not possible to install the KIM API on Apple macOS. We describe a workaround in the KIM API installation documentation, but this only works for 32 bits. We would like to find a more general solution that will work for both 32 bit and 64 bit architectures and allow the KIM API to be installed via Homebrew. If you are interested in helping, please read the details below and get in touch with us. We could use the help!

The underlying technology for macOS is known as the Darwin operating system. This system uses the LLVM compiler infrastructure and clang (C and C++) compiler front ends to LLVM as the official development tools for macOS.

The KIM API requires a Fortran compiler, but unfortunately clang does not contain one. Luckily, the GCC (gcc, g++, gfortran, etc.) compiler suite can be used as front-end compilers with LLVM. The Homebrew package management system for macOS makes it easy to get GCC compilers and a host of other software installed on your macOS system. Currently, essentially all Homebrew packages are installed as pre-compiled binaries ("bottles"). The OpenKIM project would like to make the KIM API and OpenKIM Models available as precompiled binaries on macOS through the Homebrew system.

However, there is a problem. The gfortran compiler front-end has an incompatibility with the LLVM ld linker that shows up when building shared libraries from Fortran code that is interoperable with C code. This means that the KIM API and OpenKIM Models cannot be successfully built on macOS using the GCC suite. (We have a work-around, but it forces us to compile for a 32 bit architecture, which is not a viable long-term solution.) This problem is known to exist for multiple versions of gfortran and multiple versions of macOS. See below for example code and compilation instructions that manifest the problem.

We have reported (in 2014: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59888) the issue to the gfortran development community, but a solution does not seem to be forthcoming. In considering all the options, we have decided that the best solution (that we have a reasonable chance of making work ourselves) is to find a way to edit the assembly code and/or the object (.o) files generated by gfortran to make them work with the LLVM ld linker. On macOS .o files are stored in "Mach-O" format. So, this would probably involve finding, or creating, an appropriate Mach-O file editor and figuring out how to appropriately edit the object files for the KIM API and OpenKIM Models to make them work correctly with the LLVM ld linker.

We are looking for someone who has (or is willing to develop) the expertise necessary in this area to help us create such a solution. If you are interested, know someone who might be interested, or have any ideas for how to go about creating a solution to this problem, we would like to hear from you. Please send a message to api@openkim.org with your thoughts.

Below is a minimal example that generates the issue and some sample output from the compiler and linker showing the problem.


foo.f90:

module foo
contains
  subroutine bar
    use, intrinsic :: iso_c_binding
    call gee(c_funloc(gee))
  end subroutine
  subroutine gee(f) bind(c)
    use, intrinsic :: iso_c_binding
    type(c_funptr) :: f
  end subroutine
end module foo

$ gfortran --version
GNU Fortran (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-305
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
LTO support using: LLVM version 9.0.0, (clang-900.0.39.2) (static support for 21, runtime is 21)
TAPI support using: Apple TAPI version 900.0.15 (tapi-900.0.15)
$ gfortran -c foo.f90
$ gfortran -shared foo.o
ld: illegal text-relocation to '_gee' in foo.o from 'lC0' in foo.o for architecture x86_64
collect2: error: ld returned 1 exit status