[fpm] can fpm be used to build a dynamic link library?

Hi, I was just wondering if fpm could be used to build a dll/so as a library output? I have seen how to generate a static lib but haven’t seen in the manuals any info regarding dynamic libs.

Today I manage to do it with CMake. Would like to see if fpm could help doing it in a more “clean” manner?

1 Like

Last time I checked (which was a while back) it couldn’t. Probably a worthwhile feature to add if not present.

Note there should already be a GitHub issue for this.

You are right: Producing shared libraries · Issue #681 · fortran-lang/fpm · GitHub the issue is still open.

Not that fpm shouldn’t at some point be able to do it for you, but would this work for your needs?

I did it by hand with a simple file and it works, I also saw here how to do it with ifort https://community.intel.com/t5/Intel-Fortran-Compiler/Creating-dll-from-fortran-file/m-p/1182026 from a single source file. I guess that is more or less what CMake is currently doing for me? the goal was to see if it could be easily doable within a fpm build. Just out of curiosity :slight_smile:

I would like to share a very simple Makefile if you need to create a shared library from the static one generated by fpm.
fpm is used to build the static library and the latter is copied to the root of the build folder. Then it is used to create the shared library with gfortran according to the defined PLATFORM. You can add additional target according to your needs.

LIBNAME=mylib
PLATFORM=linux
BUILD_DIR=./build

all: $(LIBNAME)

$(LIBNAME): build copy_static shared copy_shared

build:
	fpm build --profile=release

copy_static:
	cp $(shell find ./build -type f -name lib$(LIBNAME).a) $(BUILD_DIR)

shared: shared_$(PLATFORM)

shared_linux:
	gfortran -shared -o $(BUILD_DIR)/lib$(LIBNAME).so -Wl,--whole-archive $(BUILD_DIR)/lib$(LIBNAME).a -Wl,--no-whole-archive

shared_darwin: 
	gfortran -dynamiclib -install_name @rpath/lib$(LIBNAME).dylib -static-libgfortran -static-libquadmath -static-libgcc -o $(BUILD_DIR)/lib$(LIBNAME).dylib -Wl,-all_load $(BUILD_DIR)/lib$(LIBNAME).a -Wl,-noall_load

shared_windows: 
	gfortran -shared -static -o $(BUILD_DIR)/lib$(LIBNAME).dll -Wl,--out-implib=$(BUILD_DIR)/lib$(LIBNAME).dll.a,--export-all-symbols,--enable-auto-import,--whole-archive $(BUILD_DIR)/lib$(LIBNAME).a -Wl,--no-whole-archive
7 Likes

Welcome @mskocic and thanks for the Makefile :+1: I haven’t check the inners of how fpm does its magic but would be interesting if something like this could be added :thinking:

1 Like

I didn’t look in details at the fpm internals but I assume it might be challenging to deal with rpath according to the platforms and the whole set of options for the different available compilers. Windows is, in my point of view, always a special case where there is a ton of specific options ( :woozy_face:).

You can also remove the static options for windows and Darwin but you will have to provide the dependencies i.e at least libgfortran libquadmath and for MSYS2 libwinpthread and libgcc_s_seh.

Or the user installs gcc with brew on macOS or with MSYS2 on windows.

Thank you! Very useful.

I got inspired and created a test repository that has a couple of dependencies and it uses the same kind of Makefile idea that you have posted. The repository has 3 dependencies as (blas, lapack and linpack). Note that those dependencies are in the subfolders of this package (so it is selfcontained). a zvode test program is ran in the end. Here is the repository GitHub - ettaka/fpm-dependencies: Test project for fpm with dependencies. Note that I had to add the static library dependencies (libblas.a, liblapack.a and liblinpack.a between the -Wl,--whole-archive and -Wl,--no-whole-archive flags too (in addition to libfpm_dependencies.a). Otherwise, it compiles a shared library libfpm_dependencies.so but all those symbols in the other library dependencies will be missing.

I am wondering what people think about this way of orginizing the build with dependencies at the moment? What is the future plan in fpm for doing this and creating shared libraries?

Btw. I tried to use the toml file to define dependencies but fpm could not find the library if it were not in a subfolder of the project and when it did the build failed when there were too many dependencies (or files not sure what triggered the failure). I should try to reproduce that and report it more carefully.

1 Like

@henilp105 has been working on dynamic library support in fpm. Henil, can you please comment here on your prototype?

3 Likes

Hello @certik,

We’ve initiated the development of a prototype for the dynamic library in fpm. Currently, we’re exploring two potential approaches: integrating tables into the fpm.toml file or incorporating flags into the build process ([fpm] Discovery of installed fpm packages). Additionally, we’re refering to various system-specific flags and issues like RPATH and libfortran/libquadmath ,( as previously mentioned above) . @arteevraina, your insights on the implementation aspects would be great.

4 Likes

Hi, just wanted to check if there are any updates on this topic?

1 Like

@henilp105 thanks for the work. What is the status of the dynamic library building with fpm?

1 Like

Hi @hkvzjal,

The PR is currently under review at feat: init shared library support. by arteevraina · Pull Request #1050 · fortran-lang/fpm · GitHub. It would be great if you could assist with the review process to help expedite things. Your input would be much appreciated!

3 Likes

Being an advocate of static libraries I have not done this in a while, but as long as the object files are position-independent (if not the default, that usually means compiling with the -PIC option) at least on Unix and Linux (might have to add a pragma in the code on MSWindows?) you could expand a static library back to *.o files and build a shared library from them. There was even an option on the GNU commands (“-Wl, --whole_archive” I think) that would let you give the static library on the build command without taking it apart back to object files if I remember correctly.

Not at a place at the moment where I can check, but this was done as a prototype fpm add-on like fpm-man, fpm-time, fpm-gdb were. If that would be a useful work-around in the meantime I will resurrect that if that would be useful. It was just to create a demo plugin for fpm so if that is an ill-advised approach anyone can speak up but it was very simple and I used it pre-fpm successfully, but a long time ago. Personally, accept with a few things (MPI, X11 Windows, …) I eschew shared dynamic libraries so I might remember this wrong :> . With what I principally work with static is HIGHLY prefereable.

Great! I was not aware of this PR, I will take a look and try to help with it! Thanks @henilp105

2 Likes