HI all
I am trying to use SWIG to export C++ code to Python.
The C sample I read on the web site does work but I have problem with C++ code.
Here are the lines I call
swig -c++ -python SWIG_TEST.i
g++ -c -fPIC SWIG_TEST.cpp SWIG_TEST_wrap.cxx -I/usr/include/python2.4/
gcc --shared SWIG_TEST.o SWIG_TEST_wrap.o -o _SWIG_TEST.so -lstdc++
When I am finished I receive the following error message
ImportError: ./_SWIG_TEST.so: undefined symbol: Py_InitModule4
Do you know what it is?
It looks like you aren't linking to the Python runtime library. Something like adding -lpython24 to your gcc line. (I don't have a Linux system handy at the moment).
you might try building the shared library using gcc
g++ -shared SWIG_TEST.o SWIG_TEST_wrap.o -o _SWIG_TEST.so
rather than using ld directly.
As Mark said, it's a problem linking to the python library. A nice way to get hints as to just which flags you need to successfully link can be gotten by running python-config --ldflags. In fact, a particularly painless way of compiling your test is the following:
swig -c++ -python SWIG_TEST.i
g++ -c `python-config --cflags` -fPIC SWIG_TEST.cpp SWIG_TEST_wrap.cxx
gcc --shared `python-config --ldflags` SWIG_TEST.o SWIG_TEST_wrap.o -o _SWIG_TEST.so -lstdc++
Note that python-config isn't perfect; it sometimes gives you extra things, or conflicting things. But this should certainly help a lot.
Related
There are similar questions but their answers did not work for my issue.
I have a c++ program with #include <boost/test/unit_test.hpp> on top (among other includes).
To compile correctly, if I understood, I should do the command:
g++ -g -L/path_to_boost_lib -lboost_lib myprog.cpp -o myprog.exe
If i do a locate, I get /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.
Hence I edited my call to g++ by doing:
g++ -g -L/usr/lib/x86_64-linux-gnu -lboost_unit_test_framework myprog.cpp -o myprog.exe
But I still get errors of the type undefined reference to boost::unit_test.
I also tried the option -I/usr/include/ which contains the boost folder, without success.
It's because of the order. The GCC linker goes through the artifacts left-to-right, and every unknown symbol it encounters in an object file must be resolved by an artifact occurring afterwards.
The right command is thus:
g++ -g myprog.cpp -L/usr/lib/x86_64-linux-gnu -lboost_unit_test_framework -o myprog.exe
See this answer for a more thorough explanation.
I suggest using a build tool like CMake that takes care of such low-level details for you.
I am creating a gcc shared library having a static library dependency.
I compile the parts for static library as following:
gcc -c -m64 -O2 -fPIC -std=c99 -Wall ms*.c //there are 10 C files, no warnings
Next I create a static library with:
ar rc static_lib.a ms*.o
Next I compile the parts for my program as following:
g++ -c -m64 -O2 -fPIC -std=c++14 -Wall ab*.cpp //there are 5 C++ files, just -Wunused-variable warnings
Then I create a shared library as following:
g++ -shared -g -Wall ab*.o static_lib.a -o shared_lib.so
in the normal case, this shared_lib.so will be called by a Ruby program using a foreign function interface. There is no problem if I do it on ubuntu or mac(.dylib), but if I try this on debian stretch I get an error related to the static library as if the configurations are not set properly. If I run the application without foreign function interface, such as creating a tester and running with the cpp file main function as following:
> g++ -o library_test ab*.o static_lib.a
> ./library_test
There is no problem!
My question is what kind of configuration for creating a shared library may be missing here to not get that undesirable behaviour. Especially on debian stretch 9.5!
Or is there a way that I can understand if there is a problem in the shared library.
From the comments, you indicate the problem is with a #define. Those are preprocessor directives. Libraries are for the linker.
You might be confused because g++ does include the preprocessor phase, and might call the linker depending on the requested output. Still, g++ follows the C++ language rules.
I am trying to get the Cplex basic LP example to work. The code can be found here. I am completely new with c++, but hope to be able to get this running.
I am trying to compile it on linux. I am using the following command to run it
g++ -D IL_STD -I /opt/ibm/ILOG/CPLEX_Studio1271/opl/include ilolpex1.cpp
The -D IL_STD was put there to solve an error as found here. The -I ... was put there to specify the location of the header files. I came up with this myself after a lot of trying and googling, so i am in no way sure this is correct.
Anyway, i when i run it i get errors of undefined references:
/tmp/ccl9O1YF.o: In function `populatebyrow(IloModel, IloNumVarArray, IloRangeArray)':
ilolpex1.cpp:(.text+0x18f): undefined reference to `IloNumVar::IloNumVar(IloEnv, double, double, IloNumVar::Type, char const*)'
I did not make any changes in the file, so i assume the only thing which can be wrong is how the files are linked. I have the feeling it probably just is a simple setting, but after hours of looking i still have no idea how to fix it.
The easiest way to compile the ilolpex1.cpp example is to use the Makefile that is included with the installation. For example, you should do the following:
$ cd /opt/ibm/ILOG/CPLEX_Studio1271/cplex/examples/x86-64_linux/static_pic
$ make ilolpex1
This will produce output, like the following:
g++ -O0 -c -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include ../../../examples/src/cpp/ilolpex1.cpp -o ilolpex1.o
g++ -O0 -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include -L../../../lib/x86-64_linux/static_pic -L../../../../concert/lib/x86-64_linux/static_pic -o ilolpex1 ilolpex1.o -lconcert -lilocplex -lcplex -lm -lpthread
This will tell you everything you'll need to know if you choose to compile your own application by hand in the future. The details about this are described in the documentation (e.g., here).
Obviously, the iloplex1.cpp file is just a demo how to use IloCplex.
What you yet need is IloCplex itself. This should come either as (a) further source file(s) you have to compile with the demo or as a library you link against.
Have a look at your cplex directories, you might find a lib[...].a file somewhere there, possibly in /opt/ibm/ILOG/CPLEX_Studio1271/opl/lib.
You can link against using GCC's (clang's) -l and -L options. Be aware that when using -l, you leave out lib and .a (-l [...] with above (invalid) sample name).
I am trying to use v8 in a Dart native extension.
The v8 getting started guide says to compile the hello world example like this.
g++ -I. -Iinclude samples/hello-world.cc -o hello-world -Wl,--start-group \
out.gn/x64.release/obj/{libv8_{base,libbase,external_snapshot,libplatform,libsampler},\
third_party/icu/libicu{uc,i18n},src/inspector/libinspector}.a \
-Wl,--end-group -lrt -ldl -pthread -std=c++0x
Dart says to compile native extensions like so:
g++ -fPIC -I{path to SDK include directory} -DDART_SHARED_LIB -c sample_extension.cc
gcc -shared -m32 -Wl,-soname,libsample_extension.so -o libsample_extension.so sample_extension.o
This is the hybrid I came up with
g++ -fPIC -I{path to SDK include directory} -Iinclude -DDART_SHARED_LIB -c sample_extension.cc -std=c++0x
gcc -shared -Wl,-soname,libsample_extension.so -Wl,--start-group out.gn/x64.release/obj/{libv8_{base,libbase,external_snapshot,libplatform,libsampler},third_party/icu/libicu{uc,i18n},src/inspector/libinspector}.a -Wl,--end-group -o libsample_extension.so sample_extension.o -lrt -ldl -pthread -std=c++0x
However, while trying to run my application, I get an error stating that v8 is not linked properly.
dart: symbol lookup error: /mnt/c/Users/zvacu/Documents/Code/Dart/require/libsample_extension.so: undefined symbol: _ZN2v82V828InitializeICUDefaultLocationEPKcS2_
I can manage to link it properly when using the hello world example provided.
Doing a little research it seems like the problem it is on the -shared property on the second command. You need to pay attention with C++ and shared libraries, so check if your library get's all its dependencies by:
ldd /mnt/c/Users/zvacu/Documents/Code/Dart/require/libsample_extension.so
After this you will get a list of all dependencies, then you will need to search if there is anyone missing.
If this does not answer your question, see this related answer:
Undefined symbol when loading a shared library
I have a requirement of creating a C++ program which exposes certain functions through HTTP. For that reason I was trying to use libmicrohttpd for the same. Now this library is written in C. However I am kind of new to C++ and am trying to compile this C and C++ code given here. (Which can be git cloned from here)
Now I need help in understanding how g++ may be used to compile a program which is not written completely in C++. And/or how to compile the above linked code.
PS: Working in linux
And finally if someone can point to an easier alternative than libmicrohttpd - I am all ears.
Edit to Edit:
Finally got it working. Compiled the individual cpp files with gcc and then linked everything using g++. I have no clue how this came to work, maybe some one can reply below.
I have made the following script to compile and link:
LOC="path/to/directory"
gcc -c httphandler.cpp -o httphandler.o -I $LOC
gcc -c strutil.cpp -o strutil.o -I $LOC
gcc -c api.cpp -o api.o -I $LOC
gcc -c executor.cpp -o executor.o -I $LOC
g++ -o out httphandler.o strutil.o api.o executor.o -lmicrohttpd -lboost_regex
But in the final step I am getting the following error:
/usr/bin/ld: strutil.o: undefined reference to symbol '__cxa_free_exception##CXXABI_1.3'
/usr/bin/ld: note: '__cxa_free_exception##CXXABI_1.3' is defined in DSO /usr/lib/x86_64-linux-gnu/libstdc++.so.6 so try adding it to the linker command line
/usr/lib/x86_64-linux-gnu/libstdc++.so.6: could not read symbols: Invalid operation
What gives?
For starters, don't compile the C code with g++, use gcc instead. Then just include the header file and use the functions normally. When linking don't forget to link with the object file(s) generated from compiling the libmicrohttpd source file(s).