# Distribute shared libraries or not?

**URL:** <https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532>\
**Category:** Help\
**Created:** [March 4, 2024, 11:44am UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532 "2024-03-04T11:44:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 11:44am UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/1 "2024-03-04T11:44:44Z")

</div>

Hello everybody,

Very often, I need to write Python wrappers for my Fortran libraries where I create a shared library of my Fortran code and plug it into Python through its C API. The shared library will have, at least, dependencies on libgfortran and libquadmath.

I was wondering what do you think is the best strategy: embed all the gfortran dependencies or ask the user to install gfortran through homebrew for MacOS and msys2 for windows. On linux, the situation is much easier where most of the time libgfortran is installed by default.

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [March 4, 2024, 12:39pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/2 "2024-03-04T12:39:08Z")

</div>

Good question. IMO, asking the user to install gfortran, while doable, makes the distribution process unnecessarily complex. Another drawback, is that each package will be quite heavy because of the dependencies.  
There is the same issue with intel fortran, since you need to distribute libifcoremd, libifportmd, libmmd… And if you are on Windows you need to make sure the end user has compatible C++ redistribuables (vcruntime).  
I am not too familiar with Python package management as I usually rather work with nuget packages. What I would do in this case is create one package that contains the redistribuable libraries (and no other code), and a second package with my library that simply reference the first one. By doing so, you can also control the version that is used to run your lib.

---

<div class="post-metadata">

**Author:** ![jeff](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jeff/32/7201_2.png) [@jeff](https://fortran-lang.discourse.group/u/jeff)\
**Post date:** [March 4, 2024, 12:42pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/3 "2024-03-04T12:42:01Z")

</div>

I have always included the GNU Fortran dependencies when distributing Windows libraries or executables that need them. Speaking from experience, Windows users, including developers, will not tolerate having to install msys2.

You’ll probably have much better luck suggesting installing Homebrew on macOS. Distributing a shared library for macOS is tricky, though. Won’t it need to be signed and notarized?

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 12:42pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/4 "2024-03-04T12:42:08Z")

</div>

I haven’t thought of this approach to create a dedicated package for the redistribuable libraries. Thanks 🙂

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 12:46pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/5 "2024-03-04T12:46:32Z")

</div>

I also thought that asking the Windows user to install msys2 might be cumbersome. I am not familiar with the macOS ecosystem and I don’t know if it needs to be signed or notarized ☹

After looking at this [discussion](https://fortran-lang.discourse.group/t/distributing-fortran-projects-for-windows-macos/760), it seems that for macOS homebrew is the way to go.

---

<div class="post-metadata">

**Author:** ![feenberg](https://avatars.discourse-cdn.com/v4/letter/f/c2a13f/32.png) [@feenberg](https://fortran-lang.discourse.group/u/feenberg)\
**Post date:** [March 4, 2024, 1:25pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/6 "2024-03-04T13:25:00Z")

</div>

I distribute an OSX binary created from gfortran and have had no user complaints. It seems that with recent versions of OSX there is a popup that warns the user that the binary might be dangerous, but apparently users are used to that and click through it. I add the options  
` -static-libgfortran -static-libgcc`  
to the compile as few users will have those libraries and even fewer will know how to install them. If you have read that OSX doesn’t support static executables, I would characterize that statement as “just close enough to the truth to be misleading”. You can’t include the OSX libraries that are present in every installation of OSX, but you can include any other libraries your program needs.

I’d love to create the executable with a github action, but so far haven’t gotten that to work. If anyone has a suggestion…

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 3:13pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/7 "2024-03-04T15:13:37Z")

</div>

Currently, this is what I am doing. I use the static linking for macOS and Windows to avoid dependencies on libgfortran and libquadmath. On Linux (centos and Debian) the static linking is not possible. I was just wondering what would be the best way in the case I cannot use the static linking.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [March 4, 2024, 3:50pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/8 "2024-03-04T15:50:02Z")

</div>

> [@mskocic](#):
>
> On Linux (centos and Debian) the static linking is not possible.

What do you mean exactly?

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 4:20pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/9 "2024-03-04T16:20:55Z")

</div>

On Centos 7 and Debian 12, I have tried the static linking for libgfortran and libquadmath and I got an error from the linker saying that the static versions of the libraries (libgfortran\*.a and libquadmath\*.a) are not available.  
After some googling, I found that in fact many distributions do not provide the static versions of libgfortran and libquadmath.

I might have missed something but I did not succeed in statically linking on Linux.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [March 4, 2024, 4:24pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/10 "2024-03-04T16:24:32Z")

</div>

> [@mskocic](#):
>
> After some googling, I found that in fact many distributions do not provide the static versions of libgfortran and libquadmath.

OK, in Ubuntu 23.10 I have the `.a` and `.so` of libgfortran, but indeed the libquadmath is available only in `.so`.

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 4:45pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/11 "2024-03-04T16:45:16Z")

</div>

This might be a solution for Windows users [Quick Installer for Windows](https://fortran-lang.discourse.group/t/quickstart-fortran-installer-for-windows/2270) for quickly installing and setting the gfortran compiler as well as all necessary libraries.

---

<div class="post-metadata">

**Author:** ![jacobwilliams](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jacobwilliams/32/10_2.png) [@jacobwilliams](https://fortran-lang.discourse.group/u/jacobwilliams)\
**Post date:** [March 4, 2024, 5:03pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/12 "2024-03-04T17:03:52Z")

</div>

Making your library into a `conda` package is another solution to this problem. It does mean your users have to install `conda` and perhaps be required to understand conda environments (although there are ways to build a stand-alone installer for a conda package that somewhat hides that). The gfortran and [intel runtime dependencies](https://anaconda.org/intel/repo) are available there, as well as many other dependencies in the scientific ecosystem. Also, it’s cross-platform.

---

<div class="post-metadata">

**Author:** ![mskocic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mskocic/32/3378_2.png) [@mskocic](https://fortran-lang.discourse.group/u/mskocic)\
**Post date:** [March 4, 2024, 6:52pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/13 "2024-03-04T18:52:46Z")

</div>

I’ll take a look at packaging for conda even though I am not very familiar with the conda eco-system. Thanks! 🙂

---

<div class="post-metadata">

**Author:** ![shahmoradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahmoradi/32/3151_2.png) [@shahmoradi](https://fortran-lang.discourse.group/u/shahmoradi)\
**Post date:** [March 5, 2024, 2:46am UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/14 "2024-03-05T02:46:16Z")

</div>

> [@feenberg](#):
>
> -static-libgfortran -static-libgcc

Static linking with gfortran libraries requires static versions of the libraries, which GCC does not distribute by default. There is no way but to rebuild gfortran from the source for static libraries. I raised this issue to GCC developers several years ago and there was little interest in providing the static versions of the libraries by default.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [March 5, 2024, 7:43am UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/15 "2024-03-05T07:43:51Z")

</div>

There is the long standing discussion in the Linux community about static vs dynamic libraries. When I started with Linux 20 years ago, I learned to only use dynamic libraries for everything, as most distributions still recommend today. But I changed my mind, I think static libraries are better in almost every case (the final executable is smaller, faster, no dependencies, etc.). Only with some foundational system libraries like libc it makes sense to use shared libraries in my opinion. Another is a Python extension module.

Compilers should always allow static linking if requested.

---

<div class="post-metadata">

**Author:** ![feenberg](https://avatars.discourse-cdn.com/v4/letter/f/c2a13f/32.png) [@feenberg](https://fortran-lang.discourse.group/u/feenberg)\
**Post date:** [March 5, 2024, 12:25pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/16 "2024-03-05T12:25:41Z")

</div>

> > [@feenberg](#):
> >
> > -static-libgfortran -static-libgcc
> 
> Static linking with gfortran libraries requires static versions of the  
> libraries, which GCC does not distribute by default. There is no way but  
> to rebuild gfortran from the source for static libraries. I raised this  
> issue to GCC developers several years ago and there was little interest  
> in providing the static versions of the libraries by default.

Indeed there is widespread and unjustified hostility to static linking  
that I have never understood, however your comment may be unnecessarily  
discouraging to potential users. Over the years I have installed gfortran  
on Windows, FreeBSD, NetBSD and OSX from package sources and the -static  
option has worked in all of them without further action. So gfortran  
packagers seem to understand the utility of static linking and make  
provision for it.

Daniel Feenberg

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [March 5, 2024, 2:17pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/17 "2024-03-05T14:17:07Z")

</div>

Personally, I have always favored static libs over dynamic ones. This goes back 20 or so years now when I was running primarily on Cray XT systems that only supported static linking for applications running on the backend. The micro-kernel based OS used on the backend didn’t support dynamic libs. A Cray support engineer told me that the reason Cray didn’t support dynamic libs was that they needed to be read at the start of each process in a run from hard disks that were usually mounted on slow NFS systems. For an application that might use thousands of processes, this lead to the possibility that the disk access requests to roll in the dynamic libs might swamp the system. This has been fixed for the most part over the years placing the libs on a parallel file system instead of NFS. The big issue with static libs is some linkers have a hard time finding all the entry points with just one reference to the lib in a link statement. ie. you have to sometimes do stupid tricks like

gfortran -o a.x main.f90 lib1.a lib2.a lib1.a lib3.a

etc.

Cray now allows you to link in dynamic libs because as mentioned some system libs and other components (MPI etc) don’t ship with a static lib by default anymore.

---

<div class="post-metadata">

**Author:** ![MarDie](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mardie/32/54_2.png) [@MarDie](https://fortran-lang.discourse.group/u/MarDie)\
**Post date:** [March 5, 2024, 5:08pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/18 "2024-03-05T17:08:13Z")

</div>

The big advantage of dynamic/shares libraries is the possibility to centrally deploy (security) fixes. With static libraries, each dependent software needs to be rebuilt with the fixed libraries. One example where something similar to static linking went terribly wrong was the log4j security issue in Java.

The downside of shared linking are incompatibilities caused by breaking changes in the libraries. Theoretically, semantic versioning can solve that but practically it still causes problems.

Linux distributions “solve” the issues related to shared libraries by sticking to exactly one veraion of the library. Hence, each package has to be compiled especially for the target version of the OS and security fixes are often backported because real updates will break things.

Conda shows that dynamic linking and support for various library versions is possible

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [March 5, 2024, 5:31pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/19 "2024-03-05T17:31:14Z")

</div>

> [@rwmsu](#):
>
> gfortran -o a.x main.f90 lib1.a lib2.a lib1.a lib3.a

I have some codes where it is necessary to add a library multiple times with linux, but it is not necessary with MacOS. I assume this is a difference in the ld utility. Is there an ld option that can be used to eliminate this under linux, and to make the linux ld work the way it does on MacOS?

The only other fix seems to be to combine some of the libraries, which introduces some additional build problems. I would like to end up with similar (or identical) compile and load statements on the two OSs.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [March 5, 2024, 6:08pm UTC](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532/20 "2024-03-05T18:08:43Z")

</div>

> [@RonShepard](#):
>
> I have some codes where it is necessary to add a library multiple times with linux, but it is not necessary with MacOS. I assume this is a difference in the ld utility. Is there an ld option that can be used to eliminate this under linux

I recently read that interesting blog article: [Library order in static linking - Eli Bendersky's website](https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking)

Maybe the following options are what you need?

> For example, circular dependency problems can be easily resolved with --start-group and --end-group.

[Next page](https://fortran-lang.discourse.group/t/distribute-shared-libraries-or-not/7532.md?page=2)
