How to create a shared object file from static library - c

How to create a shared object file from a static library? I am using Cygwin.
Is the following syntax correct?
gcc -shared -o libexample.so libexample.a

gcc -shared -o libexample.so -Wl,--whole-archive libexample.a
Pay attention that often you'll want the objects combined in your .so to be compiled as PIC, something you don't often want for a static library.

It might not work but you can always try:
ar -x libexample.a
gcc -shared *.o -o libexample.so
If it complains about -fPIC, then it probably won't work.

Related

Windows Eclipse C/C++ cannot find external library [duplicate]

I use code::blocks to compile my static library. The output result is a libstatic.a file.
Now, how do I link to my library to use functions that were compiled?
(I tried to use #include "libstatic.a" but my project doesn't compile)
cc -o yourprog yourprog.c -lstatic
or
cc -o yourprog yourprog.c libstatic.a
You should #include "libstatic.h", i.e. use the appropriate header file in your code (that's why your code doesn't compile) and include the path to your libstatic.a in the linker options as one of your input libraries.
This webpage has some examples on linking to a static library, e.g.
gcc -I. -o jvct jvct.c libjvc.a
I had to set the library path in my makefile. For this case you could use:
gcc -o myapp main.c -L. -lstatic
gcc -I. -o jvct jvct.c libjvc.a
To link purely statically, use -static
cc -static yourprogram.c libstatic.a

GNU g++ -G option to create a shared library available on Solaris not on Linux

I am using GNU g++ 4.9.2 compiler both on Solaris and Linux.
On Solaris platform, to create a shared library from a source file (a.c), I use the following command:
g++ -G a.c -o a
a becomes a shared library
a.c contains the following code:
void libfn1()
{
}
If I try not to use -G option i.e. compile as:
g++ a.c -o a
It gets a linker error: Undefined Symbol main
But, on Linux, if I do the same thing: it says:
g++: error: unrecognized command line option -G
How to create a shared library on Linux? What is the g++ option for that?
The g++ documentation says this:
These additional options are available on System V Release 4 for
compatibility with other compilers on those systems:
-G Create a shared object. It is recommended that -symbolic or -shared be
used instead.
Normally you want to generate position independent code too, for a shared library, with the -fPIC flag.
So you'd want to run:
g++ -fPIC -shared a.c -o liba.so
The process to create a shared library on a Linux system is a bit different.
Shared libraries on Linux are .so (for "shared object") files, not .g.
You do it like this:
First, you need to generate position-independent code from your C++ source. That is so your library works from wherever it is called. To do that, you should use g++'s -fPIC flag.
So, for each source file you want to be included in your library, you should only compile it to position-independent code. We'll handle linking later.
For each source file:
g++ -c -fPIC file.cpp
(The -c flag tells g++ "compile, don't link").
for each file.cpp, g++ will generate file.o, an object file containing position-independent code.
To then build the object files into a shared library, you should use
g++ -o -shared myLibrary.so {all_object_files}
So if you have file1.o, file2.o and file3.o, the command would be:
g++ -shared -o myLibrary.so file1.o file2.o file3.o
Of course, if you have a lot of files this can get pretty tedious, so you should write a Makefile to automate this process for you! Here's an example:
myLibrary.so: file1.o file2.o file3.o
$(CXX) -shared $^ -o $#
file1.o file2.o file3.o : CXXFLAGS+=-fPIC

Why does my .so have undefined symbols

Im creating a runtime loaded shared object in linux that impliments some JSON using jannson.h.
This is how I'm building the .so:
gcc -Wall -fPIC -c device_simulator_json.c
gcc -shared -Wl,-soname,device_simulator_json.so.1 -o device_simulator_json.so.1.0 device_simulator_json.o
When my application tries to load the .so, I get an error indication:
undefined symbol: json_object
I'm guessing that my .so has to include in it the jansson object. But I'm not sure which one or how. I can see the following jansson objects in my /usr/local/lib:
./usr/local/lib/libjansson.so.4.7.0
./usr/local/lib/libjansson.so.4
./usr/local/lib/libjansson.a
./usr/local/lib/libjansson.so
Because the .so I'm building is dynamically loaded at runtime (using dlopen), doesn't the jansson object I use also have to be built with PIC.
Thanks.
You probably should link libjansson.so inside your shared library:
gcc -L/usr/local/lib -shared -Wl,-soname,device_simulator_json.so.1 \
-o device_simulator_json.so.1.0 device_simulator_json.o -ljansson
Alternatively, you might link -ljansson into the main program (doing the dlopen). You'll better then link that program with -rdynamic
BTW, you probably should compile your shared object with all warnings and debug info:
gcc -Wall -Wextra -g -fPIC -c device_simulator_json.c
once all is debugged you might optimize with -O2

Custom C library: can functions in the same library refer to each other?

I've just started to create my own C libraries to keep my commonly used functions tidy. However, I've hit a new problem and I struggled to find information on the best route to take.
I generate my library of two functions using the following:
gcc -I. -c -fpic rand_site.c
gcc -I. -c -fpic rand_spin.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o
Each of these source files contained a single function. I was hoping to create a third function for my library that uses the two functions above but I'm not sure how to use functions from within the same library.
Am I going about this the right way? What is the best practice for doing this?
Yes, you can.
Create a header file rand_site.h and put the declaration of the function defined in rand_site.c in it.
Create a header file rand_spin.h and put the declaration of the function defined in rand_spin.c in it.
Use #include to include the two .h files in the third file, say foo.c.
Then compile foo.c and add it to the library using:
gcc -I. -c -fpic foo.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o foo.o
If you would like to create a second shared library that has foo.o, you can use:
gcc -I. -c -fpic foo.c
gcc -shared -o libfoo.so foo.o -lstatphys
If you would like to create an executable using foo.o, you can use:
gcc -I. -c foo.c
gcc foo.o -lstatphys

How to link to a static library in C?

I use code::blocks to compile my static library. The output result is a libstatic.a file.
Now, how do I link to my library to use functions that were compiled?
(I tried to use #include "libstatic.a" but my project doesn't compile)
cc -o yourprog yourprog.c -lstatic
or
cc -o yourprog yourprog.c libstatic.a
You should #include "libstatic.h", i.e. use the appropriate header file in your code (that's why your code doesn't compile) and include the path to your libstatic.a in the linker options as one of your input libraries.
This webpage has some examples on linking to a static library, e.g.
gcc -I. -o jvct jvct.c libjvc.a
I had to set the library path in my makefile. For this case you could use:
gcc -o myapp main.c -L. -lstatic
gcc -I. -o jvct jvct.c libjvc.a
To link purely statically, use -static
cc -static yourprogram.c libstatic.a

Resources