Python executable not finding libpython shared library - python

I am installing Python 2.7 on CentOS 5. I built and installed Python as follows
./configure --enable-shared --prefix=/usr/local
make
make install
When I try to run /usr/local/bin/python, I get this error message
/usr/local/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
When I run ldd on /usr/local/bin/python, I get
ldd /usr/local/bin/python
libpython2.7.so.1.0 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e9a00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00000030e9200000)
libutil.so.1 => /lib64/libutil.so.1 (0x00000030fa200000)
libm.so.6 => /lib64/libm.so.6 (0x00000030e9600000)
libc.so.6 => /lib64/libc.so.6 (0x00000030e8e00000)
/lib64/ld-linux-x86-64.so.2 (0x00000030e8a00000)
How do I tell Python where to find libpython?

Try the following:
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python
Replace /usr/local/lib with the folder where you have installed libpython2.7.so.1.0 if it is not in /usr/local/lib.
If this works and you want to make the changes permanent, you have two options:
Add export LD_LIBRARY_PATH=/usr/local/lib to your .profile in your home directory (this works only if you are using a shell which loads this file when a new shell instance is started). This setting will affect your user only.
Add /usr/local/lib to /etc/ld.so.conf and run ldconfig. This is a system-wide setting of course.

Putting on my gravedigger hat...
The best way I've found to address this is at compile time. Since you're the one setting prefix anyway might as well tell the executable explicitly where to find its shared libraries. Unlike OpenSSL and other software packages, Python doesn't give you nice configure directives to handle alternate library paths (not everyone is root you know...) In the simplest case all you need is the following:
./configure --enable-shared \
--prefix=/usr/local \
LDFLAGS="-Wl,--rpath=/usr/local/lib"
Or if you prefer the non-linux version:
./configure --enable-shared \
--prefix=/usr/local \
LDFLAGS="-R/usr/local/lib"
The "rpath" flag tells python it has runtime libraries it needs in that particular path. You can take this idea further to handle dependencies installed to a different location than the standard system locations. For example, on my systems since I don't have root access and need to make almost completely self-contained Python installs, my configure line looks like this:
./configure --enable-shared \
--with-system-ffi \
--with-system-expat \
--enable-unicode=ucs4 \
--prefix=/apps/python-${PYTHON_VERSION} \
LDFLAGS="-L/apps/python-${PYTHON_VERSION}/extlib/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/extlib/lib" \
CPPFLAGS="-I/apps/python-${PYTHON_VERSION}/extlib/include"
In this case I am compiling the libraries that python uses (like ffi, readline, etc) into an extlib directory within the python directory tree itself. This way I can tar the python-${PYTHON_VERSION} directory and land it anywhere and it will "work" (provided you don't run into libc or libm conflicts). This also helps when trying to run multiple versions of Python on the same box, as you don't need to keep changing your LD_LIBRARY_PATH or worry about picking up the wrong version of the Python library.
Edit: Forgot to mention, the compile will complain if you don't set the PYTHONPATH environment variable to what you use as your prefix and fail to compile some modules, e.g., to extend the above example, set the PYTHONPATH to the prefix used in the above example with export PYTHONPATH=/apps/python-${PYTHON_VERSION}...

I had the same problem and I solved it this way:
If you know where libpython resides at, I supposed it would be /usr/local/lib/libpython2.7.so.1.0 in your case, you can just create a symbolic link to it:
sudo ln -s /usr/local/lib/libpython2.7.so.1.0 /usr/lib/libpython2.7.so.1.0
Then try running ldd again and see if it worked.

I installed Python 3.5 by Software Collections on CentOS 7 minimal. It all worked fine on its own, but I saw the shared library error mentioned in this question when I tried running a simple CGI script:
tail /var/log/httpd/error_log
AH01215: /opt/rh/rh-python35/root/usr/bin/python: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory
I wanted a systemwide permanent solution that works for all users, so that excluded adding export statements to .profile or .bashrc files. There is a one-line solution, based on the Red Hat solutions page. Thanks for the comment that points it out:
echo 'source scl_source enable rh-python35' | sudo tee --append /etc/profile.d/python35.sh
After a restart, it's all good on the shell, but sometimes my web server still complains. There's another approach that always worked for both the shell and the server, and is more generic. I saw the solution here and then realized it's actually mentioned in one of the answers here as well! Anyway, on CentOS 7, these are the steps:
vim /etc/ld.so.conf
Which on my machine just had:
include ld.so.conf.d/*.conf
So I created a new file:
vim /etc/ld.so.conf.d/rh-python35.conf
And added:
/opt/rh/rh-python35/root/usr/lib64/
And to manually rebuild the cache:
sudo ldconfig
That's it, scripts work fine!
This was a temporary solution, which didn't work across reboots:
sudo ldconfig /opt/rh/rh-python35/root/usr/lib64/ -v
The -v (verbose) option was just to see what was going on. I saw that it did:
/opt/rh/rh-python35/root/usr/lib64:
libpython3.so.rh-python35 -> libpython3.so.rh-python35
libpython3.5m.so.rh-python35-1.0 -> libpython3.5m.so.rh-python35-1.0
This particular error went away. Incidentally, I had to chown the user to apache to get rid of a permission error after that.
Note that I used find to locate the directory for the library. You could also do:
sudo yum install mlocate
sudo updatedb
locate libpython3.5m.so.rh-python35-1.0
Which on my VM returns:
/opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0
Which is the path I need to give to ldconfig, as shown above.

This worked for me...
$ sudo apt-get install python2.7-dev

On Solaris 11
Use LD_LIBRARY_PATH_64 to resolve symlink to python libs.
In my case for python3.6 LD_LIBRARY_PATH didn't work but LD_LIBRARY_PATH_64 did.
Hope this helps.
Regards

This answer would be helpful to those who have limited auth access on the server.
I had a similar problem for python3.5 in HostGator's shared hosting. Python3.5 had to be enabled every single damn time after login. Here are my 10 steps for resolution:
Enable the python through scl script python_enable_3.5 or scl enable rh-python35 bash.
Verify that it's enabled by executing python3.5 --version. This should give you your python version.
Execute which python3.5 to get its path. In my case, it was /opt/rh/rh-python35/root/usr/bin/python3.5. You can use this path get the version again (just to verify that this path is working for you.)
Awesome, now please exit out of current shell by scl.
Now, lets get the version again through this complete python3.5 path /opt/rh/rh-python35/root/usr/bin/python3.5 --version.
It won't give you the version but an error. In my case, it was
/opt/rh/rh-python35/root/usr/bin/python3.5: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory
As mentioned in Tamas' answer, we gotta find that so file. locate doesn't work in shared hosting and you can't install that too.
Use the following command to find where that file is located:
find /opt/rh/rh-python35 -name "libpython3.5m.so.rh-python35-1.0"
Above command would print the complete path (second line) of the file once located. In my case, output was
find: `/opt/rh/rh-python35/root/root': Permission denied
/opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0
Here is the complete command for the python3.5 to work in such shared hosting which would give the version,
LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5 --version
Finally, for shorthand, append the following alias in your ~/.bashrc
alias python351='LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5'
For verification, reload the .bashrc by source ~/.bashrc and execute python351 --version.
Well, there you go, now whenever you login again, you have got python351 to welcome you.
This is not just limited to python3.5, but can be helpful in case of other scl installed softwares.

I installed using the command:
./configure --prefix=/usr \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--enable-unicode=ucs4 &&
make
Now, as the root user:
make install &&
chmod -v 755 /usr/lib/libpython2.7.so.1.0
Then I tried to execute python and got the error:
/usr/local/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
Then, I logged out from root user and again tried to execute the Python and it worked successfully.

All it needs is the installation of libpython [3 or 2] dev files installation.

just install python-lib. (python27-lib). It will install libpython2.7.so1.0. We don't require to manually set anything.

Related

How to get libdrmaa.so to use locally installed GLIBC? [duplicate]

My linux (SLES-8) server currently has glibc-2.2.5-235, but I have a program which won't work on this version and requires glibc-2.3.3.
Is it possible to have multiple glibcs installed on the same host?
This is the error I get when I run my program on the old glibc:
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
So I created a new directory called newglibc and copied the following files in:
libpthread.so.0
libm.so.6
libc.so.6
ld-2.3.3.so
ld-linux.so.2 -> ld-2.3.3.so
and
export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH
But I get an error:
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)
So it appears that they are still linking to /lib and not picking up from where I put them.
It is very possible to have multiple versions of glibc on the same system (we do that every day).
However, you need to know that glibc consists of many pieces (200+ shared libraries) which all must match. One of the pieces is ld-linux.so.2, and it must match libc.so.6, or you'll see the errors you are seeing.
The absolute path to ld-linux.so.2 is hard-coded into the executable at link time, and can not be easily changed after the link is done (Update: can be done with patchelf; see this answer below).
To build an executable that will work with the new glibc, do this:
g++ main.o -o myapp ... \
-Wl,--rpath=/path/to/newglibc \
-Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2
The -rpath linker option will make the runtime loader search for libraries in /path/to/newglibc (so you wouldn't have to set LD_LIBRARY_PATH before running it), and the -dynamic-linker option will "bake" path to correct ld-linux.so.2 into the application.
If you can't relink the myapp application (e.g. because it is a third-party binary), not all is lost, but it gets trickier. One solution is to set a proper chroot environment for it. Another possibility is to use rtldi and a binary editor. Update: or you can use patchelf.
This question is old, the other answers are old. "Employed Russian"s answer is very good and informative, but it only works if you have the source code. If you don't, the alternatives back then were very tricky. Fortunately nowadays we have a simple solution to this problem (as commented in one of his replies), using patchelf. All you have to do is:
$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp
And after that, you can just execute your file:
$ ./myapp
No need to chroot or manually edit binaries, thankfully. But remember to backup your binary before patching it, if you're not sure what you're doing, because it modifies your binary file. After you patch it, you can't restore the old path to interpreter/rpath. If it doesn't work, you'll have to keep patching it until you find the path that will actually work... Well, it doesn't have to be a trial-and-error process. For example, in OP's example, he needed GLIBC_2.3, so you can easily find which lib provides that version using strings:
$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3
In theory, the first grep would come empty because the system libc doesn't have the version he wants, and the 2nd one should output GLIBC_2.3 because it has the version myapp is using, so we know we can patchelf our binary using that path. If you get a segmentation fault, read the note at the end.
When you try to run a binary in linux, the binary tries to load the linker, then the libraries, and they should all be in the path and/or in the right place. If your problem is with the linker and you want to find out which path your binary is looking for, you can find out with this command:
$ readelf -l myapp | grep interpreter
[Requesting program interpreter: /lib/ld-linux.so.2]
If your problem is with the libs, commands that will give you the libs being used are:
$ readelf -d myapp | grep Shared
$ ldd myapp
This will list the libs that your binary needs, but you probably already know the problematic ones, since they are already yielding errors as in OP's case.
"patchelf" works for many different problems that you may encounter while trying to run a program, related to these 2 problems. For example, if you get: ELF file OS ABI invalid, it may be fixed by setting a new loader (the --set-interpreter part of the command) as I explain here. Another example is for the problem of getting No such file or directory when you run a file that is there and executable, as exemplified here. In that particular case, OP was missing a link to the loader, but maybe in your case you don't have root access and can't create the link. Setting a new interpreter would solve your problem.
Thanks Employed Russian and Michael Pankov for the insight and solution!
Note for segmentation fault: you might be in the case where myapp uses several libs, and most of them are ok but some are not; then you patchelf it to a new dir, and you get segmentation fault. When you patchelf your binary, you change the path of several libs, even if some were originally in a different path. Take a look at my example below:
$ ldd myapp
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./myapp)
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./myapp)
linux-vdso.so.1 => (0x00007fffb167c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a9aad2000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a9a8ce000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a9a6af000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9a9a3ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a99fe6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a9adeb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9a99dcf000)
Note that most libs are in /lib/x86_64-linux-gnu/ but the problematic one (libstdc++.so.6) is on /usr/lib/x86_64-linux-gnu. After I patchelf'ed myapp to point to /path/to/mylibs, I got segmentation fault. For some reason, the libs are not totally compatible with the binary. Since myapp didn't complain about the original libs, I copied them from /lib/x86_64-linux-gnu/ to /path/to/mylibs2, and I also copied libstdc++.so.6 from /path/to/mylibs there. Then I patchelf'ed it to /path/to/mylibs2, and myapp works now. If your binary uses different libs, and you have different versions, it might happen that you can't fix your situation. :( But if it's possible, mixing libs might be the way. It's not ideal, but maybe it will work. Good luck!
Use LD_PRELOAD:
put your library somewhere out of the man lib directories and run:
LD_PRELOAD='mylibc.so anotherlib.so' program
See: the Wikipedia article
First of all, the most important dependency of each dynamically linked program is the linker. All so libraries must match the version of the linker.
Let's take simple exaple: I have the newset ubuntu system where I run some program (in my case it is D compiler - ldc2). I'd like to run it on the old CentOS, but because of the older glibc library it is impossible. I got
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
I have to copy all dependencies from ubuntu to centos.
The proper method is following:
First, let's check all dependencies:
ldd ldc2-1.5.0-linux-x86_64/bin/ldc2
linux-vdso.so.1 => (0x00007ffebad3f000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)
linux-vdso.so.1 is not a real library and we don't have to care about it.
/lib64/ld-linux-x86-64.so.2 is the linker, which is used by the linux do link the executable with all dynamic libraries.
Rest of the files are real libraries and all of them together with the linker must be copied somewhere in the centos.
Let's assume all the libraries and linker are in "/mylibs" directory.
ld-linux-x86-64.so.2 - as I've already said - is the linker. It's not dynamic library but static executable. You can run it and see that it even have some parameters, eg --library-path (I'll return to it).
On the linux, dynamically linked program may be lunched just by its name, eg
/bin/ldc2
Linux loads such program into RAM, and checks which linker is set for it. Usually, on 64-bit system, it is /lib64/ld-linux-x86-64.so.2 (in your filesystem it is symbolic link to the real executable).
Then linux runs the linker and it loads dynamic libraries.
You can also change this a little and do such trick:
/mylibs/ld-linux-x86-64.so.2 /bin/ldc2
It is the method for forcing the linux to use specific linker.
And now we can return to the mentioned earlier parameter --library-path
/mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2
It will run ldc2 and load dynamic libraries from /mylibs.
This is the method to call the executable with choosen (not system default) libraries.
Setup 1: compile your own glibc without dedicated GCC and use it
This setup might work and is quick as it does not recompile the whole GCC toolchain, just glibc.
But it is not reliable as it uses host C runtime objects such as crt1.o, crti.o, and crtn.o provided by glibc. This is mentioned at: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location Those objects do early setup that glibc relies on, so I wouldn't be surprised if things crashed in wonderful and awesomely subtle ways.
For a more reliable setup, see Setup 2 below.
Build glibc and install locally:
export glibc_install="$(pwd)/glibc/build/install"
git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`
Setup 1: verify the build
test_glibc.c
#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>
atomic_int acnt;
int cnt;
int f(void* thr_data) {
for(int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
}
return 0;
}
int main(int argc, char **argv) {
/* Basic library version check. */
printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());
/* Exercise thrd_create from -pthread,
* which is not present in glibc 2.27 in Ubuntu 18.04.
* https://stackoverflow.com/questions/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
}
Compile and run with test_glibc.sh:
#!/usr/bin/env bash
set -eux
gcc \
-L "${glibc_install}/lib" \
-I "${glibc_install}/include" \
-Wl,--rpath="${glibc_install}/lib" \
-Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
-std=c11 \
-o test_glibc.out \
-v \
test_glibc.c \
-pthread \
;
ldd ./test_glibc.out
./test_glibc.out
The program outputs the expected:
gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674
Command adapted from https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location but --sysroot made it fail with:
cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install
so I removed it.
ldd output confirms that the ldd and libraries that we've just built are actually being used as expected:
+ ldd test_glibc.out
linux-vdso.so.1 (0x00007ffe4bfd3000)
libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
/home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)
The gcc compilation debug output shows that my host runtime objects were used, which is bad as mentioned previously, but I don't know how to work around it, e.g. it contains:
COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o
Setup 1: modify glibc
Now let's modify glibc with:
diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
## -16,11 +16,14 ##
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <stdio.h>
+
#include "thrd_priv.h"
int
thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
{
+ puts("hacked");
_Static_assert (sizeof (thr) == sizeof (pthread_t),
"sizeof (thr) != sizeof (pthread_t)");
Then recompile and re-install glibc, and recompile and re-run our program:
cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh
and we see hacked printed a few times as expected.
This further confirms that we actually used the glibc that we compiled and not the host one.
Tested on Ubuntu 18.04.
Setup 2: crosstool-NG pristine setup
This is an alternative to setup 1, and it is the most correct setup I've achieved far: everything is correct as far as I can observe, including the C runtime objects such as crt1.o, crti.o, and crtn.o.
In this setup, we will compile a full dedicated GCC toolchain that uses the glibc that we want.
The only downside to this method is that the build will take longer. But I wouldn't risk a production setup with anything less.
crosstool-NG is a set of scripts that downloads and compiles everything from source for us, including GCC, glibc and binutils.
Yes the GCC build system is so bad that we need a separate project for that.
This setup is only not perfect because crosstool-NG does not support building the executables without extra -Wl flags, which feels weird since we've built GCC itself. But everything seems to work, so this is only an inconvenience.
Get crosstool-NG, configure and build it:
git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`
The build takes about thirty minutes to two hours.
The only mandatory configuration option that I can see, is making it match your host kernel version to use the correct kernel headers. Find your host kernel version with:
uname -a
which shows me:
4.15.0-34-generic
so in menuconfig I do:
Operating System
Version of linux
so I select:
4.14.71
which is the first equal or older version. It has to be older since the kernel is backwards compatible.
Setup 2: optional configurations
The .config that we generated with ./ct-ng x86_64-unknown-linux-gnu has:
CT_GLIBC_V_2_27=y
To change that, in menuconfig do:
C-library
Version of glibc
save the .config, and continue with the build.
Or, if you want to use your own glibc source, e.g. to use glibc from the latest git, proceed like this:
Paths and misc options
Try features marked as EXPERIMENTAL: set to true
C-library
Source of glibc
Custom location: say yes
Custom location
Custom source location: point to a directory containing your glibc source
where glibc was cloned as:
git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
Setup 2: test it out
Once you have built he toolchain that you want, test it out with:
#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
x86_64-unknown-linux-gnu-gcc \
-Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
-Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
-v \
-o test_glibc.out \
test_glibc.c \
-pthread \
;
ldd test_glibc.out
./test_glibc.out
Everything seems to work as in Setup 1, except that now the correct runtime objects were used:
COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o
Setup 2: failed efficient glibc recompilation attempt
It does not seem possible with crosstool-NG, as explained below.
If you just re-build;
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`
then your changes to the custom glibc source location are taken into account, but it builds everything from scratch, making it unusable for iterative development.
If we do:
./ct-ng list-steps
it gives a nice overview of the build steps:
Available build steps, in order:
- companion_tools_for_build
- companion_libs_for_build
- binutils_for_build
- companion_tools_for_host
- companion_libs_for_host
- binutils_for_host
- cc_core_pass_1
- kernel_headers
- libc_start_files
- cc_core_pass_2
- libc
- cc_for_build
- cc_for_host
- libc_post_cc
- companion_libs_for_target
- binutils_for_target
- debug
- test_suite
- finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.
therefore, we see that there are glibc steps intertwined with several GCC steps, most notably libc_start_files comes before cc_core_pass_2, which is likely the most expensive step together with cc_core_pass_1.
In order to build just one step, you must first set the "Save intermediate steps" in .config option for the intial build:
Paths and misc options
Debug crosstool-NG
Save intermediate steps
and then you can try:
env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`
but unfortunately, the + required as mentioned at: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536
Note however that restarting at an intermediate step resets the installation directory to the state it had during that step. I.e., you will have a rebuilt libc - but no final compiler built with this libc (and hence, no compiler libraries like libstdc++ either).
and basically still makes the rebuild too slow to be feasible for development, and I don't see how to overcome this without patching crosstool-NG.
Furthermore, starting from the libc step didn't seem to copy over the source again from Custom source location, further making this method unusable.
Bonus: stdlibc++
A bonus if you're also interested in the C++ standard library: How to edit and re-build the GCC libstdc++ C++ standard library source?
#msb gives a safe solution.
I met this problem when I did import tensorflow as tf in conda environment in CentOS 6.5 which only has glibc-2.12.
ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by /home/
I want to supply some details:
First install glibc to your home directory:
mkdir ~/glibc-install; cd ~/glibc-install
wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.gz
tar -zxvf glibc-2.17.tar.gz
cd glibc-2.17
mkdir build
cd build
../configure --prefix=/home/myself/opt/glibc-2.17 # <-- where you install new glibc
make -j<number of CPU Cores> # You can find your <number of CPU Cores> by using **nproc** command
make install
Second, follow the same way to install patchelf;
Third, patch your Python:
[myself#nfkd ~]$ patchelf --set-interpreter /home/myself/opt/glibc-2.17/lib/ld-linux-x86-64.so.2 --set-rpath /home/myself/opt/glibc-2.17/lib/ /home/myself/miniconda3/envs/tensorflow/bin/python
as mentioned by #msb
Now I can use tensorflow-2.0 alpha in CentOS 6.5.
ref: https://serverkurma.com/linux/how-to-update-glibc-newer-version-on-centos-6-x/
Can you consider using Nix http://nixos.org/nix/ ?
Nix supports multi-user package management: multiple users can share a
common Nix store securely, don’t need to have root privileges to
install software, and can install and use different versions of a
package.
I am not sure that the question is still relevant, but there is another way of fixing the problem: Docker. One can install an almost empty container of the Source Distribution (The Distribution used for development) and copy the files into the Container. That way You do not need to create the filesystem needed for chroot.
If you look closely at the second output you can see that the new location for the libraries is used. Maybe there are still missing libraries that are part of the glibc.
I also think that all the libraries used by your program should be compiled against that version of glibc. If you have access to the source code of the program, a fresh compilation appears to be the best solution.
"Employed Russian" is among the best answer, and I think all other suggested answer may not work. The reason is simply because when an application is first created, all its the APIs it needs are resolved at compile time. Using "ldd" u can see all the statically linked dependencies:
ldd /usr/lib/firefox/firefox
linux-vdso.so.1 => (0x00007ffd5c5f0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f727e708000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f727e500000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f727e1f8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f727def0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f727db28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f727eb78000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f727d910000)
But at runtime, firefox will also load many other dynamic libraries, eg (for firefox) there are many "glib"-labelled libraries loaded (even though statically linked there are none):
/usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
/usr/lib/x86_64-linux-gnu/libavahi-glib.so.1.0.2
Manytimes, you can see names of one version being soft-linked into another version. Eg:
lrwxrwxrwx 1 root root 23 Dec 21 2014 libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2
-rw-r--r-- 1 root root 160832 Mar 1 2013 libdbus-glib-1.so.2.2.2
This therefore means different version of "libraries" exists in one system - which is not a problem as it is the same file, and it will provide compatibilities when applications have multiple versions dependencies.
Therefore, at the system level, all the libraries are almost interdependent on one another, and just changing the libraries loading priority via manipulating LD_PRELOAD or LD_LIBRARY_PATH will not help - even it can load, runtime it may still crash.
http://lightofdawn.org/wiki/wiki.cgi/-wiki/NewAppsOnOldGlibc
Best alternative is chroot (mentioned by ER briefly): but for this you will need to recreate the entire environment in which is the original binary execute - usually starting from /lib, /usr/lib/, /usr/lib/x86 etc. You can either use "Buildroot", or YoctoProject, or just tar from an existing Distro environment. (like Fedora/Suse etc).
When I wanted to run a chromium-browser on Ubuntu precise (glibc-2.15), I got the
(typical) message "...libc.so.6: version `GLIBC_2.19' not found...".
I considered the fact, that files are not needed permamently, but only for start.
So I collected the files needed for the browser and sudo and created a mini-glibc-2.19-
environment, started the browser and then copied the original files back
again. The needed files are in RAM and the original glibc is the same.
as root
the files (*-2.15.so) already exist
mkdir -p /glibc-2.19/i386-linux-gnu
/glibc-2.19/ld-linux.so.2 -> /glibc-2.19/i386-linux-gnu/ld-2.19.so
/glibc-2.19/i386-linux-gnu/libc.so.6 -> libc-2.19.so
/glibc-2.19/i386-linux-gnu/libdl.so.2 -> libdl-2.19.so
/glibc-2.19/i386-linux-gnu/libpthread.so.0 -> libpthread-2.19.so
mkdir -p /glibc-2.15/i386-linux-gnu
/glibc-2.15/ld-linux.so.2 -> (/glibc-2.15/i386-linux-gnu/ld-2.15.so)
/glibc-2.15/i386-linux-gnu/libc.so.6 -> (libc-2.15.so)
/glibc-2.15/i386-linux-gnu/libdl.so.2 -> (libdl-2.15.so)
/glibc-2.15/i386-linux-gnu/libpthread.so.0 -> (libpthread-2.15.so)
the script to run the browser:
#!/bin/sh
sudo cp -r /glibc-2.19/* /lib
/path/to/the/browser &
sleep 1
sudo cp -r /glibc-2.15/* /lib
sudo rm -r /lib/i386-linux-gnu/*-2.19.so

django i18n: Make sure you have GNU gettext tools

I try django-admin.py makemessages -l zh_CN but has error :
CommandError: Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed.
after I use brew install gettext,it still get wrong.
Do I need to do something? here is my terminal screenshot
Please guide me thank you.
In Ubuntu:
$ sudo apt-get install gettext
For Mac users, after installing Homebrew and gettext as #Louis Barranqueiro says (steps 1 and 2):
Install Homebrew : /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install GNU gettext : brew install gettext
You shouldn't use brew link gettext --force in step 3, because it is risky (as Brew advises if you try). A better workaround is to set a new PATH variable for your virtual environment. So, in the postactivate file, which is located in the bin folder of your virtual environment folder, type:
export TEMP_PATH=$PATH
export PATH=$PATH:/usr/local/Cellar/gettext/0.19.7/bin
Note that you have to replace 0.19.7 by the version that is installed in your machine.
And in your predeactivate file, which is located in the same folder of postactivate file, type:
export PATH=$TEMP_PATH
unset TEMP_PATH
Now you can use the python manage.py makemessages -l <desired_language> without worries. :)
Cheers.
This procedure worked for me (OSX 10.11.2 - python v3.5 and Django 1.8)
It should work with your configuration.
Install gettext GNU tools with Homebrew using Terminal
Install Homebrew : /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install GNU gettext : brew install gettext
Create symlink : brew link gettext --force
This solution worked for me ( win. 7, 8 and 10 )
You need to download two folders:
gettext-runtime_0.18.1.1-2_win32
gettext-tools-dev_0.18.1.1-2_win32
You can find them here.
After you download them, unzip them and add the directory of the bin file of the both folders to the system variables PATH of your pc.
You will also need a file named libstdc++-6.dll download it from here and place it in your system directory. You will find adequate details on system directory here.
And that’s it. Hope it is useful for you.
Just below solution solved my problem. I am using Windows 10 64bit
1- Go to this link :
https://mlocati.github.io/articles/gettext-iconv-windows.html
2- Download 32 or 64 bit shared and static windows installation files
3-Install both of files
4-Restart your computer
Hi first of all make sure that your virtual environment is not in your root folder. I think it's better practice to keep your virtual environment outside of the root folder. Obviously make sure your environment is activated. Of course make sure you have gettext installed as well.
If your env folder is in your root folder
To test this just make sure you add {% load i18n %} in all your templates, choose a template and do something like this:
<h1>{% trans 'My Test to be translated' %}</h1>
Now run this command
django-admin makemessages -l 'zh_CN' -i your_venv
(Make sure you replace your_venv to the name of your virtual environment.
After you run the above command, you should get this in your terminal.
processing locale zh_CN
Now you should have a locale folder like this: locale/cn/LC_MESSAGES/django.po
Now you will need to compile the messages. Run this command
django-admin compilemessages
In your locale folder, now you should get you should see django.mo file as well, but you will notice the difference in django.po file. Just add your translation there, and you can test again by setting your en language to LANGUAGE_CODE = 'zh_CN' then just refresh and test the h1 string will be translated to Chinese.
In order for the above to work in your settings.py ensure you have this here, for now most important is the LOCALE_PATHS, but please check if this ('zh_CN', _('Chinese')), is correct
LANGUAGES = [
('zh_CN', _('Chinese')),
('en', _('English')),
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LOCALE_PATHS = [
os.path.join(BASE_DIR, 'locale'),
]
In this reply, the most important part is to realize where your virtual environment is located. Reason why you get all these errors.
Please make sure you refer to this video here, it's a great tutorial.
https://www.youtube.com/watch?v=xI97sLMd1rM
#max-malysh's answer solved it for me —without touching system files.
Copy and run each of the following:
brew install gettext
GETTEXT_PATH="/usr/local/Cellar/gettext/0.19.8.1/bin"
FILE="venv/bin/activate"
echo "" >> $FILE
echo "export PATH=\$PATH:$GETTEXT_PATH" >> $FILE
source venv/bin/activate
GETTEXT_PATH="/usr/local/Cellar/gettext/0.19.8.1/bin" stores gettext_path in a shell variable —adapt the version number according to what brew install gettext
FILE="venv/bin/activate" stores the path to the venv shell script
echo "" >> $FILE adds an empty line at the end of the to make sure the next command is on its own line
echo "export PATH=\$PATH:$GETTEXT_PATH" >> $FILE adds a command to the venv shell script; this command adds the path to gettext binaries to the global $PATH variable, so that they are used before OS binaries.
source venv/bin/activate runs the venv shell script so that variables are properly set. You can run this command more than once.
If you're using Docker just simply run below command:
apt-get update
Then:
apt-get install gettext
If you use fish shell, another way around is to add this path to $fish_user_paths.This variable is prepended to $PATH, so you don't have to set it in all your projects.
You can do it with the following command line :
set -U fish_user_paths /usr/local/Cellar/gettext/0.19.8.1/bin $fish_user_paths
Remember to replace 0.19.8.1 with your gettext version.
This sets $fish_user_paths as a Universal Variable. Here's what help says about Universal Variables :
A universal variable is a variable whose value is shared across all
instances of fish, now and in the future – even after a reboot. You
can make a variable universal with set -U
So setting this variable in your shell once (no need to do it in a config file) will save it even after logging out or rebooting.
that works for windows users.
i am using django 2
access this https://mlocati.github.io/articles/gettext-iconv-windows.html
2 download the static version for your system
after downloaded execute the setup.
restart your pc and it will work.
That is all. THANKS.!!!!
the problem is hinted in the output from brew...
it has installed the GNU gettext but hasn't linked it into your bin directory because OSX already provides a different version of gettext...
so Django doesn't know to run the version you installed from brew.
apparently brew is too cautious here though and you should just link it https://stackoverflow.com/a/9787791/202168

DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both

I've been usually installed python packages through pip.
For Google App Engine, I need to install packages to another target directory.
I've tried:
pip install -I flask-restful --target ./lib
but it fails with:
must supply either home or prefix/exec-prefix -- not both
How can I get this to work?
Are you using OS X and Homebrew? The Homebrew python page https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md calls out a known issue with pip and a work around.
Worked for me.
You can make this "empty prefix" the default by adding a
~/.pydistutils.cfg file with the following contents:
[install]
prefix=
Edit: The Homebrew page was later changed to recommend passing --prefix on the command line, as discussed in the comments below. Here is the last version which contained that text. Unfortunately this only works for sdists, not wheels.
The issue was reported to pip, which later fixed it for --user. That's probably why the section has now been removed from the Homebrew page. However, the problem still occurs when using --target as in the question above.
I believe there is a simpler solution to this problem (Homebrew's Python on macOS) that won't break your normal pip operations.
All you have to do is to create a setup.cfg file at the root directory of your project, usually where your main __init__.py or executable py file is. So if the root folder of your project is: /path/to/my/project/, create a setup.cfg file in there and put the magic words inside:
[install]
prefix=
OK, now you sould be able to run pip's commands for that folder:
pip install package -t /path/to/my/project/
This command will run gracefully for that folder only. Just copy setup.cfg to whatever other projects you might have. No need to write a .pydistutils.cfg on your home directory.
After you are done installing the modules, you may remove setup.cfg.
On OSX(mac), assuming a project folder called /var/myproject
cd /var/myproject
Create a file called setup.cfg and add
[install]
prefix=
Run pip install <packagename> -t .
Another solution* for Homebrew users is simply to use a virtualenv.
Of course, that may remove the need for the target directory anyway - but even if it doesn't, I've found --target works by default (as in, without creating/modifying a config file) when in a virtual environment.
*I say solution; perhaps it's just another motivation to meticulously use venvs...
I hit errors with the other recommendations around --install-option="--prefix=lib". The only thing I found that worked is using PYTHONUSERBASE as described here.
export PYTHONUSERBASE=lib
pip install -I flask-restful --user
this is not exactly the same as --target, but it does the trick for me in any case.
As other mentioned, this is known bug with pip & python installed with homebrew.
If you create ~/.pydistutils.cfg file with "empty prefix" instruction it will fix this problem but it will break normal pip operations.
Until this bug is officially addressed, one of the options would be to create your own bash script that would handle this case:
#!/bin/bash
name=''
target=''
while getopts 'n:t:' flag; do
case "${flag}" in
n) name="${OPTARG}" ;;
t) target="${OPTARG}" ;;
esac
done
if [ -z "$target" ];
then
echo "Target parameter must be provided"
exit 1
fi
if [ -z "$name" ];
then
echo "Name parameter must be provided"
exit 1
fi
# current workaround for homebrew bug
file=$HOME'/.pydistutils.cfg'
touch $file
/bin/cat <<EOM >$file
[install]
prefix=
EOM
# end of current workaround for homebrew bug
pip install -I $name --target $target
# current workaround for homebrew bug
rm -rf $file
# end of current workaround for homebrew bug
This script wraps your command and:
accepts name and target parameters
checks if those parameters are empty
creates ~/.pydistutils.cfg file with "empty prefix" instruction in it
executes your pip command with provided parameters
removes ~/.pydistutils.cfg file
This script can be changed and adapted to address your needs but you get idea. And it allows you to run your command without braking pip. Hope it helps :)
If you're using virtualenv*, it might be a good idea to double check which pip you're using.
If you see something like /usr/local/bin/pip you've broken out of your environment. Reactivating your virtualenv will fix this:
VirtualEnv: $ source bin/activate
VirtualFish: $ vf activate [environ]
*: I use virtualfish, but I assume this tip is relevant to both.
I have a similar issue.
I use the --system flag to avoid the error as I decribe here on other thread where I explain the specific case of my situation.
I post this here expecting that can help anyone facing the same problem.

Set default python 2.7.

I have just installed python 2.7 using macports as:
sudo port install py27-numpy py27-scipy py27-matplotlib py27-ipython +notebook py27-pandas py27-sympy py27-nose
during the process it found some issues, mainly broken files related with py25-haslib that I managed to fix. Now it seems eveything is ok. I tested a few programs and they run as expected. Currently, I have two versions of python: 2.5 (Default, from when I worked in my former institution) and 2.7 (just installed):
which python
/usr/stsci/pyssg/Python-2.5.1/bin/python
which python2.7
/opt/local/bin/python2.7
The next move would be set the new python version 2.7 as default:
sudo port select --set python python27
sudo port select --set ipython ipython27
My question is: is there a way to go back to 2.5 in case something goes wrong?
I know a priori, nothing has to go wrong. But I have a few data reduction and analysis routines that work perfectly with the 2.5 version and I want to make sure I don´t mess up before setting the default.
if you want to revert, you can modify your .bash_profile or other login shell initialization to fix $PATH to not add "/Library/Frameworks/Python.framework/Versions/2.5/bin" to $PATH and/or to not have /usr/local/bin appear before /usr/bin on $PATH.
If you want to permanently remove the python.org installed version,
paste the following lines up to and including the chmod into a posix-
compatible shell:
tmpfile=/tmp/generate_file_list
cat <<"NOEXPAND" > "${tmpfile}"
#!/bin/sh
version="${1:-"2.5"}"
file -h /usr/local/bin/* | grep \
"symbolic link to ../../../Library/Frameworks/Python.framework/"\
"Versions/${version}" | cut -d : -f 1
echo "/Library/Frameworks/Python.framework/Versions/${version}"
echo "/Applications/Python ${version}"
set -- Applications Documentation Framework ProfileChanges \
SystemFixes UnixTools
for package do
echo "/Library/Receipts/Python${package}-${version}.pkg"
done
NOEXPAND
chmod ug+x ${tmpfile}
...excripted from troubleshooting question on python website

How to correct a compile/build issue with quickfix (v1.13.3) with Python support (... "_quickfix" import exception)

It took the equivalent of a 1/2 day for me to figure this out, so I want to share the Quickfix Engine compile problem I encountered and the solution.
I didn't get a reply from the "Quickfix Engine" help resources pointed to here:
"http://quickfixengine.org/help"... thus another reason I am providing this.
Environment: Fedora 18 -and- CentOS6 (64bit).
After successfully compiling quickfix with Python support (i.e. configure [opts]; make; make install), I got the following python import exception indicating that the python module, "_quickfix", could not be found:
==============================================
user$ python -c "import quickfix"
Traceback (most recent call last):
File " ", line 1, in
File "/home/user/APPS.d/ENTHOUGHT-PYTHON-IDE.d/x86_64.d/latest/lib/python2.7/site-packages/quickfix.py", line 7, in
import _quickfix
ImportError: No module named _quickfix
==============================================
The problem appears to be in the install script invoked by "make install".
The python interpreter is saying that the "_quickfix" module does not exit. As can be seen from the list of files install by "make install" below, there is no "_quickfix.py" file, but there is a reference to a "_quickfix.so" file and a "_quickfix.dylib" file:
/home/user/.local/lib/python2.7/site-packages/_quickfix.dylib -> /home/user/APPS.d/QUICKFIX.d/latest/lib/python/_quickfix.dylib
/home/user/.local/lib/python2.7/site-packages/_quickfix.so -> /home/user/APPS.d/QUICKFIX.d/latest/lib/python/_quickfix.so
/home/user/.local/lib/python2.7/site-packages/quickfix40.py
/home/user/.local/lib/python2.7/site-packages/quickfix41.py
/home/user/.local/lib/python2.7/site-packages/quickfix42.py
/home/user/.local/lib/python2.7/site-packages/quickfix42.pyc
/home/user/.local/lib/python2.7/site-packages/quickfix43.py
/home/user/.local/lib/python2.7/site-packages/quickfix44.py
/home/user/.local/lib/python2.7/site-packages/quickfix50.py
/home/user/.local/lib/python2.7/site-packages/quickfix50sp1.py
/home/user/.local/lib/python2.7/site-packages/quickfix50sp2.py
/home/user/.local/lib/python2.7/site-packages/quickfix.py
/home/user/.local/lib/python2.7/site-packages/quickfix.pyc
/home/user/.local/lib/python2.7/site-packages/quickfixt11.py
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix.la
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix_python.la
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix_python.so.10.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix_python.so.10 -> libquickfix_python.so.10.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix_python.so -> libquickfix_python.so.10.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix.so.14.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix.so.14 -> libquickfix.so.14.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/libquickfix.so -> libquickfix.so.14.0.0
/home/user/APPS.d/QUICKFIX.d/latest/lib/pkgconfig/quickfix.pc
SOLUTION:
The problem is that the first two entries above, which are symbolic links, are broken.
First, the destination directory is incorrect:
/home/user/APPS.d/QUICKFIX.d/latest/lib/python/...
should actually be:
/home/user/APPS.d/QUICKFIX.d/latest/lib/...
So we fix that first:
user$ cd /home/user/.local/lib/python2.7/site-packages
user$ rm _quickfix.so _quickfix.dylib
user$ ln -s /home/user/APPS.d/QUICKFIX.d/latest/lib/_quickfix.so _quickfix.so
user$ ln -s /home/user/APPS.d/QUICKFIX.d/latest/lib/_quickfix.dylib _quickfix.dylib
Next, with destination directory location corrected, the symbolic links are still broken; this time because the file names that they point to in that (just corrected) destination directory don't exist (i.e. "_quickfix.so" and "_quickfix.dylib" don't exist).
After playing around a little, I got things to work by creating those missing files like so:
user$ cd /home/user/APPS.d/QUICKFIX.d/latest/lib
user$ ln -s libquickfix_python.so _quickfix.so
user$ ln -s <???> _quickfix.dylib # Actually I didn't create this one yet. It's not yet clear to me what it should point to. I Will update this post later.
-
Note: Because I compiled QuickFix so that it does not install to the traditional "/usr/local/" directory structure, I had to append my "LD_LIBRARY_PATH" to include: "/home/user/APPS.d/QUICKFIX.d/latest/lib"
With minimal testing, things seem to work now (or at least in the right direction):
user$ python -c "import quickfix"; echo ${?}
0
user$ python -c "import quickfix42"; echo ${?}
0
When I figure out what the second link should be (if it is necessary), or if I should encounter any run-time errors with the corrections I implemented, I'll update/edit this post.
I hope this helps someone.
Noel
Had the same problem in Ubuntu 13.04. configured with python support and used the default destination (/usr/local/...). After successful compilation then worked out a similar solution with the following steps;
Create missing files/symlinks;
cd /usr/local/lib
sudo ln -s libquickfix_python.so _quickfix.so
sudo ln -s _quickfix.so _quickfix.dylib
Change/update existing symlinks to new location:
cd /usr/lib/python2.7/dist-packages/
sudo ln -s /usr/local/lib/_quickfix.so _quickfix.so
sudo ln -s /usr/local/lib/_quickfix.so _quickfix.dylib
Add new library path
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}/usr/local/lib
You do not need to create multiple symlinks - you only need to remove the bad symlinks and create one new symlink for _quickfix.so for everything to work:
rm /usr/local/lib/python2.7/site-packages/_quickfix.dylib
rm /usr/local/lib/python2.7/site-packages/_quickfix.so
ln -s /usr/local/lib/libquickfix_python.dylib /usr/local/lib/python2.7/site-packages/_quickfix.so
This is on OS X. For Linux you will need to use the following (as the dylib extension is OS X specific)
ln -s /usr/local/lib/libquickfix_python.so /usr/local/lib/python2.7/site-packages/_quickfix.so

Categories

Resources