I have a weird problem.
I am working on a shared library, written using C and a GUI application written on C++. GUI application uses the shared library. This shared library uses SQLite amalgamation and links statically. GUI also uses SQLite for some configuration purpose. It is also statically linked. Both of them uses latest SQLite version.
My shared library uses FTS4. I have enabled FTS4 by providing the compile time options while compiling the shared library. All works well with the shared library. All my tests in the shared library codebase is passing.
Problem happens when I start using this in the GUI program. I am getting error like, Unknown module FTS4. This is weird because I have it linked statically in my shared library and all this GUI program does is to dynamically link to my library. When I set the FTS compilation options to the GUI program, error goes away and all works well.
In short,
libfoo.so - Statically links SQLite with FTS4 options turned on
foo - Statically links SQLIte with out any special compile time options. Dynamically links to libfoo.
I am not sure why this is happening. Any help would be great!
It sounds like all the sqlite functions in the shared library are being exported. As a result, when you load the shared object, all of these functions get resolved to the main application, which also defines identical copies of the symbol names, but with different functionality.
You may have better luck compiling your shared object with a map file looking something like:
{
global:
*;
local:
sqlite3*;
};
put it into a file called foo.map, and when linking libfoo.so (assuming using gcc)
gcc -Wl,--version-script=foo.map -o libfoo.so <dependent files>
This should hopefully cause the use of the internal symbols within the .so rather than the ones defined in the main application.
Related
I currently have an application that runs on a desktop and a phone. The desktop requires a full-featured libfoo.so, but the mobile version only requires a small subset of libfoo.so. Someone else has already implemented libfoo-phone.so, and it uses the same function names as libfoo.so for the functions that it actually implements.
I am currently including libfoo-phone.h, which works as usual because its being linked against at compile time. However, when I link at runtime via dlopen, I won't be able to include the header file. Is there an easy way to make this work without a huge wrapper that makes 100's of calls to dlsym?
Why link at runtime? Just link to the appropriate .so depending on the current build target (phone vs desktop). The platforms dynamic linker will load the *.so for you automatically when the executable is run, and you don't have to worry about runtime loading of a library. You can include the header, reference the symbols all you want, and there won't be any problems.
I have a library which at compile time is building a shared object, called libEXAMPLE.so (in the so.le folder), and a dll by the name of EXAMPLE.so (in the dll folder). The two shared objects are quite similar in size and appear to be exactly the same thing. Scouring the internet revealed that there might be a difference in the way programs use the dll to do symbol resolution vs the way it is done with the shared object.
Can you guys please help me out in understanding this?
"DLL" is how windows like to name their dynamic library
"SO" is how linux like to name their dynamic library
Both have same purpose: to be loaded dynamically.
Windows uses PE binary format and linux uses ELF.
PE:
http://en.wikipedia.org/wiki/Portable_Executable
ELF:
http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
I suppose a Linux OS.
In Linux, static libraries (.a, also called archives) are used for linking at compile time while shared objects (.so) are used both for linking at load time and at run time.
In your case, it seems that for some reason the library differentiate the files for linking at load time (libEXAMPLE.so) and linking at run time (EXAMPLE.so) even though those 2 files are exactly the same.
I am new to C++ programming. There are 2 libraries in my program, one needs to be linked dynamically, and the other needs to be linked statically, how can I set this up in Eclipse? I am using
Eclipse CDT + MinGW + Windows 7.
Thanks.
It's not entirely clear what you're after here.
Most of static vs. dynamic is in the library itself, not how you link to it. You can have a static library, which is basically just a collection of object files, stuffed together into a single file, with a directory to tell what parts were originally which files.
You can also have a DLL. When you create a DLL, the linker will normally also create a link library for that DLL. This library basically just contains stubs -- enough information so the linker can insert a link to the DLL into another DLL or executable.
When you use a DLL, you basically have three options for how to use it:
The most common case: the DLL will be loaded as the parent executable is loaded.
delayload: doesn't load that DLL until/unless you actually use a function from it (handy if you have, for example, a special DLL that's only used under, say, Windows Vista or newer).
Explicit dynamic linking. Here, you don't tell the linker about the DLL or an associated library at all. You call LoadLibrary and GetProcAddress to load the library, and get a callable function address.
I have been involved in some debate with respect to libraries in Linux, and would like to confirm some things.
It is to my understanding (please correct me if I am wrong and I will edit my post later), that there are two ways of using libraries when building an application:
Static libraries (.a files): At link time, a copy of the entire library is put into the final application so that the functions within the library are always available to the calling application
Shared objects (.so files): At link time, the object is just verified against its API via the corresponding header (.h) file. The library isn't actually used until runtime, where it is needed.
The obvious advantage of static libraries is that they allow the entire application to be self-contained, while the benefit of dynamic libraries is that the ".so" file can be replaced (ie: in case it needs to be updated due to a security bug) without requiring the base application to be recompiled.
I have heard some people make a distinction between shared objects and dynamic link libraries (DLL's), even though they are both ".so" files. Is there any distinction between shared objects and DLLs when it comes to C/C++ development on Linux or any other POSIX compliant OS (ie: MINIX, UNIX, QNX, etc)? I am told that one key difference (so far) is that shared objects are just used at runtime, while DLL's must be opened first using the dlopen() call within the application.
Finally, I have also heard some developers mention "shared archives", which, to my understanding, are also static libraries themselves, but are never used by an application directly. Instead, other static libraries will link against the "shared archives" to pull some (but not all) functions/resources from the shared archive into the static library being built.
Thank you all in advance for your assistance.
Update
In the context in which these terms were provided to me, it was effectively erroneous terms used by a team of Windows developers that had to learn Linux. I tried to correct them, but the (incorrect) language norms stuck.
Shared Object: A library that is automatically linked into a program when the program starts, and exists as a standalone file. The library is included in the linking list at compile time (ie: LDOPTS+=-lmylib for a library file named mylib.so). The library must be present at compile time, and when the application starts.
Static Library: A library that is merged into the actual program itself at build time for a single (larger) application containing the application code and the library code that is automatically linked into a program when the program is built, and the final binary containing both the main program and the library itself exists as a single standalone binary file. The library is included in the linking list at compile time (ie: LDOPTS+=-lmylib for a library file named mylib.a). The library must be present at compile time.
DLL: Essentially the same as a shared object, but rather than being included in the linking list at compile time, the library is loaded via dlopen()/dlsym() commands so that the library does not need to be present at build time for the program to compile. Also, the library does not need to be present (necessarily) at application startup or compile time, as it is only needed at the moment the dlopen/dlsym calls are made.
Shared Archive: Essentially the same as a static library, but is compiled with the "export-shared" and "-fPIC" flags. The library is included in the linking list at compile time (ie: LDOPTS+=-lmylibS for a library file named mylibS.a). The distinction between the two is that this additional flag is required if a shared object or DLL wants to statically link the shared archive into its own code AND be able to make the functions in the shared object available to other programs, rather than just using them internal to the DLL. This is useful in the case when someone provides you with a static library, and you wish to repackage it as an SO. The library must be present at compile time.
Additional Update
The distinction between "DLL" and "shared library" was just a (lazy, inaccurate) colloquialism in the company I worked in at the time (Windows developers being forced to shift to Linux development, and the term stuck), adhering to the descriptions noted above.
Additionally, the trailing "S" literal after the library name, in the case of "shared archives" was just a convention used at that company, and not in the industry in general.
A static library(.a) is a library that can be linked directly into the final executable produced by the linker,it is contained in it and there is no need to have the library into the system where the executable will be deployed.
A shared library(.so) is a library that is linked but not embedded in the final executable, so will be loaded when the executable is launched and need to be present in the system where the executable is deployed.
A dynamic link library on windows(.dll) is like a shared library(.so) on linux but there are some differences between the two implementations that are related to the OS (Windows vs Linux) :
A DLL can define two kinds of functions: exported and internal. The exported functions are intended to be called by other modules, as well as from within the DLL where they are defined. Internal functions are typically intended to be called only from within the DLL where they are defined.
An SO library on Linux doesn't need special export statement to indicate exportable symbols, since all symbols are available to an interrogating process.
I've always thought that DLLs and shared objects are just different terms for the same thing - Windows calls them DLLs, while on UNIX systems they're shared objects, with the general term - dynamically linked library - covering both (even the function to open a .so on UNIX is called dlopen() after 'dynamic library').
They are indeed only linked at application startup, however your notion of verification against the header file is incorrect. The header file defines prototypes which are required in order to compile the code which uses the library, but at link time the linker looks inside the library itself to make sure the functions it needs are actually there. The linker has to find the function bodies somewhere at link time or it'll raise an error. It ALSO does that at runtime, because as you rightly point out the library itself might have changed since the program was compiled. This is why ABI stability is so important in platform libraries, as the ABI changing is what breaks existing programs compiled against older versions.
Static libraries are just bundles of object files straight out of the compiler, just like the ones that you are building yourself as part of your project's compilation, so they get pulled in and fed to the linker in exactly the same way, and unused bits are dropped in exactly the same way.
I can elaborate on the details of DLLs in Windows to help clarify those mysteries to my friends here in *NIX-land...
A DLL is like a Shared Object file. Both are images, ready to load into memory by the program loader of the respective OS. The images are accompanied by various bits of metadata to help linkers and loaders make the necessary associations and use the library of code.
Windows DLLs have an export table. The exports can be by name, or by table position (numeric). The latter method is considered "old school" and is much more fragile -- rebuilding the DLL and changing the position of a function in the table will end in disaster, whereas there is no real issue if linking of entry points is by name. So, forget that as an issue, but just be aware it's there if you work with "dinosaur" code such as 3rd-party vendor libs.
Windows DLLs are built by compiling and linking, just as you would for an EXE (executable application), but the DLL is meant to not stand alone, just like an SO is meant to be used by an application, either via dynamic loading, or by link-time binding (the reference to the SO is embedded in the application binary's metadata, and the OS program loader will auto-load the referenced SO's). DLLs can reference other DLLs, just as SOs can reference other SOs.
In Windows, DLLs will make available only specific entry points. These are called "exports". The developer can either use a special compiler keyword to make a symbol an externally-visible (to other linkers and the dynamic loader), or the exports can be listed in a module-definition file which is used at link time when the DLL itself is being created. The modern practice is to decorate the function definition with the keyword to export the symbol name. It is also possible to create header files with keywords which will declare that symbol as one to be imported from a DLL outside the current compilation unit. Look up the keywords __declspec(dllexport) and __declspec(dllimport) for more information.
One of the interesting features of DLLs is that they can declare a standard "upon load/unload" handler function. Whenever the DLL is loaded or unloaded, the DLL can perform some initialization or cleanup, as the case may be. This maps nicely into having a DLL as an object-oriented resource manager, such as a device driver or shared object interface.
When a developer wants to use an already-built DLL, she must either reference an "export library" (*.LIB) created by the DLL developer when she created the DLL, or she must explicitly load the DLL at run time and request the entry point address by name via the LoadLibrary() and GetProcAddress() mechanisms. Most of the time, linking against a LIB file (which simply contains the linker metadata for the DLL's exported entry points) is the way DLLs get used. Dynamic loading is reserved typically for implementing "polymorphism" or "runtime configurability" in program behaviors (accessing add-ons or later-defined functionality, aka "plugins").
The Windows way of doing things can cause some confusion at times; the system uses the .LIB extension to refer to both normal static libraries (archives, like POSIX *.a files) and to the "export stub" libraries needed to bind an application to a DLL at link time. So, one should always look to see if a *.LIB file has a same-named *.DLL file; if not, chances are good that *.LIB file is a static library archive, and not export binding metadata for a DLL.
You are correct in that static files are copied to the application at link-time, and that shared files are just verified at link time and loaded at runtime.
The dlopen call is not only for shared objects, if the application wishes to do so at runtime on its behalf, otherwise the shared objects are loaded automatically when the application starts. DLLS and .so are the same thing. the dlopen exists to add even more fine-grained dynamic loading abilities for processes. You dont have to use dlopen yourself to open/use the DLLs, that happens too at application startup.
I suspect some kind of misunderstanding here, but header files, at least of the .h variety used for compiling source code, are most definitely NOT checked during link time.
.h, and for that matter, .c/.cpp files, are only involved during the compilation phase, which includes preprocessing. Once the object code has been created the header file is long gone well before the linker gets around to dealing with things.
In my quest to learn C++, I have come across dynamic and static libraries.
I generally get the gist of them: compiled code to include into other programs.
However, I would like to know a few things about them:
Is writing them any different than a normal C++ program, minus the main() function?
How does the compiled program get to be a library? It's obviously not an executable, so how do I turn, say 'test.cpp' into 'test.dll'?
Once I get it to its format, how do I include it in another program?
Is there a standard place to put them, so that whatever compilers/linkers need them can find them easily?
What is the difference (technically and practically) between a dynamic and static library?
How would I use third party libraries in my code (I'm staring at .dylib and .a files for the MySql C++ Connector)
Everything I have found relating to libraries seems to be targeting those who already know how to use them. I, however, don't. (But would like to!)
Thanks!
(I should also note I'm using Mac OS X, and although would prefer to remain IDE-neutral or command-line oriented, I use QtCreator/Netbeans)
Is writing them any different than a normal C++ program, minus the main() function?
No.
How does the compiled program get to be a library? It's obviously not an executable, so how do I turn, say 'test.cpp' into 'test.dll'?
Pass the -dynamiclib flag when you're compiling. (The name of the result is still by default a.out. On Mac OS X you should name your dynamic libraries as lib***.dylib, and on Linux, lib***.so (shared objects))
Once I get it to its format, how do I include it in another program?
First, make a header file so the the other program can #include to know what functions can be used in your dylib.
Second, link to your dylib. If your dylib is named as libblah.dylib, you pass the -lblah flag to gcc.
Is there a standard place to put them, so that whatever compilers/linkers need them can find them easily?
/usr/lib or /usr/local/lib.
What is the difference (technically and practically) between a dynamic and static library?
Basically, for a static lib, the whole library is embedded into the file it "links" to.
How would I use third party libraries in my code (I'm staring at .dylib and .a files for the MySql C++ Connector)
See the 3rd answer.
Is writing them any different than a normal C++ program, minus the main() function?
Except for the obvious difference that a library provides services for other programs to use, usually (*) there isn't a difference.
* in gcc classes/functions are exported by default - this isn't the case in VC++, there you have to explicitly export using __declspec(export).
How does the compiled program get to be a library? It's obviously not an executable, so how do I turn, say 'test.cpp' into 'test.dll'?
This depends on your compiler. In Visual Studio you specify this in your project configuration. In gcc to create a static library you compile your code normally and then package it in an archive using ar. To create a shared you compile first (with the -fpic flag to enable position independent code generation, a requirement for shared libraries), then use the -shared flag on the object files. More info can be found in the man pages.
Once I get it to its format, how do I include it in another program?
Again this is a little compiler-dependant. In VS, if it's a shared library, when including the class/function you wish to use it should be marked with a __declspec(import) (this is usually done with ifdefs) and you have to specify the .lib file of the shared library for linkage. For a static library you only have to specify the .lib file (no export/import needed since the code will end up in your executable).
In gcc you only need to specify the library which you link against using -llibrary_name.
In both cases you will need to provide your client some header files with the functions/classes that are intended for public use.
Is there a standard place to put them, so that whatever compilers/linkers need them can find them easily?
If it's your own library then it's up to you. Usually you can specify the linker additional folders to look in. We have a lib folder in our source tree where all .lib (or .a/.so) files end up and we add that folder to the additional folder to look in.
If you're shipping a library on UNIX the common place is usually /usr/lib (or /usr/local/lib), this is also where gcc searches in by default.
What is the difference (technically and practically) between a dynamic and static library?
When you link a program to static libraries the code of the libraries ends up in your executable. Practically this makes your executable larger and makes it harder to update/fix a static library for obvious reasons (requires a new version of your executable).
Shared libraries are separate from your executable and are referenced by your program and (usually) loaded at runtime when needed.
It's also possible to load shared libraries without linking to them. It requires more work since you have to manually load the shared library and any symbol you wish to use. On Windows this is done using LoadLibrary/GetProcAddress and on POSIX systems using dlsym/dlopen.
How would I use third party libraries in my code?
This is usually accomplished by including the necessary header files and linking with the appropriate library.
A simple example to link with a static library foo would look like this: gcc main.cpp -o main.o -L/folder/where/foo.a/is/at -lfoo.
Most open source projects have a readme that gives more detailed instructions, I'd suggest to take a look at it if there is one.
Is writing [libraries] any different than a normal C++ program, minus the main() function?
That depends on your definition of "different." From the language's point of view, you write a file or collection of files, don't put in a main() and you tell the compiler to generate a library instead of an executable.
However, designing libraries is much harder because you have no control over the code that calls you. Libraries need to be more robust against failure than normal code. You can't necessarily delete pointers somebody passes to your function. You can't tell what macros will mess with your code. You also can't accidentally pollute the global namespace (eg., don't put using namespace std at the beginning of your header files).
How does the compiled program get to be a library? It's obviously not an executable, so how do I turn, say 'test.cpp' into 'test.dll'?
That depends on the compiler. In Visual C++ this is a project config setting. In gcc (going from memory) it's something like gcc -c foo.c -shared.
Once I get it to its format, how do I include it in another program?
That depends on your compiler and linker. You make sure the header files are available via a project setting or environment variable, and you make sure the binaries are available via a different project setting or compiler variable.
Is there a standard place to put them, so that whatever compilers/linkers need them can find them easily?
That depends on the operating system. In UNIX you're going to put things in places like /usr/lib, /usr/local/lib. On Windows people used to put DLLs in places like C:\WINDOWS but that's no longer allowed. Instead you put it in your program directory.
What is the difference (technically and practically) between a dynamic and static library?
Static libraries are the easier, original model. At compile time the linker puts all the functions from the library into your executable. You can ship the executable without the library, because the library is baked in.
Dynamic libraries (also called shared libraries) involve the compiler putting enough information in the executable that at runtime the linker will be able to find the correct libraries and call the methods in there. The libraries are shared across the whole system among the programs that use them. Using dynamic linking (dlsym(), et. al.) adds a few details to the picture.
How would I use third party libraries in my code (I'm staring at .dylib and .a files for the MySql C++ Connector)
That's going to depend on your platform, and unfortunately I can't tell you much about .dylib files. .a files are static libraries, and you simply need to add them to your final call to gcc (gcc main.c foo.a -o main if you know where foo.a is, or gcc main.c -lfoo -o main if the system knows where foo.a, foo.la, or foo.so are). Generally you make sure the compiler can find the library and leave the linker to do the rest.
The difference between a static and dynamic library is that the linking is done at compile time for static libraries, embedding the executable code into your binary, while for dynamic libraries linking is done dynamically at program start. The advantages are that the libraris can be separately distributed, updated and the code (memory) can be shared among several programs.
To use a library you simply provide -l to g++ for a lib.a or lib.so
I'm writing this to be more pragmatic than technically correct. It's enough to give you the general idea of what you're after.
Is writing them any different than a normal C++ program, minus the main() function?
For a static library, there's really not much difference.
For a dynamic library, the most likely difference you'll need to be aware of is that you may need to export the symbols you want to be available outside your library. Basically everything you don't export is invisible to users of your library. Exactly how you export, and whether you even need to by default, depends on your compiler.
For a dynamic library you also need to have all symbols resolved, which means the library can't depend on a function or variable that comes from outside the library. If my library uses a function called foo(), I need to include foo() in my library by writing it myself or by linking to another library that supplies it. I can't use foo() and just assume the user of my library will supply it. The linker won't know how to call a foo() that doesn't yet exist.
How does the compiled program get to be a library? It's obviously not an executable, so how do I turn, say 'test.cpp' into 'test.dll'?
It's similar to how you turn test.cpp into test.exe - compile and link. You pass options to the compiler to tell it whether to create an executable, a static library, or a dynamic library.
Once I get it to its format, how do I include it in another program?
In your source code, you include header files necessary to use the library, much as you would include a header file for code that's not in a library. You'll also need to include the library on your link line, telling the linker where to find the library. For many systems, creating a dynamic library generates two files, the shared library and a link library. It's the link library that you include on the link line.
Is there a standard place to put them, so that whatever compilers/linkers need them can find them easily?
There is an environment variable that tells the linker where to look for libraries. The name of that variable is different from one system to another. You can also tell the linker about additional places to look.
What is the difference (technically and practically) between a dynamic and static library?
A static library gets copied into the thing it is linked to. An executable will include a copy of the static library and can be run on another machine without also copying the static library.
A dynamic library stays in a separate file. The executable loads that separate file when it runs. You have to distribute a copy of the dynamic library with your program or it won't run. You can also replace the dynamic library with a new version, and as long as the new library has the same interface it will still run with the old executable. It also may save space if several executables use the same dynamic library. In fact dynamic libraries are often called shared libraries.
How would I use third party libraries in my code
Same as you would use one you created yourself, as described above.