Shared library from C and C++ object files - c++

Can I create a shared library from the C and C++ object files?. If possible where should I use it? (in C/C++ applications or both).

You can create shared library from .o file (Create from C or C++ file) and use it into C or C++ application.
There is here and here tutorials about shared library that show how compile shared library and how use it.
If you have any question about it, you are welcome.

Not all situation you can do that. If you have source code, you can compile them as:
gcc -fPIC exam.c -o exam.o
gcc -shared exam.o -o libexam.so
PIC means position-independent code. And if a object file is compiled with -fPIC, it can be used to create shared lib.

Related

Why does including -fPIC to compile a static library cause a segmentation fault at run time?

I'm compiling C++ static library with g++ and using the -fPIC option. I must use the -fPIC option because eventually this library will be linked with other static libraries to form a dynamic library.
When I test the static library locally, it works completely fine when I don't include the -fPIC option. But as soon as I compile the library with -fPIC, I receive a segmentation fault error at run-time when calling one of the functions.
What reasons could including -fPIC to compile a static library cause a segementation fault at run-time?
A dynamic library is supposed to be loaded at run-time and can therefore not have position-dependent code.
A static library, on the other hand, is just an archive of object files.
When linking with a dynamic library, the linker adds the name of the library in the executable file, so the loader can load it when it loads the program. When the linker links with a static library, it basically extracts the object files and links with them like any other object file.
So unless you create an executable where all other object files are position-independent (you use -fPIC for your the programs code) then you can't link with a static library which uses position-independent code, the generated executable is simply not set up for it.

Should c++ object files be linked through g++ only?

I read somewhere that c++ object files must be linked only through g++ not gcc. Is it true? if yes, then how to link object files belong to c, c++ and asm?
If you use g++ to link, then it will automatically link with the C++ runtime library. If you link with gcc you have to link with the runtime manually.
That's the only difference.
The gcc and g++ programs are only special front-end wrapper programs, that invoke the correct preprocessor, compiler, assembler and linker for the files provided.
Yes, you have to use G++ to link C++ due to name mangling.
See the topic here https://en.wikipedia.org/wiki/Name_mangling
C++ names are C-abi compatible, you can link C++ object files to C code.

Building a static c++ lib on linux - do I need to link to other libraries?

I have been building a static library on Linux. So far it is purely self contained and all code inside does not use anything other than the standard library. I have recently made a change and now some compilation units are using boost code. I have been building the library using the following:
g++ -c -Wall -pedantic *.cpp
ar -cvq libbfclass.a *.o
My question is this: is it necessary for me to adapt this method to deal with the use of the new libraries or will I just need to provide the link library when building the executable that uses my own library? From what I understand a static library is basically just an archive of object files, but I was wondering if I need to modify my build scripts in order to make everything work as it should, or if it is only necessary when building executables???
You are correct - a static library is just an archive of object files. Symbols are resolved when you compile the final executable, so that's when you need to provide the references to the other libraries.

How to use Libraries

For some reason I'm never able to use external libraries in any language. I'm looking for instructions/explanations of how to use external libraries, as well as how they work. When I search online, I get fragments that never seem to apply to whatever library I download and try and use. I work on both a mac and a pc, and C++ examples are fine. I use eclipse IDE with the C++ plug in. If there are instructions that apply to all libraries that would be great.
Say you have a class Unuseful defined as follows:
File Unuseful.h:
class Unuseful {
public:
void printUnusefulStatement();
};
File Unuseful.cpp:
#include "unuseful.h"
#include <iostream>
void Unuseful::printUnusefulStatement()
{
std::cout << "Hello world!" << std::endl;
}
Now, you have another class that needs printing unuseful statements:
Unuseful u;
u.printUnusefulStatement();
This means that you want to use an external library containing the specific implementation (printUnusefulStatement) that you want to include in your code.
You may use this library in two ways:
By providing the source code to the compiler
By providing a binary file (which had been previously compiled for your architecture), to the linker
Case 1: using a library at compile time
This is the simplest case.
You have the source code of the library you have to use and you simply have to compile it together with your existing code (say main.cpp file).
Typically you are the author and user of the library (a class that accomplishes a task you need).
Compiling with this command:
g++ main.cpp unuseful.cpp
allows you to use the implementation you need in your main.cpp file.
Case 2: linking a library
More often than Case 1, you don't have the source code of the library you want to use. You only have the header file (Unuseful.h, to continue with the example) and a static or shared library (probably[*] libunuseful.a and libunuseful.so files, respectively).
The static library is an archive of object files (*.o) that are linked inside your final executables, the shared libraries instead are loaded dynamically - at run time (look at this page for a better understanding of the difference).
Static libraries are created by simply archiving the *.o files with the ar program:
# Create the object files (only one here)
g++ -c unuseful.cpp
# Create the archive (insert the lib prefix)
ar rcs libunuseful.a unuseful.o
Shared libraries are created with the g++ -shared option:
# Create the object file with Position Independent Code[**]
g++ -fPIC -c unuseful.cpp
# Crate the shared library (insert the lib prefix)
g++ -shared -o libunuseful.so unuseful.o
Let's suppose now you have the Unuseful.h file and the shared library (libunuseful.so file) and you have a main.cpp file that instantiates a Unuseful object and calls the printUnusefulStatement method.
If you try to compile this file (g++ main.cpp) the linker will complain because it cannot find the printUnusefulStatement symbol.
It's time to use the library:
g++ main.cpp -L. -lunuseful
The -L option tells the linker where to search for library files and the -l flag tells the linker the name of the libraries to be used (without the lib prefix).
Now the executable (a.out, because I didn't specify a different name) is created, and you have used a library to implement a functionality you needed (printUnusefulStatement).
Since the shared library is loaded at run-time, the execution of the a.out executable may fail because the system is not able to find the library.
Typically this can be solved by appropriately setting an environment variable indicating which paths to use to search for dynamic libraries:
# Set the LD_LIBRARY_PATH [*]
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
Done, now your executable has been compiled and it will be able to run and load the library it needs.
Conclusion
This is a rapid overview on libraries which I hope can help you understand how they are used and provided to others.
There are many many aspects that should be investigated in more detail, if you are interested: g++ options when creating shared libraries, ar options, environment variables, the shared libraries format and so on.
[*]: In a Unix environment
[**]: If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines. [From the g++ man page]
Here's where you start
http://en.wikipedia.org/wiki/Library_(computing)
Basically, a 'library' is a collection of compiled functions and class declarations.
On a Mac there are also "frameworks" which are somewhat similar to Pascal's units and contain both the declarations and the compiled code.
In managed languages like Java or C# there are packages and assemblies. Both are closely related to libraries.
To use libraries in C or C++ you've got to have a .lib-file (or .a-file for most POSIX or GCC toolchain based compilers) and the prototypes of the functions which are compiled into the .lib file. Depending on your development environment (for Eclipse you are most likely using the GCC compiler and GNU toolchain with LD linker), you just specify the library files (.lib or .a) as the input to the linker. Most of the time the library is accompanied with header files which contain the definitions of function prototypes.
Even if you did not know about the linker, which is strange enough, the libraries are still used in your program implicitly - the std::cout is in the libstdc++ or the C Run-Time Library.
As an example of a huge library and a useful set of C++ classes you might want to look at Boost.
To write GUI on Windows you can use the WinAPI which is described in MSDN.
To write GUI on Mac you can use Carbon API which is somewhat similar to WinAPI, but is now deprecated. The only way to write "legit" GUI for MacOS is to use Cocoa and Objective-C.
To write cross-platform GUI you can use a lot of libraries: Qt, wxWidgets, GTK among them.
The last, but not the least. C++ is not the best language for GUI.
The best way to use external C++ libraries is make use of a C++ package manager, go and learn one of these:
conan
vcpkg
hunter
cppan
build2
Some of them involve using CMake, you can find a well written tutorial on it here.
.

Can I build a shared library by linking static libraries?

I have a bunch of static libraries (*.a), and I want to build a shared library (*.so) to link against those static libraries (*.a). How can I do so in gcc/g++?
You can (just extract all the .o files and link them with -shared to make a .so), but whether it works, and how well it works, depends on the platform and whether the static library was compiled as position-independent code (PIC). On some platforms (e.g. x86_64), non-PIC code is not valid in shared libraries and will not work (actually I think the linker will refuse to make the .so). On other platforms, non-PIC code will work in shared libraries, but the in-memory copy of the library is not sharable between different programs using it or even different instances of the same program, so it will result in HUGE memory bloat.
I can't see why you couldn't just build the files of your dynamic library to .o files and link with;
gcc -shared *.o -lstaticlib1 -lstaticlib2 -o mylib.so