I built few open source binary/libraries and found that the binary/library is dependent on other libraries statically.I want it to link dynamically. This would allow my binaries be moved to any location and will be path independent. I mean if i export the Library path the binary should be able to locate the library and run successfully.
Write an interface header file containing signature declarations of all functions from required dependent libraries. Include it in your code.
Depending on requirement, use a platform specific loadlibrary function to load it, and then use getprocaddress like function to get the address of required function.
Use those addresses to invoke that function thereafter from your code
While compiling and linking make sure you dont statically link those dependent libraries.
Related
I want to include an external library as a subproject into my own project and link its target(s) statically against my own lib.
The said project somewhere in its CMake calls the following find-functions:
find_library(MBEDTLS_LIBRARY mbedtls)
find_library(MBEDX509_LIBRARY mbedx509)
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
The subproject expects mbedtls to already be installed somewhere on the system, but it didn't consider the fact that I want to link statically. My approach is to now FetchContent mbedtls and provide the find_library() calls with the prebuilt static libraries.
Now I need a way provide those find_library-calls with the right search directory, of course without modifying its source code. Can I somehow set a prefix path? I know I could probably set CMAKE_PREFIX_PATH but that seems like an ugly hack and it would probably affect other find_library()-calls within the project which also exist. Is there a more "constrained" way?
Can I somehow set a prefix path?
Setting a prefix path won't help find_library to locate the library, because command find_library searches the file at configuration stage, but the library is built only on build stage.
Instead, you may write the target name to the CACHE variable, which is passed to find_library as the first argument:
When find the result variable to be already set, find_library won't search the library file.
In most cases a project uses result of find_library in the call to target_link_libraries, so having the library target in the result variable will fit to the project's expectations.
Example:
FetchContent_Declare(mbedtls ...)
FetchContent_MakeAvailable(mbedtls)
set(MBEDTLS_LIBRARY MbedTLS::mbedtls CACHE INTERNAL "mbedtls library target")
With such setup the following
find_library(MBEDTLS_LIBRARY mbedtls)
will do nothing, since the variable MBEDTLS_LIBRARY is already set.
And if the project will use this variable like
target_link_libraries(<executable> ${MBEDTLS_LIBRARY})
then it effectively gets
target_link_libraries(<executable> MbedTLS::mbedtls)
Name of the target which should be assigned to the variable could sometime be found from the project's documentation, but otherwise you need to look into the project's sources (CMakeLists.txt).
E.g. in case of mbedtls project, the library target mbedtls is created with add_library() call, and MbedTLS::mbedtls is created as ALIAS for it.
I have a module module1 in a file called mymodule.f90. What should I do in order to make module1 usable like fortran intrinsic module?, i.e. it need only be called in a use statement (use module1) in any programs, subroutines, or functions that use it but I don't need to link /path/to/mymodule/ when compiling those procedures.
I use gfortran, but possibly in the future I will also have to use the Intel fortran compiler.
So maybe I'm misunderstanding you, but you want to use a module without having to tell the compiler where to find the .mod file (that contains the interface definitions for whatever module1 exports), or the linker where the object code can be found?
If so, for GFortran the solution is to download the GCC source code, add your own module as an intrinsic module, and then build your own custom version of GFortran. As a word of warning, unless you're familiar with the GFortran/GCC internals, while this isn't rocket science, it isn't trivial either.
For Intel Fortran, where you presumably don't have access to the source code of the compiler, I suppose you're out of luck.
My suggestion is to forget about this, and instead tell the compiler/linker where your .mod files and object files can be found. There are tools like make, cmake etc. that can help you automate this.
When you compile mymodule.f90 you will obtain an object file (mymodule.o) and a module file (mymodule1.mod). The compiler needs to have access to the module file when it compiles other files that use mymodule1, and the linker needs to have access to the object file when it generates the binary.
You don't need to specify the location of intrinsic modules because they are built in into the compiler. That will not be the case with your modules: you may be able to set up your environment in a way that the locations of your files allow the compiler to find the files without explicitly specifying their paths in compilation or linking commands, but the fact that you don't see it does not mean it's not happening.
For the Intel compiler, the answer is given by https://software.intel.com/en-us/node/694273 :
Directories are searched for .mod files in this order:
1 Directory of the source file that contains the USE statement.
2 Directories specified by the module path compiler option.
3 Current working directory.
4 Directories specified by the -Idir (Linux* and OS X*) or /include (Windows*) option.
5 Directories specified with the CPATH or INCLUDE environment variable.
6 Standard system directories.
For gfortran I have not found such a clear ordered list, but relevant information can be found in
https://gcc.gnu.org/onlinedocs/gfortran/Directory-Options.html
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options
It should be clear to you that a compiler won't be able to understand module files created by other compilers, or even by different enough versions of the same compiler. Therefore, you would need a copy of your "always available" module for each compiler you use, and if you are using multiple versions of a compiler you may need up to one per version - each of them in a different directory to avoid errors.
As you can see, this is not particularly practical, and it is indeed far from common practice. It is usually easier and more clear to the user to specify the path to the relevant module file in the compilation command. This is quite easy to set up if you compile your code using tools such as make.
Finally, remember that, if you make such arrangements for module files, you will also need to make arrangements for the corresponding object files at the linking stage.
Does anyone know where I can find a Firebreath sample (either Mac OS X or Windows) that illustrates how to create a plugin that includes 1 or more other libraries (.DLLs or .SOs) that each rely on other sub-projects built as static libraries (LIBs)?
For example, let's say that the Firebreath plugin is called PluginA, and that PluginA calls methods from DLL_B and DLL_C. DLL_B and DLL_C are C++ projects. DLL_B calls methods from another project called LIB_D, and DLL_C calls methods from a project called DLL_E.
Therefore, the final package should contain the following files:
PluginA.dll
DLL_B.dll (which also incorporates LIB_D)
DLL_C.dll
DLL_E.dll
I am currently forced to dump all source files in the pluginA solution, but this is just a bottleneck (for example I cannot call libraries written in other languages, such as Objective-C on Mac OS X).
I tried following the samples on Firebreath, but couldn't get them to work, and I found no samples from other users that claimed they were able to get it to work. I tried using CMAKE, and also running the solutions directly from X-Code, but the end result was the same (received linking errors, after deployment DLL_C couldn't find DLL_E etc.)
Any help would be appreciated - thank you,
Mihnea
You're way overthinking this.
On windows:
DLLs don't depend on a static library because if they did it would have been compiled in when they were built.
DLLs that depend on another DLL generally just need that other DLL to be present in the same location or otherwise in the DLL search path.
Those two things taken into consideration, all you need to do is locate the .lib file that either is the static library or goes with the .dll and add a target_link_library call for each one. There is a page on firebreath.org that explains how to do this.
On linux it's about the same but using the normal rules for finding .so files.
I am in the midst of evaluating the benefits of changing our program from 30+ statically linked libraries to 30+ dynamically linked libraries. We hope by changing to DLL, it will reduce the link time.
One immediate problem is the requirement to add __declspec in front of all the classes to create the lib file for other dlls to link. Is there a way to get around that? Is there a flag in the compiler to force a lib generation so to make all classes inside the DLL available for export? If not, is there any existing script/program that will do that? That will certainly make the switch from statically linked library to a dynamic one a lot easier. If not, what is the rationale behind __declspec? Why not an option to make all dll functions exportable?
Thank you.
Perhaps it's too late, but have you looked into using a DEF file?
There is one another way to solve your problem.
You just need to create one definition file(.def) and export all the methods or class you want to share.
U will also have to set :
Properties->Linker->Input->Module Definition File -> add name of your created .def file.
Now use run time dynamic linking:
In project where you want to call the exported methods use LoadLibrary to get handle of your Dll and call the required method using GetProcAddress.
I know very little about DLL's and LIB's other than that they contain vital code required for a program to run properly - libraries. But why do compilers generate them at all? Wouldn't it be easier to just include all the code in a single executable? And what's the difference between DLL's and LIB's?
There are static libraries (LIB) and dynamic libraries (DLL) - but note that .LIB files can be either static libraries (containing object files) or import libraries (containing symbols to allow the linker to link to a DLL).
Libraries are used because you may have code that you want to use in many programs. For example if you write a function that counts the number of characters in a string, that function will be useful in lots of programs. Once you get that function working correctly you don't want to have to recompile the code every time you use it, so you put the executable code for that function in a library, and the linker can extract and insert the compiled code into your program. Static libraries are sometimes called 'archives' for this reason.
Dynamic libraries take this one step further. It seems wasteful to have multiple copies of the library functions taking up space in each of the programs. Why can't they all share one copy of the function? This is what dynamic libraries are for. Rather than building the library code into your program when it is compiled, it can be run by mapping it into your program as it is loaded into memory. Multiple programs running at the same time that use the same functions can all share one copy, saving memory. In fact, you can load dynamic libraries only as needed, depending on the path through your code. No point in having the printer routines taking up memory if you aren't doing any printing. On the other hand, this means you have to have a copy of the dynamic library installed on every machine your program runs on. This creates its own set of problems.
As an example, almost every program written in 'C' will need functions from a library called the 'C runtime library, though few programs will need all of the functions. The C runtime comes in both static and dynamic versions, so you can determine which version your program uses depending on particular needs.
Another aspect is security (obfuscation). Once a piece of code is extracted from the main application and put in a "separated" Dynamic-Link Library, it is easier to attack, analyse (reverse-engineer) the code, since it has been isolated. When the same piece of code is kept in a LIB Library, it is part of the compiled (linked) target application, and this thus harder to isolate (differentiate) that piece of code from the rest of the target binaries.
One important reason for creating a DLL/LIB rather than just compiling the code into an executable is reuse and relocation. The average Java or .NET application (for example) will most likely use several 3rd party (or framework) libraries. It is much easier and faster to just compile against a pre-built library, rather than having to compile all of the 3rd party code into your application. Compiling your code into libraries also encourages good design practices, e.g. designing your classes to be used in different types of applications.
A DLL is a library of functions that are shared among other executable programs. Just look in your windows/system32 directory and you will find dozens of them. When your program creates a DLL it also normally creates a lib file so that the application *.exe program can resolve symbols that are declared in the DLL.
A .lib is a library of functions that are statically linked to a program -- they are NOT shared by other programs. Each program that links with a *.lib file has all the code in that file. If you have two programs A.exe and B.exe that link with C.lib then each A and B will both contain the code in C.lib.
How you create DLLs and libs depend on the compiler you use. Each compiler does it differently.
One other difference lies in the performance.
As the DLL is loaded at runtime by the .exe(s), the .exe(s) and the DLL work with shared memory concept and hence the performance is low relatively to static linking.
On the other hand, a .lib is code that is linked statically at compile time into every process that requests. Hence the .exe(s) will have single memory, thus increasing the performance of the process.