Create STATIC and SHARED libraries with Clang - c++

What is the minimal commmand line way to create an static and a dynamic library with Clang under Linux and Windows, and then, link it against an executable?
Suppose the project contains a main.cpp file with the main function, an lib_header.h file under /include/project_name and a lib_source.c or lib_source.cpp under /src
Thanks

For both static and dynamic libraries, you first compile the source files individually:
clang -c -o lib_source.o lib_source.c -fPIC
For the static library on Linux, archive all .o files together:
ar r library.a lib_source.o
For the shared library, link with the -shared flag:
clang -shared -o library.so lib_source.o

Related

linker delets library and does not recognize it

I am compiling a C program with g++ and linking it to a library mylib.lib which is located in the same folder as the sourcecode by:
user$ g++ myprog.c -o mylib.lib
and the compiler behaves in a strange way. first of all it gives the error 'undefined reference to fun1' . this should not happen because fun1 is in mylib.lib. secondly it deletes mylib.lib . I also tried a different way:
user$ g++ myprog.c mylib.lib
In this case I get the same error: 'undefined reference to fun1'
Finally I tried to add mylib by:
renamed mylib.lib to libmylib.lib
2.
user$ g++ myprog.c -L/Dima/Tests -l mylib
In this case the error is 'cannot find lmylib' although it is located in /Dima/Tests. how do I compile it correctly?
You're not building a library, you are trying to create an executable program named mylib.lib. That's why the linker is invoked.
If you want to create a library, it depends on the toolchain you target, but generally speaking you only create object files, and create an archive of those object files.
For the GNU toolchain (GCC and the GNU binutils linker) you use the ar program to create this archive.
$ g++ mylib.c -c # Create object file named `mylib.o`
$ ar crv libmylib.a mylib.o # Create the static library
Now you have a static library containing the object file myprog.o which is compiled from myprog.c. To use it do something like
$ g++ myprog.c -L. -lmylib -o myprog
The above command tells the linker to look in the current directory (-L.) and link with the library mylib (the linker automatically looks for libmylib.a).
Also, when using the GNU linker it's important that you put the libraries after any source or object files.

How do you link a static library to a shared library

I'm trying to link a static library to a shared library via a command like
g++ -shared obj.o archive.a -o libLib.so
But at run time I keep getting unresolved system that should be link at compile time from archive.a. I've tried
g++ -shared obj.o -Wl,-Bstatic archive.a -Wl,-Bdynamic -o libLib.so
and
g++ -shared obj.o -Wl,-whole-archive archive.a -Wl,-no-whole-archive -o libLib.so
with no success. I feel like I'm missing something basic here...
You practically cannot (i.e. should never) do that. Shared libraries should be position independent code, but static libraries are not.
If you want to link libaa into libfoo.so build or get a shared (PIC) library libaa.so, not a static (non-PIC) library libaa.a
So a file foo1.cc going into a shared library libfoo.so should be compiled as
g++ -c -fPIC -Wall -O foo1.cc -o foo1.pic.o
and the library will be linked as
g++ -shared foo1.pic.o foo2.pic.o -o libfoo.so
You could link another shared library libsmiling.so into libfoo.so e.g. by appending -lsmiling to the above command. But you can't link libraries into static libraries, just copy their members.
But a file going into a static library libfoo.a is just compiled as
g++ -Wall -O foo1.cc -o foo1.o
so when you extract that foo1.o member from libfoo.a it is not PIC (and that is very inefficient)
In principle you could put a non-PIC object code in a shared library. In practice, you should never do that, because the amount of relocation is so large that it defeats the purpose of shared libraries. If you did that, text memory won't be sharable and the dynamic linker would have a lot of relocation work.
Code inside .so shared objects should be PIC to permit ld.so to mmap it at different address segments in different processes.
So you could find a sequence of commands to link a static library into a shared one, e.g. extract using ar x all the members of the libbar.a then link all these extracted bar*.o with foo*.pic.o but that would be a mistake. Don't link static non-PIC libraries or object files to PIC shared libraries.
For details (with a focus on Linux) read ld.so(8), ld(1), ELF wikipage, Levine's book: Linkers and loaders, Drepper's paper: How To Write Shared Libraries
PS. Some very few static libraries contain PIC code because they could be used to make shared libraries. For example my Debian provides the libc6-pic package giving notably the /usr/lib/x86_64-linux-gnu/libc_pic.a static PIC library -usable to build some variant of libc.so -e.g. if I wanted to put my own malloc in libc.so! - without recompiling every glibc source file.

An executable and a shared library dependent on a same statically linked library

Suppose you're developing a shared library libshared.so.
And you have a static library libstatic.a with some internal classes and functionality you need. You'd like to link it to your .so like this:
g++ -o libshared.so -shared myObj.o -lstatic
Also you have an executable.sh which will use your .so and dynamically open it in the runtime
dlopen("libshared.so", RTLD_NOW)
You know this executable was as well statically linked against libstatic.a (but you're not sure the version of the library is exactly the same as yours).
So the question is:
Is it safe and correct to statically link your libshared.so against libstatic.a when you know the same library is already used in executable.sh?
You should avoid linking a static library into a shared one.
Because a shared library should have position independent code (otherwise, the dynamic linker has to do too much relocation, and you lose the benefits of shared libraries), but a static library usually does not have PIC.
Read Drepper's paper: How to write a shared library
You build your library with
g++ -Wall -O -fPIC mySrc.cc -c -o myObj.pic.o
g++ -o libshared.so -shared myObj.pic.o -lotherlib

Linux executable file as shared library

I'm trying to compile an executable file which i want also to use as shared library. When i'm clearly compile and linking it as "executable" - everything fine - file could start and work correctly. At this phase i cant correctly linking other libraries with it (tons of redefinitions in log). When i'm trying to add options -Fpic -shared - program copiles successfully, but starting with segmentation fault. How can i make it executable and "sharedlibrary" at the same time?
A single file cannot be a shared library and an executable at the same time. But you can link your object files twice to make both. It'd go something like this:
g++ -c -o module.o module.cpp # create an object that has no main()
g++ -shared -fPIC -o libmodule.so module.o # build shared library
g++ -o program module.o main.cpp # build executable
Or instead, the last line could link the shared library (in which case you'll need the library present when you run the executable):
g++ -o program -l module main.cpp

How to create a shared library (.so) in an automake script?

Given some source file test.cpp I would like to create a shared library libtest.so . I am trying to do this within the scope of an automake file however I cannot seem to get this to work.
For example under g++ I do the following:
g++ -shared -fPIC test.cpp -o libtest.so
Then I can create another file that will depend on the shared library as follows:
g++ mytest.cpp libtest.so -o blah
I have read that automake only supports making shared libraries via libtool. I have tried to get my automake script to work as follows but it never seems to produce an .so . The closest I have gotten is for it to produce an .la and .o file:
In configure.ac:
AC_ENABLE_SHARED
AC_DISABLE_STATIC
AC_PROG_LIBTOOL(libtool)
in Makefile.am
lib_LTLIBRARIES=libtest.la
libtest_la_SOURCES=test.cpp
libtest_la_CFLAGS=-fPIC
libtest_la_CPPFLAGS=-fPIC
libtest_la_CXXFLAGS=-fPIC
libtest_la_LDFLAGS= -shared -fPIC
Could someone give me an example of building an .so based on the above?
If you just put LT_INIT in configure.ac and in Makefile.am, do:
lib_LTLIBRARIES = libtest.la
libtest_la_SOURCES = test.cpp
libtest_la_LDFLAGS = -version-info 0:0:0
you should get a .so. You should not specify -fPIC to CFLAGS, etc. The -version-info
specifier is not necessary, but is a good idea.