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

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.

Related

Undefined reference to __dso_handle_ - compiling C++ on cygwin

I have a basic Hello World C++ program that I am trying to compile and run on cygwin with g++. The code is:
#include <iostream>
using namespace std;
int main() {
cout << "Hello world." << endl;
return 0;
}
Compiling it with: g++ helloWorld.cpp -o h results in the following error:
/tmp/ccDO1S4J.o:helloWorld.cpp:(.rdata$.refptr.__dso_handle[.refptr.__dso_handle]+0x0): undefined reference to__dso_handle'
collect2: error: ld returned 1 exit status`
I have been reading up on some other threads that indicate that it might be a linker problem and that invoking the linker separately or with verbose output might lead to some more clues.
So, I did:
1. g++ -c helloWorld.cpp -o helloWorld.o (this works - no errors).
2. ld -o h helloWorld.o causes a lot of undefined reference to __main or std::cout etc. errors.
I think this is a linking issue and that I need to link another library perhaps. Any pointers on how to solve this are most welcome.
Re-installing g++ via the installer application on cygwin worked.

Cannot call XInitThreads

I have written an SFML C++ game, and tried to start using threads, but after a while everything crashes. After searching I found out the fix seems to be to call XInitThreads();
but this does not work somehow.
simplified code:
#include <X11/Xlib.h>
int main() {
XInitThreads();
//other stuff
return 1337;
}
The error message I get when i try to compile is "undefined reference to symbol 'XInitThreads'. Could it be that the header file is working but there is no file where that method is implemented?
"undefined reference to symbol" is a linker error, not a compiler error. If you get this message, the compiler has already finished compiled the file into an object file, but is unable to find the shared library which contains the function to link the object file into an executable.
If you're using gcc, it generally means you have to add some -l flags, like so:
$ gcc prog.c -lX11
note that the order of -lX11 in the compiler argument matters, you would get an error if you do this:
$ gcc -lX11 prog.c
/tmp/ccBCxiFT.o: In function `main':
:(.text+0x5): undefined reference to `XInitThreads'
collect2: error: ld returned 1 exit status
You should add link X11 library setting -lX11 to your project. If you are using Eclipse navigate to projectproperties->C/C++ Build->Settings->Tool Settings->GCC Linker->Libraries and add "X11"
Add header-
#include<X11/Xlib.h>
Compile your source code using-
gcc <filename.extension> -lX11
Tested in Ubuntu 16.04 LTS

Linker Error using g++ with Qt 4.5.1

I'm trying to test out a new dev environment and I am having some problems referencing some of the required Qt libraries.
First I ran this:
$ g++ HelloWorld.C -o HelloWorld -I /usr/local/Trolltech/Qt-4.5.1/include/QtCore/ -I /usr/local/Trolltech/Qt-4.5.1/include/
and got this error:
/tmp/ccmsm4kZ.o: In function `QString::QString(char const*)':
HelloWorld.C:(.text._ZN7QStringC2EPKc[_ZN7QStringC5EPKc]+0x1d): undefined reference to `QString::fromAscii_helper(char const*, int)'
/tmp/ccmsm4kZ.o: In function `QString::~QString()':
HelloWorld.C:(.text._ZN7QStringD2Ev[_ZN7QStringD5Ev]+0x2d): undefined reference to `QString::free(QString::Data*)'
collect2: ld returned 1 exit status
So then I added reference to the QtCore library via:
$ g++ HelloWorld.C -o HelloWorld -I /usr/local/Trolltech/Qt-4.5.1/include/QtCore/ -I /usr/local/Trolltech/Qt-4.5.1/include/ -L /usr/local/Trolltech/Qt-4.5.1/lib -lQtCore
which removed the compile errors, however when I try to run the program I get this error:
./HelloWorld: error while loading shared libraries: libQtCore.so.4: cannot open shared object file: No such file or directory
I wasn't able to find a solution for this problem via google. Anyone have advice?
That error indicates that while the linker can find the library at compilation, it can't find it during runtime.
You should update your LD_LIBRARY_PATH to include that location like this:
In ~.bashrc probably somewhere near the bottom:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/Trolltech/Qt-4.5.1/lib
Alternatively, if you want to make this persistent throughout your system (and have root access), you can make an entry in /etc/ld.so.conf.d (on RedHat, I'm not sure about the other distributions)
touch /etc/ld.so.conf.d/qt.conf
Add the path to this file, and then update your runtime via /sbin/ldconfig

Google RE2 library cannot compile with 'make testinstall' in ubuntu

Gurus!
I am using Ubuntu 13.10 64-bit to compile latest Google RE2 library, but 'make testinstall' failed to compile, here is the log:
kevin#ubuntu:~/re2$ make testinstall
cp testinstall.cc obj
(cd obj && g++ -I/usr/local/include -L/usr/local/lib testinstall.cc -lre2 -pthread -o testinstall)
/tmp/ccSsaSXS.o: In function main':
testinstall.cc:(.text+0xce): undefined reference tore2::FilteredRE2::FirstMatch(re2::StringPiece const&, std::vector > const&) const'
/usr/local/lib/libre2.so: undefined reference to pthread_rwlock_rdlock'
/usr/local/lib/libre2.so: undefined reference topthread_rwlock_wrlock'
/usr/local/lib/libre2.so: undefined reference to pthread_rwlock_destroy'
/usr/local/lib/libre2.so: undefined reference topthread_rwlock_init'
/usr/local/lib/libre2.so: undefined reference to `pthread_rwlock_unlock'
collect2: error: ld returned 1 exit status
make: * [testinstall] Error 1
I tried to replace -pthread with -lpthread, still failed, then I dumped libre2.so and found that pthread_xxx is in it.
Here is the issue tracking in RE2 forum: https://code.google.com/p/re2/issues/detail?id=100
Anyone here have ever complied RE2 successfully ? Thank you!
See this comment:
Adding -pthread to LDFLAGS seems to fix make test (all tests are
passing), but not make testinstall.
That will get you to the next error
Depending on what you build it for 'make testinstall' might not be necessary.
I just needed to get python re2 port working, and this can be installed after running make install.
I encounter this problem before. Modify the makefile and use -lpthread instead of -pthread.
So I tried looking for the lines in testinstall.cc that were causing the symbol errors and I found out that the only line was on line 18:
18 - f.firstMatch(:abbccc:, ids);
I commented this line out (so that the FullMatch function below is still called) and just ran g++ testinstall.cc -lre2 -pthread -o testinstall (basically what the Makefile does) and I was able to get a binary successfully. Although this might not really solve the problem, its good to know that we can still use the RE2::Fullmatch and partial match functions
If I were to guess, maybe there is a dependency somewhere inside the filtered_re2 module?
I had the same problem. But if you compile with -static everything goes well.
nm -C shows that the "missing" symbol exists in both .a and .so files.

Octave sample code failing to compile in g++?

I'm attempting to get the Octave C++ code here to compile in g++ (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 4.6.4).
This trimmed version of the above will compile in g++:
#include <iostream>
#include <octave/oct.h>
using namespace std;
int main() {
// Matrix L=Matrix(2,2);
return 0;
}
but if I unremark out the line Matrix L=Matrix(2,2); then compile with g++ temp.cpp it gives the error message:
/tmp/ccTa3Am5.o: In function `Array2<double>::~Array2()':
temp.cpp:(.text._ZN6Array2IdED2Ev[_ZN6Array2IdED5Ev]+0x1f): undefined reference to `Array<double>::~Array()'
/tmp/ccTa3Am5.o: In function `Array<double>::Array(dim_vector const&)':
temp.cpp:(.text._ZN5ArrayIdEC2ERK10dim_vector[_ZN5ArrayIdEC5ERK10dim_vector]+0x26): undefined reference to `Array<double>::get_size(dim_vector const&)'
/tmp/ccTa3Am5.o:(.rodata._ZTV5ArrayIdE[vtable for Array<double>]+0x10): undefined reference to `Array<double>::~Array()'
/tmp/ccTa3Am5.o:(.rodata._ZTV5ArrayIdE[vtable for Array<double>]+0x18): undefined reference to `Array<double>::~Array()'
collect2: ld returned 1 exit status
I'm unsure why. Perhaps I'm missing an #include, perhaps I don't have an appropriate file installed, perhaps I'm not linking to the appropriate library, or perhaps I'm misusing Octave in some way.
Question: Why is this failing to compile? How can I fix it?
It compiles fine if I use mkoctfile --link-stand-alone temp.cpp as indicated at the above site, however, I'd like to use g++ if possible, since I eventually want to be able to call Octave functions from another program I've written in C++.
As indicated in my comment a simple example can be found in this Howto. So in your case a simple way to achieve compilation will be creating a makefile as follows:
makefile:
all: temp
clean:
-rm temp.o temp
temp: temp.o
mkoctfile --link-stand-alone -o temp temp.o
temp.o: temp.cpp
g++ -c -I$(OCTAVE_INCLUDE)
-I$(OCTAVE_INCLUDE)octave -o temp.o temp.cpp
$(OCTAVE_INCLUDE) is an environment variable that should be set to your octave include path (e.g. /usr/include/octave-x.x.xx). Then you can simply compile and link your test application using the command make all.
You need to link to the octave library. If the library is octave.a:
g++ -loctave temp.cpp
Add the library directories to your link command:
your-local-path\octave-x.x.xx\lib\
your-local-path\octave-x.x.xx\lib\octave\x.x.xx\
mkoctfile -L"\your-path\octave-x.x.xx\lib" -L"\your-path\octave-x.x.x\lib\octave\x.x.xx" --link-stand-alone temp.cpp
For cxx11 linker errors:
Converting std::__cxx11::string to std::string
"If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC."
Defining the following macro before including any standard library headers should fix your problem:
#define _GLIBCXX_USE_CXX11_ABI 0