Building shared library with Eclipse CDT directly - c++

I would like to move the building of my C++ project completely to Eclipse CDT, however I am facing some configuration problems. Here is my old g++ compiler call:
g++ -I/home/lib/tinyxml
-I/usr/lib/jvm/java-6-openjdk/include
-L/usr/local/lib -L/home/konrad/tinyxml
-lboost_system
-lboost_thread
-lboost_regex
-fPIC
-shared
-o libagent.so
agent.cpp AgentSocket.cpp ThreadInfo.cpp
/home/lib/tinyxml/tinyxml.cpp
/home/lib/tinyxml/tinyxmlerror.cpp
/home/lib/tinyxml/tinyxmlparser.cpp
/home/lib/tinyxml/tinystr.cpp
When creating the project I choose Shared Library > Emtpy Project
Here are my problems:
The Eclipse CDT generates the makefile in a way, it first compiles every .cpp file and then recompile it to the shared library. This let's me face one or more issues. I would like to jump this step and run it in the same way I did in the console.
I cannot configure -L and -l options into the C++ building configuration, as Eclipse CDT offers these option only for the C++ linking part, but not for the C++ compiler part, but I need them already there, as the project doesn't compile without errors.

That's not a problem, but actually how makefiles usually are constructed. This way, if you change one source file, you don't have to recompile all other source files, but only the one that has changed. It minimizes recompilation time.
That shouldn't be a problem, because they are options that are only used during linking. Compilation of source files into object files shouldn't depend on external libraries.

Related

C++ make link step : Undefined symbols for architecture x86_64

I am trying to link a compiled research experiment project, built in C/C++.
The project is dependant on HyperNEAT and robot simulation software WeBots.
I have cloned and built the HyperNEAT project successfully (in that project there are other dependancies such as Boost, TinyXML, JGTL (custom library) and other unrelated subprojects).
I have made a makefile including all neccesary header search paths and library paths, and compiling the two main .cpp files:
/ModHyperNEAT/mod_ctrler7.cpp
/ModSupervisor/mod_supervisor.cpp
works, giving me 2 .o files.
However, in the make link step, when I want to create (separate) executables of both files, I am getting the 'undefined symbols for architecture x86_64' error (see pastebin here: http://pastebin.com/kiwwCcUf). It seems that C++ standard datatypes and functions such as
std::string::end() const cannot be found.
I have googled and searched SO for answers regarding this, and it seems that either libraries are missing or binary incompatible if i understand correctly, but the libraries are there and both projects have been compiled with the -lstdc++ flag.
This is the make link step (and the used macro's from the makefile) :
CC = gcc
CFLAGS = -v -g -lstdc++ -Wall -Wno-error -ferror-limit=100 -fmessage-length=0
DEFINES = -DHCUBE_NOGUI -DTIXML_USE_STL
FLAGS = $(CFLAGS) $(DEFINES)
LIB_TINYXML = -L/Users/michahell/Documents/projects_c++/HyperNEAT/tinyxmldll/out
LIB_HYPERNEAT = -L/Users/michahell/Documents/projects_c++/HyperNEAT/NE/HyperNEAT/out
LIB_BOOST = -L/usr/local/Cellar/boost/1.57.0/lib
LIB_WEBOTS = -I/Applications/Webots/lib
LIBS = $(LIB_TINYXML) $(LIB_HYPERNEAT) $(LIB_BOOST) $(LIB_WEBOTS)
LIBFLAGS = -ltinyxmlpluslib -lboost_filesystem-mt -lboost_random-mt -lboost_system-mt -lNEATLib_d -lHypercube_NEAT_Base_d
WEBOTS_DYLIB = -dylib_file /Applications/Webots/lib/libController.dylib:/Applications/Webots/lib/libController.dylib
$(CC) $(FLAGS) $(LIBS) ./mod_ctrler7.o $(WEBOTS_DYLIB) $(LIBFLAGS)
I found out that to link to .dylib's I had to use a specific flag and specify the full path, hence the $(WEBOTS_DYLIB) macro.
I am using the -lstdc++ flag because in the HyperNEAT project that flag was also used for building that library. If i exclude this flag, i get a lot of errors during compilation (libc++ and libstdc++ incompatibility as I now understand). All of the library paths check out, and .a and/or .dylib files are present.
My knowledge of C/C++ and GCC tooling is very limited, as I have never had to use it before.
I think it might have to do with the fact that the HyperNEAT project contains a Boost 1.57.0 distribution which is used for their build, and that i have a separate (using homebrew) Boost version installed on my system, which is the same version:
$ brew info boost
boost: stable 1.57.0 (bottled), HEAD
http://www.boost.org
/usr/local/Cellar/boost/1.57.0 (10572 files, 439M) *
What could be the cause of this error failing my link step? Anyone should be able to reproduce my linker errors if both HyperNEAT and my project are cloned and put their root dirs in the same location. WeBots should be downloaded but only for the header includes and libraries. And of course my makefile paths should be modified.
If anyone can give me tips on how to solve this problem, i would GREATLY appreciate it!
It turns out that, for some reason, I had to include the lstdc++ flag to the library link flags and not as a compiler flag, AND the stdlib=libstdc++ as compiler flag.

NVCC attempting to link unnecessary objects

I have a project that I'm working on making run with CUDA. For various reasons, it needs to compile an executable either with or without GTK support, without recompiling all of the associated files. Under C, I accomplished this by compiling a base version of the objects to *.o and a GTK version of the objects to *.gtk.o. Thus, I can link to that library and if it needs to use GTK it will pull in those functions (and their requirements); if it doesn't it won't touch those objects.
Converting to nvcc has caused some issues: it works in either always or never GTK mode; but if I compile the libraries with the additional GTK objects, it refuses to ignore them and link a GTKless executable. (It fails with errors about being unable to find the cairo functions I call.)
I'm guessing that nvcc is linking to (at least one of) its helper functions embedded in the object, which is causing the linker to resolve the entire object.
Running ar d <lib> <objects.gtk.o> to manually strip them from the library will "fix" the problem, so there isn't a real dependency there.
I'm compiling/linking with
/usr/local/cuda/bin/nvcc --compiler-options -Wall --compiler-options -pipe
-rdc=true -O0 -g -G -I inc -I inc/ext -arch compute_20 -o program
program.cu obs/external.o libs/base.a libs/extra.a libs/core.a -lm
How can I get nvcc to ignore the unneeded objects?
How can I get nvcc to ignore the unneeded objects?
Before you can achieve that, you need to understand which symbol is causing the *.gtk.o objects to be pulled in from the library when they shouldn't be.
The way to do that is to run link with -Wl,--print-map, and look for linker messages such as:
Archive member included because of file (symbol)
libfoo.a(foo.o) main.o (foo)
Above, main.o referenced foo, which is defined in libfoo.a(foo.o), which caused foo.o to be pulled in into the main binary.
Once you know which symbols cause xxxx.gtk.o to be pulled into the link, searching the web and/or NVidia documentation may reveal a way to get rid of them.

Eclipse C++: Setting Compiler Options For Specific Files

I have a CUDA C++ project I am writing and compiling using Eclipse Nsight. My goal is to end up with an executable from the file that contains the main function, then to produce an individual shared library for each class in the project without needing to compile outside of the IDE. I can do this by creating a project for each class, then including all of them in the main project, but I would like a way to write all the files in a single Eclipse project and still end up with the desired artifacts. The project structure is as follows:
ClassA.h
ClassA.cu
ClassB.h
ClassB.cu
main.cpp
I am looking to compile the project and end up with the following artifacts:
ClassA.so
ClassB.so
main.exe
Ideally, I would like to know if there is a way to group specific files and set the compiler options for just that group of files. i.e.
nvcc ClassA.cu -shared -fPIC -o ClassA.so
nvcc ClassB.cu -shared -fPIC -o ClassB.so
g++ main.cpp -lClassA.so -lClassB.so -o main.exe
I know this is an unusual request, but this is part of a larger project architecture I am trying to bring from the land of emacs and compile shell scripts into the world of IDEs.
Option A: Write and maintain a custom make file.
Option B: Create 3 projects - exe and two shared libraries.

Having troubles with mixing library types (static vs. dynamic)

After battling my makefile woes I'm now onto problems with how the two libraries are supposed to interact. So, this is on Linux (CentOS 6.2 - 6.4, not that that seems to make much difference in terms of tools). The project, on the whole, is to be deployed in two flavors
A C++ Static library which is used for linking with other C++ appications (a *.a file)
A shared *.so which is deployed through python using Boost.python
I have everything compiling, but I'm not linking correctly somehow. In the case of the static library, it is built in two ways:
If meant to be linked with other C++ code, -fPIC is not used
If meant to be linked into the python module, use -fPIC
I control this through passing parameters to the make program. Presently, I'm trying to build the boost python module because the static stuff compiles just fine. So, I have dependencies on the boost libraries and zlib. The final linking command looks like this:
g++ -o pythonmod.so -L/boost/boost_libs -L/zlibs -lz -lboost_python -lboost_thread -lboost_regex -lboost_system /path/to/static.a -fPIC -shared [many_objects]
The "many_objects" comes from the various wrappers, and other code, that wraps the "pure" C++ from the boost.python layer in the code. Each of these object files are compiled with -fPIC as well. Their compiled with:
g++ -I/boost/boost_1_47 -I/usr/include/python2.6 -D _linux -MMD -std=c++0x -c -m32 -fPIC <input> -o <output>
The lines compiling the object files for the archive file look quite similar to the above only they do not include the python include directory.
I've found other links here to similar problems and tried the solutions but to no avail thus far. For example, this link uses -Wl,--whole-archive ... -Wl,--no-whole-archive. I tried this solution when I was trying to link in the static library archive before I was compiling it with -fPIC. Now that I'm doing that, I've tried this solution but also to no avail. In each case, every time I load up python and import the module, I get some sort of undefined symbol error --> something went wrong during linking.
How should I mix these libraries together to make the python module work?
After joining the gcc-help mailing list I received the pointer I needed to resolve the issue. The problem turned out to the ordering of the libraries used for linking on the build command line. Basically, the object files generated during the build for the *.so needed to be placed first. Then, the references to the boost and other libraries. Reordering the object files to reference the objects built for wrapping the static library before the other libraries was the key. No longer am I seeing weird "unresolved objects" when loading my python module.
After 4 or 5 years of using Visual Studio, my gcc knowledge had become sufficiently rusty that I'd forgotten the importance of ordering when it comes to linking.

Why doesn't exist a relink button in compilers?

I work in Linux with c++, using eclipse. But i have worked with Visual Studio too. They haven't got (or at least I donĀ“t know how to do it) a button to relink a project.
Example:
I have a big project (1), with hundreds of cpp. That project uses a small library (2) to do foo. If I change foo behavior, and compile it, generating a library, I need to clean the big proyect (1), re-compile, that links the external libraries (2) and works.
The problem is the big project doesn't change, but with hundreds of cpps, its compile time is about 5 min. 5 min is a small change in a second library.
Is possible to avoid this problem?
Thanks in advance
I suspect, but it is just a guess, your project is missing a dependency between your foo library and other deliverables in your project.
In this way, when you modify foo, the compiler does not know that it needs to recompile (as much as required by the change in foo) the rest of the project, and this forces you to manually clean and rebuild.
Usually a dependency is specified in a highly compiler-specific way, maybe this other post from S.O can help you, or just google "eclipse c++ dependency management".
You would generally use make with a makefile for this.
With this method, you can generate your own rules for building code, including bypassing compilation of lots of source files if you only thing needed is relinking.
For example, the makefile:
prog: main.o other.o makefile
gcc -o prog main.o other.o
main.o: main.c makefile
gcc -c -o main.o main.c
other.o: other.c makefile
gcc -c -o other.o other.c
would not recompile main.c if the only file you changed was other.c. It would simply compile other.c to make other.o, then link other.o and main.o together to create prog.
That's generally how it's done in the "command line" world. It's likely that it's also how it's done behind the curtains in many IDEs as well, just hidden from you.
What you'll need to find out is why the dependency checking is not working as expected. Without further information on how your project is set up, it's a little hard to be definitive.
Add your static library under the Linker-Settings->Miscellaneous->Other objects. Your executable will just be relinked, in case the library is newer. No compilation.