I am trying to install the Haskell Platform on Linux for the first time (I'm also a fairly new Linux user). The victim system is a fresh Red Hat system. And everything involved here should be 64 bit.
The directions at the platform website [1] indicate that I need a ghc7.0.3 to boostrap things. They provide a link to a generic binary of ghc-7.0.3 to do this. I fetched this and ran
$ ./configure ...
$ make install ...
as per the directions without incident (it is a binary, so no compilation needed)
However, when I tried to run ghci I get the output.
$ ghci
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... <command line>: can't load .so/.DLL for: gmp (libgmp.so: cannot open shared object file: No such file or directory)
For some reason ghci cannot find libgmp.so. Running ghci ultimately invokes
/usr/local/lib/ghc-7.0.3/ghc
with a mess of options. I checked the dependencies via ldd
$ ldd /usr/local/lib/ghc-7.0.3/ghc
linux-vdso.so.1 => (0x00007fffe5f5c000)
libncursesw.so.5 => /lib64/libncursesw.so.5 (0x0000003ee7000000)
librt.so.1 => /lib64/librt.so.1 (0x0000003ee5800000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003ef3000000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003ee5000000)
libgmp.so.3 => /usr/lib64/libgmp.so.3 (0x0000003ee4400000)
libm.so.6 => /lib64/libm.so.6 (0x0000003ee4c00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003ee5400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ee4800000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003ef3400000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ee4000000)
and it shows that it foud libgmp. libgmp is in /usr/local/lib and /usr/local/lib64.
I am not sure how to get further with this. Any suggestions?
[1] http://hackage.haskell.org/platform/linux.html
You either add /usr/local/lib and/or /usr/local/lib64 to $LD_LIBRARY_PATH, or add them to /etc/ld.so.conf, or (since you already have /usr/lib64/libgmp.so.3) add a missing symbolic link:
cd /usr/lib64
sudo ln -s libgmp.so.3 libgmp.so
(and perhaps the same for /usr/lib).
Note that /usr/lib64/libgmp.so.3 might be a different version from /usr/local/lib64/libgmp.so, make sure ghc can actually be used with the former.
Installing gmp-devel package helped in my case (opensuse)
I'm not sure that setting a symbolic link from libgmp.so to libgmp.so.3 is the right way to go. What happens when you get a version update and so libgmp.so.3 disappears. Setting LD_LIBRARY_PATH seems like a better solution.
There's also another solution for RedHat/CentOS and by extension probably Fedora: install the gmp-devel package. This sets up the symbolic link above, but does so with in the distribution (so updates should update the symbolic link also).
Related
I've just compiled an executable with stack build and then just copying over the executable to a different machine, however running the application results in:
./app: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
I'm guessing I need to install some packages from the appropriate Linux distro's packages - but is there more efficient way then googling for each error that comes up and trying to identify the package?
I've tried running executable within some docker images:
fpco/haskell-scratch, debian:stretch-slim which all result in the same behaviour:
sudo docker run --rm -it -v $(pwd):/abcxyz fpco/haskell-scratch sh
# /abcxyz/app
/abcxyz/app: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
Update
With the debian image I installed openssl:
apt-get install openssl
New error:
/abcxyz/app: error while loading shared libraries: libgmp.so.10: cannot open shared object file: No such file or directory
apt-get install libgmp-dev
And it works...
This is actually not specific to Haskell, but rather to the way Linux dynamically links shared libraries. You can use ldd <file>:
% ldd ./StateSort
linux-vdso.so.1 (0x00007ffd29385000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007fd986bd1000)
libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fd98693e000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fd986736000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fd986532000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fd986314000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fd985f5c000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fd986f1d000)
If there are missing libraries, you will notice them right away: the right hand side with the path to the so file will be absent.
You will then have to refer to your Linux distro's package management system to find out what package may contain the desired so file. For Ubuntu you would use apt-file, for ArchLinux − pkgfile, and so on.
I must warn you that ldd actually executes some of the code found in a file, so a malicious program may take over and wreak havoc. If you want to dissect an executable of unknown origin this way, you must do so in a disposable forensic containment. As I understand, this is not applicable in the case at hand, but nevertheless I must warn you.
I am building tmux-2.0 from sources on a pretty regular Linux host. First attempt failed as it turned out that the version of libevent installed is older than required, so I proceeded to download and build libevent-2.0.22 from sources (current at the time of writing) first.
Building of libevent succeeded flawlessly, and I thought I could then retry building tmux with the following:
PKG_CONFIG_PATH=$PATH_TO_MY_BUILT_LIBEVENT/lib/pkgconfig ./configure ...
The above invocation succeeded, so did subsequent make and make install.
Running my newly build tmux, however, aborts with a missing shared object, not surprisingly libevent-2.0.so.5:
tmux: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory
I thought building against a custom library implies it will also be used at runtime? ldd on my tmux gives me:
linux-vdso.so.1 => (0x00007fff8f5ff000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003cf8800000)
libncurses.so.5 => /lib64/libncurses.so.5 (0x0000003cf7e00000)
libevent-2.0.so.5 => not found
librt.so.1 => /lib64/librt.so.1 (0x0000003ce8600000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003cea200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ce7600000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003cf7200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003ce7e00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003ce8200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ce7200000)
So, libevent-2.0.so.5 is not found.
Do I need to resort to setting, I don't know, LIBS, LDFLAGS or some other variables or switches to configure script above, so that, I don't know, the paths to my newly built libevent are embedded in tmux binary, courtesy of ld?
I do not have root access - university Linux workstation - and frankly I don't need one, I think. I also do not want to muck about with LD_LIBRARY_PATH or the like. Suffice to say, doing LD_LIBRARY_PATH=$PATH_TO_MY_LIBEVENT/lib tmux works fine. But I want it to work "by default", locating and using my libevent.
I guess the solution would apply to pretty much any software using the "GNU build system". What's the right thing to do here?
You built against a library, but the system doesn't know where the library is. Since you don't want to install the library, but rather leave it in the place where you built it, you could solve it with -rpath= option of the linker — it embeds a search path for libraries into the executable file.
Just rebuild your application with it being added to your LDFLAGS, like LDFLAGS="-rpath=/home/mypath/to/libevent" (but note, it is a linker option, and it is possible that in the makefile as a linker used the gcc itself — gcc does not know the option, then you need to write it likeLDFLAGS="-Wl,-rpath=/home/mypath/to/libevent" to force gcc to pass the option down to the actual linker)
By the way, actually you can change rpath even without recompiling the application — there's a tool patchelf for that job.
I am having issues linking to a Haskell library we wrote. It goes wrong on Ubuntu, but not on Arch Linux. The error on Ubuntu we get is this:
/usr/bin/ld: warning: libHSdeepseq-1.3.0.0-ghc7.4.1.so, needed by /usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so, not found (try using -rpath or -rpath-link)
/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so: undefined reference to 'deepseqzm1zi3zi0zi0_ControlziDeepSeq_zdfNFDataArrayzuzdcrnf1_info'
The issue seems to be caused by the fact that libHScontainers-0.4.2.1-ghc7.4.1.so is incorrectly linked as one can see by the output of ldd:
ldd /usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so
linux-vdso.so.1 => (0x00007fffe95a2000)
libHSdeepseq-1.3.0.0-ghc7.4.1.so => not found
libHSbase-4.5.0.0-ghc7.4.1.so => not found
libHSghc-prim-0.2.0.0-ghc7.4.1.so => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f89a5a59000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f89a569a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f89a5fd8000)
Apparently the dependent libraries can not be found. They are installed. However if I do the same on Arch:
ldd /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/libHSdeepseq-1.3.0.2-ghc7.8.3.so
linux-vdso.so.1 (0x00007fff09dfe000)
libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fb8d3e96000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007fb8d3b91000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fb8d3988000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fb8d3784000)
libffi.so.6 => /usr/lib/libffi.so.6 (0x00007fb8d357b000)
libHSarray-0.5.0.0-ghc7.8.3.so => /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/../array-0.5.0.0/libHSarray-0.5.0.0-ghc7.8.3.so (0x00007fb8d32e1000)
libHSbase-4.7.0.1-ghc7.8.3.so => /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/../base-4.7.0.1/libHSbase-4.7.0.1-ghc7.8.3.so (0x00007fb8d2967000)
libHSinteger-gmp-0.5.1.0-ghc7.8.3.so => /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/../integer-gmp-0.5.1.0/libHSinteger-gmp-0.5.1.0-ghc7.8.3.so (0x00007fb8d274c000)
libHSghc-prim-0.3.1.0-ghc7.8.3.so => /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/../ghc-prim-0.3.1.0/libHSghc-prim-0.3.1.0-ghc7.8.3.so (0x00007fb8d24cf000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fb8d212c000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fb8d1f10000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007fb8d435f000)
The libraries are found.
As suggested I can solve this on Ubuntu by using -rpath in the application we try to link to the Haskell library. But this means that we have to do this for every Haskell package which seems wrong to me.
We can also fix this by adding a line to /etc/ld.so.conf.d/ghc.conf. But this also has to be done for every package and is not user-friendly.
A few questions I have:
What is the correct way to fix this?
Why are the packages in ghc-dynamic incorrectly linked?
Why is the linker able to find libHScontainers-0.4.2.1-ghc7.4.1.so but not libHSdeepseq-1.3.0.0-ghc7.4.1.so?
I strongly suspect that this is because the Haskell libraries installed by ghc have the locations of their dependencies (the RPATH field of their ELF header; you can verify using readelf -d) defined in terms of $ORIGIN. When library X depends on library Y, library X can indicate that library Y should be found in a location relative to its own location by using $ORIGIN. This is supported by the dynamic linker, but is not supported by the static linker.
(I'm speculating here:) Your library will define the location of its direct dependencies (in your case, I'm guessing, this includes containers) in terms of its own RPATH, which is not in terms of $ORIGIN. This is why the linker can find those, but not its transitive dependencies (again, I'm guessing, this includes deepseq in your case).
So why the difference between Arch Linux and Ubuntu? (Speculating further.) This is because unlike on Arch Linux, Ubunbu's linker uses --as-needed by default. You see, ghc will link your library against all its dependencies (including transitive ones), but then the linker will omit some of those dependencies because it doesn't directly depend on them. You could verify this by relinking with --no-as-needed.
Note that these errors by the static linkers really aren't errors, but warnings: it tries to resolve symbols, but it can't; but the dynamic linker will be able to anyway. So you can instruct the linker to ignore these errors (--unresolved-symbols=ignore-all) and all should be well.
I've been battling with adding explicit support in Cabal for generating Haskell libraries for use in C programs, and found the same problem. See https://github.com/haskell/cabal/pull/2540#issuecomment-95984067 for details.
I installed Qt4 in my local home in a Ubuntu system and the Qt4 libraries are in ~/lib. I have another program (hawkeye for genome assembly) dependent on Qt4 however when I run that it gives the error message:
error while loading share libraries: libQt3Support.so.4: cannot open shared object file: No such file or directory
I checked ~/lib and all the Qt libs are there. Do I need to add the path ~/lib to anywhere?
A good way to debug problems like this is to take a look at the ldd output. For example:
$ ldd yourProg
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/libc.so.6 (0xb7e3d000)
libQtGui.so => /usr/lib/libQtGui.so.4.7.0 (0xb7f7f000)
libQt3Support.so => (not found)
...
The above output will tell you if it's picking up your copy of Qt or the system version. Then you can set LD_LIBRARY_PATH or edit ld.so.conf and rerun ldconfig. For example:
$ export LD_LIBRARY_PATH=/path/to/your/qt
$ ldd yourProg
Or (as root):
# echo "/path/to/your/qt" >> /etc/ld.so.conf
# ldconfig
$ ldd yourProg
I'm running eclipse on Ubuntu using a g++ compiler and I'm trying to run a sample program that utilizes xerces.
The build produced no errors however, when i attempted to run the program, I would receive this error:
error while loading shared libraries: libxerces-c-3.1.so: cannot open shared object file: No such file or directory
libxerces-c-3.1.so is in the directory /opt/lib which I have included as a library in eclipse. The file is there when I checked the folder. When I perform an echo $LD_LIBRARY_PATH, /opt/lib is also listed.
Any ideas into where the problem lies? Thanks.
An ldd libxerces-c-3.1.so command yields the following output:
linux-vdso.so.1 => (0x00007fffeafff000)
libnsl.so.1 => /lib/libnsl.so.1 (0x00007fa3d2b83000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fa3d2966000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fa3d265f000)
libm.so.6 => /lib/libm.so.6 (0x00007fa3d23dc000)
libc.so.6 => /lib/libc.so.6 (0x00007fa3d2059000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fa3d1e42000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa3d337d000)
Try running ldconfig as root to see if it solves the problem.
Run ldd libxerces-c-3.1.so and examine the output to see if all dependencies can be found.
There are many ways to do this, most already mentioned here. BUT you want to avoid accidentally copying your library files into/over those of the system. This is easily done since people have little imagination in making original unique names for their libraries.
So there are a couple of things to think about:
Do you need these files to be a permanent part of your system?
Do you only need to install for testing and frequent updates?
Do you only need them for running that particular command once or twice?
Where are your native libraries located?
To find your various library locations on your system (apart from using find), look here:
cat /etc/ld.so.conf
cat /etc/ld.so.conf.d/*
On Linux there are some standard places:
/lib # for base system (don't use this!)
/usr/lib # for package manger installed apps
/usr/local/lib # for user installed apps
There are many others, but you should most likely stay with /usr/local/lib.
Next you need to tell your system where to find these libraries. The cool system dude (who knows what he is doing) way to do this is using ldconfig, however, you may do stuff you regret, if you make a mistake here. The safest way to use that command is by using the flags -v -n to make the command verbose and to specify what library directory you need to add.
sudo ldconfig -v -n /usr/local/lib/your-uber-libs
Done. But if you only wanna test something, then rather use your LD_LIBRARY_PATH directly from command line, like this:
LD_LIBRARY_PATH=/usr/local/lib/your-uber-libs ./your_uber_command
Alternatively, add the following to your .bashrc script.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/your-uber-libs
Now you can run your dynamically linked command.
I copied all the library files from /opt/lib into /usr/lib and the program works now. Thanks for the response.
Try installing the library libxerces-c3.1 as. Use the command mentioned below to install the library.
sudo apt-get install libxerces-c3.1
This worked like a charm for me.