Why doesn't exist a relink button in compilers? - c++

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.

Related

Error when linking shared library after compiling objects

I compiled the object files, and then tried to compile the executable, which failed by saying that there are undefined references to functions in "theLib".
g++ -I./theLib/src -c -o obj/main.o src/main.cpp
(works so far)
g++ -L./theLib -Wl,-rpath=./theLib obj/main.o -ltheLib -o exe
(error: libtheLib.so: undefined reference to 'some_function')
I checked for answers everywhere, and they all just suggest moving the -ltheLib part after the dependencies (which I did). But it still doesn't work. What really boggles my mind is that the same library compiles just fine for an example in a different directory.
The library is in C. Can that mess up trying to compile C++? Or am I just missing something with compiling the .o files first?
Turns out the library depended on functions that I had to implement and provide in my own source code. I never knew that some libraries did that, but lesson learned. Once I implemented the functions that were causing the errors and added those source files, it worked.

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.

How to force Eclipse to use g++ instead of gcc?

I already asked how to call a C++ constructor from a C file in How to call a C++ constructor from a C-File. Now when I successfully apply these methods suggested there, I receive an error
fatal error: string: No such file or directory compilation terminated
this error message points to the line: #include <string> in a header of a .cpp file.
I already found out that <string> is used by c++/g++ and <string.h> by c/gcc. Well the problem got clearer, when I checked the console output and there I can see, the (.cpp) file with the error was called by the gcc, which actually expects the <string.h> but that's not my intention - I need to compile it with the g++.
Now my question is: Can I force Eclipse to use a specific compiler? Here, for example just g++ (I heared it is capable of C-code too.) - Or even better, is there a way to chose the compiler for each directory in the workspace ?
Thanks for your advises
Answer respecting the wish of being able to specify the compiler for every subfolder:
What you are searching is probably a makefile project. That allows you to specify the toolchain, being for example the preprocessor, compiler and linker. g++ is an example for such a toolchain, as much as clang++ would be.
You can generate such a project in eclipse, writing the makefiles by hand, or use some build environment, such as CMake, which I would recommend for better portable code.
Both solutions would allow you to specify the compiler, as well as the compile flags, for every single directory of your project, if you wished so.
Writing a makefile for your existing C/C++ project can be achieved by completing the following steps:
in the folder where your source file is, right click and create a new file. New > File
name it makefile and click Finish
The new makefile should pop up in the editor and can be filled like follows:
makefile:
all: executable_name
clean:
-rm main.o executable_name[.exe on windows] executable_name
executable_name: main.o
g++ -g -o executable_name main.o
main.o: main.cpp
g++ -c -g main.cpp
Change Project's Setting can force eclipse to compile using g++:

Build CUDA and C++ using Autotools

I'm setting up Autotools for a large scientific code written primarily in C++, but also some CUDA. I've found an example for compiling & linking CUDA code to C code within Autotools, but I cannot duplicate that success with C++ code. I've heard that this is much easier with CMake, but we're committed to Autotools, unfortunately.
In our old hand-written Makefile, we simply use a make rule to compile 'cuda_kernels.cu' into 'cuda_kernels.o' using nvcc, and add cuda_kernels.o to the list of objects to be compiled into the final binary. Nice, simple, and it works.
The basic strategy with Autotools, on the other hand, seems to be to use Libtool to compile the .cu files into a 'libcudafiles.la', and then link the rest of the code against that library. However, this fails upon linking, with a whole bunch of "undefined reference to ..." statements coming from the linker. This seems like it might be a name-mangling issue with g++ vs. the nvcc compiler (which would explain why it works with C code), but I'm not sure what to do at this point.
All .cpp and .cu files are in the top/src directory, and all the compilation is done in the top/obj directory. Here's the relevant details of obj/Makefile.am:
cuda_kernals.cu.o:
$(NVCC) -gencode=arch=compute_20,code=sm_20 -o $# -c $<
libcudafiles_la_LINK= $(LIBTOOL) --mode=link $(CXX) -o $# $(CUDA_LDFLAGS) $(CUDA_LIBS)
noinst_LTLIBRARIES = libcudafiles.la
libcudafiles_la_SOURCES = ../src/cuda_kernels.cu
___bin_main_LDADD += libcudafiles.la
___bin_main_LDFLAGS += -static
For reference, the example which I managed to get working on our GPU cluster is available at clusterchimps.org.
Any help is appreciated!
libtool in conjunction with automake currently generates foo.lo (libtool-object metadata) files, the non-PIC (static) object foo.o, and the PIC object .libs/foo.o.
For consistent .lo files, I'd use a rule like:
.cu.lo:
$(LIBTOOL) --tag=CC --mode=compile $(NVCC) [options...] -c $<
I have no idea if, or how, -PIC flags are handled by nvcc. More options here. I don't know what calls you are making from the program, but are you forward declaring CUDA code with C linkage? e.g.,
extern "C" void cudamain (....);
It seems others have run up against the libtool problem. At worst, you might need a 'script' solution that mimics the .lo syntax and file locations, as described on the clusterchimps site.

Building shared library with Eclipse CDT directly

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.