While compiling most of the opensource libraries, make command generates .la file, which will have library_names and current=11 age=9 revision=0 version information.
I understand that version information current=11 age=9 revision=0 is generated from the flag version-info in Makefile.am. By just knowing the version information, how does make generate library names?
Example : For libcrack.so
dlname='libcrack.so.2'
# Names of this library.
library_names='libcrack.so.2.9.0 libcrack.so.2 libcrack.so'
# Version information for libcrack.
current=11
age=9
revision=0
version info is specified in Makefile.am as follows
libcrack_la_LDFLAGS = -version-info 11:0:9
Now the question is: How does make generate libcrack.so.2.9.0 with the number 2.9.0 by just taking version-info?
Usually libtool library version system uses the following format
soname.so.<current-age>.<age>.<revision>
That is why in example quoted in the question, libcrack.so.(11-9).9.0 = libcrack.2.9.0.
More detailed information can be found at library versioning
Related
I followed many tutorials to get boost installed, firstyly I downloaded boost and added path with:
path=%path%;
c:\program files (x86)\code block\mingw\bin
secondly I ran
bootstrap.bat gcc
and then
b2 toolset=gcc
but there is no such lib installed as UUID which I really need to my project. Is there any way to make it happen as I haven't found any specific help among all those topics and I'm getting really confused. I'm working on win10 if that makes any difference.
Did you read documentation?
Boost UUID library is header-only library. See Configuration:
The library does not require building or any special configuration to be used.
So you have to download boost library and unpack it to some place in your disk (for example to c:\boost). Path to boost library will be c:\boost\boost_1_62_0. Then you have to specify the compiler the place where the boost library is located. It is compiler or IDE specific way. But the common way is to use "Additional Include Directories" option of compiler. It is -I for GCC and /I for MS VC++. Last step is to write include directive in your c++ code. For example:
#include <boost/uuid/uuid.hpp>
For code example see Example and files in boost/libs/uuid/test/ folder
I am working on a library in C, let us call it ninja.
Ninja depends upon some under laying libraries (which we also provide) (e.g jutsu, goku, bla).
These are all placed in a shared library folder, let us say /usr/lib/secret/.
The clients whom are using this project wants to be able to havde ninja version 1 and 2 laying side by side, this it not so hard. The problem comes when ninja 1 dependes up on for instance jutsu 1 and ninja 2 depends upon jutsu 3. How the h... do we/I do so so that when installing ninja from our package repository. It knows the correct version of jutsu. Of course the rpm/deb package should depend upon the correct version of the jutsu package.
so what we want is when, we execute for instance zypper in ninja. and it installs and compiles on the system, it knows which jutsu library to take with out been given a version number.
So we in the make file don't have to do this:
gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu_2
But just
gcc ninja.c -o ninja -L /usr/local/lib/secret/ -l jutsu
NOTE: I know it is random to use ninja and so on, but I am not allowed to publish the real library names
You want to use an SONAME. Describing all the steps necessary is probably too large a scope for a good StackOverflow answer, but I can give an overview and point to some documentation.
An SONAME is a special data field inside a shared library. It is typically used to indicate compatibility with other versions of the same library; if two different versions of a shared library have the same SONAME, the linkers will know that either one can fill the dependency on that library. If they have a different SONAME, they can't.
Example: I have libdns88 and libbind-dev version 1:9.8.4.dfsg.P1-6+nmu2+deb7u1 installed on a Debian wheezy system. I build a binary called samurai with -ldns. The GNU linker finds "libdns.so" in my library search path and dynamically links samurai with it. It reads the SONAME field from libdns.so (which is a symlink to libdns.so.88.1.1). The SONAME there is "libdns.so.88".
$ objdump -p /usr/lib/libdns.so | grep SONAME
SONAME libdns.so.88
The libdns developers (or maybe packagers) chose that SONAME to indicate that any version 88.* of libdns is expected to be binary compatible with any other version 88.*. They use that same SONAME for all versions with a compatible ABI. When the ABI had a change, they changed the SONAME to libdns.so.89, and so on. (Most well-managed libraries don't change their ABI that often.)
So the library dependency written into the samurai binary is just libdns.so.88. When I run samurai later, the dynamic linker/loader looks for a file called "libdns.so.88" instead of just "libdns.so".
Also by convention, the name of an rpm or deb package should change when the SONAME of the library contained changes. That's why there is a libdns88 package separate from the libdns100 package, and they can be installed side by side without interfering with each other. My samurai package will have a dependency on "libdns88" and I can expect that any package called libdns88 will have a compatible ABI to the one I built it against. Tools like dpkg-shlibdeps make it simple to create the right shared library package dependencies when SONAMEs and versioned symbols are used.
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Assume that you have a static library built with gcc by another person and you want to find out the version number of gcc that was used for compiling. Is there an easy way to extract this information from the library file?
I already tried out readelf, but all the switches I've used so far did not lead to a gcc version number.
This gets recorded in DW_AT_producer attribute in DWARF debug info. So if you have debug info, try this:
objdump -Wi yourlibrary.a|grep "DW_AT_producer"
I didn't see any official documentation for this attribute, so you might have to check...
Thanks to #dbrank0 I could retrieve the gcc version information from the static library. The solution that helped is provided here: https://stackoverflow.com/a/9673793/3868995
While readelf -wi <library> only lists the included files of the library, strings -a <library> |grep "GCC: (" made the job in my case. Thanks!
I have an Autogen Makefile.am that I'm trying to use to build a test program for a shared library. To build my test binary, I want to continue building the shared library as target but I want the test program to be linked statically. I've spent the last few hours trying to craft my Makefile.am to get it to do this.
I've tried explicitly changing the LDADD line to use the .a version of the library and get a file not found error even though I can see this library is getting built.
I try to add the .libs directory to my link path via LDFLAGS and still it can't find it.
I tried moving my library sources to my test SOURCES list and this won't work because executable object files are built differently than those for static libraries.
I even tried replicating a lib_LIBRARIES entry for the .a version (so there's both a lib_LTLIBRARIES and a lib_LIBRARIES) and replicate all the LDFLAGS, SOURCES, dir and HEADERS for the shared version as part of the static version (replacing la with a of the form _a_SOURCES = _la_SOURCES. Still that doesn't work because now it can't figure out what to build.
My configure.ac file is using the default LT_INIT which should give me both static and dynamic libraries and as I said it is apprently building both even if the libtool can't see the .a file.
Please, anyone know how to do this?
As #Brett Hale mentions in his comment, you should tell Makefile.am that you want the program to be statically linked.
To achieve this you must append -static to your LDFLAGS.
Changing the LDFLAGS for a specific binary is achieved by changing binary_LDFLAGS (where binary is the name of the binary you want to build).
so something like this should do the trick:
binary_LDFLAGS = $(AM_LDFLAGS) -static
My main aim is to get the GSL Shell working on my OSX 10.7 system. So far I have the correct version of lua with the correct patches running. I also have a working version of GSL which compiles and runs example programs. I can build agg perfectly and also run their example programs by running make in the macosx_sdl folder.
My first question is how on earth do I create my own project with agg? I know that you are supposed to simply add the files to your project file and go, but this does not seem to want to compile for me. Is it simply a case of adding the include directory and the libagg.a?
Finally, how do I build gsl shell? Currently it complains about the agg-plot folder a lot, so where do I put the agg files to make this build, then when i've done it where do I place the agg files so that the lua scripts can get to them?!
Hope someone can help!
In general to use the AGG library you need to make sure that the compiler is able to find the headers files and, during the linking, the libraries, either in form of a static or dynamic libraries.
To make the headers files and the libraries available you need to take into account the system that is used to build the software. If a traditional makefile sistem is used you need to add some flags to make sure that the headers file can be found. This can be achieved by adding into the makefile something like:
CFLAGS += -I/path/to/agg/headers
and for the linker:
LIBS += -L/path/to/agg/library -lagg -lm
In the specific case of GSL Shell 1.1 the file "make-packages" is used in the Makefile to configure the required packages. You can add here the flags required to locate the AGG library:
AGG_INCLUDES = -I/usr/include/agg2
AGG_LIBS = -lagg -lX11 -lpthread -lsupc++
you should just modify the path provided with the "-I" option and, in AGG_LIBS, add an option "-L/path/to/agg/library" to specify the path where the AGG libraries are located.
Please note also that the agg libraries depends on other libraries. For example on linux it needs at least the X11 library. The libraries supc++ may be needed if the linking is made by invoking gcc instead of g++ because if gcc is used the C++ runtime libraries are not included.