I have created a program using a number of statically linked libraries. My question is, are these libraries required to be present when running the executable? It seems that the libraries are accessed as the program will not run if the libraries are not present and their path not included in the LIBPATH environment variable. I had the impression that since they were statically linked they would not be required at runtime.
No, static linking means they are included in the binary you build (and so they are "loaded" when you compile and link, if you will).
Related
I was recently asked why a particular library (Accelerate) is not included in the $PATH variable in our Mac environment. My response to that is that $PATH is a shell concept, not an OS concept. I don't expect libraries to be included in $PATH since they aren't executable and aren't necessarily relevant in a shell.
However, is this true? Some googling says yes, but in that case how do tools like CMake automatically find libraries with find_package and find_lapack? Is there some system specific PATH variable or another similar concept?
Yes, the PATH environment variable is for storing paths to executable files. There is to my knowledge (nor did an internet search reveal one) no standard PATH equivalent for library locations.
Tools like CMake will typically search the standard locations. For a Unix flavored OS, these often include /usr/lib, /usr/local/lib etc. See for example how CMake defines them: UnixPaths.cmake.
find_library() will search these standard locations (unless you tell it not to), and/or any path(s) given by the user.
find_package() will search for a Config or Find-module, which is responsible for finding all the necessary package components (binaries, include folders etc) and make the package ready for use within CMake. As these are written for a specific package, they will typically employ some qualified "guess work" as to where to find the package and its components (search standard locations, typical install locations and/or any other arbitrary method to accomplish its mission). So it's not CMake itself that finds the package in this case.
I am building an application with Lazarus where I use a sqlite database to store thousands of records. Right now I am linking to the sqlite library dynamically via the sqlite3.dll.
Is it possible to link to it statically? Where can I find the Lazarus compatible lib file to do that?
Note:
I only started using Lazarus and Free Pascal a month ago so something that might look very obvious to one, might not be for me. So bear with me a bit.
Cheers
Actual static linking is difficult since the TSQLite3Connection component is inherently designed to actively load the SQLite3 DLL. In other words, it's not linking against the library when you compile the program, the component is coded to dynamically load the DLL at run time.
If you are looking to have a totally self contained program, then you can accomplish this two different ways.
Create a new TSQLite3Connection component that links statically against sqlite3 instead of loading the DLL dynamically.
Include the sqlite3.dll as a resource in your program and have your program automatically deploy it before it runs.
Solution #1 is not trivial and not for the faint of heart. I've done it, and I intended to include a link to the component, but the result isn't stable. The problem is that you have to compile a static version of sqlite3, which isn't a real problem, but you have to do it with something like gcc under MinGW and that introduces issues. Compiling with gcc under MinGW means you have to then link in libgcc.a, and because FreePascal's internal linker doesn't know how to interpret stdcall symbols properly, you also have to link against MinGW's libkernel32.a, and libmsvcrt.a. The result just isn't stable. Crashes galore.
Solution #2 should be fairly easy, but the Lazarus maintainers make it a little hard. The part where you store the dll inside the executable as a resource is easy enough to do. And so is writing it out as a temp file. The problem is that you can't tell the TSQLite3Connection component where to find it after. So it looks in the executable's folder, or in system folders. Neither of which can necessarily be written to by the executable. The only place you can guarantee that your program will be able to write to is a temp folder. So what I did is created a new version of TSQLite3Connection component call TSQLite3DynConnection, meaning you can dynamically specify where the DLL is. I made a published property called ClientLibrary where you can specify the location of the dll (it doesn't have to end in .dll, so you can use system temp filename generation routines). You can get this component at: http://icculus.org/~kfitzner/misc/sqlite3dyndll.zip. It will compile against Lazarus 1.6.2 FP 3.0.0, or FP 1.0.6 / FP 2.6.0, which are the two versions I use.
I'll update this answer if I can get the statically linked version stable.
2 Dec 2016 update: I managed to get a static version stable.
I'm using Qt Creator 3.5.1 (opensource) with Qt 5.5.1. There I've created a shared library, and I can successfully build it. In the resulting build folder I find the so-file as expected, but I can't find the header files which are needed to use the library. Are the header files not expected to turn up here? I though the build folder would contain everything needed in order to make use of the library. Is that not the case?
I don't think they should be placed there. That is the build directory, not the installation directory. You can however also define the installation behaviour; see Advanced Usage - Installing Files. You choose which headers to distribute and which are private and place the public ones in the proper position.
I'm using premake5 to build a complex application on multiple platforms. My application links against both static and shared/dynamic external libraries.
There seems to be significant build chain dependencies that break premake generated 'gmake' make files in this case.
Case in Point:
If you mix shared and static libraries in premake 'link' statements, GCC seems to get confused and expect your shared library references to actually be static libraries. When it can't find them the link stage fails. This is normally handled by prefixing your shared libs with '-Bdynamic'. Unfortunately there is no way to tell premake5 that an external link lib is static or dynamic, so you have to manually fixup the make files, which defeats the purpose of a build utility.
This is kind of a showstopper. I don't think you can just feed "-Bdynamic" into the linkoptions because it must be followed by the list of shared libraries.
Seems like a bug in gmake action (or at least a missing functionality)
For those, the best approach is to go to the Premake page on Github (https://github.com/premake/premake-core) and create a new issue.
And if you have the time to provide a small reproductible project (a static lib project, a dynamic one, and an application using both, each with only 1 cpp or some simple stuff + the premake script) and attach it to the issue, it would also be really appreciated (and much easier to treat this issue ^^)
I'm developing a closed source application and to do so in accordance with the LGPL I have to dynamically link Qt's libraries to my application. Does Qt do this by default or do I have to take steps to do so? If that's the case how would I go about doing it?
Qt uses dynamic linking by default.
You'll notice this immediately during deployment to a non-developer machine, because your code will not run without the Qt libraries.
If your concern is the LGPL, just be careful when compiling Qt itself. Most LGPL violations with Qt are not because of static linking (since dynamic is the default), but for compiling Qt with non-default parameters.
LGPL is not just that the library must be provided along your binaries, but also that you specify how your users can build themselves the LGPL part. If you compile Qt yourself and do not use the pre-compiled binaries from the website, you must document that part of your build configuration in your release!
As soon as you get something running on your program, start preparing a release version for a non-developer environment without Qt installed. Your program should fail as soon as you delete the DLLs that you must copy along your program (or whatever format your OS uses).
It does it by default, statically linking seems to be quite involved judging by the many questions on the site regarding it.