Linking shared library to executable - c

libourown.so provides function f definition
After execution of gcc command,
gcc a.o libourown.so.1 -o app
1)
Does libourown.so get linked to app at runtime , when f is called in app? or Does libourown.so gets linked to app at build time?
2)
Does libc.so get linked at runtime to app, after printf is called in app ? or Does libc.so gets linked to app at build time?

The answer is same to both of your questions. The shared libraries are not built into your executable (that's one of the main reasons why they came into existence in the first place!).
When you run your app, the drynamic linker/loader ld.so loads the necessary libraries.
You can see the shared libraries needed by your application by running:
$ ldd ./app
on the command line.
You may find this very useful to understand shared libraries on Linux: how to write shared libraries

To answer your "Does libourown.so get linked to app at runtime , when f is called in app? or Does libourown.so gets linked to app at build time?"
Dynamic libraries are linked as soon as they are brought into ram. The same answer valid for both of your questions. This type of linking done is known as load time linking.
Another method of doing it is to use the concept of run time linking. Using functions like dlopen(), dlsym()

The whole point of a shared object is that it won't be linked statically to your executable, but rather sit in the memory and serve those who need it.
Look at this thread:
how can I link a shared object in C?

It's impossible to statically link to a .so file: this file is missing information which is necessary for the linker to work. If you need to statically link to libourown.so, you have two options:
generate the static version of the library, libourown.a, and link against that
use a tool like statifier to embed libourown.so in your executable.
Libc is linked to executables dynamically by default. You can link to it statically using -static option. It should be noted that statically linking to libc will do more harm than good, because other libraries your executable is using are likely to be linked agains libc dynamically, and linking to the same library twice leads to a disaster.

Related

What is the difference between shared and dynamic libraries in C?

I don't understand the difference between the two types of libraries, and many websites say that they are the same thing, but at school we use two different commands to create them
dynamic library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -ldl
to execute:
$ ./main ./libsample.so
shared library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -L. -lsample
to execute:
$ LD_LIBRARY_PATH=. ./main
Can someone help me in understanding the difference between the two "codes"?
Dynamic Linked Library (.DLL) is the terminology used by Microsoft Windows. Shared Object (.so) is the terminology used by Unix and Linux.
Other than that, conceptually they're the same.
Regarding your snippets of commands, I guess the difference (and I'm only guessing here, because you didn't show us the relevant parts) is how the library is loaded. There is "link time loading" where the library is tied to the executable by the linker¹. And there is "runtime loading", where the program sort of "ingests" the dynamic/shared library.
runtime loading is done in Windows with the LoadLibrary (there's an …A and a …W variant) function, and on Unix/Linux with dlopen (which is made available by libdl which is linked to by that -ldl library link statement).
1: The linker is the program that creates the actually executable file from the intermediary objects created by the various compiler stages.
Dynamic and shared libraries are usually the same. But in your case, it looks as if you are doing something special.
In the shared library case, you specify the shared library at compile-time. When the app is started, the operating system will load the shared library before the application starts.
In the dynamic libary case, the library is not specified at compile-time, so it's not loaded by the operating system. Instead, your application will contain some code to load the library.
The first case is the normal case. The second case is a special use and it's mainly relevant if your application support extensions such a plug-ins. The dynamic loading is required because there can be many plug-ins and they are built after your application. So their names are not available at compile-time.

How can I statically link a dylib to my program on macOS?

my c program calls:
hLibrary = dlopen("libPCBUSB.dylib", RTLD_LAZY);
and I seem to need this file in the directory when I run the executable after calling gcc main.c.
i.e. I run ./a.out and it all works as long as the dylib is in that directory.
In order to produce an executable with that dylib statically built in I've been trying all sorts of linking options but failing.
What is the correct way to compile my c program (in macOS Darwin not linux) to include this lib so the end user will not need it on their Mac?
Dynamic libraries (.dylib) can't be statically linked. If you have access to the source code for building the library, you can convert it to a static library and statically link against it in your app. If this is a 3rd-party binary-only library, you will need to ask the vendor for a static version of the library, and if that's not available, you will need to stick with linking it dynamically.
Note that dlopen() is not the only way to link against a dylib, you can also use -l, then you don't need to mess around with dlsym() etc. to get to the entry points. Either way requires shipping the library with your app of course.

How can I compile a library archive with a source code file with gcc?

TL;DR - I need to compile archive.a with test.o to make an executable.
Background - I am trying to call a function in a separate library from a software package I am modifying but the function (a string parser) is creating a segmentation violation. The failure is definitely happening in the library and the developer has asked for a test case where the error occurs. Rather than having him try to compile the rather large software package that I'm working on I'd rather just send him a simple program that calls the appropriate function (hopefully dying at the same place). His library makes use of several system libraries as well (lapack, cblas, etc.) so the linking needs to hit everything I think.
I can link to the .o files that are created when I make his library but of course they don't link to the appropriate system libraries.
This seems like it should be straight forward, but it's got me all flummoxed.
The .a extension indicates that it is a static library. So in order to link against it you can use the switches for the linking stage:
gcc -o myprog -L<path to your library> main.o ... -larchive
Generally you use -L to add the path where libraries are stored (unless it is in the current directory) and you use -l<libname> to sepecify a library. The libraryname is without extension. If the library is named libarchive.a you would still give -larchive.
If you want to specify the full name of the library, then you would use i.e. -l:libname.a
update
If the libraypath is /usr/lib/libmylibrary.a you would use
-L/usr/lib -lmylibrary

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Link my shared library to another (CMAKE)

I'm currently trying to link a CXX library that I've written to a VTK, a CMake made library - to end up creating a shared library that has my code's functionality and can resolve the symbols from VTK. I need the end result to be shared because I'd need to call the library up at runtime in Java.
It sounds like you need to use target_link_libraries, so a minimal CMake block might look like,
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_library(mylib SHARED sourcefile.cxx sourcefile2.cxx)
target_link_libraries(mylib vtkRendering)
This would add a shared library called mylib (libmylib.so on Linux), that links to vtkRendering (multiple libraries could be added here). Check out 'cmake --help-commands' for a full list of CMake commands.

Resources