How to find the version number of libxxx.a - macos

I'm probably not finding the right search words, but I can't find out how to get
the version number of a static (or dynamic ) lib without writing a program. Surely there must be a unix application to do this (with equivalent on os x). (I tried the finder info, and
it told me that .a files are files to be opened by text wrangler!).
Thanks.

A static lib is just an archive of object files; it doesn't have an implicit version number. Many libraries will have an explicit version number, some symbol like FOO_VERSION_ with contents "1.2.3", but there's obviously no generic way to find any such symbols.
Dynamic libs are a different story. They have two version numbers, "current" and "compatibility". See the manpage for otool, but you can easily parse whichever one you want out of the -l (in the LC_ID_DYLIB command) or -L output (look for the library's own name).

Related

why does the order of '-Lpath/to/lib' matter?

I'm getting a linker error 'undefined reference to' when linking a library with my program. I've read this post and I understand that the order of libraries matter. Does the order of '-Lpath/to/lib' also matter? The problem i'm facing solved when I change the order of '-L..' option rather than '-l'. please shed some light.
-L controls link directories, -l for link libraries (actual files). So, by changing order of -L flags, you can cause a different library with the same filename to be selected - directories are searched by the order provided with -L (left to right)
In your case, sounds like the library file originally selected did not contain some of the functionality - that's why you got 'undefined reference to'.
In general it may be worth either using -l with full path to the specific library, or a build system (I like CMake) where you can set this as an explicit option (and maybe print the selected file in a message during build).

How to link a library by its exact name with gcc?

I am trying to generate a dynamic library target.so and to do this I need to link it dynamically to a library in which the version number appears at the end:
/path/to/library/lib_with_version_number.so.28
If the name of the library was only,
/path/to/library/lib_without_version_number.so
I can use
-L/path/to/library/ -l_without_version_number
(because I don't wan't to have the complete library path when I run ldd command).
My question is: How to do the same with the version number?
If you have an unavoidable need to link a library libfoo.a or libbar.so.x.y.z
by exactly that name, rather than by following the usually wiser -lfoo convention, you can do so by using the -l: option instead, e.g.
-l:libfoo.a -l:libbar.so.x.y.z
This choice makes no difference to the behaviour of the -L option.

"Couldn't find function symbol in library" - JS-Ctypes

My C++ Library function is int RFD_startBackgroundThread()
My code in the overlay.js is
uri = addon.getResourceURI("components/mac/libReverbFirefoxExtensionLib.dylib");
this.extensionLib = ctypes.open(uri.path);
this.startBackgroundThread = this.extensionLib.declare("RFD_startBackgroundThread", ctypes.default_abi, ctypes.unsigned_int);
The code throws an exception on the last line. It says "Couldn't find function symbol in library".
The library is a "fat dylib binary" combining both i386 and x86_64 (but not PPC arch) on OS X Lion (10.7). Firefox version 11.
Desperately need help.
Thanks.
Rahul.
In most Unix platforms, including OS X, C functions are mapped to symbols just by prefixing with an underscore, so int foo(int) ends up as just _foo.
But that doesn't work for C++, because in C++, you can have two different functions with the same name, in a variety of different ways—you can have int foo(int) and double foo(double), or int MyClass::foo(int), or int foo<int>(int), and so on. So, C++ functions have to be "mangled" to give a unique string. (And then, that unique string is treated like a C function—that is, prefixed with an "_".)
jsctypes knows about knocking off the _, but it can't know how to mangle your function, because you're just giving it a name, not a full prototype. So, you have to figure out in some other way that the mangled name of your function is _Z25RFD_startBackgroundThreadv.
There's no portable standard for how names get mangled. However, the C++ ABI that Apple uses is based on the Itanium C++ API, which requires an API to mangle and demangle C++ functions. Xcode comes with a tool called c++filt that wraps up that API for use at the command line—but it only handles demangling, not mangling. So, it can tell you that _Z25RFD_startBackgroundThreadv means RFD_startBackgroundThread(), but it can't get the other way around.
One way to get the mangled name is to start with nm libfoo.dylib, then use c++filt to check the ones that look like good candidates, until you find one that matches the prototype you're looking for.
Another way is to automate that. Something like this:
nm libfoo.dylib | awk 'NF==2 {printf "%s ",$1; system("c++filt " $2)} NF!=2{print $0}'
… will print the demangled names of all of your symbols.
But probably the best way to go about it is to create a tiny .cpp file that has nothing in it but that one prototype, compile it, and use "otool -SV tiny.a" to see the mangled name.
So, it's not that hard to get the name of the symbol for the C++ function you want to call.
But that doesn't mean you can just call it as if it were a C function. For one pretty obvious example, if you want to call (non-static) Foo::bar(int), you'd better have a valid thing to pass as a "this" pointer, and know how to pass it. See https://bugzilla.mozilla.org/show_bug.cgi?id=505907 for details on what jsctypes in Mozilla can't do, and why.
Well, the problem was, the library does not store the symbol as-is. To see the actual names of the symbols dump the library using nm library-name (optionally redirecting it to a txt file, easier to read).
The symbol in my case was written as __Z25RFD_startBackgroundThreadv. Apparently, I had to know off one underscore and use only _Z25RFD_startBackgroundThreadv.
Thanks to Michael Dautermann!

Using -Lpath -lname options vs. providing the library file directly

Recently, I got into a problem with linking and VPATH with the side effect of this question.
Assume you are implementing a library and you want to link your tests with it. You have two options (that I know of):
Using -L and -l options:
gcc main.o -Lpath/to/lib -lname
Giving the library file directly:
gcc main.o path/to/lib/libname.a
My question is, given the fact that I am linking to my own library under implementation (and not one that is installed, and therefore placed in /usr/lib for example), is there any advantage in choosing either method?
Currently I use the first method, but the second method allows me to solve the problem I had with VPATH. I am particularly interested in knowing whether there are certain caveats with the second method, before making the switch.
The only difference I can think of is that the first method allows the linker to choose a shared library if it exists. The second doesn't, because you explicitly name a .a static archive.
If you were using a shared library there is a difference: if the second form names a shared library without a soname the application would have a DT_NEEDED tag of path/to/lib/libname.so, but for the first form would have the tag with the value libname.so. (If the shared library has a soname that would be used for the DT_NEEDED tag however the path was specified.)

Size of a library and the executable

I have a static library *.lib created using MSVC on windows. The size of library is say 70KB. Then I have an application which links this library. But now the size of the final executable (*.exe) is 29KB, less than the library. What i want to know is :
Since the library is statically linked, I was thinking it should add directly to the executable size and the final exe size should be more than that? Does windows exe format also do some compression of the binary data?
How is it for linux systems, that is how do sizes of library on linux (*.a/*.la file) relate with size of linux executable (*.out) ?
-AD
A static library on both Windows and Unix is a collection of .obj/.o files. The linker looks at each of these object files and determines if it is needed for the program to link. If it isn't needed, then the object file won't get included in the final executable. This can lead to executables that are smaller then the library.
EDIT: As MSalters points out, on Windows the VC++ compiler now supports generating object files that enable function-level linking, e.g., see here. In fact, edit-and-continue requires this, since the edit-and-continue needs to be able to replace the smallest possible part of the executable.
There is additional bookkeeping information in the .lib file that is not needed for the final executable. This information helps the linker find the code to actually link. Also, debug information may be stored in the .lib file but not in the .exe file (I don't recall where debug info is stored for objs in a lib file, it might be somewhere else).
The static library probably contains several functions which are never used. When the linker links the library with the main executable, it sees that certain functions are never used (and that their addresses are never taken and stored in function pointers), it just throws away the code. It can also do this recursively: if function A() is never called, and A() calls B(), but B() is never otherwise called, it can remove the code for both A() and B(). On Linux, the same thing happens.
A static library has to contain every symbol defined in its source code, because it might get linked into an executable which needs just that specific symbol. But once it is linked into an executable, we know exactly which symbols end up being used, and which ones don't. So the linker can trivially remove unused code, trimming the file size by a lot. Similarly, any duplicate symbols (anything that's defined in both the static library and the executable it's linked into gets merged into a single instance.
Disclaimer: It's been a long time since I dealt with static linking, so take my answer with a grain of salt.
You wrote: I was thinking it should add directly to the executable size and final exe size should be more than that?
Naive linkers work exactly this way - back when I was doing hobby development for CP/M systems (a LONG time ago), this was a real problem.
Modern linkers are smarter, however - they only link in the functions referenced by the original code, or as required.
Additionally to the current answers, the linker is allowed to remove function definitions if they have identical object code - this is intended to help reduce the bloating effects of templated code.
#All: Thanks for the pointers.
#Greg Hewgill - Your answer was a good pointer. Thanks.
The answer i found out was as follows:
1.)During Library building what happens is if the option "Keep Program debug databse" in MSVC (or something alike ) is ON, then library will have this debug info bloating its size.
but when i statically include that library and create a executable, the linker strips all that debug info from the library before geenrating the exe and hence the exe size is less than that of the library.
2.) When i disabled the option "Keep Program debug databse", i got an library whose size was smaller than the final executable, which was what i thought is nromal in most situations.
-AD

Resources