issue with linking c/c++ - c++

I have a bit of an issue in static linking. I have a static library (libkells.lib) which is made up of a header file containing function declarations and a .cpp file containing the function implementations. I successfully compiled the two into an .o file and then built the static library out of them.
Then I have a file mcmd.cpp which calls the functions in the .lib file. I have included the header file involved in the static library into this mcmd.cpp file. This file (mcmd.cpp) successfully compiles into an .o file but when I try to build it into an executable file, my compiler returns a message like this:
libkells.lib(libkells.o): In function ZNKSt13move_iteratorIPSsE4baseEv
. Undefined reference to __cxa_end_catch, Undefined reference to
__cxa_begin_catch
and so many other errors. When I look keenly at these error messages, these errors seem to originate from some header file called include/c++/bits/stl_iterator.h. I'm using mingw 4.7.1 on Windows. What is it that I'm not doing right?

You are not linking against libstdc++ or not using g++, in short the 'gcc' driver, being the C driver, not the C++ driver, doesn't link the C++ runtime at the end. If you want, you can explicitly add -lstdc++ to the command line, or, definitely the first choice in general, just use 'g++'

Related

Undefined symbol issue with Makefile

I am writing a Makefile and I have a Views.h with functions being declared in it that are being called in Views.cpp. Views.cpp #includes "Views.h", so I am sure I am linking them correctly.
However, I still get a bunch of undefined reference errors in my Views.cpp when I run the make command. The undefined reference errors are all regarding the functions in Views.h.
I believe the problem is that the functions in View.h are being declared there, not actually defined or implemented, and are actually in a .lib file in a folder called Library in my project directory.
My issue then is how do I write a Makefile that links the .lib file to my Views.h file, so that my Views.cpp can use the functions?
Also, I have the corresponding .dll file as well. I understand both are library files, 1 is dynamic and the other is static. But how do I link them?

Mixing C++ code with C code in a library produces undefined symbol errors

I have a library that consists of some .c modules and some .cpp modules. I assume that's fine when the library is linked into a C++ main program. But when I attempt to link that library into a C program, I get linker errors for 'standard C++ library' modules.
gcc -o PSEQ.app -Xlinker --allow-shlib-undefined pseq.app.o -L../librep -lrep
..librep/ssuinventbean.cpp:62: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
The program in question is not written in C++ - and it does not reference the ssuinventbean.cpp module. I asked a similar question about unreferenced shared library modules complaining about stuff called from there, and was told that the --allow-shlib-undefined linker flag could be used to get around that. I tried using that flag in the gcc command above, but obviously it doesn't work as advertised when the library in question is a statically linked library.
Normally, that wouldn't be a problem. I can make sure that all the modules in my application libraries have all of their references satisfied. But in this case, the reference is to the standard C++ library, which I assume would've been included if the main module of the program in question were in C++. So, catch-22? Can I not have C++ code in a library if that library will be linked against a non-C++ app - even if the .cpp module in question is never referenced? Do I have to segregate all C++ library code into its own .a files to be included only when building apps that call that code?
I found out what was causing this. It turned out that somebody had put a variable definition into a .h file that was pulled into this .cpp file. I guess it's undefined what the compiler will do with a global variable in a .h file (it could end up getting defined in multiple .c or .cpp files that pull it in).
Anyway the .cpp file in question apparently pulled in that .h file as extern "C" code, which caused something else to pull in the .cpp module (presumably to pick up the global variable). After I commented out the global variable in the .h file, the app was able to build with gcc instead of g++ on the linker line in my makefile. Problem solved.
It turns out that the link maps generated in linux by these flags are very useful. Told me that the global variable was what caused the otherwise unreferenced .cpp module to be included...
MAPFLAGS = -Xlinker --cref -Xlinker -Map=MAP

SWIG undefined symbols

I am using SWIG to wrap C++ code in Ruby.
I have eight classes defined in eight separate files in a specific location. I had two approaches to wrapping them in Ruby.
In the first approach, I put all the classes in one file, placed that file in the same directory as the SWIG interface file and everything is okay.
I am, however, requested to link to the original location of the files, and have my interface file in a different directory. When I compile, I compile all the files in their directory plus the wrapper code and there are no errors produced. However, I get undefined symbols.
A part of my compile shell script is:
g++ -std=c++11 -fPIC -c ../../dir1/dir2/Class.cpp
g++ -std=c++11 -fPIC -c mymodule_wrap.cxx -I/usr/include/ruby-1.9.1 -I/usr/include/ruby-1.9.1/x86_64-linux
I compile all the other seven files in the same way as the "File.cpp" one. No compilation errors.
Then, when I try the following
require 'mymodule'
c = Mymodule::Class.new
I get an undefined symbol for the Class' constructor (I demangled the undefined symbol using c++filt), which is declared and defined.
Is there something wrong in the way I compile? Or are there some problems when it comes to different locations of the header/source files and the SWIG interface file? Because this is in no way different from when I have all the classes in one file, except for the location.
EDIT:
If i move the definitions of the declared functions in the header files I get no undefined symbols. That means that it actually doesn't even reach the definitions in the cpp files. But why? When I had all classes unseparated I still kept the definitions in a cpp files and the declarations in a header file...
When creating the shared library, it didn't know where the object files of the source code were, therefore it never knew the definitions of whatever was declared in the header files.
For me, all the object files were created in the same folder as the interface file where I was compiling everything, and I added this:
g++ -shared Class.o mymodule_wrap.o -o mymodule.so
to my compile shell script. Before I was using the extconf makefile creating script, and I am not sure where it searched for the object files.

Trouble including third-party code in my C++ application

I'm trying to include some networking code into my C++ application. I downloaded CSimpleSocket and I copied all the .h and .cpp files into the directory where my main file is. Then I tried including one of the headers, but the linker just barfs up a bunch of errors, like:
[Linker error] undefined reference to CPassiveSocket::CPassiveSocket(CSimpleSocket::CSocketType)'
[Linker error] undefined reference to `CSimpleSocket::Initialize()'
[Linker error] undefined reference to `CPassiveSocket::Listen(unsigned char const*, short, int)'
[Linker error] undefined reference to `CPassiveSocket::Accept()'
and others. Everything is in one directory, so I don't think that's the problem. The code I'm using to include is #include "PassiveSocket.h". I'm using Dev-C++, if that makes any difference. I don't understand what I'm doing wrong, so if somebody could help me, that would be great.
Forgive me if this is a really dumb question, but I'm trying to learn C++, and it's not easy. Thanks for your help.
The reason you're getting this error is because your compiler can't find the binary that corresponds to the CSimpleSocket headers. It's as if you wrote
void someFunction(int someArg);
And then never provided the implementation for someFunction.
To use a third party library you need two things:
Header files (.h, .hpp, etc...)
Library files (.a, .lib, etc...)
Once you've got your header files and library files you need to put them in a place your compiler can find them. This place will vary depending on your OS, environment variables and compiler configuration.
Now that they're somewhere the compiler can find them you need to tell the compiler to use them. Header files are used with the #include command and library files are linked by providing arguments to the compiler.
Behind the scenes Dev-C++ uses the MinGW GNU GCC compiler, it invokes a command similar to g++ file1.cpp file2.cpp ... filen.cpp -o filename that tells the program g++ to compile a C++ executable named "filename" using files 1 to n. There are other flags that can be added to g++ such as telling it where to search and what to link.
The name of the CSimpleSocket library when compiled is "clsocket" so we need to find a way to configure Dev-C++ to add -lclsocket to the g++ command. I don't use Dev-C++ so I can't help you here but you're probably looking for "Linking Options" or something similar in your compile configuration. You also need to make sure the .lib and .h files are on the search path which should also be configurable in Dev-C++.
CSimpleSocket also provides an installer that should automatically create the .lib file and place the .lib and .h in places where they can be found, you should consider using that installer.
I think the complexity of this answer highlights the abysmal state of the C++ library integration ecosystem. Unfortunately there is no concept of a "module" in C++ at the time of writing.

How to compile an application that uses head files from source?

This question has probally been answered countless numbers of times - there have been simular questions which I've read about but I just still don't understand it.
I have the sources to the libaiml project - a C++ interrepter for aiml a specification for a chatterbox program.
Within the source of the example program, it contains an #include call to a header file :
#include "../src/aiml.h"
the header file is there, I compiled and linked the program and it states that the header file can't be found.
Various of answers state that the header file needs to be compiled into a static library (a .a file) but how would the program reference the .h file when it's not compiled into the library binary?
Also I tried to compile the srcs into a library with G++ and ar , but it contains alot of errors.
Am I doing anything wrong?
Am I doing anything wrong?
Yes: you completely mis-stated what actually happens to you. You said "it states that the header file can't be found", and "I compiled and linked the program".
But what's really happening is that you've compiled and failed to link the program, and the errors have nothing to do with the header file; rather you are getting missing symbols at link time.
To fix your problem, you must link the libaiml library to your executable (this library should have been built when you built in the ../src/ directory. Something like this should work:
g++ -I../src -o program program.cc -L../src -laiml