Hello world with boost python and python 3.2 - c++

So I'm trying to interface python 3.2 and c++ using boost python, and have come across many many issues. I've finally gotten it to compile using the 2.7 libraries and it works, but I can't seem to make it work with python 3.2.
Here's the c++ code
#include <iostream>
using namespace std;
void say_hello(const char* name) {
cout << "Hello " << name << "!\n";
}
int main(){return 0;}
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("say_hello", say_hello);
}
If I compile it using the 2.7 libraries it works just fine, but when I use the 3.2 libraries I get tons of undefined references from libboost_python.so
Otherwise I wrote a little bit of python to make it work:
from distutils.core import setup
from distutils.extension import Extension
setup(name="PackageName",
ext_modules=[
Extension("hello", ["testBoost.cpp"],
libraries = ["boost_python"])
])
and this will create an so using python 3.2 or 2.7 build, but when I open the python 3 interpreter and attempt to import the so it give me the error undefined symbol PyClass_Type from libboost_python.so again. Any ideas? Is boost python compatible with python 3.x?
If the information is useful, here is my attempted compile using 3.2:
$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python -lpython3.2mu
/tmp/ccdmU1Yu.o: In function `PyInit_hello':
testBoost.cpp:(.text+0xc2): undefined reference to `boost::python::detail::init_module(PyModuleDef&, void (*)())'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Size'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromStringAndSize'
/usr/local/lib/libboost_python.so: undefined reference to `Py_InitModule4_64'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_FromFormat'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_Divide'
/usr/local/lib/libboost_python.so: undefined reference to `PyNumber_InPlaceDivide'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_AsLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_InternFromString'
/usr/local/lib/libboost_python.so: undefined reference to `PyClass_Type'
/usr/local/lib/libboost_python.so: undefined reference to `PyString_AsString'
/usr/local/lib/libboost_python.so: undefined reference to `PyInt_FromLong'
/usr/local/lib/libboost_python.so: undefined reference to `PyFile_AsFile'
collect2: ld returned 1 exit status
And the error from the python 3 interpreter is
File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/libboost_python.so.1.47.0: undefined symbol: PyClass_Type
Thanks for any help!

I had the exact same problem, with Ubuntu 12.04. I installed the 1.48 version of the library and had to link with libboost_python-py32.so instead of libboost_python.so After this the linker errors was gone.

The above c++ code compiles into a module with
$ g++ testBoost.cpp -I/usr/include/python3.2 -I/usr/local/include/boost/python -lboost_python3 -lpython3.2mu -o hello.so -shared
This compile command adds -lboost_python3, and -shared, and also the naming convention for python extension modules. You should also install the python3-dev package, and configure/build/install boost with python3, if you haven't already.
In python 3, I can then do the following:
$ python3
Python 3.2 (r32:88445, Mar 25 2011, 19:28:28)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello
>>> hello.say_hello('bill')
Hello bill!
>>>
You should be off to the races at that point.

Although this discussion old, just for the record:
Modify project-config.jam to change the python version to your setup
# Python configuration
using python : 3.4 : /usr ;
Then build boost:
./b2 clean
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release stage
./b2 --with-python link=static cxxflags="-std=c++11 -fPIC" variant=release install
The later command requires super user privileges. Then move to the folder containing C++ code for the extension:
g++ -std=c++11 hellopy.cpp -I/usr/include/python3.4 -I/usr/local/include/boost/python -lboost_python3 -o hello.so -shared -fPIC
You can then import hello into your python environment.

Linking in the python libraries (for e.g. -L/usr/lib/x86_64-linux-gnu -lpython2.7 on linux or find_package(PythonLibs) in CMake1) will make this linker issue go away.
Here is a more detailed explanation of the issue below. On the command line,
$ nm --dynamic <path-to>/libboost_python.so | grep PyString_Size
If you are feeling lazy and assuming your libboost_python is linking to python2.7, just run this
$ nm --dynamic `locate libboost_python27.so | awk 'NR==1'` | grep PyString_Size
You should see something like
U PyString_Size
So PyString_Size is undefined (U) in libboost_python27.so. This is what the linker was complaining about. We've confirmed that. Now let's look for this symbol in libpython.
$ nm --dynamic `locate libpython2.7.so | awk 'NR==1'` | grep PyString_Size
On my machine, I saw something like this:
00000000000f0530 T PyString_Size
The T indicates that the text for this symbol is at the address indicated. So this is proof that we were not linking in libpython in addition to libboost_python.
1 Why aren't you using CMake? :)

Related

Fortran Coarray cant compile

Im trying to compile an example of Coarray Fortran file.
https://github.com/ljdursi/coarray-examples
The command for compile is:
mpifort diffusion/diffusion-coarray.f90 -fcoarray=lib -o diffusion/diffusion-coarray -L ${PATH_TO_OPENCOARRAY_LIB} -lcaf_mpi
I've already installed the OpenCoarrays, using spack
But there is an error:
/usr/bin/ld: cannot find -lcaf_mpi
collect2: error: ld returned 1 exit status
Without -lcaf_mpi the error is:
/tmp/ccOdrmfc.o: In function `MAIN__':
diffusion-coarray.f90:(.text+0x32): undefined reference to `_gfortran_caf_num_images'
diffusion-coarray.f90:(.text+0x4c): undefined reference to `_gfortran_caf_this_image'
diffusion-coarray.f90:(.text+0x66): undefined reference to `_gfortran_caf_this_image'
diffusion-coarray.f90:(.text+0x77): undefined reference to `_gfortran_caf_num_images'
diffusion-coarray.f90:(.text+0x8a): undefined reference to `_gfortran_caf_num_images'
diffusion-coarray.f90:(.text+0xaa): undefined reference to `_gfortran_caf_this_image'
diffusion-coarray.f90:(.text+0xbd): undefined reference to `_gfortran_caf_this_image'
diffusion-coarray.f90:(.text+0xf4): undefined reference to `_gfortran_caf_num_images'
End etc.
Where is the problem?
Thanks for help. I've solved the problem. If anyone will be interested, here is my solution:
1. Install Linuxbrew following their instructions:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
test -d ~/.linuxbrew && PATH="$HOME/.linuxbrew/bin:$HOME/.linuxbrew/sbin:$PATH"
test -d /home/linuxbrew/.linuxbrew && PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
test -r ~/.bash_profile && echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.bash_profile
echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.profile
Install OpenCoarrays library brew install opencoarrays
Now we can compile files with caf and cafrun
Compile .exe-file caf fname.f90 -o test.exe
Run the program cafrun -np (numimages) test.exe
Hope it will be helpful for someone!
P.S. My OS is Ubuntu 16.04.4 LTS, gfortran: GNU Fortran 5.4.0 20160609 so the rest of necessary tools (for example, compiler caf and launcher cafrun are the part of OpenCoarrays package) will be installed by following the instruction.

TCL - undefined reference to `_imp__Tcl_ResetResult' for g++

I am relatively new to TCL and I am trying to execute a C++ program using SWIG on Windows 10. Using command prompt. I am not using Visual Studio
I am basically trying to run r_cpp using C++ MinGW from TCL
C:\swigwin-3.0.12\Examples\r\class>swig -c++ -tcl example.i`
C:\swigwin-3.0.12\Examples\r\class>g++ -c example.cxx
C:\swigwin-3.0.12\Examples\r\class>g++ -c example_wrap.cxx -I/Tcl/include/tcl8.6
C:\swigwin-3.0.12\Examples\r\class>g++ -shared example.o example_wrap.o -o example.dll
example_wrap.o:example_wrap.cxx:(.text+0x981): undefined reference to `_imp__Tcl_ResetResult'`example_wrap.o:example_wrap.cxx:(.text+0x995): undefined reference to `_imp__Tcl_SetObjResult'`example_wrap.o:example_wrap.cxx:(.text+0x9b9): undefined reference to `_imp__Tcl_SetErrorCode'
example_wrap.o:example_wrap.cxx:(.text+0x9cf): undefined reference to `_imp__Tcl_ResetResult'
example_wrap.o:example_wrap.cxx:(.text+0x9f3): undefined reference to `_imp__Tcl_SetErrorCode
example_wrap.o:example_wrap.cxx:(.text+0xa1e): undefined reference to `_imp__Tcl_AppendResult'
example_wrap.o:example_wrap.cxx:(.text+0xa3c): undefined reference to `_imp__Tcl_NewStringObj'
collect2.exe: error: ld returned 1 exit status
Can someone please help me on this??
Should I make changes to my Makefile.in in the folder?????
Its been a while since I've done C but I would think that you are not linking in the static/shared library that has the functions that g++ is complaining about. In this case the tcl library something like libTclXX.dll. I'm not too familiar with command lines on windows but something like -llibtclXX.dll -L path_to_tcllib could be added. If I recall correctly tcl does provide a stub library for you to link staticially your extension then at runtime the shared library can be use to resolve the functions... so something like -llibtclstubs.dll . look in your installed lib directory for actual names of these libraries.

mingw building error: undefined reference to `__chkstk_ms'

I've just installed mingw in windows, and I write a helloWorld program to test it. Code:
#include <stdio.h>
int main(){
printf("hello, world!\n");
return 0;
}
Result:
C:/MinGW/lib/crt2.o:crt1.c:(.text+0x1f1): undefined reference to `__chkstk_ms'
C:/MinGW/lib/libmingwex.a(glob.o):glob.c:(.text+0x5e3): undefined reference to `__chkstk_ms'
C:/MinGW/lib/libmingwex.a(glob.o):glob.c:(.text+0x690): undefined reference to `__chkstk_ms'
C:/MinGW/lib/libmingwex.a(glob.o):glob.c:(.text+0x7e9): undefined reference to `__chkstk_ms'
C:/MinGW/lib/libmingwex.a(glob.o):glob.c:(.text+0x82d): undefined reference to `__chkstk_ms'
C:/MinGW/lib/libmingwex.a(glob.o):glob.c:(.text+0xc0d): more undefined references to `__chkstk_ms' follow
There is a similar question asked here. But I checked the MinGW installation manager and it seems taht I didn't install old version of gcc or g++. Can any buddy help? Thanks!
By the way, since I'm using pythonxy as my python environment, there is also a C:/MinGW32-xy directory under my C:, which is not included in the system variable 'path'. Would that affect?
Well, I checked my system varialble in detail and found that the C:/MinGW32-xy/bin was before C:/MinGW/bin. So when I typed gcc -v in the command line, it shows that MinGW32-xy was at work. I switched their order, the problem was solved.
However, I don't really know the difference between the MinGW and MinGW32-xy. Can any buddy give me a hint?
i use mingw 4.7.1
i make a file name main.cpp in E:\Portable Apps
my gcc is in C:\Program Files\CodeBlocks\MinGW\bin
i type this in cmd (cmd = command line) and it work fine for me:
e:
cd\Portable Apps
"C:\Program Files\CodeBlocks\MinGW\bin\gcc" -c "main.cpp"
"C:\Program Files\CodeBlocks\MinGW\bin\gcc" "main.o" -o "hello 1.exe" -L"main.cpp"

Trying to understand linking procedure for writing Python/C++ hybrid

I want to start learning more about using SWIG and other methods to interface Python and C++. To get started, I wanted to compile this simple program mentioned in another post:
#include <Python.h>
int main()
{
Py_Initialize();
PyRun_SimpleString ("import sys; sys.path.insert(0, '/home/ely/Desktop/Python/C-Python/')");
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
pModule = PyImport_ImportModule("hello");
if(pModule == NULL){
printf("Error importing module.");
exit(-1);
}
pFunc = PyObject_GetAttrString(pModule, "Hello");
PyEval_CallObject(pFunc, NULL);
Py_Finalize();
return 0;
}
where the file "hello.py" just has the contents:
def Hello():
print "Hello world!"
Note: I already have python2.7-dev and python-dev and libboost-python-dev installed. But when I go to compile the code, I get errors that I believe are due to incorrectly linking to the Python libraries.
ely#AMDESK:~/Desktop/Python/C-Python$ gcc -I/usr/include/python2.7 test.cpp /tmp/ccVnzwDp.o: In function `main':
test.cpp:(.text+0x9): undefined reference to `Py_Initialize'
test.cpp:(.text+0x23): undefined reference to `PyImport_ImportModule'
test.cpp:(.text+0x58): undefined reference to `PyObject_GetAttrString'
test.cpp:(.text+0x72): undefined reference to `PyEval_CallObjectWithKeywords'
test.cpp:(.text+0x77): undefined reference to `Py_Finalize'
/tmp/ccVnzwDp.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
I was fishing around for examples of this online, and I found the following syntax, which causes the code to compile into an object file, but then I am unable to actually execute the file.
ely#AMDESK:~/Desktop/Python/C-Python$ gcc -c -g -I/usr/include/python2.7 test.cpp
ely#AMDESK:~/Desktop/Python/C-Python$ ./test.o
bash: ./test.o: Permission denied
ely#AMDESK:~/Desktop/Python/C-Python$ chmod ug=rx ./test.o
ely#AMDESK:~/Desktop/Python/C-Python$ ./test.o
bash: ./test.o: cannot execute binary file
ely#AMDESK:~/Desktop/Python/C-Python$ sudo chmod ug=rx ./test.o
ely#AMDESK:~/Desktop/Python/C-Python$ ./test.o
bash: ./test.o: cannot execute binary file
The same behavior as above is still seen if I use g++ instead of gcc.
Help in understanding my error in linking would be great, and even better for any sort of explanation that helps me understand the "logic" behind the kind of linking I need to do, so that I'll remember better what possible things I am forgetting the next time. Thanks!
What you are seeing are linker errors. To fix those, you need to link python2.7 library.
Try next line :
gcc -I/usr/include/python2.7 test.c -lpython2.7
it should work.
First, do you compile C or C++ code?
Use gcc for the former, and g++ for the latter. C++ code needs some additional linking to be performed.
Second: you have to link your program to libpython2.7.so to embed the interpreter into it. To do this, add -lpython2.7 to gcc command line.
test.o is not your executable file, that's why you can't execute it.
The default name for your program is a.out, try running that. You can specify a name for your program using the -o option.

Compile C++ and OpenSSL on Ubuntu 11.10

I got a serious problem compiling my C++ and OpenSSL project on my Ubuntu 11.10.
The compiling command is:
g++ -Wall -lssl -lm -lcrypto -I ./src ./src/server.cpp -o ./bin/server
I receive these errors:
server.cpp:(.text+0x8ff): undefined reference to `RSA_new'
server.cpp:(.text+0x92d): undefined reference to `PEM_read_RSAPrivateKey'
server.cpp:(.text+0xa85): undefined reference to `RSA_size'
server.cpp:(.text+0xaa1): undefined reference to `RSA_size'
server.cpp:(.text+0xae7): undefined reference to `RSA_private_decrypt'
server.cpp:(.text+0xd84): undefined reference to `BF_set_key'
server.cpp:(.text+0xf1d): undefined reference to `BF_ecb_encrypt'
server.cpp:(.text+0x13c6): undefined reference to `BF_ecb_encrypt'
collect2: ld returned 1 exit status
make: *** [server] Error 1
I successfully installed openssl and libssl-dev but the problem persists.
I tried to compile the project on Linux Mint 12 with the kernel 3.0 and I had the same problem.
On my old Linux OS with the kernel 2.6 the project compiled and worked fine (using the same Makefile and the same sources).
Please help me!
Generally you need to have the -l link flags after the code that references them. Try
g++ -Wall -I ./src ./src/server.cpp -o ./bin/server -lssl -lm -lcrypto
As the comment to this answer states, the linker only looks for undefined symbols to include in the order the parameters are listed.
That is, if your cpp file uses the libraries, the libraries have to be listed after the cpp file.
Those error are from crypto library, check whether ssl and crypto libraries are available in /usr/lib or where ever u installed if not install them and have u set the library search path for libssl and libcrypto in your compiling command?