Statically linking a fortran mpi parallel program - fortran

I'm trying to statically link the Nasa Parallel Benchmarks (NPB). My goal is to avoid installing the fortran compiler (mpif77) on the cluster nodes.
I don't see any static linking options in the mpif77 documentation.

OpenMPI can be built as a static library. Try linking with -static. See https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gfortran/Option-Summary.html#Option-Summary for more options.
See http://www.open-mpi.org/faq/?category=building#static-build if the static library is not built and contact your tech support or do it yourself if you are an admin.

Related

How to package c++ dependencies on linux

I'm developing a c++ program on Ubuntu 16.04 using cmake, compiling with g++5 and clang++-3.8.
Now I'd like to make this Program availabile for 14.04, too, but as I'm using a lot of c++14 features I can't just recompile it on that system. Instead, I wanted to ask if/how it is possible to package all dependencies (in particular the c++ standard library) in a way that I can just unpack a folder on the target system and run the app.
Ideally I'm looking for some automated/scripted solution that I can add to my cmake build.
Bonus Question:
For now, this is just a simple command line program for which I can easily recompile all 3rd party dependencies (and in fact I do). In the long run however, I'd also like to port a QT application. Ideally the solution would also work for that scenario.
The worst part of your contitions is an incompatible standard library.
You have to link it statically anyway (see comments to your answer).
A number of options:
Completely static linking:
I think it's easiest way for you, but it requires that you can build (or get by any way) all third-party libs as static. If you can't for some reason it's not your option.
You just build your app as usual and then link it with all libs you need statically (see documentation for your compiler). Thus you get completely dependencies-free executable, it will work on any ABI-compatible system (you may need to check if x86 executable works on x86_64).
Partially static linking
You link statically everything you can and dynamically other. So you distribute all dynamic libs (*.so) along with you app (in path/to/app/lib or path/to/app/ folder), so you don't depend on system libraries. Create your deb package which brings all files into /opt or $HOME/appname folder. You have to load all dynamic libs either "by hand" or ask compiler to do it on linking stage (see documentation).
Docker container
I don't know much about it but I know exactly it requires that docker be installed on target system (not your option).
Useful links:
g++ link options
static linking manual
Finding Dynamic or Shared Libraries
There are similar docs for clang, google it.

Can a statically linked application also link to some dynamic libraries?

I'm building an application using Qt 5.8 and setting up for static builds (since this seems to be the best way to get OpenSSL working when deploying the application to other computers). However, we also have a dependency on WebEngine which cannot be built statically.
Is it possible to build the application using a statically built Qt5.8 but still dynamically link the WebEngine libraries when compiling?
I can get the application working with a fully dynamic build - so will it simply dynamically link any libraries that weren't built into the static compiler? Obviously, I will still need to provide the dynamic library with the executable when deploying.
Yes you can. Almost all build systems used in Qt (qmake, cmake, qbs) provide easy options for linking both static and dynamic libraries.
What build system are you using?
Yes, you can do it. I had to build Net-SNMP which gave me a ./configure file in which I mentioned the shared and static library, wherein the system libraries were dynamically linked and OpenSSL was statically linked.
You can go through ./configure file post downloading Net-SNMP and go through the file which does the same task and tweak the values according to your usage and environment.
Additionally, go through link 1 and link 2 which will give you a brief idea about how to create a shared and dynamic library.

Statically linking boost program_options

One of the few Boost libraries that are not header only (therefore need to be compiled separately) is program_options.
I need to run a program that I compile on my PC in a cluster that has no Boost installed.
I don't have administrative rights to install Boost and contacting the cluster's admin is too burocractic and slow.
How can I compile my program in my PC (which has Boost) such that it includes program_options (I think this is called static linking)?
Now, I plan to run several instances of my program. Is static linking the best approach? Every instance of my program will load a separate instance of program_options, which is wasteful. Is there a better alternative? Some sort of "local dynamic linking" that I can setup on the cluster without root access?
You can compile and install Boost, or just Boost Options, as a local user. Then compile your program against this local version. Finally, run your code with an updated LD_LIBRARY_PATH environment variable that includes where the Boost Options library lives.

Why does intel compiler produce output that requires libiomp5mt.dll, even though I ask for static linking?

I'm compiling an openmp project with the /MT switch (or equivalently in visual studio settings, "C++: Code Generation: Runtime Library: Multi Threaded".
Visual Studio still, however, reports that my output requires libiomp5mt.dll (multi threading dll) when I thought the above setting was asking for static linking.
Is there another option somewhere I missed?
Alternatively, if the dll is a requirement, I presume I'm allowed to redistribute Intel's dll alongside my own application?
The Intel website says:
You are strongly encouraged to dynamically link in the compatibility OpenMP* run-time library libiomp (i.e libiomp5md.lib and libiomp5md.dll , located in the [Compiler Dir]\lib directory), even if other libraries are linked statically. Linking to static OpenMP* run-time library (i.e libiomp5mt.lib) is not recommended. Because multiple OpenMP libraries in one appliation causes performance problems (too many threads) and may cause correctness problems if more than one copy is initialized.
So although you can configure OpenMP to link statically, and this configuration is independent of the C runtime, you are recommended not to.
Intel's OpenMP licence allows for royalty free redistribution as far as I can tell. You should check the licence that came with your OpenMP just to be on the safe side.
The above switch is for C++ runtime only, OpenMP is an external library which is not a part of the C++ runtime. Hence the switch doesn't have any effect on it.
As per the redistribution of the DLL, look at the license of the product the DLL was shipped with. You're probably allowed to redistribute it.
There are two ways of creating code libraries. As static Libs and as Dlls (Extentsions: *.lib and * dll).
If there is only a Dll available, you can only link to it dynamically, not statically. What may be confusing you is that a Dll usually has a lib file you link to which has all the entry points into the Dll.

How and when is static linking performed (MinGW)?

I had a lot of pain linking a C++ application to another C++ library with Fortran90 dependencies (MinGW, TDM g++ and gfortran). I either have to use gfortran for linking or the application crashes on startup (in global constructors keyed to __cxa_get_globals_fast). However this is not acceptable, I would like to use g++ for linking (Qt GUI).
It seems to me that the dependencies of the libraries cannot be linked statically with gcc, linking is only performed when main() is available. Why?
I guess partly because code for certain initializations have to be inserted before main().
Why is it that the statically linked application needs DLL-s, such as mingwm10.dll or pthreadGCE2.dll at runtime? Why can't these be statically linked?
UPDATE: I just found these websites:
http://www.deer-run.com/~hal/sol-static.txt
http://www.iecc.com/linker/
The main difference between linking with gfortran and using ld/gcc/g++ to link is that gfortran links the standard fortran libraries by default, whereas with another linker you will need to manually specify the libraries to link. I wasn't able to find them with a quick search, but it should be along the lines of -lgfortran.
Also, gfortran has some specific instructions for initialisation routines that need to be called for certain fortran intrinsics to work if your main program is not written in fortran. If you haven't called these routines then this might cause a crash.
Why is it that the statically linked application needs DLL-s, such as mingwm10.dll or pthreadGCE2.dll at runtime? Why can't these be statically linked?
They can, but static library versions are not provided due to the fundamental advantage of dynamic libraries: bugs can be fixed without rebuilding the executables.