Missing librefblas.a - fortran

Trying to compile some Fortran code using gfortran 9.x.x on my CentOS 7.xx machine. Have a particular version of the code that requires linking to LAPACK and BLAS (specifcially, liblapack.a, and librefblas.a). Have LAPACK (and all the -devel libs), and BLAS (same about -devel libs) installed (both available in the CentOS base repo).
While I (and therefore the linker) can find liblapack.a (its in /usr/lib64), no trace of librefblas.a (which causes the linker to complain bitterly, and the compilation to crash and burn).
In fact, I tried installing both BLAS and OpenBLAS on the same machine, but that didn't help -- librefblas.a still nowhere to be found.

The first thing to try is to use the regular libblas. Either change your Makefile to to use libblas instead of librefblas or make a symlink. Then check if you have any unresolved reference. Or do the same for OpenBLAS and point your makefile to libopenblas. Note that OpenBLAS also includes LAPACK.
Background: BLAS and LAPACK are publicly available interfaces. There is a reference implementation available, but also many alternative optimized or machine-specific ones. It should not matter which one you use so it seems unnecessary to specifically require the reference one. Normally, your Linux distribution libblas is the reference one anyway. It is probably just a quirk of your Makefile.

no trace of librefblas.a
The CentOS 7 lapack-3.4.2-8.el7 package build doesn't create or install the file librefblas.a .
I.e. no available package providing /usr/lib64/librefblas.a .
The package blas-static provides one file only : /usr/lib64/libblas.a
Build librefblas.a :
tar xvf lapack-3.4.2-clean.tgz
https://src.fedoraproject.org/repo/p....4.2-clean.tgz
cd lapack-3.4.2/
cp make.inc.example make.inc
make blaslib
... And librefblas.a will be created.

do this in the package folder:
sudo ln -s $HOME/lapack-3.9.0/librefblas.a /usr/local/lib/librefblas.a
solved

Related

Linking to GNU scientific library on cluster?

I am running a code (iHARM2D) which requires the GNU scientific library library (GSL) on a cluster. Since the GSL library is not installed on the cluster, I have to compile it there and properly link it during compilation of the actual code. In my shell script I write
cd whereGSLsource
./configure --prefix=/homefolder/iHARM/GSLcompiled
make && make install
This compiles the GSL and puts the results in /homefolder/iHARM/GSLcompiled/lib, /homefolder/iHARM/GSLcompiled/include etc.
According to this answer, I should be able to compile by writing the following lines into my shell script before compilation of my main code
export CPATH="/homefolder/iHARM/GSLcompiled/include":$CPATH
export LIBRARY_PATH="/homefolder/iHARM/GSLcompiled/lib":$LIBRARY_PATH
However, this does not seem to link GSL properly because the compilation returns errors of the type "undefined reference to `gsl_some_function'". (It works on my computer when default installation and linking of GSL is used.)
Another possibility suggested by the GSL output during compilation or this answer is to modify the LD_LIBRARY_PATH variable
LD_LIBRARY_PATH="/homefolder/iHARM/GSLcompiled/lib":$LD_LIBRARY_PATH
But this gives the same result. Similarly it does not when I try to link using the -L and -I option
cd iHARM
gcc -someoptions -I../GSLcompiled/include/ -L../GSLcompiled/lib ./some.o -o harm
Another option suggested by GSL was to use
gcc -someoptions -Wl,-rpath -Wl,"/homefolder/iHARM/GSLcompiled/lib" ./some.o -o harm
However, neither of these work.
How do I link the GSL properly then?
(I am not very experienced in this so this might also be some really basic mistake in the syntax or so.)
Run first configure --help; you'll find out that it accepts the --enable-static option which you do want to use.
BTW you could (and probably should) install Linux on your laptop and compile on it (then scp a mostly statically linked binary to your cluster).
You'll better share a common --prefix for all your autoconf-ed software. See this. Read the documentation of autoconf. Let's suppose you always use --prefix=$HOME/soft (which don't require any root permission).
You could compile with make then do a make install DESTDIR=/tmp/gslinst so that installed things go into /tmp/gslinst which you would inspect and latter copy appropriately to a directory related to your prefix.
You'll find both libgsl.a and libgslcblas.a. On my Debian system, the libgsl-dev package provides them (so I don't need to rebuild it).
Then you'll use these static libraries. You could provide a full path for them, that is use $HOME/soft/lib/libgsl.a explicitly in your linking gcc command for harm, e.g. link it with
gcc some.o $HOME/soft/lib/libgsl.a -o harm
but YMMV. Order of arguments to gcc matters a lot.
You don't need or want to mess with $LD_LIBRARY_PATH or -Wl,-rpath with static linking. Read about rpath when you want dynamic linking.
See also what pkg-config tells.

What is needed to use a newer version of GCC than the platform provides

I am looking at the potential to use a newer version of GCC (e.g. 5.2) than is provided by some of the platforms that I need to support (GCC 4.1) as I would like to at least have C++11 features, and maybe even some C++14 things. I just provide an executable program, not static or shared libraries that I expect users of the platform to be able to link with.
I was able to compile GCC 5.2 and Boost 1.59 (the only lib with a C++ API I am using currently) and get it working with the so's for those placed alongside the executable and adding $ORIGIN to RPATH on a test system which has 4.4.
But I am unclear on what else I need to do this fully and ensure everything is correct/safe. e.g. I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe? Is their a standard set of rules to tell?
Also wondering if I should statically link some things and again what the rules are? e.g. just using "-static" fails because it goes looking for a static pthread that I don't have on that system (and I assume other system-provided libraries). Ideally I want to keep the size of my package down.
But I am unclear on what else I need to do this fully and ensure everything is correct/safe. e.g. I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe? Is their a standard set of rules to tell?
Run ldd on your executables and shared libraries to make sure that it loads libstdc++ and libgcc_s from the correct location, if you link them dynamically. These are the only two dependencies normally required to run your applications built with g++.
Normally, you do not need to provide your own versions of libraries with C interface, unless your application requires newer versions with incompatible APIs.
Recent GCC compilers have a lot of dependencies.
On some distributions, you could ask for them : on Debian or related you might aptitude build-dep gcc (provided you have deb-src: in your /etc/apt/sources.list) which would dowload the build dependencies of the system's gcc (which might have a lot of common dependencies with the latest GCC).
Otherwise, GCC source code contain a contrib/download_prerequisites script which should be handy.
Read carefully the GCC building procedure. Don't forget to compile it outside of the source tree. You might want to pass --program-suffix=-5-mine to its configure
Of course you'll also need to build all the other software needed to compile (or to cross-compile) your code with the newly built GCC, including binutils, gdb, and perhaps a C library
Alternatively use a chroot (or some container à la docker) to install a newer Linux system...
I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe?
No. If you build GCC on the system you want to deploy to then the GCC binaries and shared libraries will depend on the system versions of libc, libpthread etc.
If you then use that GCC to compile your software, and deploy the new libstc++.so.6 alongside your software (using $ORIGIN so it will be found), then it will still use the system versions of those libraries. Which is exactly what should happen and what you want to happen. Rebuilding them would achieve nothing and simply mean you have more libraries to deploy alongside your software.
Follow directions to build from source. Revise your question if you face a problem.
I think there is an easier way then compiling GCC yourself. [Unfortunately I figured that out after compiling it from source a number of time :) ]
For example in Ubuntu there is a PPA for precompiled GCC versions which are not there yet in the official repository.
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-5 g++-5
sudo update-alternatives
sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 20
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

Installing gfortran in Cygwin

I am trying to compile a modelling program in Cygwin using either a gfortran or g95 compiler. I have installed both compilers, but when I go to configure the program, it checks for the compilers and does not find then (error: Fortran compiler cannot create executables). I am new to Cygwin-- I suspect it is something with how/where I installed the compilers...Any ideas?
Thank you,
L.
For me, it's more helpful to have executable code to go through the process, so I'm going to put some in. This is addressing your concern,
I suspect it is something with how/where I installed the compilers...
because the installation from apt-cyg should be helpful in letting the system know where to look for the compilers. I'm also addressing a possible linkage issue.
bballdave025#MY-MACHINE /cygdrive/c/bballdave025
$ apt-cyg install gcc-fortran libgfortran5
If you don't have apt-cyg yet, follow these instructions from another answer.
# Get to where your setup executable lives.
# This is what you used to install Cygwin the first time.
# Note that mine is for the 64-bit version, and that
# I keep mine in C:\cygwin64. Your path might be
# different. You also might need to re-download
# The setup executable from Cygwin.
$ cd /path/to/setup_install/setup_x86-64.exe -q -P wget
$ wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
$ chmod +x apt-cyg
$ mv apt-cyg /usr/local/bin
The libgfortran5 (or a more recent version, if available when you search) might be necessary. Here's why I think this might be the case.
bballdave025#MY-MACHINE /cygdrive/c/bballdave025
$ man gcc | grep -A 3 "[ ]*[-]l[ ]\{0,2\}library$"
-llibrary
-l library
Search the library named library when linking. (The second
alternative with the library as a separate argument is only for
POSIX compliance and is not recommended.)
(Note that I haven't included some parts of the result that aren't useful and can be fixed by prefixing the command with MANWIDTH=160, cf here.)
There is a little more detail and a little different result from the answer to a question about the lib prefix on files:
You can name a library whatever you want, but if you want gcc's -l flag to find the right one, you need to name it the way that link describes. For example, gcc -o myapp myapp.c -lm, [w]ill compile myapp.c, link the resulting object with libm.a, and output an executable called myapp. These days, there might be a more complicated search path involving dynamic library names, etc., but you should get the basic idea from this example. [In addition, you can look at this section f]rom the gcc man page:
-l library ...
... surrounds library with lib and .a and searches several directories.
The basic reason for all of that info is this: it is very possible that, in order to link with the gfortran library, you need to have installed a package named something like libgfortran. I don't know for sure how this works, especially with the Cygwin man page being slightly different, but it's worth a try. The likely extra thing you would need in this case is something like
apt-cyg install libgfortran
or
apt-cyg install libgfortran5
Here's some helpful info on how I found what to install. When I had a similar problem, I went to the Cygwin package search, but I only got three entries with three versions of netcdf-fortran
(archived). I wanted gfortran, so I kept looking
I found a great gfortran answer in this SO answer. With that answer, I went back to the Complete Cygwin Package List, armed with my trusty Ctrl + F, since I knew there were packages different from what came back from the search. The complete list had
cygwin64-gcc-fortran GCC for Cygwin 64bit toolchain (Fortran)`
gcc-fortran GNU Compiler Collection (Fortran)
and entries for libgfortran.
Hopefully some of this information will be helpful, or at least educational.
This problem is common for beginners with autotools. It can be:
missing libraries; this can be missing libraries for your project or compiler/system libraries, like libgfortran or similar for g95.
autotools can not detect your compiler;
dynamic libraries problem; runtime path to the dynamic libraries not set. See LD_LIBRARY_PATH for linux environment.
cross-compiling problem, I do not know much about cygwin but that can be an issue. I am not expert of cross-compiling either. It can also be another situation that I am not aware of.
I ran into the 1st and 3rd situations.
Approaches of solutions.
make sure you can manually compile and run a simple hello world program. Install the missing libraries if necessary. Also make sure that you can link your hello world program against the same libraries used by your modelling program, this last statement could lead you to the 3rd situation.
add the path to your compiler to the PATH variable or similar variable in cygwin. Or explicitly give the full path to your compiler to configure.
add the path to your libraries to the runtime libraries path LD_LIBRARY_PATH for linux environment or similar variable in cygwin. In one of my cases, the problem was that the test program that autotools uses to test the compiler could not run. It was successfully compiled but could not run. I installed all the libraries that my project uses in a path that was not included in library path. What happened was that the path to those libraries were set in the configure.ac or makefile.am so that the compiling was OK. But the running of the test program included in configure could not find them. This is a problem mostly for dynamically linked libraries. Adding the path to my .so to the LD_LIBRARY_PATH solved the problem.
well, I can not really help. The only solution that I can suggest is to install a linux system (dual boot or virtual machine) if you know how to do it, because I will not be there to help.
The following link can also help.

How can I link to an older version of a shared library

I'm building my program on my computer, on which libtiff.so -> libtiff.so.5.
And then pushing the builds on another machine on which libtiff.so -> libtiff.so.4.
At runtime, my program exists : « error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory ».
I cannot upgrade the other machine, and I would like to avoid compiling on a virtual machine (with the same linux version than the executing machine). Therefore, I would like to force the compiler to use the libtiff.so.4 instead of libtiff.so.5.
I have libtiff.so.4 installed on my computer (as well as libtiff.so.5). How can I force the linkage with this version instead of the newer version. I thought about moving the libtiff.so -> libtiff.so.4, but I'm afraid of breaking my system if it needs the latest version (apt-get purge libtiff5 gives an error because some other package needs it).
Is it possible to link with an older (installed) version of a library? If yes, how?
And is it harmfull to change the symbolic link of libtiff.so to the older version? If not, will it solve my issue?
You can use this syntax to link to a specific version of a library:
gcc [other options] -l:libtiff.so.4
You do not need to specify a path; the usual directories are searched in order to find the library.
Note: as Michael Wild mentioned, you should have the header files for that version installed instead of the newest ones.
As others have mentioned, you can force the linker by specifying the full versioned name, or even the absolute path.
However, I would strongly advice against doing so. The problem is, that the installed headers correspond to the newer version of the library. If there have been API/ABI-breaking changes between these library versions, the program might work, crash intermittently, or if you're lucky, not work at all.
Instead you should temporarily install the development package that corresponds to the libtiff.so.4 library. If on Debian/Ubuntu or similar, this would be the libtiff4-dev package.
Specify the full path to the .so: instead of -ltiff pass /lib64/libtiff.so.4 to the linker.
You see that error when application is running. So you can either stop your application and then exrract your library tar file. Or, force to link the lib file to the newer version after you extract. In second case, you will use something like:
ln -fs libversionname libfile
Example:
ln -fs libomyapp.1.1.3 libomyapp.lib
This links your libomyapp.lib to the version specified. This can be your older vsersion or your newer version.
But as said, best way to work is to bring down your application to properly match to the expected lib functionality to work without errors or issues.

How to install the program depending on libstdc++ library

My program is written in C++, using GCC on Ubuntu 9.10 64 bit. If depends on /usr/lib64/libstdc++.so.6 which actually points to /usr/lib64/libstdc++.so.6.0.13. Now I copy this program to virgin Ubuntu 7.04 system and try to run it. It doesn't run, as expected. Then I add to the program directory the following files:
libstdc++.so.6.0.13
libstdc++.so.6 (links to libstdc++.so.6.0.13)
Execute command:
LD_LIBRARY_PATH=. ./myprogram
Now everything is OK. The question: how can I write installation script for such program? myprogram file itself should be placed to /usr/local/bin. What can I do with dependencies? For example, on destination computer, /usr/lib64/libstdc++.so.6 link points to /usr/lib64/libstdc++.so.6.0.8. What can I do with this?
Note: the program is closed-source, I cannot provide source code and makefile.
If you're working on Ubuntu, making a .deb (Debian Package) seems to way to go. Here is a link to get you started.
Your package will state it depends on some other packages (typically the packages that includes libstdc++.so.6.0.13 - i guess the package name is something like libstdc++) and dependencies will be installed when you install your own package using dpkg -i <yourpackage>.deb.
Afterwards, you'll be able to uninstall it using dpkg -r <yourpackage>.
Anyway, never ship such standards files with your own archive. Dependencies exists for this exact purpose.
Hope it helps.
The real problem is that you try to install a binary that use newer versions os common libraries that the ones available on Ubuntu 9.10. The best option should be to make a specific target for the old Ubuntu 7.10 an compile it with the old libraries (that's a backport).
Then you should make two (or more) .deb packages, one for Ubuntu 9.10 and one for Ubuntu 7.10.
Another possibility is to continue doing what you are doing now : set LD_LIBRARY_PATH to point to the desired version of libstdc++ and other necessary libraries. You just set this environment variable in a launcher shell script. In you script you check if the new libraries are available or not and you set your LB_LIBRARY_PATH (say to /usr/local/lib/myprogram/) only if needed. But as others poster pointed out : that's a very bad practice. Anyway, never try to put these provided libraries at their standard place in Ubuntu 9.10, you would risk broking the target system and causing update problems for users or your program if these libraries are officially backported someday.
But if you choose to include your own set of system libraries there is still another way to go than the above one: just link these libraries statically. If a program is the only user of a library as it will probably be in the above scenario you'll lose all advantages of using a shared dynamic library, then why bother with using it at all ? And with stacically linked libraries you won't have to install them.