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.
Related
I recently made a small library in C, and I wanted to put it together with the standard libraries so I don't have to always copy the files for each new project.
Where do I have to put it so I can import it like the standard libraries?
Compiler : MinGW
OS: Windows
You need to create a library, but you don't necessarily need to put it in the same place as MinGW's standard libraries (in fact I think that's a bad idea).
It is better to put your own library/libraries in specific place and then use the -I compiler flag to tell the compiler where to find the header files (.h, .hpp, .hh) and the -L linker flag to tell the linker where to find the library archives (.a, .dll.a). If you have .dll files you should make sure they are in your PATH environment variable when you run your .exe or make sure the .dll files are copied in the same folder as your .exe.
If you use an IDE (e.g. Code::Blocks or Visual Studio Code) you can set these flags in the global IDE compiler/linker settings so you won't have to add the flags for each new project.
Then when building a project that uses your library you will need to add the -l flag with the library name to your linker flags, but without the lib prefix and without the extension (e.g. to use libmystuff.a/libmystuff.dll.a specify linker flag -lmystuff). The use of the -static flag will tell the linker to use the static library instead of the shared library if both are available.
I have created a minimal example library at https://github.com/brechtsanders/ci-test to illustrate on how to create a library that can be build both as static and shared (DLL) library on Windows, but the same code also compiles on
macOS and Linux.
If you don't use build tools like Make or CMake and want do the steps manually they would look like this for a static library:
gcc -c -o mystuff.o mystuff.c
ar cr libmystuff.a mystuff.c
To distribute the library in binary form you should distribute your header files (.h) and the library archive files (.a).
I am new to cmake so, sorry if this question is very basic.
I want to build my project as statically linked with each standard library it uses.
Like, in gcc if we want to link the standard system libraries(libc, libgcc etc) as static, we specify '-static' option at the time of compilation.(Like gcc main.c -static -o main).
How we can achieve the same in cmake?
I have read multiple threads to define a how to define a library, how to build, link(as static & shared). But that is all for a custom library, I need information for standard system libraries.
[Edit]
In my project, I am using yocto at the top and the cmake is been used underneath it. running directly cmake works fine, as the generated executable has no dependencies on any shared library, all the used libraries are linked statically. But compiling from yocto causing the issue. the executable generated from the yocto build shows the dependencies on several standard shared libraries.
How we can specify static linking of standard libraries in yocto cmake?
Thanks in advance.
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.
In the process of porting a C project from Linux to Windows
Have installed MinGW
Have compiled my shared library using a Makefile
This produces libExample.so
Now I'm trying to link this shared library to a test harness so I can see if everything is working as expected
In the harness Makefile I specify the location of the library, e.g. -LE:/libExample_dir and the name of the library -lExample
but its complaining it cannot find the library, i.e. linker is failing with cannot find -lExample - is there some difference with windows regarding .so and .dll or perhaps pathnames that I am missing?
You need to fix the make file so shared libraries are generated with a .dll extension.
If I had to guess, I'd say that while renaming the generated file is enough to make the linker happy, the loader still expects the .so extension because that's the name that was compiled in...
Using MinGw to compile C code to produce a shared library, remember to rename the output from libExample.so to libExample.dll otherwise the linker will fail to find your library
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.