Reputation: 7061
I have this problem all the time in Linux programming. As long as all the manuals and almost all the source code for Linux are C-centric, all references to some function needs only some include <something.h>
line and the function is accessible from the C/C++ code.
But I am programming in assembly language and know almost nothing about C/C++.
In order to be able to call some function, I have to import it from the corresponding .so library.
How to determine the file name of the library? It often differs from the name of the library itself and is not specified in the manuals.
For example, the name of the XLib is actually libX11.so.6
. The name of the XShm extension library seems to be libXext.so.6
.
Is there easy way to determine the secret real name of the library, using provided C manuals and references?
Upvotes: 1
Views: 3184
Reputation: 550
This is another not-100%-accurate method that may give you some ideas as to how you can narrow things down a bit. It doesn't exactly fit the question because it uses common linux utilities instead of man files, but it may still be helpful.
For example, on Arch Linux, if you were interested in a function in GLFW/glfw3.h
, you could find out who owns that file:
$ pacman -Qo /usr/include/GLFW/glfw3.h
/usr/include/GLFW/glfw3.h is owned by glfw 3.1-1
Find out which .so
files are in that package:
$ pacman -Ql glfw | grep 'so$'
glfw /usr/lib/libglfw.so
And, if needed, find the actual file that link points to:
$ readlink -f /usr/lib/libglfw.so
/usr/lib/libglfw.so.3.1
This will depend on your distribution. I believe on Ubuntu/Debian you'd use dpkg-query
instead.
Edit: DevSolar points out in a comment that you can use apt-file search <header>
and apt-file list <package>
instead of dpkg-query -S <header>
and dpkg-query -L <package>
. apt-file
appears to work even for packages that aren't installed (though it seems slower?).
I also noticed that (on my Ubuntu VM at least) that, e.g., libglfw-dev contains the libglfw.so
symlink, while libglfw2 contains the actual libglfw.so.2
object.
Once you have a set of .so
files, you can check them for whatever function you are interested in:
$ nm -D /usr/lib/libglfw.so | grep "glfwCreateWindow"
0000000000007cd0 T glfwCreateWindow
Note that I pulled this last step from a comment on the previous question and don't fully understand it. Maybe you could even skip the earlier steps and rely on nm
and grep
alone?
Upvotes: 3
Reputation: 6449
This is not a sure fire way, but it can help in many cases.
Basically, you can usually find the library name at the bottom of the man
page.
Eg, man XCreateWindow
says libX11
on the last line. Then you look for libX11.so
and use nm
or readelf
to see all exported functions.
Another example, man XShm
says libXext
at the bottom. And so on.
UPDATE
If the function is in section (2) of the man pages, it's a system call (see man man
) and is provided by glibc, which would be libc-2.??.so
.
Lastly (thanks Basile), if the function does not mention the library, it is also most likely provided by glibc.
DISCLAIMER: Again this is not a 100% accurate method -- but it should help in most cases.
Upvotes: 2
Reputation: 1
As I commented, you could use gcc
to link your program, and then it should be able to accept -lX11
; by using gcc -v
instead of gcc
you'll find out what is actually linked and how.
However, you have a much more significant issue than finding the lib*.so.*
; most C or C++ APIs are described in header files, and these C or C++ header files also contain symbolic constants (like O_RDONLY
for open(2)...) or macros (like WIFEXITED
in POSIX wait ...) whose value or expansion you should manually find in header files or documentations. (Quite often, such constants are either preprocessor #define
-d constants or enum
values). Also, some headers -in particular in C++- contains a lot of inline
-d functions (or macros)!
A possible way might be to generate some C files to find all these constants, enums, macros, inlined functions..., and/or to customize the GCC compiler (e.g. with MELT ...) to find them.
So my message is that for better or worse, the C language is deeply tied to Linux & POSIX.
You might restrict yourself to use only syscalls(2) from your assembler code. Then you won't use libX11
and you don't need any header or constant (except the ones for syscalls, starting from <asm/unistd.h>
).
BTW, in 2015, coding entirely in assembler for performance reasons is a mistake. The compiler is generating better code than you reasonably can (as soon as you have more than a few hundred machine instructions). In practice, you can code in assembler with GCC by using extended asm
instructions in your C functions.
Or are you building your own compiler ? Then you should have told so in your question!
Read also the Program Library HowTo & the Linux Assembly HowTo
Upvotes: 0
Reputation: 44063
You can ask gcc
to tell you which file it would use for linking like so:
gcc --print-file-name=libX11.so
Sample output:
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libX11.so
This file will usually be a symlink, so you'll have to pipe it through readlink
or realpath
to get the actual file. For example:
readlink -f $(gcc --print-file-name=libXext.so)
Sample output:
/usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
Upvotes: 0