I am implementing a C++ program that uses python/C++ Extensions. As of now I am explicitly linking my program to python static library I compiled. I am wondering is there any way to link my program with system installed python(i mean the default python installation that comes with linux)
Yes. There is a command line utility called python-config:
Usage: /usr/bin/python-config [--prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--help]
For linkage purposes, you have to invoke it with --ldflags parameter. It will print a list of flags you have to pass to the linker (or g++) in order to link with system installed python libraries:
$ python-config --ldflags
-L/usr/lib/python2.6/config -lpthread -ldl -lutil -lm -lpython2.6
It also can give you flags to compilation with --cflags parameter:
$ python-config --cflags
-I/usr/include/python2.6 -I/usr/include/python2.6 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
Say you have a test program in test.cpp file, then you can do something like this in order to compile and link:
g++ $(python-config --cflags) -o test $(python-config --ldflags) ./test.cpp
That will link your program with shared libraries. If you want to go static, you can pass -static option to the linker. But that will link with all static stuff, including a runtime. If you want to go just with static python, you have to find those libraries yourself. One of the option is to parse python-config --ldflags output and look for libraries with .a extensions. But I'd rather stick to all dynamic or all static.
Hope it helps. Good luck!
Related
I want to use pytwed package, but instruction says to produce a shared library loadable in python2 following:
gcc -std=c99 twed_wrap.c -lm -lpython2.7 -shared -o twed.so -fPIC -I /usr/lib64/python2.7/site-packages/numpy/core/include/ -I /usr/include/python2.7
I am doing it for the first time, so I am not able to understand the whole syntax, what it is doing and what all path it's asking about?
Can some one help?
Thanks for your time and patience.
I am just getting started with Cython and am trying to compile a "Hello World" script. I am trying to use gcc -Os /User/Documents/Python/Test\ Python/helloCopy.c -I/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m -l, but I don't know what to add after the -l. Other forum pages say to "include -lpython2.7 (or whatever version of Python you're using) on the linker command-line" but that produces ld: library not found for -lpython3.5
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Should I be directing the -l to a particular folder?
I do not know what resource you're using, but this does not say anything about a -l flag. It suggests
cython -a helloCopy.pyx
This creates a yourmod.c file, and the -a switch produces an annotated html file of the source code. Pass the -h flag for a complete list of supported flags.
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o helloCopy.so helloCopy.c
(Linux)
On macOS I would try to compile with
gcc -I/usr/bin/python -o helloCopy.so helloCopy.c
to use the standard version of Python.
I have troubles using a Python interface generated with SWIG (I have OSX 10.11.12). After compiling and linking everything together as such:
swig -python erk_integrator.i
gcc -c -fPIC -O3 model.c auxiliary_functions.c timing_functions.c
gcc -c -fPIC -O3 erk_integrator.c erk_integrator_wrap.c -I. -I/usr/local/include/python2.7
gcc -lpython -dynamiclib model.o erk_integrator.o erk_integrator_wrap.o auxiliary_functions.o timing_functions.o -o _erk_integrator.so
I try a test script, but Python throws a fatal error:
/usr/local/bin/python test_erk.py
Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6
But when I run
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 test_erk.py
everything works as it should. However, I need to use /usr/local/bin/python (from Homebrew) instead of the system Python.
I think something goes wrong in the linking step. Many thanks for helping!
This blog post helped me solve it: blog.tim-smith.us/2015/09/python-extension-modules-os-x
It turns out on OSX you need
-undefined dynamic_lookup
instead of
-lpython
I want to embed python in C. But I find that the version of python interpreter which is embedded in my program is 2.7 (The default version on mac).
How could I specify particular version of python interpreter when I compile the c codes in mac os x. The gcc in os x is definitely different from in linux.
I have already installed python3 through HomeBrew.
Thanks a lot.
UPDATE:
I try to use python3.4-config --cflags and python3.4-config --ldflags to find out the required compiler and linker flags. Then I get these recommended flags when compiling & linking:
-I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -Wno-unused-result -Werror=declaration-after-statement -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include
and
-L/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/config-3.4m -ldl -framework CoreFoundation -lpython3.4m
After this, I assemble these flags along with source file into gcc, and obtain an error:
Undefined symbols for architecture x86_64:
"_PyUnicodeUCS2_FromString", referenced from:
_main in py2-5d8da5.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The C code which I test here comes from Python Documentation
I got the same errors when trying to do this tutorial on OSX. You don't need all of the flags that the config utility spits out. You definitely don't need the corefoundation framework if you're just doing the embedding tutorial. Just use the include directory for headers:
-I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m
, and the library to link to:
-L/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/config-3.4m -lpython3.4m
so here's a one-liner to compile and link:
gcc -I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -I/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -L/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/config-3.4m -lpython3.4m /path/to/main.c -o /path/to/output/executable
Two problems I'm having with copperhead at the minute, which I suspect are related.
Running a sample file (samples/axpy.py) generated lots of little warnings, but this one stood out.
g++ -pthread -fno-strict-aliasing -g -O2 -g -fwrapv -O2 -Wall -fPIC -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -DNDEBUG -I/usr/include/python2.6 -I/usr/local/lib/python2.6/dist-packages/copperhead-0.1a1-py2.6.egg/copperhead/include -I/usr/local/cuda/include /tmp/codepy-compiler-cache-v5-uid1000/202478034fea29b82d046b259bd6f43e/module.o /tmp/codepy-compiler-cache-v5-uid1000/fdcb04ede426b146cfce8894e99eeb57/gpu.o -L/usr/lib -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcuda -lcudart -lboost_python-gcc43-mt -lpthread -ldl -lutil -o /tmp/codepy-compiler-cache-v5-uid1000/202478034fea29b82d046b259bd6f43e/codepy.temp.202478034fea29b82d046b259bd6f43e.module.so
/usr/bin/ld: skipping incompatible /usr/local/cuda/lib/libcudart.so when searching for -lcudart
/usr/bin/ld: cannot find -lboost_python-gcc43-mt
collect2: ld returned 1 exit status
Few things to notice;
g++ is has correctly picked up the correct CUDA lib dir to use (lib64), but doesn't see libcudart.so in there, which it is.
/usr/local/cuda/lib64/libcudart.so.4.0.12: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
Next, boost_python isn't found; I've heard from a few places that this is due to ubuntu breaking a package convention somewhere, and people has said they've fixed it by changing the pycuda configure options, but haven't said what to change it to... (Example)
Anyone got any ideas for either the cudart or boot issues?
It is finding libcudart. What you
are seeing is only an informational
warning: -L options are
searched in order and the linker is
finding the 32 bit version first,
because you gave
-L/usr/local/cuda/lib before -L/usr/loca/cuda/lib64.
For the libboost_python problem,
just link with -lboost_python. The
Ubuntu systems I use (64 bit
10.04LTS with boost-python 1.40) have a series of cascading symbolic
links to that canonical
library name that make the linker
find the correct library without any
further intervention.